summaryrefslogtreecommitdiffstats
path: root/client/dominoclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/dominoclient.cpp')
-rw-r--r--client/dominoclient.cpp1195
1 files changed, 1195 insertions, 0 deletions
diff --git a/client/dominoclient.cpp b/client/dominoclient.cpp
new file mode 100644
index 0000000..4fee0cd
--- /dev/null
+++ b/client/dominoclient.cpp
@@ -0,0 +1,1195 @@
+/*
+ Copyright (C) 2006 Michael Lentner <michaell@gmx.net>
+
+ based on KDE2 Default KWin client:
+ Copyright (C) 1999, 2001 Daniel Duley <mosfet@kde.org>
+ Matthias Ettrich <ettrich@kde.org>
+ Karol Szwed <gallium@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include "dominoclient.h"
+#include "clientData.h"
+
+#include <kconfig.h>
+#include <kglobal.h>
+#include <qlayout.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <X11/extensions/shape.h>
+#include <qwmatrix.h>
+#include <qpainter.h>
+#include <qsettings.h>
+
+
+namespace Domino
+{
+
+static DominoHandler* clientHandler;
+static bool Domino_initialized = false;
+const int titleEdgeTop = 3;
+const int titleEdgeBottom = 1;
+static int titleHeight;
+
+static QPixmap* buttonPix;
+static QPixmap* buttonHidePix;
+static QPixmap* titleBarPix;
+static QPixmap* borderTopLeftPix;
+static QPixmap* borderTopRightPix;
+static QPixmap* borderBottomPix;
+static QPixmap* borderBottomLeftPix;
+static QPixmap* borderBottomRightPix;
+static QPixmap* borderLeftPix;
+static QPixmap* borderRightPix;
+
+
+static QPixmap* closeButtonIcon;
+static QPixmap* minButtonIcon;
+static QPixmap* maxButtonIcon;
+static QPixmap* helpButtonIcon;
+static QPixmap* onAllDesktopsButtonIcon;
+static QPixmap* shadeButtonIcon;
+static QPixmap* aboveButtonIcon;
+static QPixmap* belowButtonIcon;
+
+static QPixmap* pressedCloseButtonIcon;
+static QPixmap* pressedMinButtonIcon;
+static QPixmap* pressedMaxButtonIcon;
+static QPixmap* pressedHelpButtonIcon;
+static QPixmap* pressedOnAllDesktopsButtonIcon;
+static QPixmap* pressedShadeButtonIcon;
+static QPixmap* pressedAboveButtonIcon;
+static QPixmap* pressedBelowButtonIcon;
+
+static QPixmap* mouseOverCloseButtonIcon;
+static QPixmap* mouseOverMinButtonIcon;
+static QPixmap* mouseOverMaxButtonIcon;
+static QPixmap* mouseOverHelpButtonIcon;
+static QPixmap* mouseOverOnAllDesktopsButtonIcon;
+static QPixmap* mouseOverShadeButtonIcon;
+static QPixmap* mouseOverAboveButtonIcon;
+static QPixmap* mouseOverBelowButtonIcon;
+
+static bool buttonInputShape;
+static QBitmap* buttonShapeBitmap;
+
+static QColor background;
+static QColor topGradientColor;
+static QColor bottomGradientColor;
+static QColor topBorderGradientColor;
+static QColor bottomBorderGradientColor;
+static bool showButtonIcons;
+static bool showInactiveButtons;
+
+const int titleGradientHeight = 10;
+const int bottomBorderHeight = 8;
+const int borderWidth = 5;
+
+// ===========================================================================
+
+DominoHandler::DominoHandler()
+{
+ int ignore, maj, min;
+
+ if(XShapeQueryExtension(qt_xdisplay(), &ignore, &ignore) &&
+ XShapeQueryVersion(qt_xdisplay(), &maj, &min) &&
+ maj >= 1 && min >= 1) {
+
+ buttonInputShape = true;
+ }
+ else
+ buttonInputShape = false;
+
+ clientHandler = this;
+ readConfig( false );
+ createPixmaps();
+ Domino_initialized = true;
+}
+
+
+DominoHandler::~DominoHandler()
+{
+ Domino_initialized = false;
+ freePixmaps();
+ clientHandler = NULL;
+}
+
+KDecoration* DominoHandler::createDecoration( KDecorationBridge* b )
+{
+ return new DominoClient( b, this );
+}
+
+bool DominoHandler::reset( unsigned long changed )
+{
+ Domino_initialized = false;
+ changed |= readConfig( true );
+ if( changed & SettingColors )
+ { // pixmaps need to be recreated
+ freePixmaps();
+ createPixmaps();
+ }
+ Domino_initialized = true;
+ // SettingButtons is handled by KCommonDecoration
+ bool need_recreate = ( changed & ( SettingDecoration | SettingFont | SettingBorder )) != 0;
+ if( need_recreate ) // something else than colors changed
+ return true;
+ resetDecorations( changed );
+ return false;
+}
+
+
+unsigned long DominoHandler::readConfig( bool update )
+{
+ unsigned long changed = 0;
+ KConfig conf("kwindominorc");
+ conf.setGroup("General");
+
+ titleHeight = QMAX(QFontMetrics(options()->font(true)).height(), 16);
+ background = qApp->palette().active().background();
+
+ customBorderColor = conf.readBoolEntry("customBorderColor", true);
+ borderColor = customBorderColor ? conf.readEntry("borderColor", "#777B7F") : background;
+
+ customButtonColor = conf.readBoolEntry("customButtonColor", false);
+ buttonColor = customButtonColor ? conf.readEntry("buttonColor", "#212121") : background;
+ customButtonIconColor = conf.readBoolEntry("customButtonIconColor", false);
+ buttonIconColor = customButtonIconColor ? conf.readEntry("buttonIconColor", "#000000") : "#000000";
+ showInactiveButtons = conf.readBoolEntry("showInactiveButtons", false);
+ showButtonIcons = conf.readBoolEntry("showButtonIcons", false);
+ darkLines = conf.readBoolEntry("darkFrame", false);
+
+ if(!conf.readBoolEntry( "customGradientColors", false)) {
+ topGradientColor = alphaBlendColors(background, Qt::white, 180);
+ bottomGradientColor = alphaBlendColors(background, Qt::black, 230);
+ topBorderGradientColor = alphaBlendColors(borderColor, Qt::white, 180);
+ bottomBorderGradientColor = alphaBlendColors(borderColor, Qt::black, 230);
+ }
+ else {
+ topGradientColor = conf.readEntry("topGradientColor", "#ffffff");
+ bottomGradientColor = conf.readEntry("bottomGradientColor", "#000000");
+ topBorderGradientColor = topGradientColor;
+ bottomBorderGradientColor = bottomGradientColor;
+ }
+
+ if( update ) {
+ changed |= SettingColors; // just recreate the pixmaps and repaint
+ }
+
+ if(conf.readBoolEntry("useDominoStyleContourColors", true)) {
+ QSettings s;
+ buttonContourColor = s.readEntry("/domino/Settings/buttonContourColor", background.dark(250).name());
+ buttonMouseOverContourColor = s.readEntry("/domino/Settings/buttonMouseOverContourColor", background.dark(250).name());
+ buttonPressedContourColor = s.readEntry("/domino/Settings/buttonPressedContourColor", background.dark(250).name());
+ }
+ else {
+ buttonContourColor = conf.readEntry("buttonContourColor", background.dark(250).name());
+ buttonMouseOverContourColor = conf.readEntry("buttonMouseOverContourColor", background.dark(250).name());
+ buttonPressedContourColor= conf.readEntry("buttonPressedContourColor", background.dark(250).name());
+ }
+
+ return changed;
+}
+
+
+// This paints the button pixmaps upon loading the style.
+void DominoHandler::createPixmaps()
+{
+
+ QImage edges;
+ QImage topLines;
+ QImage rightLines;
+ QImage bottomLines;
+
+ if(darkLines) {
+ edges = qembed_findImage("client_edges_dark");
+ topLines = qembed_findImage("client_topLines_dark");
+ rightLines = qembed_findImage("client_rightLines_dark");
+ bottomLines = qembed_findImage("client_bottomLines_dark");
+ }
+ else {
+ edges = qembed_findImage("client_edges");
+ topLines = qembed_findImage("client_topLines");
+ rightLines = qembed_findImage("client_rightLines");
+ bottomLines = qembed_findImage("client_bottomLines");
+ }
+
+
+
+
+ int titleBarHeight = titleHeight+titleEdgeTop+titleEdgeBottom;
+ QWMatrix m;
+ m.rotate(180);
+
+ titleBarPix = new QPixmap(QSize(10, titleBarHeight));
+ titleBarPix->fill(background);
+ QRect r(titleBarPix->rect());
+ QPainter p(titleBarPix);
+ QRect rect(r.x(), r.y(), r.width(), titleGradientHeight);
+ renderGradient(&p, rect, topGradientColor, background, "titleBar");
+ p.drawPixmap(0, 0, topLines);
+ p.end();
+
+
+
+ ///////// borders
+ // sides
+ QPixmap sideLinesRight = rightLines;
+
+ borderRightPix = new QPixmap(5, 10);
+ borderRightPix->fill(borderColor);
+ p.begin(borderRightPix);
+ p.drawPixmap(3, 0, sideLinesRight);
+ p.end();
+
+ borderLeftPix = new QPixmap(borderRightPix->xForm(m));
+ // edges
+ borderTopLeftPix = new QPixmap(QSize(5, titleBarHeight));
+ borderTopLeftPix->fill(borderColor);
+ p.begin(borderTopLeftPix);
+ r = QRect(0, 0, 5, titleGradientHeight);
+ // if the gradient color is equal to the background color, we make the border also flat.
+ renderGradient(&p, r, topGradientColor == background ? borderColor : topBorderGradientColor, borderColor, "borderTopLeftPix");
+ borderTopRightPix = new QPixmap(*borderTopLeftPix);
+ p.drawPixmap(0, 1, edges, 0, 0, 5, 6);
+ p.drawTiledPixmap(0, 7, 2, titleBarHeight, sideLinesRight.xForm(m));
+ p.end();
+ p.begin(borderTopRightPix);
+ p.drawPixmap(0, 1, edges, 5, 0, 5, 6);
+ p.drawTiledPixmap(3, 7, 2, titleBarHeight, sideLinesRight);
+ p.end();
+
+
+ borderBottomRightPix = new QPixmap(QSize(5, bottomBorderHeight));
+ borderBottomRightPix->fill(borderColor);
+ p.begin(borderBottomRightPix);
+ r = QRect(0, bottomBorderHeight-6, 5, 6);
+ renderGradient(&p, r, borderColor, bottomGradientColor == background ? borderColor : bottomBorderGradientColor, "borderBottomRightPix");
+ borderBottomLeftPix = new QPixmap(*borderBottomRightPix);
+ p.drawPixmap(0, bottomBorderHeight-7, edges, 5, 6, 5, 6);
+ p.drawPixmap(3, 0, sideLinesRight, 0, 0, 2, borderBottomLeftPix->height()-7);
+ p.end();
+
+
+ p.begin(borderBottomLeftPix);
+ p.drawPixmap(0, bottomBorderHeight-7, edges, 0, 6, 5 ,6);
+ p.drawPixmap(0, 0, sideLinesRight.xForm(m), 0, 0, 2, borderBottomLeftPix->height()-7);
+ p.end();
+
+ borderBottomPix = new QPixmap(QSize(10, bottomBorderHeight));
+ borderBottomPix->fill(background);
+ p.begin(borderBottomPix);
+ r = QRect(0, bottomBorderHeight-6, 10, 6);
+ renderGradient(&p, r, background, bottomGradientColor, "borderBottom");
+ p.drawPixmap(0, bottomBorderHeight-2, bottomLines);
+ p.end();
+
+
+
+ ///////// buttons
+ ////////////////////////////////////////////////////////////////////////
+
+ if(buttonInputShape) {
+ QRegion buttonClip(6,2,6,1);
+ buttonClip += QRegion(5,3,8,1);
+ buttonClip += QRegion(4,4,10,1);
+ buttonClip += QRegion(3,5,12,1);
+ buttonClip += QRegion(2,6,14,6);
+ buttonClip += QRegion(3,12,12,1);
+ buttonClip += QRegion(4,13,10,1);
+ buttonClip += QRegion(5,14,8,1);
+ buttonClip += QRegion(6,15,6,1);
+
+ buttonShapeBitmap = new QBitmap(16, titleBarHeight, true);
+ QPainter p(buttonShapeBitmap);
+ p.setClipRegion(buttonClip);
+ p.fillRect(QRect(0, 0, 16, titleBarHeight), Qt::color1);
+ }
+
+ QPixmap* buttonShadow = new QPixmap(qembed_findImage("clientButtonShadow"));
+ QPixmap* buttonPressed = new QPixmap(qembed_findImage("clientButtonPressed"));
+
+ buttonPix = new QPixmap(QSize(16, titleBarHeight));
+ p.begin(buttonPix);
+ p.drawTiledPixmap(0, 0, titleBarHeight, titleBarHeight, *titleBarPix, 0, titleEdgeTop);
+
+ //////////// custom color
+ r = QRect(buttonPix->rect());
+ QRegion buttonClip(5,2,6,1);
+ buttonClip += QRegion(4,3,8,1);
+ buttonClip += QRegion(3,4,10,1);
+ buttonClip += QRegion(2,5,12,6);
+ buttonClip += QRegion(3,11,10,1);
+ buttonClip += QRegion(4,12,8,1);
+ buttonClip += QRegion(5,13,6,1);
+
+ p.setClipRegion(buttonClip);
+ p.fillRect(QRect(0, 0, r.width(), r.height()), buttonColor);
+ QRect gr(0, -3, r.width(), titleGradientHeight);
+ renderGradient(&p, gr, topGradientColor, buttonColor, "titleBar");
+ p.setClipping(false);
+ ///////////
+ p.drawPixmap(0, 0, *buttonShadow);
+ p.end();
+
+
+ QPixmap* pressedButtonPix = new QPixmap(*buttonPix);
+ p.begin(pressedButtonPix);
+ p.drawPixmap(0, 0, tintImage(qembed_findImage("clientButtonContour"), buttonPressedContourColor));
+ p.drawPixmap(0, 0, *buttonPressed);
+ p.end();
+
+
+ QPixmap* mouseOverButtonPix = new QPixmap(*buttonPix);
+ p.begin(mouseOverButtonPix);
+ p.drawPixmap(0, 0, tintImage(qembed_findImage("clientButtonContour"), buttonMouseOverContourColor));
+ p.end();
+
+
+ p.begin(buttonPix);
+ p.drawPixmap(0, 0, tintImage(qembed_findImage("clientButtonContour"), buttonContourColor));
+ p.end();
+
+
+ buttonHidePix = new QPixmap(QSize(buttonPix->width(), titleBarHeight));
+ p.begin(buttonHidePix);
+ p.drawTiledPixmap(0, 0, buttonHidePix->width(), buttonHidePix->height(), *titleBarPix, 0, titleEdgeTop);
+ p.end();
+
+
+
+
+ ///////// icons
+ ///////////////////////////////////////////////////////////////////////
+
+ QPixmap* icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("closeButtonIcon"), buttonIconColor) : qembed_findImage("closeButtonIcon"));
+ closeButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(closeButtonIcon, 5, 5, icon);
+ pressedCloseButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedCloseButtonIcon, 5, 5, icon);
+ mouseOverCloseButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverCloseButtonIcon, 5, 5, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("maxButtonIcon"), buttonIconColor) : qembed_findImage("maxButtonIcon"));
+ maxButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(maxButtonIcon, 4, 4, icon);
+ pressedMaxButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedMaxButtonIcon, 4, 4, icon);
+ mouseOverMaxButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverMaxButtonIcon, 4, 4, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("minButtonIcon"), buttonIconColor) : qembed_findImage("minButtonIcon"));
+ minButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(minButtonIcon, 5, 9, icon);
+ pressedMinButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedMinButtonIcon, 5, 9, icon);
+ mouseOverMinButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverMinButtonIcon, 5, 9, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("helpButtonIcon"), buttonIconColor) : qembed_findImage("helpButtonIcon"));
+ helpButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(helpButtonIcon, 5, 4, icon);
+ pressedHelpButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedHelpButtonIcon, 5, 4, icon);
+ mouseOverHelpButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverHelpButtonIcon, 5, 4, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("onAllDesktopsButtonIcon"), buttonIconColor) : qembed_findImage("onAllDesktopsButtonIcon"));
+ onAllDesktopsButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(onAllDesktopsButtonIcon, 6, 6, icon);
+ pressedOnAllDesktopsButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedOnAllDesktopsButtonIcon, 6, 6, icon);
+ mouseOverOnAllDesktopsButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverOnAllDesktopsButtonIcon, 6, 6, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("aboveButtonIcon"), buttonIconColor) : qembed_findImage("aboveButtonIcon"));
+ aboveButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(aboveButtonIcon, 5, 4, icon);
+ pressedAboveButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedAboveButtonIcon, 5, 4, icon);
+ mouseOverAboveButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverAboveButtonIcon, 5, 4, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("aboveButtonIcon").xForm(m), buttonIconColor) : qembed_findImage("aboveButtonIcon").xForm(m));
+ belowButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(belowButtonIcon, 5, 4, icon);
+ pressedBelowButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedBelowButtonIcon, 5, 4, icon);
+ mouseOverBelowButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverBelowButtonIcon, 5, 4, icon);
+ delete icon;
+
+ icon = new QPixmap(customButtonIconColor ? tintImage(qembed_findImage("minButtonIcon"), buttonIconColor) : qembed_findImage("minButtonIcon"));
+ shadeButtonIcon = new QPixmap(*buttonPix);
+ bitBlt(shadeButtonIcon, 5, 5, icon);
+ pressedShadeButtonIcon = new QPixmap(*pressedButtonPix);
+ bitBlt(pressedShadeButtonIcon, 5, 5, icon);
+ mouseOverShadeButtonIcon = new QPixmap(*mouseOverButtonPix);
+ bitBlt(mouseOverShadeButtonIcon, 5, 5, icon);
+ delete icon;
+
+ delete mouseOverButtonPix;
+ delete pressedButtonPix;
+}
+
+void DominoHandler::freePixmaps()
+{
+
+ delete buttonPix;
+ delete buttonHidePix;
+ buttonPix = 0;
+ delete titleBarPix;
+ delete borderTopRightPix;
+ delete borderTopLeftPix;
+ delete borderBottomRightPix;
+ delete borderBottomLeftPix;
+ delete borderLeftPix;
+ delete borderRightPix;
+ delete borderBottomPix;
+
+ delete closeButtonIcon;
+ delete maxButtonIcon;
+ delete minButtonIcon;
+ delete helpButtonIcon;
+ delete onAllDesktopsButtonIcon;
+ delete aboveButtonIcon;
+ delete belowButtonIcon;
+ delete shadeButtonIcon;
+
+ delete pressedCloseButtonIcon;
+ delete pressedMaxButtonIcon;
+ delete pressedMinButtonIcon;
+ delete pressedHelpButtonIcon;
+ delete pressedOnAllDesktopsButtonIcon;
+ delete pressedAboveButtonIcon;
+ delete pressedBelowButtonIcon;
+ delete pressedShadeButtonIcon;
+
+ delete mouseOverCloseButtonIcon;
+ delete mouseOverMinButtonIcon;
+ delete mouseOverMaxButtonIcon;
+ delete mouseOverHelpButtonIcon;
+ delete mouseOverOnAllDesktopsButtonIcon;
+ delete mouseOverShadeButtonIcon;
+ delete mouseOverAboveButtonIcon;
+ delete mouseOverBelowButtonIcon;
+
+
+
+ if(buttonInputShape)
+ delete buttonShapeBitmap;
+
+}
+
+bool DominoHandler::supports( Ability ability )
+{
+ switch( ability )
+ {
+ case AbilityAnnounceButtons:
+ case AbilityButtonMenu:
+ case AbilityButtonOnAllDesktops:
+ case AbilityButtonSpacer:
+ case AbilityButtonHelp:
+ case AbilityButtonMinimize:
+ case AbilityButtonMaximize:
+ case AbilityButtonClose:
+ case AbilityButtonAboveOthers:
+ case AbilityButtonBelowOthers:
+ case AbilityButtonShade:
+ return true;
+ default:
+ return false;
+ };
+}
+
+// ===========================================================================
+
+DominoButton::DominoButton(ButtonType type, DominoClient *parent, const char *name)
+ : KCommonDecorationButton(type, parent, name)
+{
+ isMouseOver = false;
+ client = parent;
+#ifdef ShapeInput
+ if(buttonInputShape && buttonShapeBitmap ) {
+ XShapeCombineMask (qt_xdisplay(),
+ winId(),
+ ShapeInput,
+ 0,
+ 0,
+ buttonShapeBitmap->handle(),
+ ShapeSet);
+ }
+#endif
+}
+
+
+DominoButton::~DominoButton()
+{
+}
+
+
+void DominoButton::reset(unsigned long changed)
+{
+ if (changed&SizeChange || changed&ManualReset) {
+ setBackgroundOrigin(QWidget::WidgetOrigin);
+ setErasePixmap(showInactiveButtons ? *buttonPix : *buttonHidePix);
+ }
+
+
+ if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) {
+ this->update();
+ }
+
+
+}
+
+
+void DominoButton::drawButton(QPainter *p)
+{
+ if (!Domino_initialized)
+ return;
+
+ bool down = isDown() || isOn();
+ if(down || (( isMouseOver || showButtonIcons) && (showInactiveButtons || decoration()->isActive() || client->titleBarMouseOver)) ) {
+ switch (type()) {
+ case CloseButton:
+ p->drawPixmap(0, 0, down ? *pressedCloseButtonIcon : isMouseOver ? *mouseOverCloseButtonIcon : *closeButtonIcon);
+ break;
+ case HelpButton:
+ p->drawPixmap(0, 0, down ? *pressedHelpButtonIcon : isMouseOver ? *mouseOverHelpButtonIcon : *helpButtonIcon);
+ break;
+ case MinButton:
+ p->drawPixmap(0, 0, down ? *pressedMinButtonIcon : isMouseOver ? *mouseOverMinButtonIcon : *minButtonIcon);
+ break;
+ case MaxButton:
+ p->drawPixmap(0, 0, down ? *pressedMaxButtonIcon : isMouseOver ? *mouseOverMaxButtonIcon : *maxButtonIcon);
+ break;
+ case OnAllDesktopsButton:
+ p->drawPixmap(0, 0, down ? *pressedOnAllDesktopsButtonIcon : isMouseOver ? *mouseOverOnAllDesktopsButtonIcon : *onAllDesktopsButtonIcon);
+ break;
+ case ShadeButton:
+ p->drawPixmap(0, 0, down ? *pressedShadeButtonIcon : isMouseOver ? *mouseOverShadeButtonIcon : *shadeButtonIcon);
+ break;
+ case AboveButton:
+ p->drawPixmap(0, 0, down ? *pressedAboveButtonIcon : isMouseOver ? *mouseOverAboveButtonIcon : *aboveButtonIcon);
+ break;
+ case BelowButton:
+ p->drawPixmap(0, 0, down ? *pressedBelowButtonIcon : isMouseOver ? *mouseOverBelowButtonIcon : *belowButtonIcon);
+ break;
+ case MenuButton:
+ default:
+ break;
+ }
+ }
+ else {
+ if((client->titleBarMouseOver && type() != MenuButton) || (decoration()->isActive() && !showInactiveButtons && type() != MenuButton)) {
+ p->drawPixmap(0, 0, *buttonPix);
+ }
+ }
+}
+
+
+
+void DominoButton::enterEvent(QEvent */*e*/)
+{
+
+ if(!client->isActive() && !showInactiveButtons)
+ client->titleBarMouseOver = true;
+
+ isMouseOver=true;
+ repaint(false);
+}
+
+
+void DominoButton::leaveEvent(QEvent */*e*/)
+{
+ isMouseOver=false;
+ repaint(false);
+ client->titleBarMouseOver = false;
+}
+
+
+// ===========================================================================
+
+DominoClient::DominoClient( KDecorationBridge* b, KDecorationFactory* f )
+ : KCommonDecoration( b, f )
+{
+}
+
+DominoClient::~DominoClient()
+{
+
+ delete titleBar;
+ delete borderTopLeft;
+ delete borderTopRight;
+ delete borderBottomLeft;
+ delete borderBottomRight;
+ delete borderLeft;
+ delete borderRight;
+ delete borderBottom;
+}
+
+QString DominoClient::visibleName() const
+{
+ return "Domino";
+}
+
+QString DominoClient::defaultButtonsLeft() const
+{
+ return "MF";
+}
+
+QString DominoClient::defaultButtonsRight() const
+{
+ return "HIAX";
+}
+
+bool DominoClient::decorationBehaviour(DecorationBehaviour behaviour) const
+{
+ switch (behaviour) {
+ case DB_MenuClose:
+ return true;
+ case DB_WindowMask:
+ return true;
+ case DB_ButtonHide:
+ return true;
+ default:
+ return KCommonDecoration::decorationBehaviour(behaviour);
+ }
+}
+
+int DominoClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const
+{
+ bool maximized = maximizeMode() == MaximizeFull && !options()->moveResizeMaximizedWindows();
+
+ switch (lm) {
+ case LM_BorderLeft:
+ case LM_BorderRight:
+ if(respectWindowState && maximized)
+ return 0;
+ return borderWidth;
+
+ case LM_BorderBottom: {
+ if(respectWindowState && maximized)
+ return 0;
+ return bottomBorderHeight; // = 8
+ }
+
+ case LM_TitleEdgeLeft:
+ case LM_TitleEdgeRight:
+ return borderWidth + 3;
+
+ case LM_TitleEdgeTop:
+ return titleEdgeTop; // = 3
+
+ case LM_TitleEdgeBottom:
+ return titleEdgeBottom; // = 1
+
+ case LM_TitleBorderLeft:
+ case LM_TitleBorderRight:
+ return 1;
+
+ case LM_TitleHeight: {
+ return titleHeight;
+ }
+
+ case LM_ButtonWidth:
+ return 16; // pixmap width
+
+ case LM_ButtonHeight:
+ return titleHeight;
+
+ case LM_ButtonSpacing:
+ return 3;
+
+ case LM_ExplicitButtonSpacer:
+ return 2;
+
+ default:
+ return KCommonDecoration::layoutMetric(lm, respectWindowState, btn);
+ }
+}
+
+KCommonDecorationButton *DominoClient::createButton(ButtonType type)
+{
+ switch (type) {
+ case MenuButton: {
+ DominoButton* menu = new DominoButton(MenuButton, this, "menu");
+ menuButton = menu;
+ connect(menu, SIGNAL(destroyed()), this, SLOT(menuButtonDestroyed()));
+ return menu;
+ break;
+ }
+ case OnAllDesktopsButton: {
+ return new DominoButton(OnAllDesktopsButton, this, "on_all_desktops");
+ }
+ case HelpButton: {
+ return new DominoButton(HelpButton, this, "help");
+ }
+ case MinButton: {
+ return new DominoButton(MinButton, this, "minimize");
+ }
+ case MaxButton: {
+ return new DominoButton(MaxButton, this, "maximize");
+ }
+ case CloseButton: {
+ return new DominoButton(CloseButton, this, "close");
+ }
+ case AboveButton: {
+ return new DominoButton(AboveButton, this, "above");
+ }
+ case BelowButton: {
+ return new DominoButton(BelowButton, this, "below");
+ }
+ case ShadeButton: {
+ return new DominoButton(ShadeButton, this, "shade");
+ }
+ default:
+ return 0;
+ }
+}
+
+
+void DominoClient::init()
+{
+
+ menuButton = 0;
+ globalMouseTracking = false;
+ titleBarMouseOver = false;
+ QWidget* w = new QWidget(KDecoration::initialParentWidget(), "clientMainWidget", WNoAutoErase|WStaticContents);
+ setMainWidget(w);
+
+ widget()->setBackgroundMode(NoBackground);
+ widget()->installEventFilter(this);
+ createLayout();
+
+ KCommonDecoration::reset(SettingButtons);
+ iconChange();
+ connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
+ connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
+}
+
+void DominoClient::createLayout()
+{
+
+ int titleBarHeight = titleHeight+titleEdgeTop+titleEdgeBottom;
+
+ mainlayout = new QGridLayout(widget(), 3, 3, 0);
+ titleBar = new TitleBar(widget(), "titlebar");
+ titleBar->client = this;
+ titleBar->setMouseTracking(true);
+
+ borderTopLeft = new QWidget(widget(), "borderTopLeft", Qt::WNoAutoErase);
+ borderTopLeft->setMouseTracking(true);
+ borderTopRight = new QWidget(widget(), "borderTopRight", Qt::WNoAutoErase);
+ borderTopRight->setMouseTracking(true);
+ borderBottomLeft = new QWidget(widget(), "borderBottomLeft", Qt::WNoAutoErase);
+ borderBottomLeft->setMouseTracking(true);
+ borderBottomRight = new QWidget(widget(), "borderBottomRight", Qt::WNoAutoErase);
+ borderBottomRight->setMouseTracking(true);
+ borderLeft = new QWidget(widget(), "borderLeft", Qt::WNoAutoErase);
+ borderLeft->setMouseTracking(true);
+ borderRight = new QWidget(widget(), "borderRight", Qt::WNoAutoErase);
+ borderRight->setMouseTracking(true);
+ borderBottom = new QWidget(widget(), "borderBottom", Qt::WNoAutoErase);
+ borderBottom->setMouseTracking(true);
+
+
+ titleBar->setFixedHeight(titleBarHeight);
+ titleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ borderTopLeft->setFixedSize(borderWidth, titleBarHeight);
+ borderTopRight->setFixedSize(borderWidth, titleBarHeight);
+
+ borderLeft->setFixedWidth(borderWidth);
+ borderLeft->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+ borderRight->setFixedWidth(borderWidth);
+ borderRight->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+
+ borderBottomLeft->setFixedSize(borderWidth, bottomBorderHeight);
+ borderBottomRight->setFixedSize(borderWidth, bottomBorderHeight);
+ borderBottom->setFixedHeight(bottomBorderHeight);
+ borderBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ mainlayout->addWidget(titleBar, 0,1);
+ mainlayout->addWidget(borderTopLeft, 0,0);
+ mainlayout->addWidget(borderTopRight, 0,2);
+
+ mainlayout->addWidget(borderLeft, 1,0);
+ mainlayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding));
+ mainlayout->addWidget(borderRight, 1,2);
+
+ mainlayout->addWidget(borderBottomLeft, 2,0);
+ mainlayout->addWidget(borderBottom, 2,1);
+ mainlayout->addWidget(borderBottomRight, 2,2);
+
+ setPixmaps();
+
+}
+
+void DominoClient::setPixmaps()
+{
+ borderTopLeft->setErasePixmap(*borderTopLeftPix);
+ borderTopRight->setErasePixmap(*borderTopRightPix);
+ borderBottomLeft->setErasePixmap(*borderBottomLeftPix);
+ borderBottomRight->setErasePixmap(*borderBottomRightPix);
+ borderLeft->setErasePixmap(*borderLeftPix);
+ borderRight->setErasePixmap(*borderRightPix);
+ borderBottom->setErasePixmap(*borderBottomPix);
+
+ borderTopLeft->erase();
+ borderTopRight->erase();
+ borderBottomLeft->erase();
+ borderBottomRight->erase();
+ borderLeft->erase();
+ borderRight->erase();
+ borderBottom->erase();
+}
+
+void DominoClient::reset( unsigned long changed)
+{
+
+ widget()->repaint();
+ KCommonDecoration::reset(changed);
+ KCommonDecoration::resetButtons();
+ updateCaption();
+ setPixmaps();
+ iconChange();
+}
+
+
+void DominoClient::updateMask()
+{
+ if(maximizeMode() == MaximizeFull && !options()->moveResizeMaximizedWindows()) {
+ clearMask();
+ return;
+ }
+ QRect r(widget()->rect());
+
+ QRegion mask(r.x()+5, r.y(), r.width()-10, r.height());
+ mask += QRect(r.x()+3, r.y()+1, r.width()-6, r.height()-2);
+ mask += QRect(r.x()+2, r.y()+2, r.width()-4, r.height()-4);
+ mask += QRect(r.x()+1, r.y()+3, r.width()-2, r.height()-6);
+ mask += QRect(r.x(), r.y()+5, r.width(), r.height()-10);
+ setMask(mask);
+
+}
+
+void DominoClient::updateCaption()
+{
+ QRect r(titleBar->rect());
+
+ QPixmap* titleBar_pix = new QPixmap(r.size());
+ QPainter painter(titleBar_pix);
+ painter.drawTiledPixmap(0, 0, r.width(), r.height(), *titleBarPix);
+
+ int lw = buttonsLeftWidth()+3;
+ int rw = buttonsRightWidth();
+
+ painter.setFont(options()->font(true,false));
+ QFontMetrics fm = painter.fontMetrics();
+ int captionWidth = fm.width(caption());
+ int titleWidth = titleBar->width()-(lw+rw);
+
+
+ QRect re(titleWidth > captionWidth ? (titleWidth-captionWidth)/2+lw : lw, 0, titleWidth, r.height());
+ painter.setClipRect(re);
+ painter.setPen(options()->color(KDecorationDefines::ColorFont, isActive()));
+ painter.drawText(QRect(lw, r.y(), r.width()-(rw+lw), r.height()), titleWidth > captionWidth ? Qt::AlignCenter : Qt::AlignLeft|Qt::AlignVCenter, caption());
+ painter.end();
+
+ titleBar->setErasePixmap(*titleBar_pix);
+ titleBar->erase();
+ delete titleBar_pix;
+}
+
+void DominoClient::activeChange()
+{
+ updateButtons();
+ updateCaption();
+}
+
+void DominoClient::iconChange()
+{
+ if(menuButton) {
+ QPixmap pix(*buttonHidePix);
+ QPixmap icon = KDecoration::icon().pixmap(QIconSet::Small, QIconSet::Normal);
+ if(!icon.isNull())
+ bitBlt(&pix, 0, 0, &icon, 0, 0, -1, -1, Qt::CopyROP);
+ menuButton->setErasePixmap(pix);
+ }
+
+}
+
+void DominoClient::menuButtonDestroyed()
+{
+ menuButton = 0;
+}
+
+void DominoClient::slotShade()
+{
+ setShade( !isSetShade() );
+}
+
+
+void DominoClient::borders( int& left, int& right, int& top, int& bottom ) const
+{
+
+ left = layoutMetric(LM_BorderLeft);
+ right = layoutMetric(LM_BorderRight);
+ bottom = layoutMetric(LM_BorderBottom);
+ top = layoutMetric(LM_TitleHeight) +
+ layoutMetric(LM_TitleEdgeTop) +
+ layoutMetric(LM_TitleEdgeBottom);
+
+ widget()->layout()->activate();
+
+}
+
+void DominoClient::shadeChange()
+{
+ if(isSetShade()) {
+ mainlayout->remove(borderLeft);
+ mainlayout->remove(borderRight);
+ borderLeft->resize(borderLeft->width(), 0);
+ borderRight->resize(borderLeft->width(), 0);
+ }
+ else {
+ mainlayout->addWidget(borderLeft,1,0);
+ mainlayout->addWidget(borderRight,1,2);
+ }
+
+ widget()->layout()->activate();
+
+}
+
+void DominoClient::resize( const QSize& s )
+{
+ widget()->resize( s );
+ if(maximizeMode() == MaximizeFull && !options()->moveResizeMaximizedWindows()) {
+ borderLeft->hide();
+ borderRight->hide();
+ borderTopLeft->hide();
+ borderTopRight->hide();
+ borderBottomLeft->hide();
+ borderBottomRight->hide();
+ }
+ else if(borderLeft->isHidden()) {
+ borderLeft->show();
+ borderRight->show();
+ borderTopLeft->show();
+ borderTopRight->show();
+ borderBottomLeft->show();
+ borderBottomRight->show();
+ }
+}
+
+
+void DominoClient::resizeEvent( QResizeEvent* ev )
+{
+
+ if (!Domino_initialized || ev->size() == ev->oldSize())
+ return;
+ KCommonDecoration::resizeEvent(ev); // which calls calcHiddenButtons()
+
+ updateMask();
+ updateCaption();
+}
+void DominoClient::updateWindowShape()
+{
+}
+
+void DominoClient::showEvent(QShowEvent *)
+{
+}
+
+void DominoClient::paintEvent( QPaintEvent* )
+{
+}
+
+bool DominoClient::eventFilter(QObject*, QEvent* e)
+{
+ switch(e->type()) {
+ case QEvent::Resize:
+ resizeEvent(static_cast<QResizeEvent*>(e));
+ return true;
+ case QEvent::ApplicationPaletteChange:
+ return false;
+ case QEvent::Paint:
+ paintEvent(static_cast<QPaintEvent*>(e));
+ return true;
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent(static_cast<QMouseEvent*>(e));
+ return true;
+ case QEvent::Wheel:
+ if(titleBar->hasMouse() || isSetShade())
+ wheelEvent(static_cast<QWheelEvent*>(e));
+ return true;
+ case QEvent::MouseButtonPress:
+ processMousePressEvent(static_cast<QMouseEvent*>(e));
+ return true;
+ case QEvent::Show:
+ return true;
+ case QEvent::Enter:
+ updateButtons();
+ return true;
+ case QEvent::Leave:
+ if(globalMouseTracking && !showInactiveButtons) {
+ globalMouseTracking = false;
+ qApp->setGlobalMouseTracking( false );
+ qApp->removeEventFilter(titleBar);
+ titleBarMouseOver = false;
+ }
+ updateButtons();
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+
+void TitleBar::enterEvent(QEvent*)
+{
+ if(!client->isActive() && !showInactiveButtons) {
+ if(!client->globalMouseTracking) {
+ client->globalMouseTracking = true;
+ qApp->setGlobalMouseTracking( true );
+ qApp->installEventFilter(this);
+ client->titleBarMouseOver = true;
+ client->updateButtons();
+ }
+ }
+}
+
+
+bool TitleBar::eventFilter(QObject*o, QEvent* e) {
+
+ if(e->type() == QEvent::MouseMove && !showInactiveButtons && !client->isActive()) {
+ QPoint pos = ((QMouseEvent*)e)->pos();
+ if((dynamic_cast<QWidget*>(o) && geometry().contains(pos)) || dynamic_cast<QButton*>(o)) {
+ client->titleBarMouseOver = true;
+ }
+ else {
+ client->titleBarMouseOver = false;
+ client->updateButtons();
+ }
+ }
+ return false;
+}
+
+
+
+/////////////
+
+void renderGradient(QPainter *painter, QRect &rect,
+ QColor &c1, QColor &c2, const char* /*name*/)
+{
+ if((rect.width() <= 0)||(rect.height() <= 0))
+ return;
+
+ QPixmap *result;
+
+ result = new QPixmap(10, rect.height());
+ QPainter p(result);
+
+ int r_h = result->rect().height();
+ int r_x, r_y, r_x2, r_y2;
+ result->rect().coords(&r_x, &r_y, &r_x2, &r_y2);
+
+ int rDiff, gDiff, bDiff;
+ int rc, gc, bc;
+
+ register int y;
+
+ rDiff = ( c2.red()) - (rc = c1.red());
+ gDiff = ( c2.green()) - (gc = c1.green());
+ bDiff = ( c2.blue()) - (bc = c1.blue());
+
+ register int rl = rc << 16;
+ register int gl = gc << 16;
+ register int bl = bc << 16;
+
+ int rdelta = ((1<<16) / r_h) * rDiff;
+ int gdelta = ((1<<16) / r_h ) * gDiff;
+ int bdelta = ((1<<16) / r_h ) * bDiff;
+
+
+ for ( y = 0; y < r_h; y++ ) {
+ rl += rdelta;
+ gl += gdelta;
+ bl += bdelta;
+ p.setPen(QColor(rl>>16, gl>>16, bl>>16));
+ p.drawLine(r_x, r_y+y, r_x2, r_y+y);
+ }
+ p.end();
+
+ // draw the result...
+ painter->drawTiledPixmap(rect, *result);
+
+}
+
+
+QColor alphaBlendColors(const QColor &bgColor, const QColor &fgColor, const int a)
+{
+
+ QRgb rgb = bgColor.rgb();
+ QRgb rgb_b = fgColor.rgb();
+ int alpha = a;
+ if(alpha>255) alpha = 255;
+ if(alpha<0) alpha = 0;
+ int inv_alpha = 255 - alpha;
+
+ QColor result = QColor( qRgb(qRed(rgb_b)*inv_alpha/255 + qRed(rgb)*alpha/255,
+ qGreen(rgb_b)*inv_alpha/255 + qGreen(rgb)*alpha/255,
+ qBlue(rgb_b)*inv_alpha/255 + qBlue(rgb)*alpha/255) );
+
+ return result;
+}
+
+QImage tintImage(const QImage &img, const QColor &tintColor) {
+
+ QImage *result = new QImage(img.width(), img.height(), 32, 0, QImage::IgnoreEndian);
+ unsigned int *data = (unsigned int*) img.bits();
+ unsigned int *resultData = (unsigned int*) result->bits();
+ result->setAlphaBuffer( true );
+ int alpha;
+ int total = img.width()*img.height();
+ for ( int current = 0 ; current < total ; ++current ) {
+ alpha = qAlpha( data[ current ] );
+ resultData[ current ] = qRgba( tintColor.red(), tintColor.green(), tintColor.blue(), alpha );
+ }
+ return *result;
+}
+
+
+
+} // namespace
+
+// Extended KWin plugin interface
+extern "C" KDE_EXPORT KDecorationFactory* create_factory()
+{
+ return new Domino::DominoHandler();
+}
+
+#include "dominoclient.moc"
+