Back to index

kdeartwork  4.3.2
glowclient.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           glowclient.cpp  -  description
00003                              -------------------
00004     begin                : Thu Sep 6 2001
00005     copyright            : (C) 2001 by Henning Burchardt
00006     email                : h_burchardt@gmx.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <qapplication.h>
00019 #include <qbitmap.h>
00020 #include <qimage.h>
00021 #include <qlayout.h>
00022 #include <qpainter.h>
00023 #include <qpixmap.h>
00024 //Added by qt3to4:
00025 #include <QPaintEvent>
00026 #include <Q3PointArray>
00027 #include <QEvent>
00028 #include <QBoxLayout>
00029 #include <Q3ValueList>
00030 #include <QShowEvent>
00031 #include <QResizeEvent>
00032 #include <QVBoxLayout>
00033 #include <QMouseEvent>
00034 #include <kconfig.h>
00035 #include <kdebug.h>
00036 #include <klocale.h>
00037 #include <kpixmapeffect.h>
00038 #include <kpixmap.h>
00039 #include <kstandarddirs.h>
00040 #include <qlabel.h>
00041 #include "resources.h"
00042 #include "glowclient.h"
00043 #include "glowbutton.h"
00044 
00045 namespace Glow
00046 {
00047 
00048 static int titleHeight;
00049 static int SIDE_MARGIN;
00050 static int BOTTOM_MARGIN;
00051 static const int TITLE_MARGIN = 2;
00052 static const int TITLE_SPACING = 1;
00053 static int RESIZE_HANDLE_HEIGHT;
00054 
00055 //-----------------------------------------------------------------------------
00056 
00057 GlowClientConfig::GlowClientConfig()
00058 {
00059        themeName = "default";
00060 }
00061 
00062 void GlowClientConfig::load(KDecorationFactory *factory)
00063 {
00064        KConfig conf("kwinglowrc");
00065        conf.setGroup("General");
00066 
00067        const QColor defaultCloseButtonColor(DEFAULT_CLOSE_BUTTON_COLOR);
00068        const QColor defaultMaximizeButtonColor(DEFAULT_MAXIMIZE_BUTTON_COLOR);
00069        const QColor defaultIconifyButtonColor(DEFAULT_ICONIFY_BUTTON_COLOR);
00070        const QColor defaultHelpButtonColor(DEFAULT_HELP_BUTTON_COLOR);
00071        const QColor defaultStickyButtonColor(DEFAULT_STICKY_BUTTON_COLOR);
00072 
00073        stickyButtonGlowColor = conf.readColorEntry(
00074               "stickyButtonGlowColor", &defaultStickyButtonColor);
00075 
00076        helpButtonGlowColor = conf.readColorEntry(
00077               "helpButtonGlowColor", &defaultHelpButtonColor);
00078 
00079        iconifyButtonGlowColor = conf.readColorEntry(
00080               "iconifyButtonGlowColor", &defaultIconifyButtonColor);
00081 
00082        maximizeButtonGlowColor = conf.readColorEntry(
00083               "maximizeButtonGlowColor", &defaultMaximizeButtonColor);
00084 
00085        closeButtonGlowColor = conf.readColorEntry(
00086               "closeButtonGlowColor", &defaultCloseButtonColor);
00087 
00088        showResizeHandle = conf.readEntry("showResizeHandle", true);
00089        titlebarGradientType = conf.readNumEntry("titlebarGradientType",
00090               KPixmapEffect::DiagonalGradient);
00091 
00092        themeName = conf.readEntry ("themeName", "default");
00093 
00094        switch(KDecoration::options()->preferredBorderSize (factory)) {
00095        case KDecoration::BorderLarge:
00096               SIDE_MARGIN = 8;
00097               BOTTOM_MARGIN = 6;
00098               RESIZE_HANDLE_HEIGHT = 10;
00099               break;
00100        case KDecoration::BorderVeryLarge:
00101               SIDE_MARGIN = 12;
00102               BOTTOM_MARGIN = 12;
00103               RESIZE_HANDLE_HEIGHT = 18;
00104               break;
00105        case KDecoration::BorderHuge:
00106               SIDE_MARGIN = 18;
00107               BOTTOM_MARGIN = 18;
00108               RESIZE_HANDLE_HEIGHT = 27;
00109               break;
00110        case KDecoration::BorderVeryHuge:
00111               SIDE_MARGIN = 27;
00112               BOTTOM_MARGIN = 27;
00113               RESIZE_HANDLE_HEIGHT = 40;
00114               break;
00115        case KDecoration::BorderOversized:
00116               SIDE_MARGIN = 40;
00117               BOTTOM_MARGIN = 40;
00118               RESIZE_HANDLE_HEIGHT = 60;
00119               break;
00120        case KDecoration::BorderNormal:
00121        default:
00122               SIDE_MARGIN = 4;
00123               BOTTOM_MARGIN = 2;
00124               RESIZE_HANDLE_HEIGHT = 4;
00125        }
00126 }
00127 
00128 //-----------------------------------------------------------------------------
00129 
00130 GlowClientGlobals::~GlowClientGlobals()
00131 {
00132        deletePixmaps();
00133        m_instance = 0;
00134 }
00135 
00136 QString GlowClientGlobals::getPixmapName(PixmapType type, bool isActive)
00137 {
00138        QString s = getPixmapTypeName(static_cast<PixmapType>(type));
00139        s += "|";
00140        s += isActive ? "Active" : "NotActive";
00141        return s;
00142 }
00143 
00144 GlowClientGlobals::GlowClientGlobals()
00145        : KDecorationFactory()
00146 {
00147        _button_factory = new GlowButtonFactory();
00148        readConfig();
00149        readTheme ();
00150        if (!createPixmaps())
00151        {
00152               deletePixmaps();
00153               delete _theme;
00154               config()->themeName = "default";
00155               readTheme();
00156               createPixmaps();
00157        }
00158 }
00159 
00160 void GlowClientGlobals::readConfig()
00161 {
00162        _config = new GlowClientConfig();
00163        _config->load(this);
00164 }
00165 
00166 Q3ValueList< GlowClientGlobals::BorderSize >
00167 GlowClientGlobals::borderSizes() const
00168 {
00169     // the list must be sorted
00170     return Q3ValueList< BorderSize >() << BorderNormal <<
00171        BorderLarge << BorderVeryLarge <<  BorderHuge <<
00172        BorderVeryHuge << BorderOversized;
00173 }
00174 
00175 void GlowClientGlobals::readTheme()
00176 {
00177        QString theme_config_file = KGlobal::dirs()->findResource ("data",
00178                      QString("kwin/glow-themes/") + config()->themeName + "/" +
00179                      config()->themeName + ".theme");
00180        if (theme_config_file.isNull())
00181        {
00182               config()->themeName = "default";
00183               return;
00184        }
00185 
00186        KConfig conf (theme_config_file);
00187        _theme = new GlowTheme(default_glow_theme);
00188 
00189        _theme->buttonSize = conf.readSizeEntry ("buttonSize",
00190                      &_theme->buttonSize);
00191        _theme->stickyOnPixmap = conf.readEntry ("stickyOnPixmap",
00192                      _theme->stickyOnPixmap);
00193        _theme->stickyOffPixmap = conf.readEntry ("stickyOffPixmap",
00194                      _theme->stickyOffPixmap);
00195        _theme->maximizeOnPixmap = conf.readEntry ("maximizeOnPixmap",
00196                      _theme->maximizeOnPixmap);
00197        _theme->maximizeOffPixmap = conf.readEntry ("maximizeOffPixmap",
00198                      _theme->maximizeOffPixmap);
00199        _theme->helpPixmap = conf.readEntry ("helpPixmap",
00200                      _theme->helpPixmap);
00201        _theme->closePixmap = conf.readEntry ("closePixmap",
00202                      _theme->closePixmap);
00203        _theme->iconifyPixmap = conf.readEntry ("iconifyPixmap",
00204                      _theme->iconifyPixmap);
00205        _theme->stickyOnGlowPixmap = conf.readEntry ("stickyOnGlowPixmap",
00206                      _theme->stickyOnGlowPixmap);
00207        _theme->stickyOffGlowPixmap = conf.readEntry ("stickyOffGlowPixmap",
00208                      _theme->stickyOffGlowPixmap);
00209        _theme->maximizeOnGlowPixmap = conf.readEntry ("maximizeOnGlowPixmap",
00210                      _theme->maximizeOnGlowPixmap);
00211        _theme->maximizeOffGlowPixmap = conf.readEntry ("maximizeOffGlowPixmap",
00212                      _theme->maximizeOffGlowPixmap);
00213        _theme->helpGlowPixmap = conf.readEntry ("helpGlowPixmap",
00214                      _theme->helpGlowPixmap);
00215        _theme->closeGlowPixmap = conf.readEntry ("closeGlowPixmap",
00216                      _theme->closeGlowPixmap);
00217        _theme->iconifyGlowPixmap = conf.readEntry ("iconifyGlowPixmap",
00218                      _theme->iconifyGlowPixmap);
00219 
00220        titleHeight = QFontMetrics(KDecoration::options()->font(true)).height();
00221        if (titleHeight < SIDE_MARGIN)
00222               titleHeight = SIDE_MARGIN;
00223        if (titleHeight < _theme->buttonSize.height())
00224               titleHeight = _theme->buttonSize.height();
00225 }
00226 
00227 bool GlowClientGlobals::reset( unsigned long /*changed*/ )
00228 {
00229        deletePixmaps();
00230        delete _config;
00231        readConfig();
00232        delete _theme;
00233        readTheme ();
00234        if (! createPixmaps())
00235        {
00236               deletePixmaps();
00237               delete _theme;
00238               _config->themeName = "default";
00239               readTheme();
00240               createPixmaps();
00241        }
00242        return true; // FRAME
00243 }
00244 
00245 bool GlowClientGlobals::supports( Ability ability )
00246 {
00247     switch( ability )
00248     {
00249         case AbilityAnnounceButtons:
00250         case AbilityButtonOnAllDesktops:
00251         case AbilityButtonSpacer:
00252         case AbilityButtonHelp:
00253         case AbilityButtonMinimize:
00254         case AbilityButtonMaximize:
00255         case AbilityButtonClose:
00256             return true;
00257         default:
00258             return false;
00259     };
00260 }
00261 
00262 bool GlowClientGlobals::createPixmaps()
00263 {
00264        for( int type=0; type<=Close; type++ ) {
00265               if (! createPixmap(static_cast<PixmapType>(type), false))
00266                      return false;
00267               if (! createPixmap(static_cast<PixmapType>(type), true))
00268                      return false;
00269        }
00270        return true;
00271 }
00272 
00273 void GlowClientGlobals::deletePixmaps()
00274 {
00275        PixmapCache::clear();
00276 }
00277 
00278 const QString GlowClientGlobals::getPixmapTypeName(PixmapType type)
00279 {
00280        switch(type) {
00281               case (StickyOn):
00282                      return "StickyOn";
00283               case(StickyOff ):
00284                      return "StickyOff";
00285               case(Help):
00286                      return "Help";
00287               case(Iconify):
00288                      return "Iconify";
00289               case(MaximizeOn):
00290                      return "MaximizeOn";
00291               case(MaximizeOff):
00292                      return "MaximizeOff";
00293               case(Close):
00294                      return "Close";
00295               default:
00296                      return QString();
00297        }
00298 }
00299 
00300 bool GlowClientGlobals::createPixmap(PixmapType type, bool isActive)
00301 {
00302        QString theme_dir = KGlobal::dirs()->findResource ("data",
00303                      QString("kwin/glow-themes/") + _config->themeName + "/");
00304 
00305        QColor glow_color;
00306        QColor color = options()->color(ColorButtonBg, isActive);
00307 
00308        QImage bg_image (theme_dir+_theme->backgroundPixmap);
00309        QImage fg_image;
00310        QImage glow_image;
00311 
00312        switch(type) {
00313               case (StickyOn):
00314               {
00315                      fg_image = QImage (theme_dir+_theme->stickyOnPixmap);
00316                      glow_image = QImage (theme_dir+_theme->stickyOnGlowPixmap);
00317                      glow_color = _config->stickyButtonGlowColor;
00318                      break;
00319               }
00320               case (StickyOff):
00321               {
00322                      fg_image = QImage (theme_dir+_theme->stickyOffPixmap);
00323                      glow_image = QImage (theme_dir+_theme->stickyOffGlowPixmap);
00324                      glow_color = _config->stickyButtonGlowColor;
00325                      break;
00326               }
00327               case (Help):
00328               {
00329                      fg_image = QImage (theme_dir+_theme->helpPixmap);
00330                      glow_image = QImage (theme_dir+_theme->helpGlowPixmap);
00331                      glow_color = _config->helpButtonGlowColor;
00332                      break;
00333               }
00334               case (Iconify):
00335               {
00336                      fg_image = QImage (theme_dir+_theme->iconifyPixmap);
00337                      glow_image = QImage (theme_dir+_theme->iconifyGlowPixmap);
00338                      glow_color = _config->iconifyButtonGlowColor;
00339                      break;
00340               }
00341               case (MaximizeOn):
00342               {
00343                      fg_image = QImage (theme_dir+_theme->maximizeOnPixmap);
00344                      glow_image = QImage (theme_dir+_theme->maximizeOnGlowPixmap);
00345                      glow_color = _config->maximizeButtonGlowColor;
00346                      break;
00347               }
00348               case (MaximizeOff):
00349               {
00350                      fg_image = QImage (theme_dir+_theme->maximizeOffPixmap);
00351                      glow_image = QImage (theme_dir+_theme->maximizeOffGlowPixmap);
00352                      glow_color = _config->maximizeButtonGlowColor;
00353                      break;
00354               }
00355               case (Close):
00356               {
00357                      fg_image = QImage (theme_dir+_theme->closePixmap);
00358                      glow_image = QImage (theme_dir+_theme->closeGlowPixmap);
00359                      glow_color = _config->closeButtonGlowColor;
00360                      break;
00361               }
00362        }
00363 
00364        if (bg_image.size() != _theme->buttonSize
00365                      || fg_image.size() != _theme->buttonSize
00366                      || glow_image.size() != _theme->buttonSize)
00367               return false;
00368 
00369        QPixmap * glowPm = buttonFactory()->createGlowButtonPixmap(
00370               bg_image, fg_image, glow_image,
00371               color, glow_color);
00372        if (glowPm->isNull())
00373               return false;
00374        PixmapCache::insert(getPixmapName(type, isActive), glowPm);
00375        return true;
00376 }
00377 
00378 GlowClientGlobals *GlowClientGlobals::m_instance = 0;
00379 
00380 GlowClientGlobals *GlowClientGlobals::instance()
00381 {
00382        if( ! m_instance )
00383        {
00384               m_instance = new GlowClientGlobals();
00385        }
00386        return m_instance;
00387 }
00388 
00389 //-----------------------------------------------------------------------------
00390 
00391 GlowClient::GlowClient( KDecorationBridge* b, KDecorationFactory* f )
00392        : KDecoration( b, f ),
00393               m_stickyButton(0), m_helpButton(0), m_minimizeButton(0),
00394               m_maximizeButton(0), m_closeButton(0),
00395               m_leftButtonLayout(0), m_rightButtonLayout(0), _main_layout(0)
00396 {
00397 }
00398 
00399 void GlowClient::init()
00400 {
00401        createMainWidget(WResizeNoErase | WStaticContents | WRepaintNoErase);
00402        widget()->installEventFilter(this);
00403 
00404        createButtons();
00405        resetLayout();
00406 }
00407 
00408 GlowClient::~GlowClient()
00409 {
00410        PixmapCache::erase(QString::number(widget()->winId()));
00411 }
00412 
00413 void GlowClient::resizeEvent( QResizeEvent * )
00414 {
00415        doShape();
00416        widget()->repaint(false);
00417 }
00418 
00419 void GlowClient::paintEvent( QPaintEvent * )
00420 {
00421        GlowClientConfig *conf = GlowClientGlobals::instance()->config();
00422        QRect r_this = widget()->rect();
00423        QRect r_title = _title_spacer->geometry();
00424        QColorGroup titleCg = options()->colorGroup(ColorTitleBar, isActive());
00425        QColorGroup titleBlendCg=options()->colorGroup(ColorTitleBlend, isActive());
00426        QColorGroup cg = widget()->colorGroup();
00427        QColor titleColor = options()->color(ColorTitleBar, isActive());
00428        QColor titleBlendColor = options()->color(ColorTitleBlend, isActive());
00429        QColor bgColor = widget()->colorGroup().background();
00430        QPainter p;
00431        Q3PointArray pArray, pArray2, pArray3, pArray4;
00432 
00433        // pixmap for title bar
00434        QSize tBSize(width(), r_title.height());
00435        QSize gradientPixmapSize (tBSize-QSize(3,3));
00436        if (! gradientPixmapSize.isValid())
00437               gradientPixmapSize = QSize(0,0);
00438        KPixmap gradientPixmap(gradientPixmapSize);
00439        if (! gradientPixmapSize.isNull())
00440               KPixmapEffect::gradient(gradientPixmap, titleColor, titleBlendColor,
00441                      (KPixmapEffect::GradientType) conf->titlebarGradientType);
00442 
00443        QPixmap  * title_buffer = new QPixmap(tBSize);
00444        p.begin(title_buffer);
00445        if (! gradientPixmap.isNull())
00446               p.drawPixmap(2, 2, gradientPixmap);
00447 
00448        if (tBSize.width()>=3 && tBSize.height()>=3)
00449        {
00450               // draw caption
00451               p.setFont(options()->font(isActive()));
00452               p.setPen(options()->color(ColorFont, isActive()));
00453               p.drawText(r_title.x(), 0,
00454                      r_title.width(), r_title.height(),
00455                      Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, caption());
00456        
00457               // draw split color beneath buttons top right
00458               pArray4 = Q3PointArray(4);
00459               pArray4.setPoint(0, tBSize.width()-1, tBSize.height()/2-1);
00460               pArray4.setPoint(1, r_title.x()+r_title.width()-1+tBSize.height()/2,
00461                      tBSize.height()/2-1);
00462               pArray4.setPoint(2, r_title.x()+r_title.width()-1, tBSize.height());
00463               pArray4.setPoint(3, tBSize.width()-1, tBSize.height());
00464               p.setPen(Qt::NoPen);
00465               p.setBrush(bgColor);
00466               p.drawPolygon(pArray4);
00467                             
00468               // draw borders
00469               pArray = Q3PointArray(3);
00470               pArray.setPoint(0, tBSize.width()-1, tBSize.height()/2-1);
00471               pArray.setPoint(1, r_title.x()+r_title.width()-1+tBSize.height()/2,
00472                      tBSize.height()/2-1);
00473               pArray.setPoint(2, r_title.x()+r_title.width()-1, tBSize.height()-1);
00474               p.setPen(titleCg.mid());
00475               p.drawPolyline(pArray);
00476               p.drawLine (0, tBSize.height()-1, r_title.x()+r_title.width()-1, tBSize.height()-1);
00477 
00478               pArray2 = Q3PointArray(3);
00479               pArray2.setPoint(0, 1, tBSize.height()-2);
00480               pArray2.setPoint(1, 1, 1);
00481               pArray2.setPoint(2, tBSize.width()-2, 1);
00482               p.setPen(titleCg.light());
00483               p.drawPolyline(pArray2);
00484        }
00485 
00486        pArray3 = Q3PointArray(4);
00487        pArray3.setPoint(0, 0, tBSize.height()-1);
00488        pArray3.setPoint(1, 0, 0);
00489        pArray3.setPoint(2, tBSize.width()-1, 0);
00490        pArray3.setPoint(3, tBSize.width()-1, tBSize.height()-1);
00491        p.setPen(Qt::black);
00492        p.drawPolyline(pArray3);
00493        p.end();
00494 
00495        // insert title buffer in cache; before that, remove old buffer
00496        PixmapCache::erase(QString::number(widget()->winId()));
00497        PixmapCache::insert(QString::number(widget()->winId()), title_buffer);
00498 
00499        bitBlt(widget(), 0, 0, title_buffer);
00500        for (unsigned int i=0; i<m_buttonList.size(); ++i)
00501               m_buttonList[i]->repaint(false);
00502 
00503        p.begin(widget());
00504        p.setPen(Qt::black);
00505        //-----
00506        // draw borders
00507        p.drawLine(0,tBSize.height(),0,r_this.height()-1);
00508        p.drawLine(0,r_this.height()-1,r_this.width()-1,r_this.height()-1);
00509        p.drawLine(r_this.width()-1,r_this.height()-1,
00510               r_this.width()-1,tBSize.height()/2);
00511        //-----
00512        // fill content widget
00513        p.fillRect(1, tBSize.height(),
00514               r_this.width()-2, r_this.height()-tBSize.height()-1,
00515               options()->colorGroup(ColorFrame, isActive()).background());
00516        p.end();
00517 
00518        // paint resize handle if necessary
00519        if(conf->showResizeHandle && isResizable() && ! isShade()
00520                      && width()>=2 && height() >= RESIZE_HANDLE_HEIGHT)
00521        {
00522               p.begin(widget());
00523               p.setPen (Qt::black);
00524               p.drawLine (1, height() - RESIZE_HANDLE_HEIGHT,
00525                      width()-2, height() - RESIZE_HANDLE_HEIGHT);
00526               p.end();
00527        }
00528 }
00529 
00530 void GlowClient::showEvent( QShowEvent * )
00531 {
00532        doShape();
00533        widget()->repaint(false);
00534 }
00535 
00536 void GlowClient::mouseDoubleClickEvent( QMouseEvent *e )
00537 {
00538        if(e->button() == Qt::LeftButton && _title_spacer->geometry().contains(e->pos()))
00539               titlebarDblClickOperation();
00540 }
00541 
00542 void GlowClient::activeChange()
00543 {
00544        updateButtonPixmaps();
00545        widget()->repaint(false);
00546 }
00547 
00548 void GlowClient::iconChange()
00549 {
00550        // we have no (t yet an) icon button, so do nothing
00551 }
00552 
00553 void GlowClient::shadeChange()
00554 {
00555 }
00556 
00557 void GlowClient::captionChange()
00558 {
00559     widget()->update(_title_spacer->geometry());
00560 }
00561 
00562 QSize GlowClient::minimumSize() const
00563 {
00564     return widget()->minimumSize();
00565 }
00566 
00567 void GlowClient::resize( const QSize& s )
00568 {
00569     widget()->resize( s );
00570 }
00571 
00572 void GlowClient::borders( int& left, int& right, int& top, int& bottom ) const
00573 {
00574        left = right = SIDE_MARGIN;
00575        top = titleHeight + TITLE_MARGIN + 1;
00576        if (GlowClientGlobals::instance()->config()->showResizeHandle
00577               && isResizable())
00578               bottom = RESIZE_HANDLE_HEIGHT;
00579        else
00580               bottom = BOTTOM_MARGIN;
00581 }
00582 
00583 void GlowClient::desktopChange()
00584 {
00585        if (isOnAllDesktops()) {
00586               m_stickyButton->setPixmapName(
00587                      GlowClientGlobals::instance()->getPixmapName(
00588                             GlowClientGlobals::StickyOn, isActive()));
00589               m_stickyButton->setTipText(i18n("Not on all desktops"));
00590        } else {
00591               m_stickyButton->setPixmapName(
00592                      GlowClientGlobals::instance()->getPixmapName(
00593                             GlowClientGlobals::StickyOff, isActive()));
00594               m_stickyButton->setTipText(i18n("On all desktops"));
00595        }
00596 }
00597 
00598 void GlowClient::maximizeChange()
00599 {
00600     if (maximizeMode() == MaximizeFull) {
00601               m_maximizeButton->setPixmapName(
00602                      GlowClientGlobals::instance()->getPixmapName(
00603                             GlowClientGlobals::MaximizeOn, isActive()));
00604               m_maximizeButton->setTipText(i18n("Restore"));
00605        } else {
00606               m_maximizeButton->setPixmapName(
00607                      GlowClientGlobals::instance()->getPixmapName(
00608                             GlowClientGlobals::MaximizeOff, isActive()));
00609               m_maximizeButton->setTipText(i18n("Maximize"));
00610        }
00611 }
00612 
00613 KDecoration::Position GlowClient::mousePosition(const QPoint &pos) const
00614 {
00615        Position m = PositionCenter;
00616 
00617        int bottomSize
00618               = (GlowClientGlobals::instance()->config()->showResizeHandle)
00619               ? RESIZE_HANDLE_HEIGHT : BOTTOM_MARGIN;
00620 
00621        const int range = 14 + 3*SIDE_MARGIN/2;
00622 
00623        if ( ( pos.x() > SIDE_MARGIN && pos.x() < width() - SIDE_MARGIN )
00624               && ( pos.y() > 4 && pos.y() < height() - bottomSize ) )
00625               m = PositionCenter;
00626        else if ( pos.y() <= range && pos.x() <= range)
00627               m = PositionTopLeft;
00628        else if ( pos.y() >= height()-range && pos.x() >= width()-range)
00629               m = PositionBottomRight;
00630        else if ( pos.y() >= height()-range && pos.x() <= range)
00631               m = PositionBottomLeft;
00632        else if ( pos.y() <= range && pos.x() >= width()-range)
00633               m = PositionTopRight;
00634        else if ( pos.y() <= 4 )
00635               m = PositionTop;
00636        else if ( pos.y() >= height()-bottomSize )
00637               m = PositionBottom;
00638        else if ( pos.x() <= SIDE_MARGIN )
00639               m = PositionLeft;
00640        else if ( pos.x() >= width()-SIDE_MARGIN )
00641               m = PositionRight;
00642        else
00643               m = PositionCenter;
00644 
00645        return m;
00646 }
00647 
00648 void GlowClient::createButtons()
00649 {
00650        GlowClientGlobals *globals = GlowClientGlobals::instance();
00651        GlowButtonFactory *factory = globals->buttonFactory();
00652        QSize size = globals->theme()->buttonSize;
00653 
00654        m_stickyButton = factory->createGlowButton(widget(),
00655                                    "StickyButton", isOnAllDesktops()?i18n("Not on all desktops"):i18n("On all desktops"), Qt::LeftButton|Qt::RightButton);
00656        m_stickyButton->setFixedSize(size);
00657        connect(m_stickyButton, SIGNAL(clicked()), this, SLOT(toggleOnAllDesktops()));
00658        m_buttonList.insert(m_buttonList.end(), m_stickyButton);
00659 
00660        m_helpButton = factory->createGlowButton(widget(),
00661                                    "HelpButton", i18n("Help"));
00662        m_helpButton->setFixedSize(size);
00663        connect(m_helpButton, SIGNAL(clicked()), this, SLOT(showContextHelp()));
00664        m_buttonList.insert(m_buttonList.end(), m_helpButton);
00665 
00666        m_minimizeButton = factory->createGlowButton(widget(),
00667                                    "IconifyButton", i18n("Minimize"));
00668        m_minimizeButton->setFixedSize(size);
00669        connect(m_minimizeButton, SIGNAL(clicked()), this, SLOT(minimize()));
00670        m_buttonList.insert(m_buttonList.end(), m_minimizeButton);
00671 
00672        m_maximizeButton=factory->createGlowButton(widget(),
00673                                    "MaximizeButton", i18n("Maximize"), Qt::LeftButton|Qt::MidButton|Qt::RightButton);
00674        m_maximizeButton->setFixedSize(size);
00675        connect(m_maximizeButton, SIGNAL(clicked()), this, SLOT(slotMaximize()));
00676        m_buttonList.insert(m_buttonList.end(), m_maximizeButton);
00677 
00678        m_closeButton = factory->createGlowButton(widget(),
00679                                    "CloseButton", i18n("Close"));
00680        m_closeButton->setFixedSize(size);
00681        connect(m_closeButton, SIGNAL(clicked()), this, SLOT(closeWindow()));
00682        m_buttonList.insert(m_buttonList.end(), m_closeButton);
00683 }
00684 
00685 void GlowClient::resetLayout()
00686 {
00687        _main_layout = new QVBoxLayout(widget(), 0, 0);
00688        _main_layout->setResizeMode (QLayout::FreeResize);
00689 
00690        // update button positions and colors
00691        updateButtonPositions();
00692        updateButtonPixmaps();
00693 
00694        QBoxLayout * topLayout = new QBoxLayout(_main_layout,
00695                      QBoxLayout::LeftToRight, 0, 0);
00696        topLayout->setMargin(0);
00697        topLayout->setSpacing(TITLE_SPACING);
00698        topLayout->addSpacing(SIDE_MARGIN);
00699        QVBoxLayout *outerLeftLayout = new QVBoxLayout(topLayout);
00700        outerLeftLayout->addSpacing(TITLE_MARGIN);
00701        outerLeftLayout->addItem(m_leftButtonLayout);
00702        outerLeftLayout->addSpacing(1);
00703        topLayout->addSpacing(SIDE_MARGIN);
00704 
00705        _title_spacer = new QSpacerItem(0, titleHeight + TITLE_MARGIN + 1,
00706               QSizePolicy::Expanding, QSizePolicy::Fixed);
00707        topLayout->addItem(_title_spacer);
00708 
00709        topLayout->addSpacing(SIDE_MARGIN);
00710        QVBoxLayout *outerRightLayout = new QVBoxLayout(topLayout);
00711        outerRightLayout->addSpacing(TITLE_MARGIN);
00712        outerRightLayout->addItem(m_rightButtonLayout);
00713        outerRightLayout->addSpacing(1);
00714        topLayout->addSpacing(SIDE_MARGIN);
00715 
00716        QBoxLayout *midLayout = new QBoxLayout(
00717                      _main_layout, QBoxLayout::LeftToRight, 0, 0);
00718        midLayout->addSpacing(SIDE_MARGIN);
00719        if(isPreview())
00720               midLayout->addWidget(
00721                             new QLabel( i18n( "<b><center>Glow preview</center></b>" ), widget()));
00722        else
00723               midLayout->addItem( new QSpacerItem( 0, 0 ));
00724        midLayout->addSpacing(SIDE_MARGIN);
00725 
00726        if(GlowClientGlobals::instance()->config()->showResizeHandle
00727               && isResizable() ) {
00728               _bottom_spacer = new QSpacerItem(SIDE_MARGIN*2,
00729                      RESIZE_HANDLE_HEIGHT, QSizePolicy::Expanding, QSizePolicy::Minimum);
00730        } else {
00731               _bottom_spacer = new QSpacerItem(SIDE_MARGIN*2,
00732                      BOTTOM_MARGIN, QSizePolicy::Expanding, QSizePolicy::Minimum);
00733        }
00734        _main_layout->addItem (_bottom_spacer);
00735        _main_layout->setStretchFactor(topLayout, 0);
00736        _main_layout->setStretchFactor(midLayout, 1);
00737 }
00738 
00739 void GlowClient::updateButtonPositions()
00740 {
00741        QString buttons = options()->titleButtonsLeft() + "|"
00742               + options()->titleButtonsRight();
00743        bool leftButtons=true;
00744 
00745        // hide all buttons
00746        for( unsigned int i=0; i<m_buttonList.size(); i++ )
00747               m_buttonList[i]->hide();
00748 
00749        m_leftButtonList.clear();
00750        m_rightButtonList.clear();
00751 
00752        // reset left and right button layout
00753        if(m_leftButtonLayout)
00754               delete m_leftButtonLayout;
00755        m_leftButtonLayout = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00756        m_leftButtonLayout->setMargin(0);
00757        m_leftButtonLayout->setSpacing(TITLE_SPACING);
00758        if(m_rightButtonLayout)
00759               delete m_rightButtonLayout;
00760        m_rightButtonLayout = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00761        m_rightButtonLayout->setMargin(0);
00762        m_rightButtonLayout->setSpacing(TITLE_SPACING);
00763 
00764        for( unsigned int i=0; i<buttons.length(); i++ )
00765        {
00766               char c = buttons[i].latin1();
00767               GlowButton *button = 0;
00768               if( c=='S' ) // sticky
00769                      button = m_stickyButton;
00770               else if( c=='H' && providesContextHelp() ) // help
00771                      button = m_helpButton;
00772               else if( c=='I' && isMinimizable() ) // iconify
00773                      button = m_minimizeButton;
00774               else if( c=='A' && isMaximizable() ) // maximize
00775                      button = m_maximizeButton;
00776               else if( c=='X' && isCloseable() ) // close
00777                      button= m_closeButton;
00778               else if( c=='_' ) // spacer item
00779               {
00780                      if(leftButtons)
00781                             m_leftButtonLayout->addSpacing(4);
00782                      else
00783                             m_rightButtonLayout->addSpacing(4);
00784               }
00785               else if( c=='|' )
00786                      leftButtons = false;
00787 
00788               if (button) {
00789                      button->show(); // show visible buttons
00790                      if (leftButtons) {
00791                             m_leftButtonList.insert(m_leftButtonList.end(), button);
00792                             m_leftButtonLayout->addWidget(button);
00793                      } else {
00794                             m_rightButtonList.insert(m_rightButtonList.end(), button);
00795                             m_rightButtonLayout->addWidget(button);
00796                      }
00797               }
00798        }
00799 }
00800 
00801 void GlowClient::updateButtonPixmaps()
00802 {
00803        GlowClientGlobals *globals = GlowClientGlobals::instance();
00804 
00805        if ( isOnAllDesktops() ) {
00806               m_stickyButton->setPixmapName(globals->getPixmapName(
00807                      GlowClientGlobals::StickyOn, isActive()));
00808        } else {
00809               m_stickyButton->setPixmapName(globals->getPixmapName(
00810                      GlowClientGlobals::StickyOff, isActive()));
00811        }
00812        m_helpButton->setPixmapName(globals->getPixmapName(
00813               GlowClientGlobals::Help, isActive()));
00814 
00815        m_minimizeButton->setPixmapName(globals->getPixmapName(
00816               GlowClientGlobals::Iconify, isActive()));
00817 
00818        if ( maximizeMode() == MaximizeFull ) {
00819               m_maximizeButton->setPixmapName(globals->getPixmapName(
00820                      GlowClientGlobals::MaximizeOn, isActive()));
00821        } else {
00822               m_maximizeButton->setPixmapName(globals->getPixmapName(
00823                      GlowClientGlobals::MaximizeOff, isActive()));
00824        }
00825        m_closeButton->setPixmapName(globals->getPixmapName(
00826               GlowClientGlobals::Close, isActive()));
00827 }
00828 
00829 void GlowClient::doShape()
00830 {
00831        QRegion mask(widget()->rect());
00832        // edges
00833 
00834        mask -= QRegion(width()-1,0,1,1);
00835        mask -= QRegion(0,height()-1,1,1);
00836        mask -= QRegion(width()-1,height()-1,1,1);
00837        setMask(mask);
00838 }
00839 
00840 bool GlowClient::isLeft(GlowButton *button)
00841 {
00842        for( unsigned int i=0; i<m_leftButtonList.size(); i++ )
00843               if( m_leftButtonList[i] == button )
00844                      return true;
00845        return false;
00846 }
00847 
00848 bool GlowClient::isRight(GlowButton *button)
00849 {
00850        for( unsigned int i=0; i<m_rightButtonList.size(); i++ )
00851               if( m_rightButtonList[i] == button )
00852                      return true;
00853        return false;
00854 }
00855 
00856 void GlowClient::slotMaximize()
00857 {
00858        maximize(m_maximizeButton->lastButton());
00859 }
00860 
00861 bool GlowClient::eventFilter( QObject* o, QEvent* e )
00862 {
00863        if( o != widget())
00864               return false;
00865        switch( e->type())
00866        {
00867        case QEvent::Resize:
00868            resizeEvent( static_cast< QResizeEvent* >( e ));
00869            return true;
00870        case QEvent::Paint:
00871            paintEvent( static_cast< QPaintEvent* >( e ));
00872            return true;
00873        case QEvent::MouseButtonDblClick:
00874            mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
00875            return true;
00876        case QEvent::MouseButtonPress:
00877            processMousePressEvent( static_cast< QMouseEvent* >( e ));
00878            return true;
00879        case QEvent::Show:
00880            showEvent( static_cast< QShowEvent* >( e ));
00881            return true;
00882        default:
00883            break;
00884        }
00885     return false;
00886 }
00887 
00888 KDecoration* GlowClientGlobals::createDecoration( KDecorationBridge* bridge )
00889 {
00890        return new GlowClient( bridge, this );
00891 }
00892 
00893 } // end of namespace
00894 
00895 extern "C"
00896 KDE_EXPORT KDecorationFactory* create_factory()
00897 {
00898        return Glow::GlowClientGlobals::instance();
00899 }
00900 
00901 #include "glowclient.moc"
00902