Back to index

kdeartwork  4.3.2
kde1client.cpp
Go to the documentation of this file.
00001 /*****************************************************************
00002 kwin - the KDE window manager
00003                                                         
00004 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 ******************************************************************/
00023 
00024 #include "kde1client.h"
00025 #include <qcursor.h>
00026 #include <qlayout.h>
00027 #include <qtoolbutton.h>
00028 #include <qlabel.h>
00029 #include <qdrawutil.h>
00030 #include <qbitmap.h>
00031 #include <kdrawutil.h>
00032 #include <klocale.h>
00033 #include <kpixmap.h>
00034 #include <qdatetime.h>
00035 #include <qimage.h>
00036 #include <qtooltip.h>
00037 
00038 #include "kde1client_bitmaps.h"
00039 
00040 // Default button layout
00041 const char default_left[]  = "MS";
00042 const char default_right[] = "H_IAX";
00043 
00044 namespace KDE1
00045 {
00046 
00047 QPixmap* close_pix = 0;
00048 QPixmap* maximize_pix = 0;
00049 QPixmap* minimize_pix = 0;
00050 QPixmap* normalize_pix = 0;
00051 QPixmap* pinup_pix = 0;
00052 QPixmap* pindown_pix = 0;
00053 QPixmap* menu_pix = 0;
00054 QPixmap* question_mark_pix = 0;
00055 
00056 QPixmap* dis_close_pix = 0;
00057 QPixmap* dis_maximize_pix = 0;
00058 QPixmap* dis_minimize_pix = 0;
00059 QPixmap* dis_normalize_pix = 0;
00060 QPixmap* dis_pinup_pix = 0;
00061 QPixmap* dis_pindown_pix = 0;
00062 QPixmap* dis_menu_pix = 0;
00063 QPixmap* dis_question_mark_pix = 0;
00064 
00065 QPixmap* titleBuffer = 0;
00066 
00067 bool pixmaps_created = FALSE;
00068 
00069 inline const KDecorationOptions* options() { return KDecoration::options(); }
00070 
00071 void create_pixmaps()
00072 {
00073     if ( pixmaps_created )
00074         return;
00075     pixmaps_created = true;
00076     QColorGroup aGrp = options()->colorGroup(KDecorationOptions::ColorButtonBg, true);
00077     QColorGroup iGrp = options()->colorGroup(KDecorationOptions::ColorButtonBg, false);
00078 
00079     QPainter aPainter, iPainter;
00080     close_pix = new QPixmap(16, 16);
00081     dis_close_pix = new QPixmap(16, 16);
00082     aPainter.begin(close_pix); iPainter.begin(dis_close_pix);
00083     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, close_white_bits,
00084                   NULL, NULL, close_dgray_bits, NULL, NULL);
00085     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, close_white_bits,
00086                   NULL, NULL, close_dgray_bits, NULL, NULL);
00087     aPainter.end(); iPainter.end();
00088     close_pix->setMask(QBitmap(16, 16, close_mask_bits, true));
00089     dis_close_pix->setMask(*close_pix->mask());
00090 
00091     minimize_pix = new QPixmap(16, 16);
00092     dis_minimize_pix = new QPixmap(16, 16);
00093     aPainter.begin(minimize_pix); iPainter.begin(dis_minimize_pix);
00094     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, iconify_white_bits,
00095                   NULL, NULL, iconify_dgray_bits, NULL, NULL);
00096     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, iconify_white_bits,
00097                   NULL, NULL, iconify_dgray_bits, NULL, NULL);
00098     aPainter.end(); iPainter.end();
00099     minimize_pix->setMask(QBitmap(16, 16, iconify_mask_bits, true));
00100     dis_minimize_pix->setMask(*minimize_pix->mask());
00101 
00102     maximize_pix = new QPixmap(16, 16);
00103     dis_maximize_pix = new QPixmap(16, 16);
00104     aPainter.begin(maximize_pix); iPainter.begin(dis_maximize_pix);
00105     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, maximize_white_bits,
00106                   NULL, NULL, maximize_dgray_bits, NULL, NULL);
00107     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, maximize_white_bits,
00108                   NULL, NULL, maximize_dgray_bits, NULL, NULL);
00109     aPainter.end(); iPainter.end();
00110     maximize_pix->setMask(QBitmap(16, 16, maximize_mask_bits, true));
00111     dis_maximize_pix->setMask(*maximize_pix->mask());
00112 
00113     normalize_pix = new QPixmap(16, 16);
00114     dis_normalize_pix = new QPixmap(16, 16);
00115     aPainter.begin(normalize_pix); iPainter.begin(dis_normalize_pix);
00116     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, maximizedown_white_bits,
00117                   NULL, NULL, maximizedown_dgray_bits, NULL, NULL);
00118     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, maximizedown_white_bits,
00119                   NULL, NULL, maximizedown_dgray_bits, NULL, NULL);
00120     aPainter.end(); iPainter.end();
00121     normalize_pix->setMask(QBitmap(16, 16, maximizedown_mask_bits, true));
00122     dis_normalize_pix->setMask(*normalize_pix->mask());
00123 
00124     menu_pix = new QPixmap(16, 16);
00125     dis_menu_pix = new QPixmap(16, 16);
00126     aPainter.begin(menu_pix); iPainter.begin(dis_menu_pix);
00127     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, menu_white_bits,
00128                   NULL, NULL, menu_dgray_bits, NULL, NULL);
00129     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, menu_white_bits,
00130                   NULL, NULL, menu_dgray_bits, NULL, NULL);
00131     aPainter.end(); iPainter.end();
00132     menu_pix->setMask(QBitmap(16, 16, menu_mask_bits, true));
00133     dis_menu_pix->setMask(*menu_pix->mask());
00134 
00135     pinup_pix = new QPixmap(16, 16);
00136     dis_pinup_pix = new QPixmap(16, 16);
00137     aPainter.begin(pinup_pix); iPainter.begin(dis_pinup_pix);
00138     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, pinup_white_bits,
00139                   pinup_gray_bits, NULL, pinup_dgray_bits, NULL, NULL);
00140     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, pinup_white_bits,
00141                   pinup_gray_bits, NULL, pinup_dgray_bits, NULL, NULL);
00142     aPainter.end(); iPainter.end();
00143     pinup_pix->setMask(QBitmap(16, 16, pinup_mask_bits, true));
00144     dis_pinup_pix->setMask(*pinup_pix->mask());
00145 
00146     pindown_pix = new QPixmap(16, 16);
00147     dis_pindown_pix = new QPixmap(16, 16);
00148     aPainter.begin(pindown_pix); iPainter.begin(dis_pindown_pix);
00149     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, pindown_white_bits,
00150                   pindown_gray_bits, NULL, pindown_dgray_bits, NULL, NULL);
00151     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, pindown_white_bits,
00152                   pindown_gray_bits, NULL, pindown_dgray_bits, NULL, NULL);
00153     aPainter.end(); iPainter.end();
00154     pindown_pix->setMask(QBitmap(16, 16, pindown_mask_bits, true));
00155     dis_pindown_pix->setMask(*pindown_pix->mask());
00156 
00157     question_mark_pix = new QPixmap(16, 16);
00158     dis_question_mark_pix = new QPixmap(16, 16);
00159     aPainter.begin(question_mark_pix); iPainter.begin(dis_question_mark_pix);
00160     kColorBitmaps(&aPainter, aGrp, 0, 0, 16, 16, true, help_light_bits,
00161                   NULL, NULL, help_dark_bits, NULL, NULL);
00162     kColorBitmaps(&iPainter, iGrp, 0, 0, 16, 16, true, help_light_bits,
00163                   NULL, NULL, help_dark_bits, NULL, NULL);
00164     aPainter.end(); iPainter.end();
00165     question_mark_pix->setMask(QBitmap(16, 16, help_mask_bits, true));
00166     dis_question_mark_pix->setMask(*question_mark_pix->mask());
00167 
00168     titleBuffer = new KPixmap;
00169 }
00170 
00171 void delete_pixmaps()
00172 {
00173     delete close_pix;
00174     delete maximize_pix;
00175     delete minimize_pix;
00176     delete normalize_pix;
00177     delete pinup_pix;
00178     delete pindown_pix;
00179     delete menu_pix;
00180     delete question_mark_pix;
00181     delete dis_close_pix;
00182     delete dis_maximize_pix;
00183     delete dis_minimize_pix;
00184     delete dis_normalize_pix;
00185     delete dis_pinup_pix;
00186     delete dis_pindown_pix;
00187     delete dis_menu_pix;
00188     delete dis_question_mark_pix;
00189     delete titleBuffer;
00190     pixmaps_created = false;
00191 }
00192 
00193 void drawGradient
00194 (
00195   QPainter & p,
00196   const QRect & t,
00197   const QColor & c1,
00198   const QColor & c2
00199 )
00200 {
00201   // Don't draw a million vertical lines if we don't need to.
00202 
00203   if (c1 == c2  || QPixmap::defaultDepth() <= 8)
00204   {
00205     p.fillRect(t, c1);
00206     return;
00207   }
00208 
00209   // rikkus: Adapted from KPixmapEffect::gradient().
00210 
00211   int rca = c1.red();
00212   int gca = c1.green();
00213   int bca = c1.blue();
00214 
00215   int rDiff = c2.red()   - rca;
00216   int gDiff = c2.green() - gca;
00217   int bDiff = c2.blue()  - bca;
00218 
00219   int rl = rca << 16;
00220   int gl = gca << 16;
00221   int bl = bca << 16;
00222 
00223   int rcdelta = ((1 << 16) / t.width()) * rDiff;
00224   int gcdelta = ((1 << 16) / t.width()) * gDiff;
00225   int bcdelta = ((1 << 16) / t.width()) * bDiff;
00226 
00227   for (int x = 0; x < t.width(); x++)
00228   {
00229     rl += rcdelta;
00230     gl += gcdelta;
00231     bl += bcdelta;
00232 
00233     p.setPen(QColor(rl >> 16, gl >> 16, bl >> 16));
00234 
00235     p.drawLine(t.x() + x, 0, t.x() + x, t.y() + t.height() - 1);
00236   }
00237 }
00238 
00239 
00240 void StdClient::reset( unsigned long )
00241 {
00242     if (button[ButtonMenu] && (icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull()))
00243         button[ButtonMenu]->setIconSet(isActive() ? *menu_pix : *dis_menu_pix);
00244     if (button[ButtonSticky])
00245         button[ButtonSticky]->setIconSet(isOnAllDesktops() ? isActive() ? *pindown_pix : *dis_pindown_pix :
00246                                          isActive() ? *pinup_pix : *dis_pinup_pix );
00247     if (button[ButtonMinimize])
00248         button[ButtonMinimize]->setIconSet(isActive() ? *minimize_pix : *dis_minimize_pix);
00249     if (button[ButtonMaximize])
00250         button[ButtonMaximize]->setIconSet(isActive() ? *maximize_pix : *dis_maximize_pix);
00251     if (button[ButtonClose])
00252         button[ButtonClose]->setIconSet(isActive() ? *close_pix : *dis_close_pix);
00253     if (button[ButtonHelp])
00254         button[ButtonHelp]->setIconSet(isActive() ? *question_mark_pix : *dis_question_mark_pix);
00255 
00256     widget()->setFont(options()->font(true));
00257 }
00258 
00259 
00260 StdClient::StdClient( KDecorationBridge* b, KDecorationFactory* f )
00261     : KDecoration( b, f )
00262 {
00263 }
00264 
00265 void StdClient::init()
00266 {
00267     createMainWidget();
00268     widget()->installEventFilter( this );
00269 
00270     widget()->setFont(options()->font(isActive() ));
00271 
00272     QGridLayout* g = new QGridLayout( widget(), 0, 0, 3, 2 );
00273     g->setRowStretch( 1, 10 );
00274     if( isPreview())
00275         g->addWidget( new QLabel( i18n( "<center><b>KDE 1 preview</b></center>" ), widget()), 1, 1 );
00276     else
00277         g->addItem( new QSpacerItem( 0, 0 ), 1, 1 ); //no widget in the middle
00278     g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
00279 
00280     g->addColSpacing(0, 1);
00281     g->addColSpacing(2, 1);
00282     g->addRowSpacing(2, 1);
00283 
00284     int fh = widget()->fontMetrics().lineSpacing();
00285     titlebar = new QSpacerItem(10, fh, QSizePolicy::Expanding,
00286                             QSizePolicy::Minimum );
00287 
00288     QBoxLayout* hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00289     g->addLayout( hb, 0, 1 );
00290 
00291     // setup titlebar buttons
00292     for (int n=0; n<ButtonTypeCount; n++) button[n] = 0;
00293     addButtons(hb, options()->customButtonPositions() ? options()->titleButtonsLeft() : QString(default_left));
00294     hb->addItem(titlebar);
00295     addButtons(hb, options()->customButtonPositions() ? options()->titleButtonsRight() : QString(default_right));
00296 
00297     for (int n=0; n<ButtonTypeCount; n++) {
00298        if ( !button[n] )
00299            continue;
00300        button[n]->setBackgroundMode( PaletteBackground );
00301        button[n]->setMouseTracking( FALSE );
00302        button[n]->setAutoRaise( TRUE );
00303        button[n]->setFocusPolicy( QWidget::NoFocus );
00304        button[n]->setFixedSize( 20, 20 );
00305     }
00306 
00307 #if 0 // not sure what this is supposed to mean (and why)
00308     if ( isTransient() ) {
00309        // lighter decoration for transient windows
00310        button[1]->hide();
00311 //     button[2]->hide();
00312        button[3]->hide();
00313        button[4]->hide();
00314     }
00315 #endif
00316 }
00317 
00318 void StdClient::addButtons(QBoxLayout *hb, const QString& s)
00319 {
00320     if (s.length() > 0) {
00321         for (unsigned n=0; n < s.length(); n++) {
00322             switch (s[n]) {
00323               case 'M': // Menu button
00324                   if (!button[ButtonMenu]) {
00325                       button[ButtonMenu] = new QToolButton( widget(), 0 );
00326                       button[ButtonMenu]->setToolTip( i18n("Menu") );
00327                       button[ButtonMenu]->setCursor(ArrowCursor);
00328                       if( icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull())
00329                           button[ButtonMenu]->setIconSet(isActive() ? *menu_pix : *dis_menu_pix);
00330                       else
00331                           button[ButtonMenu]->setIconSet( icon().pixmap( QIconSet::Small, QIconSet::Normal ));
00332                       connect( button[0], SIGNAL( pressed() ), this, SLOT( menuButtonPressed() ) );
00333                       hb->addWidget(button[ButtonMenu]);
00334                   }
00335                   break;
00336 
00337               case 'S': // Sticky button
00338                   if (!button[ButtonSticky]) {
00339                      button[ButtonSticky] = new QToolButton( widget(), 0 );
00340                      button[ButtonSticky]->setIconSet( isOnAllDesktops()?*pindown_pix:*pinup_pix );
00341                      button[ButtonSticky]->setToolTip( isOnAllDesktops()?i18n("Not On All Desktops"):i18n("On All Desktops")  );
00342                      button[ButtonSticky]->setCursor(ArrowCursor);
00343                      button[ButtonSticky]->setIconSet(isOnAllDesktops() ? isActive() ? *pindown_pix : *dis_pindown_pix :
00344                                                       isActive() ? *pinup_pix : *dis_pinup_pix );
00345                      connect( button[ButtonSticky], SIGNAL( clicked() ), this, ( SLOT( toggleOnAllDesktops() ) ) );
00346                      hb->addWidget(button[ButtonSticky]);
00347                   }
00348                   break;
00349 
00350               case 'H': // Help button
00351                   if ((!button[ButtonHelp]) && providesContextHelp()) {
00352                       button[ButtonHelp] = new QToolButton( widget(), 0 );
00353                       button[ButtonHelp]->setToolTip( i18n("Help") );
00354                       button[ButtonHelp]->setIconSet( isActive() ? *question_mark_pix : *dis_question_mark_pix);
00355                       connect( button[ButtonHelp], SIGNAL( clicked() ), this, ( SLOT( showContextHelp() ) ) );
00356                       button[ButtonHelp]->setCursor(ArrowCursor);
00357                       hb->addWidget(button[ButtonHelp]);
00358                   }
00359                   break;
00360 
00361               case 'I': // Minimize button
00362                   if ((!button[ButtonMinimize]) && isMinimizable())  {
00363                       button[ButtonMinimize] = new QToolButton( widget(), 0 );
00364                       button[ButtonMinimize]->setToolTip( i18n("Minimize") );
00365                       button[ButtonMinimize]->setCursor(ArrowCursor);
00366                       button[ButtonMinimize]->setIconSet(isActive() ? *minimize_pix : *dis_minimize_pix);
00367                       connect( button[ButtonMinimize], SIGNAL( clicked() ), this, ( SLOT( minimize() ) ) );
00368                       hb->addWidget(button[ButtonMinimize]);
00369                   }
00370                   break;
00371 
00372               case 'A': // Maximize button
00373                   if ((!button[ButtonMaximize]) && isMaximizable()) {
00374                       const bool max = maximizeMode()!=MaximizeRestore;
00375                       button[ButtonMaximize] = new ThreeButtonButton( widget(), 0 );
00376                       button[ButtonMaximize]->setToolTip( max?i18n("Restore"):i18n("Maximize") );
00377                       button[ButtonMaximize]->setCursor(ArrowCursor);
00378                       button[ButtonMaximize]->setIconSet( max?(isActive() ? *normalize_pix : *dis_normalize_pix):(isActive() ? *maximize_pix : *dis_maximize_pix) );
00379                       connect( button[ButtonMaximize], SIGNAL( clicked(ButtonState) ),
00380                                this, ( SLOT( maxButtonClicked(ButtonState) ) ) );
00381                       hb->addWidget(button[ButtonMaximize]);
00382                   }
00383                   break;
00384 
00385               case 'X': // Close button
00386                   if ((!button[ButtonClose]) && isCloseable()) {
00387                       button[ButtonClose] = new QToolButton( widget(), 0 );
00388                       button[ButtonClose]->setToolTip( i18n("Close") );
00389                       button[ButtonClose]->setCursor(ArrowCursor);
00390                       button[ButtonClose]->setIconSet(isActive() ? *close_pix : *dis_close_pix);
00391                       connect( button[ButtonClose], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) );
00392                       hb->addWidget(button[ButtonClose]);
00393                   }
00394                   break;
00395 
00396               case '_': // Spacer item
00397                  hb->addItem( new QSpacerItem( 5, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
00398             }
00399         }
00400     }
00401 }
00402 
00403 void StdClient::activeChange()
00404 {
00405     bool on = isActive();
00406     if (button[ButtonMenu] && (icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull()))
00407         button[ButtonMenu]->setIconSet(on ? *menu_pix : *dis_menu_pix);
00408     if (button[ButtonSticky])
00409         button[ButtonSticky]->setIconSet(isOnAllDesktops() ? on ? *pindown_pix : *dis_pindown_pix :
00410                           on ? *pinup_pix : *dis_pinup_pix );
00411     if (button[ButtonMinimize])
00412         button[ButtonMinimize]->setIconSet(on ? *minimize_pix : *dis_minimize_pix);
00413     if (button[ButtonMaximize])
00414         button[ButtonMaximize]->setIconSet(on ? *maximize_pix : *dis_maximize_pix);
00415     if (button[ButtonClose])
00416         button[ButtonClose]->setIconSet(on ? *close_pix : *dis_close_pix);
00417     if (button[ButtonHelp])
00418         button[ButtonHelp]->setIconSet(on ? *question_mark_pix : *dis_question_mark_pix);
00419     widget()->repaint( titlebar->geometry(), false );
00420 }
00421 
00422 
00423 StdClient::~StdClient()
00424 {
00425     for (int n=0; n<ButtonTypeCount; n++) {
00426         if (button[n]) delete button[n];
00427     }
00428 }
00429 
00430 
00431 void StdClient::resizeEvent( QResizeEvent* )
00432 {
00433     QRegion rr = widget()->rect();
00434     QRect t = titlebar->geometry();
00435 //     t.setTop( 0 );
00436 //     QRegion r = rr.subtract( QRect( t.x()+1, 0, t.width()-2, 1 ) );
00437 //     setMask( r );
00438 
00439     if ( widget()->isVisibleToTLW() && !widget()->testWFlags( WStaticContents )) {
00440        // manual clearing without the titlebar (we selected WResizeNoErase )
00441        QRect cr( 2, 2, width()-4, height()- 4 );
00442        widget()->erase( QRegion( cr ).subtract( t ) );
00443     }
00444 }
00445 
00448 void StdClient::captionChange()
00449 {
00450     widget()->repaint( titlebar->geometry(), FALSE );
00451 }
00452 
00453 
00456 void StdClient::maximizeChange()
00457 {
00458     bool m = maximizeMode() == MaximizeFull;
00459     if (button[ButtonMaximize]) {
00460         button[ButtonMaximize]->setIconSet( m?*normalize_pix:*maximize_pix  );
00461         QToolTip::remove( button[ButtonMaximize] );
00462         button[ButtonMaximize]->setToolTip( m ? i18n("Restore") : i18n("Maximize") );
00463     }
00464 }
00465 
00466 
00469 void StdClient::desktopChange()
00470 {
00471     bool s = isOnAllDesktops();
00472     if (button[ButtonSticky]) {
00473         button[ButtonSticky]->setIconSet( s?*pindown_pix:*pinup_pix );
00474         QToolTip::remove( button[ButtonSticky] );
00475         button[ButtonSticky]->setToolTip( s ? i18n("Not On All Desktops") : i18n("On All Desktops") );
00476     }
00477 }
00478 
00479 void StdClient::paintEvent( QPaintEvent* )
00480 {
00481     QPainter p( widget() );
00482     QRect t = titlebar->geometry();
00483     QRegion r = widget()->rect();
00484     r = r.subtract( t );
00485     p.setClipRegion( r );
00486     qDrawWinPanel( &p, widget()->rect(), widget()->colorGroup() );
00487 //     t.setTop( 1 );
00488 //     p.setClipRegion( t );
00489 //     t.setTop( 0 );
00490 
00491     QRect titleRect( 0, 0, t.width(), t.height() );
00492     titleBuffer->resize( titleRect.width(), titleRect.height() );
00493     QPainter p2( titleBuffer );
00494 
00495     drawGradient(p2, titleRect, options()->color(KDecorationOptions::ColorTitleBar, isActive()),
00496         options()->color(KDecorationOptions::ColorTitleBlend, isActive()));
00497 //     p.setPen( options()->color(KDecorationOptions::ColorTitleBar, isActive()).light() );
00498 //     p.drawLine(t.left(), t.top()+1,  t.right(), t.top()+1);
00499     if ( isActive() )
00500        qDrawShadePanel( &p2, 0, 0, titleRect.width(), titleRect.height(),
00501                       widget()->colorGroup(), true, 1 );
00502     titleRect.setLeft( 4 );
00503     titleRect.setWidth( titleRect.width() - 2 );
00504     p2.setPen(options()->color(KDecorationOptions::ColorFont, isActive()));
00505     p2.setFont(options()->font(isActive()));
00506     p2.drawText( titleRect, AlignLeft|AlignVCenter|SingleLine, caption() );
00507     p2.end();
00508     p.end();
00509     bitBlt( widget(), t.topLeft(), titleBuffer );
00510 }
00511 
00512 
00513 void StdClient::mouseDoubleClickEvent( QMouseEvent * e )
00514 {
00515     if ( e->button() == Qt::LeftButton && titlebar->geometry().contains( e->pos() ) )
00516        titlebarDblClickOperation();
00517 }
00518 
00519 
00520 void StdClient::iconChange()
00521 {
00522     if (button[ButtonMenu]) {
00523         if ( icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull())
00524             button[ButtonMenu]->setIconSet(isActive() ? *menu_pix : *dis_menu_pix);
00525         else
00526             button[ButtonMenu]->setIconSet( icon().pixmap( QIconSet::Small, QIconSet::Normal ) );
00527         button[ButtonMenu]->repaint( FALSE );
00528     }
00529 }
00530 
00531 
00536 void StdClient::menuButtonPressed()
00537 {
00538     QRect menuRect = button[ButtonMenu]->rect();
00539     menuRect.addCoords(-1, 0, +1, +2);
00540     QPoint menuTop = button[ButtonMenu]->mapToGlobal(menuRect.topLeft());
00541     QPoint menuBottom = button[ButtonMenu]->mapToGlobal(menuRect.bottomRight());
00542     KDecorationFactory* f = factory(); // needs to be saved before
00543     showWindowMenu( QRect(menuTop, menuBottom) );
00544     if( !f->exists( this )) // destroyed, return immediately
00545         return;
00546     button[ButtonMenu]->setDown(false);
00547 }
00548 
00549 
00550 void StdClient::maxButtonClicked( ButtonState button )
00551 {
00552     maximize( button );
00553 }
00554 
00555 bool StdClient::eventFilter( QObject* o, QEvent* e )
00556 {
00557     if ( o != widget() )
00558        return false;
00559 
00560     switch ( e->type() ) {
00561     case QEvent::Resize:
00562        resizeEvent( static_cast< QResizeEvent* >( e ) );
00563        return true;
00564 
00565     case QEvent::Paint:
00566        paintEvent( static_cast< QPaintEvent* >( e ) );
00567        return true;
00568 
00569     case QEvent::MouseButtonDblClick:
00570        mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) );
00571        return true;
00572 
00573     case QEvent::MouseButtonPress:
00574        processMousePressEvent( static_cast< QMouseEvent* >( e ) );
00575        return true;
00576 
00577     default:
00578        return false;
00579     }
00580 }
00581 
00582 QSize StdClient::minimumSize() const
00583 {
00584     return widget()->minimumSize().expandedTo( QSize( 100, 50 ));
00585 }
00586 
00587 void StdClient::borders( int& left, int& right, int& top, int& bottom ) const
00588 {
00589     left = right = bottom = 6;
00590     top = 6 + widget()->fontMetrics().lineSpacing()+2;
00591 }
00592 
00593 void StdClient::resize( const QSize& s )
00594 {
00595     widget()->resize( s );
00596 }
00597 
00598 StdToolClient::StdToolClient( KDecorationBridge* b, KDecorationFactory* f )
00599     : KDecoration( b, f )
00600 {
00601 }
00602 
00603 void StdToolClient::init()
00604 {
00605     createMainWidget();
00606     widget()->installEventFilter( this );
00607 
00608     widget()->setFont(options()->font(isActive(), true ));
00609 
00610     QGridLayout* g = new QGridLayout( widget(), 0, 0, 2 );
00611     g->setRowStretch( 1, 10 );
00612     if( isPreview())
00613         g->addWidget( new QLabel( i18n( "<center><b>KDE 1 decoration</b></center>" ), widget()), 1, 1 );
00614     else
00615         g->addItem( new QSpacerItem( 0, 0 ), 1, 1 ); //no widget in the middle
00616     g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
00617 
00618     g->addColSpacing(0, 1);
00619     g->addColSpacing(2, 1);
00620     g->addRowSpacing(2, 1);
00621 
00622     closeBtn = new QToolButton( widget(), 0 );
00623     closeBtn->setToolTip( i18n("Close") );
00624     connect( closeBtn, SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) );
00625     closeBtn->setFixedSize( 13, 13);
00626     reset( -1U );
00627 
00628     QHBoxLayout* hb = new QHBoxLayout;
00629     g->addLayout( hb, 0, 1 );
00630 
00631     int fh = widget()->fontMetrics().lineSpacing()+2;
00632 
00633     titlebar = new QSpacerItem(10, fh, QSizePolicy::Expanding,
00634                             QSizePolicy::Minimum );
00635     hb->addItem( titlebar );
00636     hb->addWidget( closeBtn );
00637 }
00638 
00639 StdToolClient::~StdToolClient()
00640 {
00641 }
00642 
00643 void StdToolClient::resizeEvent( QResizeEvent* )
00644 {
00645 //     QRegion r = rect();
00646 //     QRect t = titlebar->geometry();
00647 //     t.setTop( 0 );
00648 //     r = r.subtract( QRect(0, 0, width(), 1) );
00649 //     r = r.subtract (QRect( 0, 0, 1, t.height() ) );
00650 //     r = r.subtract (QRect( width()-1, 0, 1, t.height() ) );
00651 //     setMask( r );
00652 }
00653 
00654 void StdToolClient::paintEvent( QPaintEvent* )
00655 {
00656     QPainter p( widget() );
00657     QRect t = titlebar->geometry();
00658     QRect r = widget()->rect();
00659     qDrawWinPanel( &p, r, widget()->colorGroup() );
00660     r.setTop( t.bottom()+1 );
00661     qDrawWinPanel( &p, r, widget()->colorGroup() );
00662     p.fillRect( QRect( QPoint(t.topLeft() ), QPoint( width() - t.left(), t.bottom() ) ),
00663               options()->color(KDecorationOptions::ColorTitleBar, isActive()));
00664     p.setPen( options()->color(KDecorationOptions::ColorTitleBar, isActive()).light() );
00665     t.setLeft( t.left() + 4 );
00666     t.setRight( t.right() - 2 );
00667     p.setPen(options()->color(KDecorationOptions::ColorFont, isActive()));
00668     p.setFont(options()->font(isActive(), true));
00669     p.drawText( t, AlignLeft|AlignVCenter|SingleLine, caption() );
00670 }
00671 
00672 
00673 void StdToolClient::mouseDoubleClickEvent( QMouseEvent * e )
00674 {
00675     if ( e->button() == Qt::LeftButton && titlebar->geometry().contains( e->pos() ) )
00676         titlebarDblClickOperation();
00677 }
00678 
00679 void StdToolClient::captionChange()
00680 {
00681     widget()->repaint( titlebar->geometry(), FALSE );
00682 }
00683 
00684 void StdToolClient::reset( unsigned long )
00685 {
00686     QImage img = close_pix->convertToImage();
00687     img = img.smoothScale( 12, 12 );
00688     QPixmap pm;
00689     pm.convertFromImage( img );
00690     closeBtn->setPixmap( pm );
00691     widget()->setFont(options()->font(isActive(), true ));
00692 }
00693 
00694 bool StdToolClient::eventFilter( QObject* o, QEvent* e )
00695 {
00696     if ( o != widget() )
00697        return false;
00698 
00699     switch ( e->type() ) {
00700     case QEvent::Resize:
00701        resizeEvent( static_cast< QResizeEvent* >( e ) );
00702        return true;
00703 
00704     case QEvent::Paint:
00705        paintEvent( static_cast< QPaintEvent* >( e ) );
00706        return true;
00707 
00708     case QEvent::MouseButtonDblClick:
00709        mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) );
00710        return true;
00711 
00712     case QEvent::MouseButtonPress:
00713        processMousePressEvent( static_cast< QMouseEvent* >( e ) );
00714        return true;
00715 
00716     default:
00717        return false;
00718     }
00719 }
00720 
00721 QSize StdToolClient::minimumSize() const
00722 {
00723     return widget()->minimumSize().expandedTo( QSize( 100, 50 ));
00724 }
00725 
00726 void StdToolClient::borders( int& left, int& right, int& top, int& bottom ) const
00727 {
00728     left = right = bottom = 6;
00729     top = 6 + widget()->fontMetrics().lineSpacing();
00730 }
00731 
00732 void StdToolClient::resize( const QSize& s )
00733 {
00734     widget()->resize( s );
00735 }
00736 
00737 StdFactory::StdFactory()
00738 {
00739     create_pixmaps();
00740 }
00741 
00742 StdFactory::~StdFactory()
00743 {
00744     delete_pixmaps();
00745 }
00746 
00747 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00748     | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00749     | NET::UtilityMask | NET::SplashMask;
00750 
00751 KDecoration* StdFactory::createDecoration( KDecorationBridge* b )
00752 {
00753     NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK, b );
00754     if( type == NET::Utility || type == NET::Menu || type == NET::Toolbar )
00755        return new StdToolClient( b, this );
00756     return new StdClient( b, this );
00757 }
00758 
00759 bool StdFactory::reset( unsigned long mask )
00760 {
00761     bool needHardReset = false;
00762 
00763     // doesn't obey the Border size setting
00764     if( mask & ( SettingFont | SettingButtons ))
00765         needHardReset = true;
00766 
00767     if( mask & ( SettingFont | SettingColors )) {
00768         KDE1::delete_pixmaps();
00769         KDE1::create_pixmaps();
00770     }
00771 
00772     if( !needHardReset )
00773         resetDecorations( mask );
00774     return needHardReset;
00775 }
00776 
00777 bool StdFactory::supports( Ability ability )
00778 {
00779     switch( ability )
00780     {
00781         case AbilityAnnounceButtons:
00782         case AbilityButtonMenu:
00783         case AbilityButtonOnAllDesktops:
00784         case AbilityButtonHelp:
00785         case AbilityButtonMinimize:
00786         case AbilityButtonMaximize:
00787         case AbilityButtonClose:
00788         case AbilityButtonSpacer:
00789             return true;
00790         default:
00791             return false;
00792     };
00793 }
00794 
00795 
00796 }
00797 
00798 extern "C"
00799 {
00800        KDE_EXPORT KDecorationFactory *create_factory()
00801        {
00802                 return new KDE1::StdFactory();
00803        }
00804 }
00805 
00806 #include "kde1client.moc"