diff --git a/clients/aurorae/src/CMakeLists.txt b/clients/aurorae/src/CMakeLists.txt
index 2a3754cfa7..cee7f85397 100644
--- a/clients/aurorae/src/CMakeLists.txt
+++ b/clients/aurorae/src/CMakeLists.txt
@@ -3,9 +3,6 @@ include_directories( ./lib )
set(kwin3_aurorae_PART_SRCS
aurorae.cpp
- lib/auroraebutton.cpp
- lib/auroraescene.cpp
- lib/auroraetab.cpp
lib/auroraetheme.cpp
lib/themeconfig.cpp
)
@@ -20,3 +17,11 @@ install(TARGETS kwin3_aurorae DESTINATION ${PLUGIN_INSTALL_DIR} )
install( FILES aurorae.desktop DESTINATION ${DATA_INSTALL_DIR}/kwin )
install( FILES aurorae.knsrc DESTINATION ${CONFIG_INSTALL_DIR} )
+install( FILES
+ qml/aurorae.qml
+ qml/AuroraeButton.qml
+ qml/AuroraeButtonGroup.qml
+ qml/Decoration.qml
+ qml/DecorationButton.qml
+ qml/MenuButton.qml
+ DESTINATION ${DATA_INSTALL_DIR}/kwin/aurorae )
diff --git a/clients/aurorae/src/aurorae.cpp b/clients/aurorae/src/aurorae.cpp
index 5bb24f8469..8fbf96d3b5 100644
--- a/clients/aurorae/src/aurorae.cpp
+++ b/clients/aurorae/src/aurorae.cpp
@@ -16,17 +16,16 @@ along with this program. If not, see .
*********************************************************************/
#include "aurorae.h"
-#include "auroraescene.h"
#include "auroraetheme.h"
#include
-#include
-#include
-#include
#include
+#include
+#include
#include
#include
+#include
#include
namespace Aurorae
@@ -135,46 +134,15 @@ AuroraeFactory *AuroraeFactory::s_instance = NULL;
*******************************************************/
AuroraeClient::AuroraeClient(KDecorationBridge *bridge, KDecorationFactory *factory)
: KDecorationUnstable(bridge, factory)
- , m_clickInProgress(false)
{
- m_scene = new AuroraeScene(AuroraeFactory::instance()->theme(),
- options()->customButtonPositions() ? options()->titleButtonsLeft() : AuroraeFactory::instance()->theme()->defaultButtonsLeft(),
- options()->customButtonPositions() ? options()->titleButtonsRight() : AuroraeFactory::instance()->theme()->defaultButtonsRight(),
- providesContextHelp(), NULL);
- connect(m_scene, SIGNAL(closeWindow()), SLOT(closeWindow()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(maximize(Qt::MouseButtons)), SLOT(maximize(Qt::MouseButtons)), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(showContextHelp()), SLOT(showContextHelp()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(minimizeWindow()), SLOT(minimize()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(menuClicked()), SLOT(menuClicked()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(menuDblClicked()), SLOT(closeWindow()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(toggleOnAllDesktops()), SLOT(toggleOnAllDesktops()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(toggleShade()), SLOT(toggleShade()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(toggleKeepAbove()), SLOT(toggleKeepAbove()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(toggleKeepBelow()), SLOT(toggleKeepBelow()), Qt::QueuedConnection);
- connect(m_scene, SIGNAL(titlePressed(Qt::MouseButton,Qt::MouseButtons)),
- SLOT(titlePressed(Qt::MouseButton,Qt::MouseButtons)));
- connect(m_scene, SIGNAL(titleReleased(Qt::MouseButton,Qt::MouseButtons)),
- SLOT(titleReleased(Qt::MouseButton,Qt::MouseButtons)));
- connect(m_scene, SIGNAL(titleDoubleClicked()), SLOT(titlebarDblClickOperation()));
- connect(m_scene, SIGNAL(titleMouseMoved(Qt::MouseButton,Qt::MouseButtons)),
- SLOT(titleMouseMoved(Qt::MouseButton,Qt::MouseButtons)));
- connect(m_scene, SIGNAL(wheelEvent(int)), SLOT(titlebarMouseWheelOperation(int)));
- connect(m_scene, SIGNAL(tabMouseButtonPress(QGraphicsSceneMouseEvent*,int)),
- SLOT(tabMouseButtonPress(QGraphicsSceneMouseEvent*,int)));
- connect(m_scene, SIGNAL(tabMouseButtonRelease(QGraphicsSceneMouseEvent*,int)),
- SLOT(tabMouseButtonRelease(QGraphicsSceneMouseEvent*,int)));
- connect(m_scene, SIGNAL(tabRemoved(int)), SLOT(tabRemoved(int)));
- connect(m_scene, SIGNAL(tabMoved(int,int)), SLOT(tabMoved(int,int)));
- connect(m_scene, SIGNAL(tabMovedToGroup(long int,int)), SLOT(tabMovedToGroup(long int,int)));
- connect(this, SIGNAL(keepAboveChanged(bool)), SLOT(slotKeepAboveChanged(bool)));
- connect(this, SIGNAL(keepBelowChanged(bool)), SLOT(slotKeepBelowChanged(bool)));
+ connect(this, SIGNAL(keepAboveChanged(bool)), SIGNAL(keepAboveChangedWrapper()));
+ connect(this, SIGNAL(keepBelowChanged(bool)), SIGNAL(keepBelowChangedWrapper()));
}
AuroraeClient::~AuroraeClient()
{
m_view->setParent(NULL);
m_view->deleteLater();
- m_scene->deleteLater();
}
void AuroraeClient::init()
@@ -187,7 +155,6 @@ void AuroraeClient::init()
createMainWidget();
widget()->setAttribute(Qt::WA_TranslucentBackground);
widget()->setAttribute(Qt::WA_NoSystemBackground);
- widget()->installEventFilter(this);
m_view = new QDeclarativeView(widget());
m_view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
m_view->setAttribute(Qt::WA_TranslucentBackground);
@@ -198,58 +165,46 @@ void AuroraeClient::init()
QPalette pal2 = widget()->palette();
pal2.setColor(widget()->backgroundRole(), Qt::transparent);
widget()->setPalette(pal2);
+
+ // setup the QML engine
+ foreach (const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) {
+ m_view->engine()->addImportPath(importPath);
+ }
m_view->rootContext()->setContextProperty("decoration", this);
- // scene initialisation
- m_scene->setActive(isActive(), false);
- m_scene->setIcon(icon());
- m_scene->setAllDesktops(isOnAllDesktops());
- m_scene->setMaximizeMode(options()->moveResizeMaximizedWindows() ? MaximizeRestore : maximizeMode());
- m_scene->setShade(isShade());
- m_scene->setKeepAbove(keepAbove());
- m_scene->setKeepBelow(keepBelow());
- m_scene->setFont(KDecoration::options()->font(true), true);
- m_scene->setFont(KDecoration::options()->font(false), false);
+ m_view->rootContext()->setContextProperty("auroraeTheme", AuroraeFactory::instance()->theme());
+ m_view->setSource(QUrl(KStandardDirs::locate("data", "kwin/aurorae/aurorae.qml")));
AuroraeFactory::instance()->theme()->setCompositingActive(compositingActive());
}
void AuroraeClient::activeChange()
{
- if (m_scene->isActive() != isActive()) {
- m_scene->setActive(isActive());
- }
emit activeChanged();
}
void AuroraeClient::captionChange()
{
- checkTabs(true);
emit captionChanged();
}
void AuroraeClient::iconChange()
{
- m_scene->setIcon(icon());
emit iconChanged();
}
void AuroraeClient::desktopChange()
{
- m_scene->setAllDesktops(isOnAllDesktops());
emit desktopChanged();
}
void AuroraeClient::maximizeChange()
{
if (!options()->moveResizeMaximizedWindows()) {
- m_scene->setMaximizeMode(maximizeMode());
+ emit maximizeChanged();
}
- emit maximizeChanged();
}
void AuroraeClient::resize(const QSize &s)
{
- m_scene->setSceneRect(QRectF(QPoint(0, 0), s));
- m_scene->updateLayout();
m_view->resize(s);
widget()->resize(s);
updateWindowShape();
@@ -257,19 +212,31 @@ void AuroraeClient::resize(const QSize &s)
void AuroraeClient::shadeChange()
{
- m_scene->setShade(isShade());
emit shadeChanged();
}
void AuroraeClient::borders(int &left, int &right, int &top, int &bottom) const
{
const bool maximized = maximizeMode() == MaximizeFull && !options()->moveResizeMaximizedWindows();
- AuroraeFactory::instance()->theme()->borders(left, top, right, bottom, maximized);
+ if (maximized) {
+ left = m_view->rootObject()->property("borderLeftMaximized").toInt();
+ right = m_view->rootObject()->property("borderRightMaximized").toInt();
+ top = m_view->rootObject()->property("borderTopMaximized").toInt();
+ bottom = m_view->rootObject()->property("borderBottomMaximized").toInt();
+ } else {
+ left = m_view->rootObject()->property("borderLeft").toInt();
+ right = m_view->rootObject()->property("borderRight").toInt();
+ top = m_view->rootObject()->property("borderTop").toInt();
+ bottom = m_view->rootObject()->property("borderBottom").toInt();
+ }
}
void AuroraeClient::padding(int &left, int &right, int &top, int &bottom) const
{
- AuroraeFactory::instance()->theme()->padding(left, top, right, bottom);
+ left = m_view->rootObject()->property("paddingLeft").toInt();
+ right = m_view->rootObject()->property("paddingRight").toInt();
+ top = m_view->rootObject()->property("paddingTop").toInt();
+ bottom = m_view->rootObject()->property("paddingBottom").toInt();
}
QSize AuroraeClient::minimumSize() const
@@ -330,12 +297,10 @@ void AuroraeClient::reset(long unsigned int changed)
AuroraeFactory::instance()->theme()->setCompositingActive(compositingActive());
}
if (changed & SettingButtons) {
- m_scene->setButtons(options()->customButtonPositions() ? options()->titleButtonsLeft() : AuroraeFactory::instance()->theme()->defaultButtonsLeft(),
- options()->customButtonPositions() ? options()->titleButtonsRight() : AuroraeFactory::instance()->theme()->defaultButtonsRight());
+ // TODO: update buttons
}
if (changed & SettingFont) {
- m_scene->setFont(KDecoration::options()->font(true), true);
- m_scene->setFont(KDecoration::options()->font(false), false);
+ // TODO: set font
}
KDecoration::reset(changed);
}
@@ -350,22 +315,6 @@ void AuroraeClient::toggleShade()
setShade(!isShade());
}
-void AuroraeClient::slotKeepAboveChanged(bool above)
-{
- if (above && m_scene->isKeepBelow()) {
- m_scene->setKeepBelow(false);
- }
- m_scene->setKeepAbove(above);
-}
-
-void AuroraeClient::slotKeepBelowChanged(bool below)
-{
- if (below && m_scene->isKeepAbove()) {
- m_scene->setKeepAbove(false);
- }
- m_scene->setKeepBelow(below);
-}
-
void AuroraeClient::toggleKeepAbove()
{
setKeepAbove(!keepAbove());
@@ -447,72 +396,6 @@ void AuroraeClient::titleMouseMoved(Qt::MouseButton button, Qt::MouseButtons but
event = 0;
}
-void AuroraeClient::checkTabs(bool force)
-{
- if (m_scene->tabCount() == 1 && clientGroupItems().count() == 1 && !force) {
- return;
- }
- while (m_scene->tabCount() < clientGroupItems().count()) {
- m_scene->addTab(QString());
- }
- while (m_scene->tabCount() > clientGroupItems().count()) {
- m_scene->removeLastTab();
- }
- QList data;
- foreach (const ClientGroupItem &item, clientGroupItems()) {
- data << AuroraeTabData(item.title(), item.icon());
- }
- m_scene->setAllTabData(data);
- m_scene->setFocusedTab(visibleClientGroupItem());
-}
-
-bool AuroraeClient::eventFilter(QObject *o, QEvent *e)
-{
- if (o != widget()) {
- return false;
- }
- if (e->type() == QEvent::Paint) {
- checkTabs();
- }
- return false;
-}
-
-void AuroraeClient::tabMouseButtonPress(QGraphicsSceneMouseEvent *e, int index)
-{
- if (buttonToWindowOperation(e->buttons()) == OperationsOp) {
- displayClientMenu(index, e->screenPos());
- return;
- } else if (buttonToWindowOperation(e->buttons()) == ClientGroupDragOp) {
- m_scene->setUniqueTabDragId(index, itemId(index));
- }
- titlePressed(e->button(), e->buttons());
- m_clickInProgress = true;
-}
-
-void AuroraeClient::tabMouseButtonRelease(QGraphicsSceneMouseEvent *e, int index)
-{
- if (m_clickInProgress) {
- setVisibleClientGroupItem(index);
- }
- titleReleased(e->button(), e->buttons());
- m_clickInProgress = false;
-}
-
-void AuroraeClient::tabRemoved(int index)
-{
- removeFromClientGroup(index);
-}
-
-void AuroraeClient::tabMoved(int index, int before)
-{
- moveItemInClientGroup(index, before);
-}
-
-void AuroraeClient::tabMovedToGroup(long int uid, int before)
-{
- moveItemToClientGroup(uid, before);
-}
-
QString AuroraeClient::rightButtons() const
{
// TODO: make independent of Aurorae
diff --git a/clients/aurorae/src/aurorae.h b/clients/aurorae/src/aurorae.h
index 993505bbda..9052ba0e50 100644
--- a/clients/aurorae/src/aurorae.h
+++ b/clients/aurorae/src/aurorae.h
@@ -30,7 +30,6 @@ class QGraphicsScene;
namespace Aurorae
{
class AuroraeTheme;
-class AuroraeScene;
class AuroraeFactory : public QObject, public KDecorationFactoryUnstable
{
@@ -77,8 +76,8 @@ class AuroraeClient : public KDecorationUnstable
Q_PROPERTY(bool setShade READ isSetShade NOTIFY shadeChanged)
Q_PROPERTY(bool shade READ isShade WRITE setShade NOTIFY shadeChanged)
Q_PROPERTY(bool shadeable READ isShadeable)
- Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged)
- Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged)
+ Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChangedWrapper)
+ Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChangedWrapper)
// TODO: maximize mode
Q_PROPERTY(bool providesContextHelp READ providesContextHelp)
Q_PROPERTY(QRect transparentRect READ transparentRect)
@@ -114,14 +113,12 @@ Q_SIGNALS:
void iconChanged();
void maximizeChanged();
void shadeChanged();
- void keepAboveChanged();
- void keepBelowChanged();
+ void keepAboveChangedWrapper();
+ void keepBelowChangedWrapper();
public slots:
void menuClicked();
void toggleShade();
- void slotKeepAboveChanged(bool above);
- void slotKeepBelowChanged(bool below);
void toggleKeepAbove();
void toggleKeepBelow();
void titlePressed(int button, int buttons);
@@ -130,21 +127,10 @@ public slots:
void titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons);
void titleReleased(Qt::MouseButton button, Qt::MouseButtons buttons);
void titleMouseMoved(Qt::MouseButton button, Qt::MouseButtons buttons);
- void tabMouseButtonPress(QGraphicsSceneMouseEvent *e, int index);
- void tabMouseButtonRelease(QGraphicsSceneMouseEvent *e, int index);
- void tabRemoved(int index);
- void tabMoved(int index, int before);
- void tabMovedToGroup(long int uid, int before);
-
-protected:
- virtual bool eventFilter(QObject *o, QEvent *e);
private:
void updateWindowShape();
- void checkTabs(bool force = false);
- AuroraeScene *m_scene;
QDeclarativeView *m_view;
- bool m_clickInProgress;
};
}
diff --git a/clients/aurorae/src/qml/AuroraeButton.qml b/clients/aurorae/src/qml/AuroraeButton.qml
new file mode 100644
index 0000000000..190d4b12b9
--- /dev/null
+++ b/clients/aurorae/src/qml/AuroraeButton.qml
@@ -0,0 +1,329 @@
+/********************************************************************
+Copyright (C) 2012 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+
+DecorationButton {
+ function widthForButton() {
+ switch (buttonType) {
+ case "M":
+ // menu
+ return auroraeTheme.buttonWidthMenu;
+ case "S":
+ // all desktops
+ return auroraeTheme.buttonWidthAllDesktops;
+ case "H":
+ // help
+ return auroraeTheme.buttonWidthHelp;
+ case "I":
+ // minimize
+ return auroraeTheme.buttonWidthMinimize;
+ case "A":
+ // maximize
+ return auroraeTheme.buttonWidthMaximizeRestore;
+ case "X":
+ // close
+ return auroraeTheme.buttonWidthClose;
+ case "F":
+ // keep above
+ return auroraeTheme.buttonWidthKeepAbove;
+ case "B":
+ // keep below
+ return auroraeTheme.buttonWidthKeepBelow;
+ case "L":
+ // shade
+ return auroraeTheme.buttonWidthShade;
+ default:
+ return auroraeTheme.buttonWidth;
+ }
+ }
+ function pathForButton() {
+ switch (buttonType) {
+ case "S":
+ // all desktops
+ return auroraeTheme.allDesktopsButtonPath;
+ case "H":
+ // help
+ return auroraeTheme.helpButtonPath;
+ case "I":
+ // minimize
+ return auroraeTheme.minimizeButtonPath;
+ case "A":
+ // maximize
+ return auroraeTheme.maximizeButtonPath;
+ case "X":
+ // close
+ return auroraeTheme.closeButtonPath;
+ case "F":
+ // keep above
+ return auroraeTheme.keepAboveButtonPath;
+ case "B":
+ // keep below
+ return auroraeTheme.keepBelowButtonPath;
+ case "L":
+ // shade
+ return auroraeTheme.shadeButtonPath;
+ default:
+ return "";
+ }
+ }
+ function toggledPressedStatusChange() {
+ if (pressed || toggled) {
+ // pressed comes after hovered (if supported)
+ if (!decoration.active && buttonSvg.supportsInactivePressed) {
+ // if inactive and the buttons supports pressed, we use it
+ // in case we have an inactive-hover but no pressed we stay in hovered state
+ state = "inactive-pressed";
+ } else if (decoration.active && state != "inactive-hover" && buttonSvg.supportsPressed) {
+ state = "active-pressed";
+ }
+ } else {
+ if (!decoration.active && hovered && buttonSvg.supportsInactiveHover) {
+ state = "inactive-hover";
+ } else if (!decoration.active && buttonSvg.supportsInactive) {
+ state = "inactive";
+ } else if (hovered && buttonSvg.supportsHover) {
+ state = "active-hover";
+ } else {
+ state = "active";
+ }
+ }
+ }
+ width: widthForButton() * auroraeTheme.buttonSizeFactor
+ height: auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor
+ PlasmaCore.FrameSvg {
+ property bool supportsHover: hasElementPrefix("hover")
+ property bool supportsPressed: hasElementPrefix("pressed")
+ property bool supportsDeactivated: hasElementPrefix("deactivated")
+ property bool supportsInactive: hasElementPrefix("inactive")
+ property bool supportsInactiveHover: hasElementPrefix("hover-inactive")
+ property bool supportsInactivePressed: hasElementPrefix("pressed-inactive")
+ property bool supportsInactiveDeactivated: hasElementPrefix("deactivated-inactive")
+ id: buttonSvg
+ imagePath: pathForButton()
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonActive
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "active"
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonActiveHover
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "hover"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonActivePressed
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "pressed"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonActiveDeactivated
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "deactivated"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonInactive
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "inactive"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonInactiveHover
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "hover-inactive"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonInactivePressed
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "pressed-inactive"
+ opacity: 0
+ }
+ PlasmaCore.FrameSvgItem {
+ id: buttonInactiveDeactivated
+ anchors.fill: parent
+ imagePath: buttonSvg.imagePath
+ prefix: "deactivated-inactive"
+ opacity: 0
+ }
+ Component.onCompleted: {
+ if (!decoration.active && !enabled && buttonSvg.supportsInactiveDeactivated) {
+ state = "inactive-deactivated";
+ } else if (!enabled && buttonSvg.supportsDeactivated) {
+ state = "active-deactivated";
+ } else if (!decoration.active && (toggled || pressed) && buttonSvg.supportsInactivePressed) {
+ state = "inactive-pressed";
+ } else if ((toggled || pressed) && buttonSvg.supportsPressed) {
+ state = "active-pressed";
+ } else if (!decoration.active && buttonSvg.supportsInactive) {
+ state = "inactive";
+ } else {
+ state = "active";
+ }
+ if (buttonType == "H" && !decoration.providesContextHelp) {
+ visible = false;
+ } else {
+ visible = buttonSvg.imagePath != "";
+ }
+ }
+ onHoveredChanged: {
+ if (state == "active-pressed" || state == "inactive-pressed") {
+ // state change of hovered does not matter as the button is currently pressed
+ return;
+ }
+ if (hovered) {
+ if (state == "active" && buttonSvg.supportsHover) {
+ state = "active-hover";
+ } else if (state == "inactive" && buttonSvg.supportsInactiveHover) {
+ state = "inactive-hover";
+ }
+ } else {
+ if (!decoration.active && buttonSvg.supportsInactive) {
+ state = "inactive";
+ } else {
+ state = "active";
+ }
+ }
+ }
+ onPressedChanged: toggledPressedStatusChange()
+ onToggledChanged: toggledPressedStatusChange()
+ states: [
+ State { name: "active" },
+ State { name: "active-hover" },
+ State { name: "active-pressed" },
+ State { name: "active-deactivated" },
+ State { name: "inactive" },
+ State { name: "inactive-hover" },
+ State { name: "inactive-pressed" },
+ State { name: "inactive-deactivated" }
+ ]
+ transitions: [
+ Transition {
+ to: "active"
+ // Cross fade from somewhere to active
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "active-hover"
+ // Cross fade from active to hover
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActiveHover; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "active-pressed"
+ // Cross fade to pressed state
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActivePressed; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "inactive"
+ // Cross fade from hover/pressed/active to inactive
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "inactive-hover"
+ // Cross fade from inactive to hover
+ ParallelAnimation {
+ NumberAnimation { target: buttonActiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveHover; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "inactive-pressed"
+ // Cross fade to inactive pressed state
+ ParallelAnimation {
+ NumberAnimation { target: buttonActivePressed; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveHover; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactivePressed; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "active-deactivated"
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActiveDeactivated; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveDeactivated; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "inactive-deactivated"
+ ParallelAnimation {
+ NumberAnimation { target: buttonActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonActiveDeactivated; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: buttonInactiveDeactivated; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ }
+ }
+ ]
+ Connections {
+ target: decoration
+ onActiveChanged: {
+ if (!decoration.active && !enabled && buttonSvg.supportsInactiveDeactivated) {
+ state = "inactive-deactivated";
+ } else if (!enabled && buttonSvg.supportsDeactivated) {
+ state = "active-deactivated";
+ } else if (!decoration.active && (pressed || toggled) && buttonSvg.supportsInactivePressed) {
+ state = "inactive-pressed";
+ } else if (!decoration.active && hovered && buttonSvg.supportsInactiveHover) {
+ state = "inactive-hover";
+ } else if (!decoration.active && buttonSvg.supportsInactive) {
+ state = "inactive";
+ } else if ((pressed || toggled) && buttonSvg.supportsPressed) {
+ state = "active-pressed";
+ } else if (hovered && buttonSvg.supportsHover) {
+ state = "active-hover";
+ } else {
+ state = "active";
+ }
+ }
+ }
+}
diff --git a/clients/aurorae/src/qml/AuroraeButtonGroup.qml b/clients/aurorae/src/qml/AuroraeButtonGroup.qml
new file mode 100644
index 0000000000..ee92139d8b
--- /dev/null
+++ b/clients/aurorae/src/qml/AuroraeButtonGroup.qml
@@ -0,0 +1,42 @@
+/********************************************************************
+Copyright (C) 2012 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+
+Item {
+ id: group
+ property string buttons
+
+ Component.onCompleted: {
+ var component = Qt.createComponent("AuroraeButton.qml");
+ for (var i=0; i
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+
+Item {
+ property int paddingLeft
+ property int paddingRight
+ property int paddingTop
+ property int paddingBottom
+ property int borderLeft
+ property int borderRight
+ property int borderTop
+ property int borderBottom
+ property int borderLeftMaximized
+ property int borderRightMaximized
+ property int borderTopMaximized
+ property int borderBottomMaximized
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onPositionChanged: decoration.titleMouseMoved(mouse.button, mouse.buttons)
+ }
+}
diff --git a/clients/aurorae/src/qml/DecorationButton.qml b/clients/aurorae/src/qml/DecorationButton.qml
new file mode 100644
index 0000000000..f857986f83
--- /dev/null
+++ b/clients/aurorae/src/qml/DecorationButton.qml
@@ -0,0 +1,147 @@
+/********************************************************************
+Copyright (C) 2012 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+
+Item {
+ id: button
+ property string buttonType : ""
+ property bool hovered: false
+ property bool pressed: false
+ property bool toggled: false
+ enabled: {
+ switch (button.buttonType) {
+ case "X":
+ return decoration.closeable;
+ case "A":
+ return decoration.maximizeable;
+ case "I":
+ return decoration.minimizeable;
+ case "_":
+ return false;
+ default:
+ return true;
+ }
+ }
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: {
+ switch (button.buttonType) {
+ case "M":
+ return Qt.LeftButton | Qt.RightButton;
+ case "A":
+ return Qt.LeftButton | Qt.RightButton | Qt.MiddleButton;
+ default:
+ return Qt.LeftButton;
+ }
+ }
+ hoverEnabled: true
+ onEntered: button.hovered = true
+ onPositionChanged: decoration.titleMouseMoved(mouse.button, mouse.buttons)
+ onExited: button.hovered = false
+ onPressed: button.pressed = true
+ onReleased: button.pressed = false
+ onClicked: {
+ switch (button.buttonType) {
+ case "M":
+ // menu
+ decoration.menuClicked();
+ break;
+ case "S":
+ // all desktops
+ decoration.toggleOnAllDesktops();
+ break;
+ case "H":
+ // help
+ decoration.showContextHelp();
+ break;
+ case "I":
+ // minimize
+ decoration.minimize();
+ break;
+ case "A":
+ // maximize
+ decoration.maximize(mouse.buttons);
+ break;
+ case "X":
+ // close
+ decoration.closeWindow();
+ break;
+ case "F":
+ // keep above
+ decoration.toggleKeepAbove();
+ break;
+ case "B":
+ // keep below
+ decoration.toggleKeepBelow();
+ break;
+ case "L":
+ // shade
+ decoration.toggleShade();
+ break;
+ }
+ }
+ onDoubleClicked: {
+ if (button.buttonType == "M") {
+ decoration.closeWindow();
+ }
+ }
+ Component.onCompleted: {
+ switch (button.buttonType) {
+ case "S":
+ // all desktops
+ button.toggled = decoration.onAllDesktops;
+ break;
+ case "F":
+ button.toggled = decoration.keepAbove;
+ break;
+ case "B":
+ button.toggled = decoration.keepBelow;
+ break;
+ case "L":
+ button.toggled = decoration.shade;
+ break;
+ }
+ }
+ Connections {
+ target: decoration
+ onShadeChanged: {
+ if (button.buttonType != "L") {
+ return;
+ }
+ button.toggled = decoration.shade;
+ }
+ onKeepBelowChanged: {
+ if (button.buttonType != "B") {
+ return;
+ }
+ button.toggled = decoration.keepBelow;
+ }
+ onKeepAboveChanged: {
+ if (button.buttonType != "F") {
+ return;
+ }
+ button.toggled = decoration.keepAbove;
+ }
+ onDesktopChanged: {
+ if (button.buttonType != "S") {
+ return;
+ }
+ button.toggled = decoration.onAllDesktops;
+ }
+ }
+ }
+}
diff --git a/clients/aurorae/src/qml/MenuButton.qml b/clients/aurorae/src/qml/MenuButton.qml
new file mode 100644
index 0000000000..186df8111e
--- /dev/null
+++ b/clients/aurorae/src/qml/MenuButton.qml
@@ -0,0 +1,26 @@
+/********************************************************************
+Copyright (C) 2012 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+import org.kde.qtextracomponents 0.1 as QtExtra
+
+DecorationButton {
+ buttonType: "M"
+ QtExtra.QIconItem {
+ icon: decoration.icon
+ anchors.fill: parent
+ }
+}
diff --git a/clients/aurorae/src/qml/aurorae.qml b/clients/aurorae/src/qml/aurorae.qml
new file mode 100644
index 0000000000..131d9f607b
--- /dev/null
+++ b/clients/aurorae/src/qml/aurorae.qml
@@ -0,0 +1,143 @@
+/********************************************************************
+Copyright (C) 2012 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+
+Decoration {
+ id: root
+ borderLeft: auroraeTheme.borderLeft
+ borderRight: auroraeTheme.borderRight
+ borderTop: auroraeTheme.borderTop
+ borderBottom: auroraeTheme.borderBottom
+ borderLeftMaximized: auroraeTheme.borderLeftMaximized
+ borderRightMaximized: auroraeTheme.borderRightMaximized
+ borderBottomMaximized: auroraeTheme.borderBottomMaximized
+ borderTopMaximized: auroraeTheme.borderTopMaximized
+ paddingLeft: auroraeTheme.paddingLeft
+ paddingRight: auroraeTheme.paddingRight
+ paddingBottom: auroraeTheme.paddingBottom
+ paddingTop: auroraeTheme.paddingTop
+ Component.onCompleted: {
+ if (decoration.active) {
+ root.state = "active";
+ } else {
+ if (backgroundSvg.supportsInactive) {
+ root.state = "inactive";
+ } else {
+ root.state = "active";
+ }
+ }
+ }
+ PlasmaCore.FrameSvg {
+ property bool supportsInactive: hasElementPrefix("decoration-inactive")
+ id: backgroundSvg
+ imagePath: auroraeTheme.decorationPath
+ }
+ PlasmaCore.FrameSvgItem {
+ id: decorationActive
+ anchors.fill: parent
+ imagePath: backgroundSvg.imagePath
+ prefix: "decoration"
+ }
+ PlasmaCore.FrameSvgItem {
+ id: decorationInactive
+ anchors.fill: parent
+ imagePath: backgroundSvg.imagePath
+ prefix: "decoration-inactive"
+ opacity: 0
+ }
+ AuroraeButtonGroup {
+ id: leftButtonGroup
+ buttons: decoration.leftButtons
+ width: childrenRect.width
+ anchors {
+ top: parent.top
+ left: parent.left
+ leftMargin: auroraeTheme.titleEdgeLeft + root.paddingLeft
+ topMargin: root.paddingTop + auroraeTheme.titleEdgeTop + auroraeTheme.buttonMarginTop
+ }
+ }
+ AuroraeButtonGroup {
+ id: rightButtonGroup
+ buttons: decoration.rightButtons
+ width: childrenRect.width
+ anchors {
+ top: parent.top
+ right: parent.right
+ rightMargin: auroraeTheme.titleEdgeRight + root.paddingRight
+ topMargin: root.paddingTop + auroraeTheme.titleEdgeTop + auroraeTheme.buttonMarginTop
+ }
+ }
+ Text {
+ id: caption
+ text: decoration.caption
+ horizontalAlignment: auroraeTheme.horizontalAlignment
+ verticalAlignment: auroraeTheme.verticalAlignment
+ elide: Text.ElideRight
+ anchors {
+ left: leftButtonGroup.right
+ right: rightButtonGroup.left
+ top: root.top
+ topMargin: root.paddingTop + auroraeTheme.titleEdgeTop
+ leftMargin: auroraeTheme.titleBorderLeft
+ rightMargin: auroraeTheme.titleBorderRight
+ }
+ MouseArea {
+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
+ anchors.fill: parent
+ onDoubleClicked: decoration.titlebarDblClickOperation()
+ onPressed: decoration.titlePressed(mouse.button, mouse.buttons)
+ onReleased: decoration.titleReleased(mouse.button, mouse.buttons)
+ }
+ }
+ states: [
+ State { name: "active" },
+ State { name: "inactive" }
+ ]
+ transitions: [
+ Transition {
+ to: "active"
+ // Cross fade from inactive to active
+ ParallelAnimation {
+ NumberAnimation { target: decorationActive; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: decorationInactive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ ColorAnimation { target: caption; property: "color"; to: auroraeTheme.activeTextColor; duration: auroraeTheme.animationTime }
+ }
+ },
+ Transition {
+ to: "inactive"
+ // Cross fade from active to inactive
+ ParallelAnimation {
+ NumberAnimation { target: decorationActive; property: "opacity"; to: 0; duration: auroraeTheme.animationTime }
+ NumberAnimation { target: decorationInactive; property: "opacity"; to: 1; duration: auroraeTheme.animationTime }
+ ColorAnimation { target: caption; property: "color"; to: auroraeTheme.inactiveTextColor; duration: auroraeTheme.animationTime }
+ }
+ }
+ ]
+ Connections {
+ target: decoration
+ onActiveChanged: {
+ if (decoration.active) {
+ root.state = "active";
+ } else {
+ if (backgroundSvg.supportsInactive) {
+ root.state = "inactive";
+ }
+ }
+ }
+ }
+}