You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tde-style-domino/client/dominoclient.cpp

1200 lines
34 KiB

/*
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 <tdeconfig.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <tqlayout.h>
#include <tqbitmap.h>
#include <tqimage.h>
#include <tqapplication.h>
#include <tqlabel.h>
#include <tqpixmap.h>
#include <X11/extensions/shape.h>
#include <tqwmatrix.h>
#include <tqpainter.h>
#include <tqsettings.h>
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<TQResizeEvent*>(e));
return true;
case TQEvent::ApplicationPaletteChange:
return false;
case TQEvent::Paint:
paintEvent(static_cast<TQPaintEvent*>(e));
return true;
case TQEvent::MouseButtonDblClick:
mouseDoubleClickEvent(static_cast<TQMouseEvent*>(e));
return true;
case TQEvent::Wheel:
if(titleBar->hasMouse() || isSetShade())
wheelEvent(static_cast<TQWheelEvent*>(e));
return true;
case TQEvent::MouseButtonPress:
processMousePressEvent(static_cast<TQMouseEvent*>(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<TQWidget*>(o) && geometry().contains(pos)) || dynamic_cast<TQButton*>(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"