/* Copyright (C) 2006 Michael Lentner based on KDE2 Default KWin client: Copyright (C) 1999, 2001 Daniel Duley Matthias Ettrich Karol Szwed 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace Domino { static DominoHandler* clientHandler; static bool Domino_initialized = false; const int titleEdgeTop = 3; const int titleEdgeBottom = 1; static int titleHeight; static TQPixmap* buttonPix; static TQPixmap* buttonHidePix; static TQPixmap* titleBarPix; static TQPixmap* borderTopLeftPix; static TQPixmap* borderTopRightPix; static TQPixmap* borderBottomPix; static TQPixmap* borderBottomLeftPix; static TQPixmap* borderBottomRightPix; static TQPixmap* borderLeftPix; static TQPixmap* borderRightPix; static TQPixmap* closeButtonIcon; static TQPixmap* minButtonIcon; static TQPixmap* maxButtonIcon; static TQPixmap* helpButtonIcon; static TQPixmap* onAllDesktopsButtonIcon; static TQPixmap* shadeButtonIcon; static TQPixmap* aboveButtonIcon; static TQPixmap* belowButtonIcon; static TQPixmap* pressedCloseButtonIcon; static TQPixmap* pressedMinButtonIcon; static TQPixmap* pressedMaxButtonIcon; static TQPixmap* pressedHelpButtonIcon; static TQPixmap* pressedOnAllDesktopsButtonIcon; static TQPixmap* pressedShadeButtonIcon; static TQPixmap* pressedAboveButtonIcon; static TQPixmap* pressedBelowButtonIcon; static TQPixmap* mouseOverCloseButtonIcon; static TQPixmap* mouseOverMinButtonIcon; static TQPixmap* mouseOverMaxButtonIcon; static TQPixmap* mouseOverHelpButtonIcon; static TQPixmap* mouseOverOnAllDesktopsButtonIcon; static TQPixmap* mouseOverShadeButtonIcon; static TQPixmap* mouseOverAboveButtonIcon; static TQPixmap* mouseOverBelowButtonIcon; static bool buttonInputShape; static TQBitmap* buttonShapeBitmap; static TQColor background; static TQColor topGradientColor; static TQColor bottomGradientColor; static TQColor topBorderGradientColor; static TQColor 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; TDEGlobal::locale()->insertCatalogue("twin_clients"); TDEGlobal::locale()->insertCatalogue("twin_domino"); if(XShapeQueryExtension(tqt_xdisplay(), &ignore, &ignore) && XShapeQueryVersion(tqt_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; TDEConfig conf("twindominorc"); conf.setGroup("General"); titleHeight = TQMAX(TQFontMetrics(options()->font(true)).height(), 16); background = tqApp->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, TQt::white, 180); bottomGradientColor = alphaBlendColors(background, TQt::black, 230); topBorderGradientColor = alphaBlendColors(borderColor, TQt::white, 180); bottomBorderGradientColor = alphaBlendColors(borderColor, TQt::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)) { TQSettings 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() { TQImage edges; TQImage topLines; TQImage rightLines; TQImage 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; TQWMatrix m; m.rotate(180); titleBarPix = new TQPixmap(TQSize(10, titleBarHeight)); titleBarPix->fill(background); TQRect r(titleBarPix->rect()); TQPainter p(titleBarPix); TQRect rect(r.x(), r.y(), r.width(), titleGradientHeight); renderGradient(&p, rect, topGradientColor, background, "titleBar"); p.drawPixmap(0, 0, topLines); p.end(); ///////// borders // sides TQPixmap sideLinesRight = rightLines; borderRightPix = new TQPixmap(5, 10); borderRightPix->fill(borderColor); p.begin(borderRightPix); p.drawPixmap(3, 0, sideLinesRight); p.end(); borderLeftPix = new TQPixmap(borderRightPix->xForm(m)); // edges borderTopLeftPix = new TQPixmap(TQSize(5, titleBarHeight)); borderTopLeftPix->fill(borderColor); p.begin(borderTopLeftPix); r = TQRect(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 TQPixmap(*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 TQPixmap(TQSize(5, bottomBorderHeight)); borderBottomRightPix->fill(borderColor); p.begin(borderBottomRightPix); r = TQRect(0, bottomBorderHeight-6, 5, 6); renderGradient(&p, r, borderColor, bottomGradientColor == background ? borderColor : bottomBorderGradientColor, "borderBottomRightPix"); borderBottomLeftPix = new TQPixmap(*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 TQPixmap(TQSize(10, bottomBorderHeight)); borderBottomPix->fill(background); p.begin(borderBottomPix); r = TQRect(0, bottomBorderHeight-6, 10, 6); renderGradient(&p, r, background, bottomGradientColor, "borderBottom"); p.drawPixmap(0, bottomBorderHeight-2, bottomLines); p.end(); ///////// buttons //////////////////////////////////////////////////////////////////////// if(buttonInputShape) { TQRegion buttonClip(6,2,6,1); buttonClip += TQRegion(5,3,8,1); buttonClip += TQRegion(4,4,10,1); buttonClip += TQRegion(3,5,12,1); buttonClip += TQRegion(2,6,14,6); buttonClip += TQRegion(3,12,12,1); buttonClip += TQRegion(4,13,10,1); buttonClip += TQRegion(5,14,8,1); buttonClip += TQRegion(6,15,6,1); buttonShapeBitmap = new TQBitmap(16, titleBarHeight, true); TQPainter p(buttonShapeBitmap); p.setClipRegion(buttonClip); p.fillRect(TQRect(0, 0, 16, titleBarHeight), TQt::color1); } TQPixmap* buttonShadow = new TQPixmap(qembed_findImage("clientButtonShadow")); TQPixmap* buttonPressed = new TQPixmap(qembed_findImage("clientButtonPressed")); buttonPix = new TQPixmap(TQSize(16, titleBarHeight)); p.begin(buttonPix); p.drawTiledPixmap(0, 0, titleBarHeight, titleBarHeight, *titleBarPix, 0, titleEdgeTop); //////////// custom color r = TQRect(buttonPix->rect()); TQRegion buttonClip(5,2,6,1); buttonClip += TQRegion(4,3,8,1); buttonClip += TQRegion(3,4,10,1); buttonClip += TQRegion(2,5,12,6); buttonClip += TQRegion(3,11,10,1); buttonClip += TQRegion(4,12,8,1); buttonClip += TQRegion(5,13,6,1); p.setClipRegion(buttonClip); p.fillRect(TQRect(0, 0, r.width(), r.height()), buttonColor); TQRect gr(0, -3, r.width(), titleGradientHeight); renderGradient(&p, gr, topGradientColor, buttonColor, "titleBar"); p.setClipping(false); /////////// p.drawPixmap(0, 0, *buttonShadow); p.end(); TQPixmap* pressedButtonPix = new TQPixmap(*buttonPix); p.begin(pressedButtonPix); p.drawPixmap(0, 0, tintImage(qembed_findImage("clientButtonContour"), buttonPressedContourColor)); p.drawPixmap(0, 0, *buttonPressed); p.end(); TQPixmap* mouseOverButtonPix = new TQPixmap(*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 TQPixmap(TQSize(buttonPix->width(), titleBarHeight)); p.begin(buttonHidePix); p.drawTiledPixmap(0, 0, buttonHidePix->width(), buttonHidePix->height(), *titleBarPix, 0, titleEdgeTop); p.end(); ///////// icons /////////////////////////////////////////////////////////////////////// TQPixmap* icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("closeButtonIcon"), buttonIconColor) : qembed_findImage("closeButtonIcon")); closeButtonIcon = new TQPixmap(*buttonPix); bitBlt(closeButtonIcon, 5, 5, icon); pressedCloseButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedCloseButtonIcon, 5, 5, icon); mouseOverCloseButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverCloseButtonIcon, 5, 5, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("maxButtonIcon"), buttonIconColor) : qembed_findImage("maxButtonIcon")); maxButtonIcon = new TQPixmap(*buttonPix); bitBlt(maxButtonIcon, 4, 4, icon); pressedMaxButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedMaxButtonIcon, 4, 4, icon); mouseOverMaxButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverMaxButtonIcon, 4, 4, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("minButtonIcon"), buttonIconColor) : qembed_findImage("minButtonIcon")); minButtonIcon = new TQPixmap(*buttonPix); bitBlt(minButtonIcon, 5, 9, icon); pressedMinButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedMinButtonIcon, 5, 9, icon); mouseOverMinButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverMinButtonIcon, 5, 9, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("helpButtonIcon"), buttonIconColor) : qembed_findImage("helpButtonIcon")); helpButtonIcon = new TQPixmap(*buttonPix); bitBlt(helpButtonIcon, 5, 4, icon); pressedHelpButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedHelpButtonIcon, 5, 4, icon); mouseOverHelpButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverHelpButtonIcon, 5, 4, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("onAllDesktopsButtonIcon"), buttonIconColor) : qembed_findImage("onAllDesktopsButtonIcon")); onAllDesktopsButtonIcon = new TQPixmap(*buttonPix); bitBlt(onAllDesktopsButtonIcon, 6, 6, icon); pressedOnAllDesktopsButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedOnAllDesktopsButtonIcon, 6, 6, icon); mouseOverOnAllDesktopsButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverOnAllDesktopsButtonIcon, 6, 6, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("aboveButtonIcon"), buttonIconColor) : qembed_findImage("aboveButtonIcon")); aboveButtonIcon = new TQPixmap(*buttonPix); bitBlt(aboveButtonIcon, 5, 4, icon); pressedAboveButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedAboveButtonIcon, 5, 4, icon); mouseOverAboveButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverAboveButtonIcon, 5, 4, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("aboveButtonIcon").xForm(m), buttonIconColor) : qembed_findImage("aboveButtonIcon").xForm(m)); belowButtonIcon = new TQPixmap(*buttonPix); bitBlt(belowButtonIcon, 5, 4, icon); pressedBelowButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedBelowButtonIcon, 5, 4, icon); mouseOverBelowButtonIcon = new TQPixmap(*mouseOverButtonPix); bitBlt(mouseOverBelowButtonIcon, 5, 4, icon); delete icon; icon = new TQPixmap(customButtonIconColor ? tintImage(qembed_findImage("minButtonIcon"), buttonIconColor) : qembed_findImage("minButtonIcon")); shadeButtonIcon = new TQPixmap(*buttonPix); bitBlt(shadeButtonIcon, 5, 5, icon); pressedShadeButtonIcon = new TQPixmap(*pressedButtonPix); bitBlt(pressedShadeButtonIcon, 5, 5, icon); mouseOverShadeButtonIcon = new TQPixmap(*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 (tqt_xdisplay(), winId(), ShapeInput, 0, 0, buttonShapeBitmap->handle(), ShapeSet); } #endif } DominoButton::~DominoButton() { } void DominoButton::reset(unsigned long changed) { if (changed&SizeChange || changed&ManualReset) { setBackgroundOrigin(TQWidget::WidgetOrigin); setErasePixmap(showInactiveButtons ? *buttonPix : *buttonHidePix); } if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) { this->update(); } } void DominoButton::drawButton(TQPainter *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(TQEvent */*e*/) { if(!client->isActive() && !showInactiveButtons) client->titleBarMouseOver = true; isMouseOver=true; repaint(false); } void DominoButton::leaveEvent(TQEvent */*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; } TQString DominoClient::visibleName() const { return i18n("Domino"); } TQString DominoClient::defaultButtonsLeft() const { return "MF"; } TQString 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; TQWidget* w = new TQWidget(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 TQGridLayout(widget(), 3, 3, 0); titleBar = new TitleBar(widget(), "titlebar"); titleBar->client = this; titleBar->setMouseTracking(true); borderTopLeft = new TQWidget(widget(), "borderTopLeft", TQt::WNoAutoErase); borderTopLeft->setMouseTracking(true); borderTopRight = new TQWidget(widget(), "borderTopRight", TQt::WNoAutoErase); borderTopRight->setMouseTracking(true); borderBottomLeft = new TQWidget(widget(), "borderBottomLeft", TQt::WNoAutoErase); borderBottomLeft->setMouseTracking(true); borderBottomRight = new TQWidget(widget(), "borderBottomRight", TQt::WNoAutoErase); borderBottomRight->setMouseTracking(true); borderLeft = new TQWidget(widget(), "borderLeft", TQt::WNoAutoErase); borderLeft->setMouseTracking(true); borderRight = new TQWidget(widget(), "borderRight", TQt::WNoAutoErase); borderRight->setMouseTracking(true); borderBottom = new TQWidget(widget(), "borderBottom", TQt::WNoAutoErase); borderBottom->setMouseTracking(true); titleBar->setFixedHeight(titleBarHeight); titleBar->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed); borderTopLeft->setFixedSize(borderWidth, titleBarHeight); borderTopRight->setFixedSize(borderWidth, titleBarHeight); borderLeft->setFixedWidth(borderWidth); borderLeft->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Expanding); borderRight->setFixedWidth(borderWidth); borderRight->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Expanding); borderBottomLeft->setFixedSize(borderWidth, bottomBorderHeight); borderBottomRight->setFixedSize(borderWidth, bottomBorderHeight); borderBottom->setFixedHeight(bottomBorderHeight); borderBottom->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed); mainlayout->addWidget(titleBar, 0,1); mainlayout->addWidget(borderTopLeft, 0,0); mainlayout->addWidget(borderTopRight, 0,2); mainlayout->addWidget(borderLeft, 1,0); mainlayout->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Expanding, TQSizePolicy::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; } TQRect r(widget()->rect()); TQRegion mask(r.x()+5, r.y(), r.width()-10, r.height()); mask += TQRect(r.x()+3, r.y()+1, r.width()-6, r.height()-2); mask += TQRect(r.x()+2, r.y()+2, r.width()-4, r.height()-4); mask += TQRect(r.x()+1, r.y()+3, r.width()-2, r.height()-6); mask += TQRect(r.x(), r.y()+5, r.width(), r.height()-10); setMask(mask); } void DominoClient::updateCaption() { TQRect r(titleBar->rect()); TQPixmap* titleBar_pix = new TQPixmap(r.size()); TQPainter 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)); TQFontMetrics fm = painter.fontMetrics(); int captionWidth = fm.width(caption()); int titleWidth = titleBar->width()-(lw+rw); TQRect re(titleWidth > captionWidth ? (titleWidth-captionWidth)/2+lw : lw, 0, titleWidth, r.height()); painter.setClipRect(re); painter.setPen(options()->color(KDecorationDefines::ColorFont, isActive())); painter.drawText(TQRect(lw, r.y(), r.width()-(rw+lw), r.height()), titleWidth > captionWidth ? TQt::AlignCenter : TQt::AlignLeft|TQt::AlignVCenter, caption()); painter.end(); titleBar->setErasePixmap(*titleBar_pix); titleBar->erase(); delete titleBar_pix; } void DominoClient::activeChange() { updateButtons(); updateCaption(); } void DominoClient::iconChange() { if(menuButton) { TQPixmap pix(*buttonHidePix); TQPixmap icon = KDecoration::icon().pixmap(TQIconSet::Small, TQIconSet::Normal); if(!icon.isNull()) bitBlt(&pix, 0, 0, &icon, 0, 0, -1, -1, TQt::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 TQSize& 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( TQResizeEvent* ev ) { if (!Domino_initialized || ev->size() == ev->oldSize()) return; KCommonDecoration::resizeEvent(ev); // which calls calcHiddenButtons() updateMask(); updateCaption(); } void DominoClient::updateWindowShape() { } void DominoClient::showEvent(TQShowEvent *) { } void DominoClient::paintEvent( TQPaintEvent* ) { } bool DominoClient::eventFilter(TQObject*, TQEvent* e) { switch(e->type()) { case TQEvent::Resize: resizeEvent(static_cast(e)); return true; case TQEvent::ApplicationPaletteChange: return false; case TQEvent::Paint: paintEvent(static_cast(e)); return true; case TQEvent::MouseButtonDblClick: mouseDoubleClickEvent(static_cast(e)); return true; case TQEvent::Wheel: if(titleBar->hasMouse() || isSetShade()) wheelEvent(static_cast(e)); return true; case TQEvent::MouseButtonPress: processMousePressEvent(static_cast(e)); return true; case TQEvent::Show: return true; case TQEvent::Enter: updateButtons(); return true; case TQEvent::Leave: if(globalMouseTracking && !showInactiveButtons) { globalMouseTracking = false; tqApp->setGlobalMouseTracking( false ); tqApp->removeEventFilter(titleBar); titleBarMouseOver = false; } updateButtons(); return true; default: return false; } return false; } void TitleBar::enterEvent(TQEvent*) { if(!client->isActive() && !showInactiveButtons) { if(!client->globalMouseTracking) { client->globalMouseTracking = true; tqApp->setGlobalMouseTracking( true ); tqApp->installEventFilter(this); client->titleBarMouseOver = true; client->updateButtons(); } } } bool TitleBar::eventFilter(TQObject*o, TQEvent* e) { if(e->type() == TQEvent::MouseMove && !showInactiveButtons && !client->isActive()) { TQPoint pos = ((TQMouseEvent*)e)->pos(); if((dynamic_cast(o) && geometry().contains(pos)) || dynamic_cast(o)) { client->titleBarMouseOver = true; } else { client->titleBarMouseOver = false; client->updateButtons(); } } return false; } ///////////// void renderGradient(TQPainter *painter, TQRect &rect, TQColor &c1, TQColor &c2, const char* /*name*/) { if((rect.width() <= 0)||(rect.height() <= 0)) return; TQPixmap *result; result = new TQPixmap(10, rect.height()); TQPainter 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; int y; rDiff = ( c2.red()) - (rc = c1.red()); gDiff = ( c2.green()) - (gc = c1.green()); bDiff = ( c2.blue()) - (bc = c1.blue()); int rl = rc << 16; int gl = gc << 16; 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(TQColor(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); } TQColor alphaBlendColors(const TQColor &bgColor, const TQColor &fgColor, const int a) { TQRgb rgb = bgColor.rgb(); TQRgb rgb_b = fgColor.rgb(); int alpha = a; if(alpha>255) alpha = 255; if(alpha<0) alpha = 0; int inv_alpha = 255 - alpha; TQColor result = TQColor( tqRgb(tqRed(rgb_b)*inv_alpha/255 + tqRed(rgb)*alpha/255, tqGreen(rgb_b)*inv_alpha/255 + tqGreen(rgb)*alpha/255, tqBlue(rgb_b)*inv_alpha/255 + tqBlue(rgb)*alpha/255) ); return result; } TQImage tintImage(const TQImage &img, const TQColor &tintColor) { TQImage *result = new TQImage(img.width(), img.height(), 32, 0, TQImage::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 = tqAlpha( data[ current ] ); resultData[ current ] = tqRgba( 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"