summaryrefslogtreecommitdiffstats
path: root/twin-styles/smooth-blend/client/smoothblend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'twin-styles/smooth-blend/client/smoothblend.cpp')
-rw-r--r--twin-styles/smooth-blend/client/smoothblend.cpp1380
1 files changed, 1380 insertions, 0 deletions
diff --git a/twin-styles/smooth-blend/client/smoothblend.cpp b/twin-styles/smooth-blend/client/smoothblend.cpp
new file mode 100644
index 00000000..c842574d
--- /dev/null
+++ b/twin-styles/smooth-blend/client/smoothblend.cpp
@@ -0,0 +1,1380 @@
+//////////////////////////////////////////////////////////////////////////////
+// smoothblend.cpp
+// -------------------
+// Smooth Blend window decoration for TDE
+// -------------------
+// Copyright (c) 2005 Ryan Nickell
+// Please see the header file for copyright and license information.
+//////////////////////////////////////////////////////////////////////////////
+
+#include <tdeconfig.h>
+#include <tdeversion.h>
+#include <tdeglobal.h>
+#include <tdeglobalsettings.h>
+#include <tdelocale.h>
+#include <kpixmap.h>
+#include <kimageeffect.h>
+#include <kpixmapeffect.h>
+#include <kpixmap.h>
+
+#include <tqbitmap.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqpainter.h>
+#include <tqtooltip.h>
+#include <tqtimer.h>
+#include <tqapplication.h>
+
+#include "smoothblend.h"
+#include "buttons.h"
+
+using namespace smoothblend;
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendFactory Class
+//////////////////////////////////////////////////////////////////////////////
+smoothblendFactory* factory=NULL;
+
+bool smoothblendFactory::initialized_ = false;
+TQt::AlignmentFlags smoothblendFactory::titlealign_ = TQt::AlignHCenter;
+bool smoothblendFactory::cornerflags_ = true;
+int smoothblendFactory::titlesize_ = 30;
+int smoothblendFactory::buttonsize_ = 26;
+int smoothblendFactory::framesize_ = 4;
+int smoothblendFactory::roundsize_ = 50;
+bool smoothblendFactory::titleshadow_ = true;
+bool smoothblendFactory::animatebuttons = true;
+int smoothblendFactory::btnComboBox = 0;
+bool smoothblendFactory::menuClose = false;
+
+// global constants
+static const int TOPMARGIN = 4; // do not change
+static const int DECOHEIGHT = 4; // do not change
+static const int SIDETITLEMARGIN = 2;
+// Default button layout
+const char default_left[] = "M";
+const char default_right[] = "HIAX";
+
+static const uint TIMERINTERVAL = 50; // msec
+static const uint ANIMATIONSTEPS = 4;
+
+extern "C" KDecorationFactory* create_factory() {
+ return new smoothblend::smoothblendFactory();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendFactory()
+// ----------------
+// Constructor
+
+smoothblendFactory::smoothblendFactory() {
+ readConfig();
+ initialized_ = true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ~smoothblendFactory()
+// -----------------
+// Destructor
+
+smoothblendFactory::~smoothblendFactory() {
+ initialized_ = false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// createDecoration()
+// -----------------
+// Create the decoration
+
+KDecoration* smoothblendFactory::createDecoration(KDecorationBridge* b) {
+ return new smoothblendClient(b, this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// reset()
+// -------
+// Reset the handler. Returns true if decorations need to be remade, false if
+// only a repaint is necessary
+
+bool smoothblendFactory::reset(unsigned long changed) {
+ // read in the configuration
+ initialized_ = false;
+ bool confchange = readConfig();
+ initialized_ = true;
+
+ if (confchange ||
+ (changed & (SettingDecoration | SettingButtons | SettingBorder))) {
+ return true;
+ } else {
+ resetDecorations(changed);
+ return false;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// readConfig()
+// ------------
+// Read in the configuration file
+
+bool smoothblendFactory::readConfig() {
+ // create a config object
+ TDEConfig config("twinsmoothblendrc");
+ config.setGroup("General");
+
+ // grab settings
+ TQString value = config.readEntry("TitleAlignment", "AlignHCenter");
+ if (value == "AlignLeft")
+ titlealign_ = TQt::AlignLeft;
+ else if (value == "AlignHCenter")
+ titlealign_ = TQt::AlignHCenter;
+ else if (value == "AlignRight")
+ titlealign_ = TQt::AlignRight;
+
+ cornerflags_ = config.readBoolEntry("RoundCorners", true);
+ titlesize_ = config.readNumEntry("TitleSize",30);
+ buttonsize_ = config.readNumEntry("ButtonSize",26);
+ framesize_ = config.readNumEntry("FrameSize",4);
+ roundsize_ = config.readNumEntry("RoundPercent",50);
+ titleshadow_ = config.readBoolEntry("TitleShadow", true);
+ animatebuttons = config.readBoolEntry("AnimateButtons", true);
+ btnComboBox = config.readNumEntry("ButtonComboBox", 0);
+ menuClose = config.readBoolEntry("CloseOnMenuDoubleClick");
+
+ if(buttonsize_ > titlesize_ - framesize_)
+ {
+ buttonsize_ = titlesize_-framesize_;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendButton Class
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendButton()
+// ---------------
+// Constructor
+smoothblendButton::smoothblendButton(smoothblendClient *parent, const char *name, const TQString& tip, ButtonType type, int button_size, bool toggle): TQButton(parent->widget(), name),
+ client_(parent),
+ type_(type),
+ size_(button_size),
+ deco_(0),
+ lastmouse_(Qt::NoButton),
+ hover_(false)
+{
+ setBackgroundMode(NoBackground);
+ setFixedSize( ::factory->buttonSize(), ::factory->buttonSize());
+ setCursor(arrowCursor);
+ TQToolTip::add(this, tip);
+ setToggleButton(toggle);
+ //button animation setup
+ animTmr = new TQTimer(this);
+ connect(animTmr, TQT_SIGNAL(timeout() ), this, TQT_SLOT(animate() ) );
+ connect(this, TQT_SIGNAL(pressed() ), this, TQT_SLOT(buttonClicked() ) );
+ connect(this, TQT_SIGNAL(released() ), this, TQT_SLOT(buttonReleased() ) );
+ animProgress = 0;
+ m_clicked=false;
+}
+
+smoothblendButton::~smoothblendButton() {
+ if ( deco_ )
+ delete deco_;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// sizeHint()
+// ----------
+// Return size hint
+
+TQSize smoothblendButton::sizeHint() const {
+ return TQSize(::factory->buttonSize(), ::factory->buttonSize());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// buttonClicked()
+// ----------
+// Button animation progress reset so we don't get any leave event animation
+// when the mouse is still pressed
+void smoothblendButton::buttonClicked() {
+ m_clicked=true;
+ animProgress=0;
+}
+void smoothblendButton::buttonReleased() {
+ //This doesn't work b/c a released() signal is thrown when a leaveEvent occurs
+ //m_clicked=false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// animate()
+// ----------
+// Button animation timing
+void smoothblendButton::animate() {
+ animTmr->stop();
+
+ if(hover_) {
+ if(animProgress < ANIMATIONSTEPS) {
+ if (::factory->animateButtons() ) {
+ animProgress++;
+ } else {
+ animProgress = ANIMATIONSTEPS;
+ }
+ animTmr->start(TIMERINTERVAL, true); // single-shot
+ }
+ } else {
+ if(animProgress > 0) {
+ if (::factory->animateButtons() ) {
+ animProgress--;
+ } else {
+ animProgress = 0;
+ }
+ animTmr->start(TIMERINTERVAL, true); // single-shot
+ }
+ }
+ repaint(false);
+}
+//////////////////////////////////////////////////////////////////////////////
+// enterEvent()
+// ------------
+// Mouse has entered the button
+
+void smoothblendButton::enterEvent(TQEvent *e) {
+ // we wanted to pass on the event
+ TQButton::enterEvent(e);
+ // we want to do mouseovers, so keep track of it here
+ hover_=true;
+ if(!m_clicked)
+ {
+ animate();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// leaveEvent()
+// ------------
+// Mouse has left the button
+
+void smoothblendButton::leaveEvent(TQEvent *e) {
+ // we wanted to pass on the event
+ TQButton::leaveEvent(e);
+ // we want to do mouseovers, so keep track of it here
+ hover_=false;
+ if(!m_clicked)
+ {
+ animate();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mousePressEvent()
+// -----------------
+// Button has been pressed
+
+void smoothblendButton::mousePressEvent(TQMouseEvent* e) {
+ lastmouse_ = e->button();
+
+ // translate and pass on mouse event
+ int button = Qt::LeftButton;
+ if ((type_ != ButtonMax) && (e->button() != Qt::LeftButton)) {
+ button = Qt::NoButton; // middle & right buttons inappropriate
+ }
+ TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
+ button, e->state());
+ TQButton::mousePressEvent(&me);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mouseReleaseEvent()
+// -----------------
+// Button has been released
+
+void smoothblendButton::mouseReleaseEvent(TQMouseEvent* e) {
+ lastmouse_ = e->button();
+
+ // translate and pass on mouse event
+ int button = Qt::LeftButton;
+ if ((type_ != ButtonMax) && (e->button() != Qt::LeftButton)) {
+ button = Qt::NoButton; // middle & right buttons inappropriate
+ }
+ TQMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state());
+ TQButton::mouseReleaseEvent(&me);
+ if(m_clicked)
+ {
+ m_clicked=false;
+ }
+}
+
+void smoothblendButton::setOn(bool on)
+{
+ TQButton::setOn(on);
+}
+
+void smoothblendButton::setDown(bool on)
+{
+ TQButton::setDown(on);
+}
+
+//////////////////////////////////////////////////////////
+// getButtonImage()
+// ----------------
+// get the button TQImage based on type and window mode
+TQImage smoothblendButton::getButtonImage(ButtonType type)
+{
+ TQImage finalImage;
+ switch(type) {
+ case ButtonClose:
+ finalImage = uic_findImage( "close.png" );
+ break;
+ case ButtonHelp:
+ finalImage = uic_findImage( "help.png" );
+ break;
+ case ButtonMin:
+ finalImage = uic_findImage( "minimize.png" );
+ break;
+ case ButtonMax:
+ if(client_->maximizeMode() == KDecorationDefines::MaximizeFull)
+ {
+ finalImage = uic_findImage( "restore.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "maximize.png" );
+ }
+ break;
+ case ButtonSticky:
+ if(client_->isOnAllDesktops())
+ {
+ finalImage = uic_findImage( "splat.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "circle.png" );
+ }
+ break;
+ case ButtonShade:
+ if(client_->isShade())
+ {
+ finalImage = uic_findImage( "shade.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "shade.png" );
+ }
+ break;
+ case ButtonAbove:
+ if(client_->keepAbove())
+ {
+ finalImage = uic_findImage( "keep_above_lit.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "keep_above.png" );
+ }
+ break;
+ case ButtonBelow:
+ if(client_->keepBelow())
+ {
+ finalImage = uic_findImage( "keep_below_lit.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "keep_below.png" );
+ }
+ break;
+ default:
+ finalImage = uic_findImage( "splat.png" );
+ break;
+ }
+ return finalImage;
+}
+
+//////////////////////////////////////////////////////////
+// drawButton()
+// -------------------------
+// draw the pixmap button
+
+void smoothblendButton::drawButton( TQPainter *painter ) {
+ if ( !smoothblendFactory::initialized() )
+ return ;
+
+ int newWidth = width() - 2;
+ int newHeight = height() - 2;
+ int dx = (width() - newWidth) / 2;
+ int dy = (height() - newHeight) / 2;
+ TQImage tmpResult;
+ TQColorGroup group;
+ TQColor redColor(red);
+ bool active = client_->isActive();
+ TQPixmap backgroundTile = client_->getTitleBarTile(active);
+ group = KDecoration::options()->colorGroup(KDecoration::ColorTitleBar, active);
+
+ //draw the titlebar behind the buttons and app icons
+ if ((client_->maximizeMode()==client_->MaximizeFull) && !KDecoration::options()->moveResizeMaximizedWindows())
+ {
+ painter->drawTiledPixmap(0, 0, width(), height(), backgroundTile);
+ }
+ else
+ {
+ painter->drawTiledPixmap(0, 0, width(), height(), backgroundTile, 0, y()-::factory->frameSize());
+ }
+
+ TQImage buttonImage = getButtonImage(type_).smoothScale( width(),height());
+ buttonImage = KImageEffect::blend( group.background(), buttonImage, .50);
+ if (type_ == ButtonMenu) {
+ //slight movement to show the menu button is depressed
+ if (isDown()) {
+ dx++;
+ dy++;
+ }
+ TQPixmap menuButtonPixmap(client_->icon().pixmap(TQIconSet::Large, TQIconSet::Normal));
+ TQImage menuButtonImage(menuButtonPixmap.convertToImage());
+ //draw the menu button the same size as the other buttons
+ //using TQIconSet::Large gives us a 32x32 icon to resize, resizing larger than
+ //that may produce pixilation of the image
+ painter->drawImage( dx, dy, menuButtonImage.smoothScale(newWidth, newHeight) );
+ } else {
+ //highlight on a mouse over repaint
+ double factor = animProgress * 0.13;
+
+ if(!isDown())
+ {
+ switch(::factory->getBtnComboBox())
+ {
+ case 0:
+ tmpResult = KImageEffect::intensity( buttonImage, factor);
+ break;
+ case 1:
+ tmpResult = KImageEffect::fade( buttonImage, factor, group.background());
+ break;
+ }
+ }
+ else
+ {
+ tmpResult = buttonImage;
+ }
+ painter->drawPixmap( 0, 0, TQPixmap( tmpResult ) );
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendClient Class
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendClient()
+// ---------------
+// Constructor
+
+smoothblendClient::smoothblendClient(KDecorationBridge *b, KDecorationFactory *f)
+ : KDecoration(b, f),
+ mainLayout_(0),
+ titleLayout_(0),
+ topSpacer_(0),
+ titleSpacer_(0),
+ leftTitleSpacer_(0), rightTitleSpacer_(0),
+ decoSpacer_(0),
+ leftSpacer_(0), rightSpacer_(0),
+ bottomSpacer_(0), windowSpacer_(0),
+ aCaptionBuffer(0), iCaptionBuffer(0),
+ aTitleBarTile(0), iTitleBarTile(0), aTitleBarTopTile(0), iTitleBarTopTile(0),
+ pixmaps_created(false),
+ //captionBufferDirty(true),
+ s_titleHeight(0),
+ s_titleFont(TQFont()),
+ closing(false)
+ {
+ aCaptionBuffer = new TQPixmap();
+ iCaptionBuffer = new TQPixmap();
+ //s_titleFont = isTool()?smoothblendFactory::titleFontTool():smoothblendFactory::titleFont();
+ s_titleFont = options()->font();
+ s_titleHeight = smoothblendFactory::titleSize();
+ }
+//////////////////////////////////////////////////////////////////////////////////
+// ~smoothblendClient()
+// --------------------
+// Destructor
+smoothblendClient::~smoothblendClient() {
+ delete aCaptionBuffer;
+ delete iCaptionBuffer;
+}
+
+void smoothblendClient::create_pixmaps() {
+ if(pixmaps_created)
+ return;
+ KPixmap tempPixmap;
+ TQPainter painter;
+ TQColorGroup group,widgetGroup;
+ int FRAMESIZE = ::factory->frameSize();
+ // Get the color groups we need for the gradients
+ group = options()->colorGroup(KDecoration::ColorTitleBar, true);
+ widgetGroup = widget()->colorGroup();
+
+ // active top title bar tile
+ tempPixmap.resize(1, TOPMARGIN);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ -100);
+ aTitleBarTopTile = new TQPixmap(1, TOPMARGIN);
+ painter.begin(aTitleBarTopTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // inactive top title bar tile
+ group = options()->colorGroup(KDecoration::ColorTitleBar, false);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ -100);
+ iTitleBarTopTile = new TQPixmap(1, TOPMARGIN);
+ painter.begin(iTitleBarTopTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // active title bar tile
+ tempPixmap.resize(1, s_titleHeight+FRAMESIZE);
+ group = options()->colorGroup(KDecoration::ColorTitleBar, true);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ 200);
+ aTitleBarTile = new TQPixmap(1, s_titleHeight+FRAMESIZE);
+ painter.begin(aTitleBarTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // inactive title bar tile
+ group = options()->colorGroup(KDecoration::ColorTitleBar, false);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ 200);
+ iTitleBarTile = new TQPixmap(1, s_titleHeight+FRAMESIZE);
+ painter.begin(iTitleBarTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ pixmaps_created = true;
+}
+
+void smoothblendClient::delete_pixmaps() {
+ delete aTitleBarTopTile;
+ aTitleBarTopTile = 0;
+
+ delete iTitleBarTopTile;
+ iTitleBarTopTile = 0;
+
+ delete aTitleBarTile;
+ aTitleBarTile = 0;
+
+ delete iTitleBarTile;
+ iTitleBarTile = 0;
+
+ pixmaps_created = false;
+}
+//////////////////////////////////////////////////////////////////////////////
+// init()
+// ------
+// Actual initializer for class
+
+void smoothblendClient::init() {
+ createMainWidget(WResizeNoErase | WRepaintNoErase);
+ widget()->installEventFilter(this);
+ handlebar = ::factory->frameSize() < 4 ? 4 - ::factory->frameSize() : 0;
+ // for flicker-free redraws
+ widget()->setBackgroundMode(NoBackground);
+
+ _resetLayout();
+
+ create_pixmaps();
+}
+void smoothblendClient::_resetLayout()
+{
+ // basic layout:
+ // _______________________________________________________________
+ // | topSpacer |
+ // |_______________________________________________________________|
+ // | leftTitleSpacer | btns | titlebar | bts | rightTitleSpacer |
+ // |_________________|______|_____________|_____|__________________|
+ // | decoSpacer |
+ // |_______________________________________________________________|
+ // | | | |
+ // | | windowWrapper | |
+ // | | | |
+ // |leftSpacer rightSpacer|
+ // |_|___________________________________________________________|_|
+ // | bottomSpacer |
+ // |_______________________________________________________________|
+ //
+ if (!::factory->initialized()) return;
+
+ delete mainLayout_;
+ delete titleLayout_;
+ delete topSpacer_;
+ delete titleSpacer_;
+ delete leftTitleSpacer_;
+ delete rightTitleSpacer_;
+ delete decoSpacer_;
+ delete leftSpacer_;
+ delete rightSpacer_;
+ delete bottomSpacer_;
+ delete windowSpacer_;
+
+ mainLayout_ = new TQVBoxLayout(widget());
+ // title
+ titleLayout_ = new TQHBoxLayout();
+ TQHBoxLayout *windowLayout_ = new TQHBoxLayout();
+ int FRAMESIZE = ::factory->frameSize();
+
+ topSpacer_ = new TQSpacerItem(1, FRAMESIZE, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ titlebar_ = new TQSpacerItem(1, ::factory->buttonSize(),
+ TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ leftTitleSpacer_ = new TQSpacerItem(FRAMESIZE, s_titleHeight,
+ TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ rightTitleSpacer_ = new TQSpacerItem(FRAMESIZE, s_titleHeight,
+ TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ decoSpacer_ = new TQSpacerItem(1, FRAMESIZE, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ leftSpacer_ = new TQSpacerItem(::factory->frameSize(), 1,
+ TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ rightSpacer_ = new TQSpacerItem(::factory->frameSize(), 1,
+ TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ bottomSpacer_ = new TQSpacerItem(1, ::factory->frameSize(),
+ TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+
+ // sizeof(...) is calculated at compile time
+ memset(button, 0, sizeof(smoothblendButton *) * ButtonTypeCount);
+
+ // message in preview widget
+ if (isPreview()) {
+ windowLayout_->addWidget(
+ new TQLabel( i18n("<b><center>Smooth Blend</center></b>"), widget() ), 1 );
+ } else {
+ windowLayout_->addItem(new TQSpacerItem(0, 0));
+ }
+
+ // setup titlebar buttons
+ for (int n=0; n<ButtonTypeCount; n++)
+ button[n] = 0;
+ //Deal with the title and buttons
+ titleLayout_->addItem(leftTitleSpacer_);
+ addButtons(titleLayout_,
+ options()->customButtonPositions() ? options()->titleButtonsLeft() : TQString(default_left),
+ ::factory->titleSize()-1);
+ titleLayout_->addItem(titlebar_);
+ addButtons(titleLayout_,
+ options()->customButtonPositions() ? options()->titleButtonsRight() : TQString(default_right),
+ ::factory->titleSize()-1);
+ titleLayout_->addItem(rightTitleSpacer_);
+
+ //Mid - left side, middle contents and right side
+ TQHBoxLayout * midLayout_ = new TQHBoxLayout();
+ midLayout_->addItem(leftSpacer_);
+ midLayout_->addLayout(windowLayout_);
+ midLayout_->addItem(rightSpacer_);
+
+ //Layout order
+ mainLayout_->addItem( topSpacer_ );
+ mainLayout_->addLayout( titleLayout_ );
+ mainLayout_->addItem( decoSpacer_ );
+ mainLayout_->addLayout( midLayout_ );
+ mainLayout_->addItem( bottomSpacer_ );
+
+ // connections
+ connect(this, TQT_SIGNAL(keepAboveChanged(bool)), TQT_SLOT(keepAboveChange(bool)));
+ connect(this, TQT_SIGNAL(keepBelowChanged(bool)), TQT_SLOT(keepBelowChange(bool)));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// addButtons()
+// ------------
+// Add buttons to title layout
+
+void smoothblendClient::addButtons(TQBoxLayout *layout, const TQString& s, int button_size) {
+ TQString tip;
+ if (s.length() > 0) {
+ for (unsigned n=0; n < s.length(); n++) {
+ switch (s[n]) {
+ case 'M': // Menu button
+ if (!button[ButtonMenu]) {
+ button[ButtonMenu] =
+ new smoothblendButton(this, "splat.png", i18n("Menu"),ButtonMenu,button_size);
+ connect(button[ButtonMenu], TQT_SIGNAL(pressed()), this, TQT_SLOT(menuButtonPressed()));
+ connect(button[ButtonMenu], TQT_SIGNAL(released()), this, TQT_SLOT(menuButtonReleased()));
+ layout->addWidget(button[ButtonMenu]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'S': // Sticky button
+ if (!button[ButtonSticky]) {
+ if (isOnAllDesktops()) {
+ tip = i18n("Un-Sticky");
+ } else {
+ tip = i18n("Sticky");
+ }
+ button[ButtonSticky] =
+ new smoothblendButton(this, "circle.png", tip, ButtonSticky, button_size, true);
+ connect(button[ButtonSticky], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(toggleOnAllDesktops()));
+ layout->addWidget(button[ButtonSticky]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'H': // Help button
+ if ((!button[ButtonHelp]) && providesContextHelp()) {
+ button[ButtonHelp] =
+ new smoothblendButton(this, "help.png", i18n("Help"), ButtonHelp, button_size);
+ connect(button[ButtonHelp], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(showContextHelp()));
+ layout->addWidget(button[ButtonHelp]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'I': // Minimize button
+ if ((!button[ButtonMin]) && isMinimizable()) {
+ button[ButtonMin] =
+ new smoothblendButton(this, "minimize.png", i18n("Minimize"), ButtonMin, button_size);
+ connect(button[ButtonMin], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(minimize()));
+ layout->addWidget(button[ButtonMin]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'A': // Maximize button
+ if ((!button[ButtonMax]) && isMaximizable()) {
+ if (maximizeMode() == MaximizeFull) {
+ tip = i18n("Restore");
+ } else {
+ tip = i18n("Maximize");
+ }
+ button[ButtonMax] =
+ new smoothblendButton(this, "maximize.png", tip, ButtonMax, button_size, true);
+ connect(button[ButtonMax], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(maxButtonPressed()));
+ layout->addWidget(button[ButtonMax]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'X': // Close button
+ if ((!button[ButtonClose]) && isCloseable()) {
+ button[ButtonClose] =
+ new smoothblendButton(this, "close.png", i18n("Close"), ButtonClose, button_size);
+ connect(button[ButtonClose], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(closeWindow()));
+ layout->addWidget(button[ButtonClose]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'F': // Above button
+ if ((!button[ButtonAbove])) {
+ button[ButtonAbove] =
+ new smoothblendButton(this, "keep_above.png",
+ i18n("Keep Above Others"), ButtonAbove, button_size, true);
+ connect(button[ButtonAbove], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(aboveButtonPressed()));
+ layout->addWidget(button[ButtonAbove]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'B': // Below button
+ if ((!button[ButtonBelow])) {
+ button[ButtonBelow] =
+ new smoothblendButton(this, "keep_below.png",
+ i18n("Keep Below Others"), ButtonBelow, button_size, true);
+ connect(button[ButtonBelow], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(belowButtonPressed()));
+ layout->addWidget(button[ButtonBelow]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'L': // Shade button
+ if ((!button[ButtonShade]) && isShadeable()) {
+ if ( isSetShade()) {
+ tip = i18n("Unshade");
+ } else {
+ tip = i18n("Shade");
+ }
+ button[ButtonShade] =
+ new smoothblendButton(this, "shade.png", tip, ButtonShade, button_size, true);
+ connect(button[ButtonShade], TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(shadeButtonPressed()));
+ layout->addWidget(button[ButtonShade]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case '_': // Spacer item
+ layout->addSpacing(::factory->frameSize());
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// activeChange()
+// --------------
+// window active state has changed
+
+void smoothblendClient::activeChange() {
+ for (int n=0; n<ButtonTypeCount; n++)
+ if (button[n])
+ button[n]->reset();
+ widget()->repaint(false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// captionChange()
+// ---------------
+// The title has changed
+
+void smoothblendClient::captionChange() {
+ widget()->repaint(titlebar_->geometry(), false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// desktopChange()
+// ---------------
+// Called when desktop/sticky changes
+
+void smoothblendClient::desktopChange() {
+ bool d = isOnAllDesktops();
+ if (button[ButtonSticky]) {
+ TQToolTip::remove(button[ButtonSticky]);
+ TQToolTip::add(button[ButtonSticky], d ? i18n("Un-Sticky") : i18n("Sticky"));
+ button[ButtonSticky]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// iconChange()
+// ------------
+// The title has changed
+
+void smoothblendClient::iconChange() {
+ if (button[ButtonMenu]) {
+ button[ButtonMenu]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// maximizeChange()
+// ----------------
+// Maximized state has changed
+
+void smoothblendClient::maximizeChange() {
+ bool m = (maximizeMode() == MaximizeFull);
+ if (button[ButtonMax]) {
+ TQToolTip::remove(button[ButtonMax]);
+ TQToolTip::add(button[ButtonMax], m ? i18n("Restore") : i18n("Maximize"));
+ button[ButtonMax]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// shadeChange()
+// -------------
+// Called when window shading changes
+
+void smoothblendClient::shadeChange() {
+ bool s = isSetShade();
+ if (button[ButtonShade]) {
+ TQToolTip::remove(button[ButtonShade]);
+ TQToolTip::add(button[ButtonShade], s ? i18n("Unshade") : i18n("Shade"));
+ button[ButtonShade]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// keepAboveChange()
+// ------------
+// The above state has changed
+
+void smoothblendClient::keepAboveChange(bool a) {
+ if (button[ButtonAbove]) {
+ button[ButtonAbove]->setOn(a);
+ button[ButtonAbove]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// keepBelowChange()
+// ------------
+// The below state has changed
+
+void smoothblendClient::keepBelowChange(bool b) {
+ if (button[ButtonBelow]) {
+ button[ButtonBelow]->setOn(b);
+ button[ButtonBelow]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// borders()
+// ----------
+// Get the size of the borders
+
+void smoothblendClient::borders(int &left, int &right, int &top, int &bottom) const {
+ int FRAMESIZE = ::factory->frameSize();
+
+ if ((maximizeMode()==MaximizeFull) && !options()->moveResizeMaximizedWindows()) {
+ left = right = bottom = 0;
+ top = ::factory->buttonSize();
+
+ // update layout etc.
+ topSpacer_->changeSize(1, 0, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ decoSpacer_->changeSize(1, 0, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ leftSpacer_->changeSize(left, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ leftTitleSpacer_->changeSize(left, top, TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ rightSpacer_->changeSize(right, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ rightTitleSpacer_->changeSize(right, top, TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ bottomSpacer_->changeSize(1, bottom, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ } else {
+ left = right = bottom = ::factory->frameSize();
+ top = ::factory->titleSize() + (FRAMESIZE*2);
+
+ // update layout etc.
+ topSpacer_->changeSize(1, FRAMESIZE, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ decoSpacer_->changeSize(1, FRAMESIZE, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ leftSpacer_->changeSize(left, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ leftTitleSpacer_->changeSize(left, s_titleHeight, TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ rightSpacer_->changeSize(right, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding);
+ rightTitleSpacer_->changeSize(right,s_titleHeight,TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ bottomSpacer_->changeSize(1, bottom, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
+ }
+ widget()->layout()->activate();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// resize()
+// --------
+// Called to resize the window
+
+void smoothblendClient::resize(const TQSize &size) {
+ widget()->resize(size);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// minimumSize()
+// -------------
+// Return the minimum allowable size for this window
+
+TQSize smoothblendClient::minimumSize() const {
+ return widget()->minimumSize();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mousePosition()
+// ---------------
+// Return logical mouse position
+
+KDecoration::Position smoothblendClient::mousePosition(const TQPoint &point) const {
+ const int corner = 24;
+ Position pos;
+ int fs = ::factory->frameSize() + handlebar;
+ //int fs = ::factory->frameSize();
+
+ if (point.y() <= fs) {
+ // inside top frame
+ if (point.x() <= corner)
+ pos = PositionTopLeft;
+ else if (point.x() >= (width()-corner))
+ pos = PositionTopRight;
+ else
+ pos = PositionTop;
+ } else if (point.y() >= (height()-fs*2)) {
+ // inside handle
+ if (point.x() <= corner)
+ pos = PositionBottomLeft;
+ else if (point.x() >= (width()-corner))
+ pos = PositionBottomRight;
+ else
+ pos = PositionBottom;
+ } else if (point.x() <= fs ) {
+ // on left frame
+ if (point.y() <= corner)
+ pos = PositionTopLeft;
+ else if (point.y() >= (height()-corner))
+ pos = PositionBottomLeft;
+ else
+ pos = PositionLeft;
+ } else if (point.x() >= width()-fs) {
+ // on right frame
+ if (point.y() <= corner)
+ pos = PositionTopRight;
+ else if (point.y() >= (height()-corner))
+ pos = PositionBottomRight;
+ else
+ pos = PositionRight;
+ } else {
+ // inside the frame
+ pos = PositionCenter;
+ }
+ return pos;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eventFilter()
+// -------------
+// Event filter
+
+bool smoothblendClient::eventFilter(TQObject *obj, TQEvent *e) {
+ if (TQT_BASE_OBJECT(obj) != TQT_BASE_OBJECT(widget()))
+ return false;
+
+ switch (e->type()) {
+ case TQEvent::MouseButtonDblClick: {
+ mouseDoubleClickEvent(TQT_TQMOUSEEVENT(e));
+ return true;
+ }
+ case TQEvent::MouseButtonPress: {
+ processMousePressEvent(TQT_TQMOUSEEVENT(e));
+ return true;
+ }
+ case TQEvent::Paint: {
+ paintEvent(TQT_TQPAINTEVENT(e));
+ return true;
+ }
+ case TQEvent::Resize: {
+ resizeEvent(TQT_TQRESIZEEVENT(e));
+ return true;
+ }
+ case TQEvent::Show: {
+ showEvent(TQT_TQSHOWEVENT(e));
+ return true;
+ }
+ case TQEvent::Wheel: {
+ wheelEvent(TQT_TQWHEELEVENT( e ));
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mouseDoubleClickEvent()
+// -----------------------
+// Doubleclick on title
+
+void smoothblendClient::mouseDoubleClickEvent(TQMouseEvent *e) {
+ if (titlebar_->geometry().contains(e->pos()))
+ titlebarDblClickOperation();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// wheelEvent()
+// ------------
+// Mouse wheel on titlebar
+
+void smoothblendClient::wheelEvent(TQWheelEvent *e)
+{
+ if (titleLayout_->geometry().contains(e->pos()) )
+ titlebarMouseWheelOperation( e->delta());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// paintEvent()
+// ------------
+// Repaint the window
+
+void smoothblendClient::paintEvent(TQPaintEvent*) {
+ if (!::factory->initialized())
+ {
+ return;
+ }
+
+ //int FRAMESIZE = ::factory->frameSize();
+ const uint maxCaptionLength = 300; // truncate captions longer than this!
+ TQString captionText(caption());
+ if (captionText.length() > maxCaptionLength) {
+ captionText.truncate(maxCaptionLength);
+ captionText.append(" [...]");
+ }
+
+ TQColor blackColor(black);
+ TQColor redColor(red);
+ TQColorGroup group,widgetGroup;
+ TQPainter painter(widget());
+ bool active = isActive();
+ //get group information first
+ group = options()->colorGroup(KDecoration::ColorTitleBar, isActive());
+ widgetGroup = widget()->colorGroup();
+
+ TQRect topRect( topSpacer_->geometry() );
+ TQRect titleRect( titleLayout_->geometry() );
+ TQRect textRect( titlebar_->geometry() );
+ TQRect Rltitle( leftTitleSpacer_->geometry() );
+ TQRect Rrtitle( rightTitleSpacer_->geometry() );
+ TQRect Rdeco( decoSpacer_->geometry() );
+ TQRect Rleft( leftSpacer_->geometry() );
+ TQRect Rright( rightSpacer_->geometry() );
+ TQRect Rbottom( bottomSpacer_->geometry() );
+ TQRect tempRect;
+
+
+ /*
+ if(active)
+ {
+ tqDebug("paintEvent() topRect.y() = %i\tbottom() = %i",topRect.top(),topRect.bottom());
+ tqDebug("paintEvent() titleRect.y() = %i\tbottom() = %i",titleRect.top(),titleRect.bottom());
+ tqDebug("paintEvent() textRect.y() = %i\tbottom() = %i",textRect.top(),textRect.bottom());
+ tqDebug("paintEvent() Rltitle.y() = %i\tbottom() = %i",Rltitle.top(),Rltitle.bottom());
+ tqDebug("paintEvent() Rrtitle.y() = %i\tbottom() = %i",Rrtitle.top(),Rrtitle.bottom());
+ tqDebug("paintEvent() Rdeco.y() = %i\tbottom() = %i",Rdeco.top(),Rdeco.bottom());
+ tqDebug("paintEvent() Rleft.y() = %i\tbottom() = %i",Rleft.top(),Rleft.bottom());
+ tqDebug("paintEvent() Rright.y() = %i\tbottom() = %i",Rright.top(),Rright.bottom());
+ tqDebug("paintEvent() Rbottom.y() = %i\tbottom() = %i",Rbottom.top(),Rbottom.bottom());
+ }
+ */
+
+ // top
+ painter.drawTiledPixmap(topRect, active ? *aTitleBarTopTile:*iTitleBarTopTile);
+ painter.drawTiledPixmap(titleRect.x(),
+ titleRect.y(),
+ titleRect.width(),
+ titleRect.height() + Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+
+ textRect.setRect(textRect.x()+SIDETITLEMARGIN,
+ textRect.y(),
+ textRect.width()-SIDETITLEMARGIN*2,
+ textRect.height());
+ TQRect shadowRect(textRect.x()+1,textRect.y()+1,textRect.width(),textRect.height());
+ //if we are shadowing title bar text
+ if(::factory->titleShadow())
+ {
+ //shadow text
+ painter.setFont(options()->font(isActive(), false));
+ painter.setPen(blackColor);
+ painter.drawText(shadowRect,
+ ::factory->titleAlign() | AlignVCenter | TQt::SingleLine,
+ captionText);
+ }
+ // draw title text
+ painter.setFont(options()->font(isActive(), false));
+ painter.setPen(options()->color(KDecoration::ColorFont, isActive()));
+ painter.drawText(textRect,
+ ::factory->titleAlign() | AlignVCenter | TQt::SingleLine,
+ captionText);
+
+ //left of buttons and title
+ painter.drawTiledPixmap(Rltitle.x(),
+ Rltitle.y(),
+ Rltitle.width(),
+ Rltitle.height()+Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+ // left mid layout
+ painter.fillRect(Rleft,widgetGroup.background());
+
+ // right of buttons and title
+ painter.drawTiledPixmap(Rrtitle.x(),
+ Rrtitle.y(),
+ Rrtitle.width(),
+ Rrtitle.height()+Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+ // right mid layout
+ painter.fillRect(Rright,widgetGroup.background());
+
+ // bottom
+ /*
+ if(isShade())
+ {
+ frame.setRect(0,::factory->titleSize()+FRAMESIZE, width(), FRAMESIZE);
+ }
+ else
+ {
+ frame.setRect(0, height() - (FRAMESIZE*2), width(), (FRAMESIZE*2));
+ }
+ */
+ painter.fillRect(Rbottom, widgetGroup.background());
+
+ //draw a line between title bar and window contents
+ painter.setPen(group.background());
+
+ // outline outside the frame but not the corners if they are rounded
+ tempRect = widget()->rect();
+ painter.drawRect(tempRect);
+
+ bool cornersFlag = ::factory->roundedCorners();
+ if(cornersFlag) {
+ // local temp right and bottom
+ int r(width());
+ painter.setPen(group.background());
+ painter.drawPoint(4, 1);
+ painter.drawPoint(3, 1);
+ painter.drawPoint(2, 2);
+ painter.drawPoint(1, 3);
+ painter.drawPoint(1, 4);
+ painter.drawPoint(r - 5, 1);
+ painter.drawPoint(r - 4, 1);
+ painter.drawPoint(r - 3, 2);
+ painter.drawPoint(r - 2, 3);
+ painter.drawPoint(r - 2, 4);
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// updateMask()
+// ------------
+// update the frame mask
+void smoothblendClient::updateMask() {
+ bool cornersFlag = ::factory->roundedCorners();
+ if ( (!options()->moveResizeMaximizedWindows() && maximizeMode() == MaximizeFull ) )
+ {
+ setMask(TQRegion(widget()->rect()));
+ return;
+ }
+
+ int r(width());
+ int b(height());
+ TQRegion mask;
+
+ mask=TQRegion(widget()->rect());
+
+ // Remove top-left corner.
+ if(cornersFlag) {
+ mask -= TQRegion(0, 0, 5, 1);
+ mask -= TQRegion(0, 1, 3, 1);
+ mask -= TQRegion(0, 2, 2, 1);
+ mask -= TQRegion(0, 3, 1, 2);
+ mask -= TQRegion(r - 5, 0, 5, 1);
+ mask -= TQRegion(r - 3, 1, 3, 1);
+ mask -= TQRegion(r - 2, 2, 2, 1);
+ mask -= TQRegion(r - 1, 3, 1, 2);
+ }
+ //always remove one corner pixel so it simulates a soft corner like plastik
+ mask -= TQRegion(0,0,1,1);
+ mask -= TQRegion(r-1,0,1,1);
+ mask -= TQRegion(0, b-1, 1,1);
+ mask -= TQRegion(r-1,b-1,1,1);
+
+ setMask(mask);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// resizeEvent()
+// -------------
+// Window is being resized
+
+void smoothblendClient::resizeEvent(TQResizeEvent *) {
+ if (widget()->isShown()) {
+ TQRegion region = widget()->rect();
+ region = region.subtract(titlebar_->geometry());
+ widget()->erase(region);
+ updateMask();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// showEvent()
+// -----------
+// Window is being shown
+
+void smoothblendClient::showEvent(TQShowEvent *) {
+ updateMask();
+ widget()->repaint();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// maxButtonPressed()
+// -----------------
+// Max button was pressed
+
+void smoothblendClient::maxButtonPressed() {
+ if (button[ButtonMax]) {
+ maximize(button[ButtonMax]->lastMousePress());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// shadeButtonPressed()
+// -----------------
+// Shade button was pressed
+
+void smoothblendClient::shadeButtonPressed() {
+ if (button[ButtonShade]) {
+ setShade( !isSetShade());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// aboveButtonPressed()
+// -----------------
+// Above button was pressed
+
+void smoothblendClient::aboveButtonPressed() {
+ if (button[ButtonAbove]) {
+ setKeepAbove( !keepAbove());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// belowButtonPressed()
+// -----------------
+// Below button was pressed
+
+void smoothblendClient::belowButtonPressed() {
+ if (button[ButtonBelow]) {
+ setKeepBelow( !keepBelow());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// menuButtonPressed()
+// -------------------
+// Menu button was pressed (popup the menu)
+
+void smoothblendClient::menuButtonPressed() {
+ static TQTime* t = NULL;
+ static smoothblendClient* lastClient = NULL;
+ if (t == NULL)
+ t = new TQTime;
+ bool dbl = (lastClient==this && t->elapsed() <= TQApplication::doubleClickInterval());
+ lastClient = this;
+ t->start();
+ //if (button[ButtonMenu] && !dbl && !::factory->menuClosed()) {
+ if ( !dbl || !::factory->menuClosed()) {
+ TQPoint p(button[ButtonMenu]->rect().bottomLeft().x(),
+ button[ButtonMenu]->rect().bottomLeft().y());
+ KDecorationFactory* f = factory();
+ showWindowMenu(button[ButtonMenu]->mapToGlobal(p));
+ if (!f->exists(this))
+ return; // decoration was destroyed
+ button[ButtonMenu]->setDown(false);
+ }
+ else
+ {
+ closing = true;
+ }
+}
+
+void smoothblendClient::menuButtonReleased()
+{
+ if(closing)
+ {
+ closeWindow();
+ }
+}
+
+#include "smoothblend.moc"