kwin Library API Documentation

modernsys.cpp

00001 // Daniel M. DULEY <mosfet@kde.org>               original work
00002 // Melchior FRANZ  <a8603365@unet.univie.ac.at>   configuration options
00003 
00004 #include <kconfig.h>
00005 #include <kglobal.h>
00006 #include <klocale.h>
00007 #include <qlayout.h>
00008 #include <qdrawutil.h>
00009 #include <kpixmapeffect.h>
00010 #include <kdrawutil.h>
00011 #include <qbitmap.h>
00012 #include <qtooltip.h>
00013 #include <qapplication.h>
00014 #include <qlabel.h>
00015 #include "modernsys.h"
00016 
00017 #include "buttondata.h"
00018 #include "btnhighcolor.h"
00019 #include <qimage.h>
00020 
00021 namespace ModernSystem {
00022 
00023 static unsigned char iconify_bits[] = {
00024     0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00};
00025 
00026 static unsigned char close_bits[] = {
00027     0x00, 0x66, 0x7e, 0x3c, 0x3c, 0x7e, 0x66, 0x00};
00028 
00029 static unsigned char maximize_bits[] = {
00030     0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00};
00031 
00032 static unsigned char minmax_bits[] = {
00033     0x0c, 0x18, 0x33, 0x67, 0xcf, 0x9f, 0x3f, 0x3f};
00034 
00035 static unsigned char unsticky_bits[] = {
00036     0x3c, 0x42, 0x99, 0xbd, 0xbd, 0x99, 0x42, 0x3c};
00037 
00038 static unsigned char sticky_bits[] = {
00039     0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c};
00040 
00041 static unsigned char question_bits[] = {
00042     0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18};
00043 
00044 static unsigned char above_on_bits[] = {
00045     0x7e, 0x00, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00};
00046 
00047 static unsigned char above_off_bits[] = {
00048     0x18, 0x3c, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00};
00049 
00050 static unsigned char below_off_bits[] = {
00051     0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x3c, 0x18};
00052 
00053 static unsigned char below_on_bits[] = {
00054     0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x00, 0x7e};
00055 
00056 static unsigned char shade_off_bits[] = {
00057     0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00};
00058 
00059 static unsigned char shade_on_bits[] = {
00060     0x00, 0x7e, 0x7e, 0x42, 0x42, 0x42, 0x7e, 0x00};
00061 
00062 static unsigned char btnhighcolor_mask_bits[] = {
00063     0xe0,0x41,0xf8,0x07,0xfc,0x0f,0xfe,0xdf,0xfe,0x1f,0xff,0x3f,0xff,0xff,0xff,
00064     0x3f,0xff,0x3f,0xff,0xff,0xff,0xff,0xfe,0x9f,0xfe,0x1f,0xfc,0x0f,0xf0,0x03,
00065     0x00,0x40,0x80,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x20,0x99,0x0f,0x08,0xc4,
00066     0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x58,0x5f,0x43,0x68,0x61,0x6e,0x67,0x65 };
00067 
00068 static KPixmap *aUpperGradient=0;
00069 static KPixmap *iUpperGradient=0;
00070 static QPixmap *buttonPix=0;
00071 static QPixmap *buttonPixDown=0;
00072 static QPixmap *iButtonPix=0;
00073 static QPixmap *iButtonPixDown=0;
00074 
00075 static QColor *buttonFg;
00076 static bool pixmaps_created = false;
00077 
00078 static QBitmap *lcDark1;
00079 static QBitmap *lcDark2;
00080 static QBitmap *lcDark3;
00081 static QBitmap *lcLight1;
00082 static QImage *btnSource;
00083 
00084 static QString *button_pattern = NULL;
00085 static bool show_handle;
00086 static int handle_size;
00087 static int handle_width;
00088 static int border_width;
00089 static int title_height;
00090 
00091 static inline const KDecorationOptions* options()
00092 {
00093     return KDecoration::options();
00094 }
00095 
00096 static void make_button_fx(const QColorGroup &g, QPixmap *pix, bool light=false)
00097 {
00098     pix->fill(g.background());
00099     QPainter p(pix);
00100 
00101     if(QPixmap::defaultDepth() > 8){
00102         int i, destH, destS, destV, srcH, srcS, srcV;
00103         QColor btnColor = g.background();
00104 
00105         if(btnSource->depth() < 32)
00106             *btnSource = btnSource->convertDepth(32);
00107         if(light)
00108             btnColor = btnColor.light(120);
00109         btnColor.hsv(&destH, &destS, &destV);
00110         QImage btnDest(14, 15, 32);
00111 
00112         unsigned int *srcData = (unsigned int *)btnSource->bits();
00113         unsigned int *destData = (unsigned int *)btnDest.bits();
00114         QColor srcColor;
00115         for(i=0; i < btnSource->width()*btnSource->height(); ++i){
00116             srcColor.setRgb(srcData[i]);
00117             srcColor.hsv(&srcH, &srcS, &srcV);
00118             srcColor.setHsv(destH, destS, srcV);
00119             destData[i] = srcColor.rgb();
00120         }
00121         pix->convertFromImage(btnDest);
00122 
00123     }
00124     else{
00125         if(!lcDark1->mask()){
00126             lcDark1->setMask(*lcDark1);
00127             lcDark2->setMask(*lcDark2);
00128             lcDark3->setMask(*lcDark3);
00129             lcLight1->setMask(*lcLight1);
00130         }
00131         p.setPen(g.dark());
00132         p.drawPixmap(0, 0, *lcDark2);
00133         p.drawPixmap(0, 0, *lcDark1);
00134         p.setPen(g.mid());
00135         p.drawPixmap(0, 0, *lcDark3);
00136         p.setPen(g.light());
00137         p.drawPixmap(0, 0, *lcLight1);
00138     }
00139 }
00140 
00141 
00142 static void create_pixmaps()
00143 {
00144     if(pixmaps_created)
00145         return;
00146     pixmaps_created = true;
00147 
00148     lcDark1 = new QBitmap(14, 15, lowcolor_6a696a_bits, true);
00149     lcDark2 = new QBitmap(14, 15, lowcolor_949194_bits, true);
00150     lcDark3 = new QBitmap(14, 15, lowcolor_b4b6b4_bits, true);
00151     lcLight1 = new QBitmap(14, 15, lowcolor_e6e6e6_bits, true);
00152     btnSource = new QImage(btnhighcolor_xpm);
00153 
00154     if(QPixmap::defaultDepth() > 8){
00155         aUpperGradient = new KPixmap;
00156         aUpperGradient->resize(32, title_height+2);
00157         iUpperGradient = new KPixmap;
00158         iUpperGradient->resize(32, title_height+2);
00159         KPixmapEffect::gradient(*aUpperGradient,
00160                                 options()->color(KDecoration::ColorTitleBar, true).light(130),
00161                                 options()->color(KDecoration::ColorTitleBlend, true),
00162                                 KPixmapEffect::VerticalGradient);
00163         KPixmapEffect::gradient(*iUpperGradient,
00164                                 options()->color(KDecoration::ColorTitleBar, false).light(130),
00165                                 options()->color(KDecoration::ColorTitleBlend, false),
00166                                 KPixmapEffect::VerticalGradient);
00167     }
00168     // buttons
00169     QColorGroup btnColor(options()->colorGroup(KDecoration::ColorButtonBg, true));
00170     buttonPix = new QPixmap(14, 15);
00171     make_button_fx(btnColor, buttonPix);
00172     buttonPixDown = new QPixmap(14, 15);
00173     make_button_fx(btnColor, buttonPixDown, true);
00174 
00175     btnColor = options()->colorGroup(KDecoration::ColorButtonBg, false);
00176     iButtonPix = new QPixmap(14, 15);
00177     make_button_fx(btnColor, iButtonPix);
00178     iButtonPixDown = new QPixmap(14, 15);
00179     make_button_fx(btnColor, iButtonPixDown, true);
00180 
00181 
00182     if(qGray(btnColor.background().rgb()) < 150)
00183         buttonFg = new QColor(Qt::white);
00184     else
00185         buttonFg = new QColor(Qt::black);
00186 
00187     delete lcDark1;
00188     delete lcDark2;
00189     delete lcDark3;
00190     delete lcLight1;
00191     delete btnSource;
00192 }
00193 
00194 static void delete_pixmaps()
00195 {
00196     if(aUpperGradient){
00197         delete aUpperGradient;
00198         delete iUpperGradient;
00199     }
00200     delete buttonPix;
00201     delete buttonPixDown;
00202     delete iButtonPix;
00203     delete iButtonPixDown;
00204 
00205     delete buttonFg;
00206 
00207     pixmaps_created = false;
00208 }
00209 
00210 bool ModernSysFactory::read_config()
00211 {
00212     bool showh;
00213     int hsize, hwidth, bwidth, theight;
00214     QString bpatt;
00215 
00216     KConfig c("kwinmodernsysrc");
00217     c.setGroup("General");
00218     showh = c.readBoolEntry("ShowHandle", true);
00219 
00220     hwidth = c.readUnsignedNumEntry("HandleWidth", 6);
00221     hsize = c.readUnsignedNumEntry("HandleSize", 30);
00222     if (!(showh && hsize && hwidth)) {
00223         showh = false;
00224         hwidth = hsize = 0;
00225     }
00226 
00227     switch(options()->preferredBorderSize( this )) {
00228       case BorderLarge:
00229           bwidth = 8;
00230           hwidth = hwidth * 7/5;
00231           hsize  = hsize  * 7/5;
00232           break;
00233       case BorderVeryLarge:
00234           bwidth = 12;
00235           hwidth = hwidth * 17/10 + 2;
00236           hsize  = hsize  * 17/10;
00237           break;
00238       case BorderHuge:
00239           bwidth = 18;
00240           hwidth = hwidth * 2 + 6;
00241           hsize  = hsize  * 2;
00242           break;
00243       /*
00244       // If we allow these large sizes we need to change the
00245       // correlation between the border width and the handle size.
00246       case BorderVeryHuge:
00247           bwidth = 27;
00248           hwidth = hwidth * 5/2 + 15;
00249           hsize  = hsize  * 5/2;
00250           break;
00251       case BorderOversized:
00252           bwidth = 40;
00253           hwidth = hwidth * 3 + 22;
00254           hsize  = hsize  * 3;
00255           break;
00256       */
00257       case BorderNormal:
00258       default:
00259           bwidth = 4;
00260     }
00261 
00262     theight = QFontMetrics(options()->font(true)).height() + 2;
00263     if (theight < 16)
00264         theight = 16;
00265     if (theight < bwidth)
00266         theight = bwidth;
00267 
00268     if (options()->customButtonPositions()) {
00269         bpatt = "2" + options()->titleButtonsLeft() + "3t3"
00270                 + options()->titleButtonsRight() + "2";
00271     }
00272     else
00273         bpatt = "2X3t3HSIA2";
00274 
00275     if (showh == show_handle && hwidth == handle_width && hsize == handle_size
00276             && bwidth == border_width && theight == title_height
00277             && bpatt == *button_pattern)
00278         return false;
00279 
00280     show_handle = showh;
00281     handle_width = hwidth;
00282     handle_size = hsize;
00283     border_width = bwidth;
00284     title_height = theight;
00285     *button_pattern = bpatt;
00286     return true;
00287 }
00288 
00289 QValueList< ModernSysFactory::BorderSize > ModernSysFactory::borderSizes() const
00290 { // the list must be sorted
00291   return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00292       BorderVeryLarge <<  BorderHuge;
00293    // as long as the buttons don't scale don't offer the largest two sizes.
00294    //   BorderVeryLarge <<  BorderHuge << BorderVeryHuge << BorderOversized;
00295 }
00296 
00297 ModernButton::ModernButton(ModernSys *parent, const char *name, bool toggle,
00298                            const unsigned char *bitmap, const QString& tip, const int realizeBtns)
00299     : QButton(parent->widget(), name),
00300       last_button( NoButton ) 
00301 {
00302     setBackgroundMode( NoBackground );
00303 
00304     setToggleButton(toggle);
00305 
00306     setCursor( arrowCursor );
00307     realizeButtons = realizeBtns;
00308     QBitmap mask(14, 15, QPixmap::defaultDepth() > 8 ?
00309                  btnhighcolor_mask_bits : lowcolor_mask_bits, true);
00310     resize(14, 15);
00311 
00312     if(bitmap)
00313         setBitmap(bitmap);
00314     setMask(mask);
00315     hide();
00316     client = parent;
00317     QToolTip::add( this, tip );
00318 
00319 }
00320 
00321 QSize ModernButton::sizeHint() const
00322 {
00323     return(QSize(14, 15));
00324 }
00325 
00326 // Make the protected member public
00327 void ModernButton::turnOn( bool isOn )
00328 {
00329     if ( isToggleButton() )
00330         setOn( isOn );
00331 }
00332 
00333 void ModernButton::reset()
00334 {
00335     repaint(false);
00336 }
00337 
00338 void ModernButton::setBitmap(const unsigned char *bitmap)
00339 {
00340     deco = QBitmap(8, 8, bitmap, true);
00341     deco.setMask(deco);
00342     repaint();
00343 }
00344 
00345 void ModernButton::drawButton(QPainter *p)
00346 {
00347     if(client->isActive()){
00348         if(buttonPix)
00349             p->drawPixmap(0, 0, isDown() ? *buttonPixDown : *buttonPix);
00350     }
00351     else{
00352         if(iButtonPix)
00353             p->drawPixmap(0, 0, isDown() ? *iButtonPixDown : *iButtonPix);
00354     }
00355     if(!deco.isNull()){
00356         p->setPen(*buttonFg);
00357         p->drawPixmap(isDown() ? 4 : 3, isDown() ? 5 : 4, deco);
00358     }
00359 }
00360 
00361 void ModernButton::mousePressEvent( QMouseEvent* e )
00362 {
00363     last_button = e->button();
00364     QMouseEvent me ( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00365     QButton::mousePressEvent( &me );
00366 }
00367 
00368 void ModernButton::mouseReleaseEvent( QMouseEvent* e )
00369 {
00370     QMouseEvent me ( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00371     QButton::mouseReleaseEvent( &me );
00372 }
00373 
00374 
00375 void ModernSys::reset( unsigned long )
00376 {
00377     titleBuffer.resize(0, 0);
00378     recalcTitleBuffer();
00379     for (int i = 0; i < 5; button[i++]->reset());
00380     widget()->repaint();
00381 }
00382 
00383 ModernSys::ModernSys( KDecorationBridge* b, KDecorationFactory* f )
00384     : KDecoration( b, f )
00385 {
00386 }
00387 
00388 void ModernSys::init()
00389 {
00390     connect( this, SIGNAL( keepAboveChanged( bool )), SLOT( keepAboveChange( bool )));
00391     connect( this, SIGNAL( keepBelowChanged( bool )), SLOT( keepBelowChange( bool )));
00392 
00393     createMainWidget( WResizeNoErase );
00394     widget()->installEventFilter( this );
00395     bool reverse = QApplication::reverseLayout();
00396 
00397     bool help = providesContextHelp();
00398 
00399     QGridLayout* g = new QGridLayout(widget(), 0, 0, 2);
00400     if( isPreview())
00401         g->addWidget( new QLabel( i18n( "<center><b>Modern System preview</b></center>" ), widget()), 1, 1 );
00402     else
00403         g->addItem( new QSpacerItem( 0, 0 ), 1, 1 ); // no widget in the middle
00404     g->setRowStretch(1, 10);
00405     g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
00406 
00407     g->addColSpacing(0, border_width-2 + (reverse ? handle_width : 0));
00408     g->addColSpacing(2, border_width-2 + (reverse ? 0 : handle_width));
00409 
00410     g->addRowSpacing(2, border_width-2 + handle_width);
00411 
00412     QBoxLayout* hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00413     hb->setResizeMode(QLayout::FreeResize);
00414     titlebar = new QSpacerItem(10, title_height, QSizePolicy::Expanding,
00415                                QSizePolicy::Minimum);
00416 
00417     button[BtnClose] = new ModernButton(this, "close", false, close_bits, i18n("Close"));
00418     button[BtnSticky] = new ModernButton(this, "sticky", false, NULL, isOnAllDesktops()?i18n("Unsticky"):i18n("Sticky"));
00419     button[BtnMinimize] = new ModernButton(this, "iconify", false, iconify_bits, i18n("Minimize"));
00420     button[BtnMaximize] = new ModernButton(this, "maximize", false, maximize_bits, i18n("Maximize"), LeftButton|MidButton|RightButton);
00421     button[BtnHelp] = new ModernButton(this, "help", false, question_bits, i18n("Help"));
00422     button[BtnAbove] = new ModernButton(this, "above", true, above_off_bits, i18n("Keep above others"));
00423     button[BtnBelow] = new ModernButton(this, "below", true, below_off_bits, i18n("Keep below others"));
00424     button[BtnShade] = new ModernButton(this, "shade", true, shade_off_bits, isSetShade()?i18n("Unshade"):i18n("Shade") );
00425 
00426     connect( button[BtnClose], SIGNAL(clicked()), this, SLOT( closeWindow() ) );
00427     connect( button[BtnSticky], SIGNAL(clicked()), this, SLOT( toggleOnAllDesktops() ) );
00428     connect( button[BtnMinimize], SIGNAL(clicked()), this, SLOT( minimize() ) );
00429     connect( button[BtnMaximize], SIGNAL(clicked()), this, SLOT( maxButtonClicked() ) );
00430     connect( button[BtnHelp], SIGNAL(clicked()), this, SLOT( showContextHelp() ) );
00431     connect( button[BtnAbove], SIGNAL( clicked()), this, SLOT(slotAbove()) );
00432     connect( button[BtnBelow], SIGNAL( clicked()), this, SLOT(slotBelow()) );
00433     connect( button[BtnShade], SIGNAL( clicked()), this, SLOT(slotShade()) );
00434 
00435     for (int i = 0; i < (int)button_pattern->length();) {
00436         QChar c = (*button_pattern)[i++];
00437         if (c == '_')
00438             c = '3';
00439 
00440         if (c.isDigit()) {
00441             hb->addSpacing(int(c - '0'));
00442             continue;
00443         }
00444         else if (c == 'X' && isCloseable()) {
00445             hb->addWidget(button[BtnClose]);
00446             button[BtnClose]->show();
00447         }
00448         else if (c == 'S') {
00449             if(isOnAllDesktops())
00450                 button[BtnSticky]->setBitmap(unsticky_bits);
00451             else
00452                 button[BtnSticky]->setBitmap(sticky_bits);
00453             hb->addWidget(button[BtnSticky]);
00454             button[BtnSticky]->show();
00455         }
00456         else if (c == 'I' && isMinimizable()) {
00457             hb->addWidget(button[BtnMinimize]);
00458             button[BtnMinimize]->show();
00459         }
00460         else if (c == 'A' && isMaximizable()) {
00461             hb->addWidget(button[BtnMaximize]);
00462             button[BtnMaximize]->show();
00463         }
00464         else if (help && c == 'H') {
00465             hb->addWidget(button[BtnHelp]);
00466             button[BtnHelp]->show();
00467         }
00468         else if (c == 'F') {
00469             button[BtnAbove]->setBitmap(keepAbove()?above_on_bits:above_off_bits);
00470             hb->addWidget(button[BtnAbove]);
00471             button[BtnAbove]->show();
00472         }
00473         else if (c == 'B') {
00474             button[BtnBelow]->setBitmap(keepBelow()?below_on_bits:below_off_bits);
00475             hb->addWidget(button[BtnBelow]);
00476             button[BtnBelow]->show();
00477         }
00478         else if (c == 'L' && isShadeable()) {
00479             button[BtnShade]->setBitmap(isSetShade()?shade_on_bits:shade_off_bits);
00480             hb->addWidget(button[BtnShade]);
00481             button[BtnShade]->show();
00482         }
00483         else if (c == 't')
00484             hb->addItem(titlebar);
00485 
00486         if ((*button_pattern)[i] >= 'A' && (*button_pattern)[i] <= 'Z')
00487             hb->addSpacing(1);
00488     }
00489 
00490     g->addLayout( hb, 0, 1 );
00491     widget()->setBackgroundMode(NoBackground);
00492     recalcTitleBuffer();
00493     widget()->layout()->activate();
00494 }
00495 
00496 
00497 void ModernSys::maxButtonClicked( )
00498 {
00499     if (button[BtnMaximize]) {
00500         maximize(button[BtnMaximize]->last_button);
00501     }
00502 }
00503 
00504 void ModernSys::slotAbove()
00505 {
00506     setKeepAbove( !keepAbove());
00507     if (button[BtnAbove]) {
00508         button[BtnAbove]->turnOn(keepAbove());
00509         button[BtnAbove]->repaint(true);
00510     }
00511 }
00512 
00513     
00514 void ModernSys::slotBelow()
00515 {
00516     setKeepBelow( !keepBelow());
00517     if (button[BtnBelow]) {
00518         button[BtnBelow]->turnOn(keepBelow());
00519         button[BtnBelow]->repaint(true);
00520     }
00521 }
00522 
00523         
00524 void ModernSys::slotShade()
00525 {
00526     setShade( !isSetShade());
00527     if (button[BtnShade]) {
00528         button[BtnShade]->setBitmap(isSetShade() ? shade_on_bits : shade_off_bits );
00529         button[BtnShade]->repaint(true);
00530     }
00531 }
00532 
00533 void ModernSys::resizeEvent( QResizeEvent* )
00534 {
00535     recalcTitleBuffer();
00536     doShape();
00537 }
00538 
00539 void ModernSys::recalcTitleBuffer()
00540 {
00541     if(oldTitle == caption() && width() == titleBuffer.width())
00542         return;
00543 
00544     QFontMetrics fm(options()->font(true));
00545     titleBuffer.resize(width(), title_height+2);
00546     QPainter p;
00547     p.begin(&titleBuffer);
00548     if(aUpperGradient)
00549         p.drawTiledPixmap(0, 0, width(), title_height+2, *aUpperGradient);
00550     else
00551         p.fillRect(0, 0, width(), title_height+2,
00552                    options()->colorGroup(ColorTitleBar, true).
00553                    brush(QColorGroup::Button));
00554 
00555     QRect t = titlebar->geometry();
00556     t.setTop( 2 );
00557     t.setLeft( t.left() );
00558     t.setRight( t.right() - 2 );
00559 
00560     QRegion r(t.x(), 0, t.width(), title_height+2);
00561     r -= QRect(t.x()+((t.width()-fm.width(caption()))/2)-4,
00562                0, fm.width(caption())+8, title_height+2);
00563     p.setClipRegion(r);
00564     int i, ly;
00565     ly = (title_height % 3 == 0) ? 3 : 4;
00566     for(i=0; i < (title_height-2)/3; ++i, ly+=3){
00567         p.setPen(options()->color(ColorTitleBar, true).light(150));
00568         p.drawLine(0, ly, width()-1, ly);
00569         p.setPen(options()->color(ColorTitleBar, true).dark(120));
00570         p.drawLine(0, ly+1, width()-1, ly+1);
00571     }
00572     p.setClipRect(t);
00573     p.setPen(options()->color(ColorFont, true));
00574     p.setFont(options()->font(true));
00575 
00576     p.drawText(t.x()+((t.width()-fm.width(caption()))/2)-4,
00577                0, fm.width(caption())+8, title_height+2, AlignCenter, caption());
00578     p.setClipping(false);
00579     p.end();
00580     oldTitle = caption();
00581 }
00582 
00583 void ModernSys::captionChange()
00584 {
00585     recalcTitleBuffer();
00586     widget()->repaint( titlebar->geometry(), false );
00587 }
00588 
00589 void ModernSys::drawRoundFrame(QPainter &p, int x, int y, int w, int h)
00590 {
00591     kDrawRoundButton(&p, x, y, w, h,
00592                      options()->colorGroup(ColorFrame, isActive()), false);
00593 
00594 }
00595 
00596 void ModernSys::paintEvent( QPaintEvent* )
00597 {
00598     int hs = handle_size;
00599     int hw = handle_width;
00600 
00601     QPainter p( widget() );
00602     QRect t = titlebar->geometry();
00603 
00604     QBrush fillBrush(widget()->colorGroup().brush(QColorGroup::Background).pixmap() ?
00605                      widget()->colorGroup().brush(QColorGroup::Background) :
00606                      options()->colorGroup(ColorFrame, isActive()).
00607                      brush(QColorGroup::Button));
00608 
00609     p.fillRect(1, 16, width()-2, height()-16, fillBrush);
00610     p.fillRect(width()-6, 0, width()-1, height(), fillBrush);
00611 
00612     t.setTop( 2 );
00613     t.setLeft( t.left() );
00614     t.setRight( t.right() - 2 );
00615 
00616     int w = width() - hw; // exclude handle
00617     int h = height() - hw;
00618 
00619     // titlebar
00620     QColorGroup g = options()->colorGroup(ColorTitleBar, isActive());
00621     if(isActive()){
00622         p.drawPixmap(1, 1, titleBuffer, 0, 0, w-2, title_height+2);
00623     }
00624     else{
00625         if(iUpperGradient)
00626             p.drawTiledPixmap(1, 1, w-2, title_height+2, *iUpperGradient);
00627         else
00628             p.fillRect(1, 1, w-2, title_height+2, fillBrush);
00629         p.setPen(options()->color(ColorFont, isActive()));
00630         p.setFont(options()->font(isActive()));
00631         p.drawText(t, AlignCenter, caption() );
00632     }
00633 
00634     // titlebar highlight
00635     p.setPen(g.light());
00636     p.drawLine(1, 1, 1, title_height+3);
00637     p.drawLine(1, 1, w-3, 1);
00638     p.setPen(g.dark());
00639     p.drawLine(w-2, 1, w-2, title_height+3);
00640     p.drawLine(0, title_height+2, w-2, title_height+2);
00641 
00642     // frame
00643     g = options()->colorGroup(ColorFrame, isActive());
00644     p.setPen(g.light());
00645     p.drawLine(1, title_height+3, 1, h-2);
00646     p.setPen(g.dark());
00647     p.drawLine(2, h-2, w-2, h-2);
00648     p.drawLine(w-2, title_height+3, w-2, h-2);
00649     //p.drawPoint(w-3, title_height+3);
00650     //p.drawPoint(2, title_height+3);
00651 
00652     qDrawShadePanel(&p, border_width-1, title_height+3, w-2*border_width+2, h-title_height-border_width-2, g, true);
00653 
00654     if (show_handle) {
00655         p.setPen(g.dark());
00656         p.drawLine(width()-3, height()-hs-1, width()-3, height()-3);
00657         p.drawLine(width()-hs-1, height()-3, width()-3, height()-3);
00658 
00659         p.setPen(g.light());
00660         p.drawLine(width()-hw, height()-hs-1, width()-hw, height()-hw);
00661         p.drawLine(width()-hs-1, height()-hw, width()-hw, height()-hw);
00662         p.drawLine(width()-hw, height()-hs-1, width()-4, height()-hs-1);
00663         p.drawLine(width()-hs-1, height()-hw, width()-hs-1, height()-4);
00664 
00665         p.setPen(Qt::black);
00666         p.drawRect(0, 0, w, h);
00667 
00668         // handle outline
00669         p.drawLine(width()-hw, height()-hs, width(), height()-hs);
00670         p.drawLine(width()-2, height()-hs, width()-2, height()-2);
00671         p.drawLine(width()-hs, height()-2, width()-2, height()-2);
00672         p.drawLine(width()-hs, height()-hw, width()-hs, height()-2);
00673     } else {
00674         p.setPen(Qt::black);
00675         p.drawRect(0, 0, w, h);
00676     }
00677 }
00678 
00679 void ModernSys::doShape()
00680 {
00681     int hs = handle_size;
00682     int hw = handle_width;
00683     QRegion mask;
00684     mask += QRect(0, 0, width()-hw, height()-hw);
00685     //single points
00686     mask -= QRect(0, 0, 1, 1);
00687     mask -= QRect(width()-hw-1, 0, 1, 1);
00688     mask -= QRect(0, height()-hw-1, 1, 1);
00689 
00690     if (show_handle) {
00691         mask += QRect(width()-hs, height()-hs, hs-1, hs-1);
00692         mask -= QRect(width()-2, height()-2, 1, 1);
00693         mask -= QRect(width()-2, height()-hs, 1, 1);
00694         mask -= QRect(width()-hs, height()-2, 1, 1);
00695     } else
00696         mask -= QRect(width()-1, height()-1, 1, 1);
00697 
00698     setMask(mask);
00699 }
00700 
00701 void ModernSys::showEvent(QShowEvent *)
00702 {
00703     doShape();
00704     widget()->repaint();
00705 }
00706 
00707 void ModernSys::mouseDoubleClickEvent( QMouseEvent * e )
00708 {
00709     if (titlebar->geometry().contains( e->pos() ) )
00710         titlebarDblClickOperation();
00711 }
00712 
00713 void ModernSys::desktopChange()
00714 {
00715     bool sticky_on = isOnAllDesktops();
00716     button[BtnSticky]->setBitmap(sticky_on ? unsticky_bits : sticky_bits);
00717     QToolTip::remove( button[BtnSticky] );
00718     QToolTip::add( button[BtnSticky], sticky_on ? i18n("Unsticky") : i18n("Sticky"));
00719 }
00720 
00721 void ModernSys::maximizeChange()
00722 {
00723     bool m = ( maximizeMode() == MaximizeFull );
00724     button[BtnMaximize]->setBitmap(m ? minmax_bits : maximize_bits);
00725     QToolTip::remove( button[BtnMaximize] );
00726     QToolTip::add( button[BtnMaximize], m ? i18n("Restore") : i18n("Maximize"));
00727 }
00728 
00729 void ModernSys::activeChange()
00730 {
00731     widget()->repaint(false);
00732     for (int i = 0; i < 5; button[i++]->reset());
00733 }
00734 
00735 
00736 void ModernSys::keepAboveChange( bool above )
00737 {
00738     if (button[BtnAbove]) {
00739         button[BtnAbove]->setBitmap( above ? above_on_bits : above_off_bits );
00740         button[BtnAbove]->repaint(false);
00741     }
00742 }
00743         
00744 void ModernSys::keepBelowChange( bool below )
00745 {
00746     if (button[BtnBelow]) {
00747         button[BtnBelow]->setBitmap( below ? below_on_bits : below_off_bits );
00748         button[BtnBelow]->repaint(false);
00749     }
00750 }
00751 
00752 
00753 ModernSys::Position ModernSys::mousePosition( const QPoint& p) const
00754 {
00755     Position m = KDecoration::mousePosition( p );
00756 
00757     const int range = 14 + 3*border_width/2;
00758     const int border = show_handle ? handle_width + border_width : border_width;
00759     const int range2 = show_handle ? handle_width + border_width : range;
00760     const int range3 = show_handle ? handle_width + range : range;
00761 
00762     if ( ( p.x() > border_width && p.x() < width() - border )
00763          && ( p.y() > 4 && p.y() < height() - border ) )
00764         m = PositionCenter;
00765     else if ( p.y() <= range && p.x() <= range)
00766         m = PositionTopLeft;
00767     else if ( p.y() >= height()-range2 && p.x() >= width()-range2)
00768         m = PositionBottomRight;
00769     else if ( p.y() >= height()-range3 && p.x() <= range)
00770         m = PositionBottomLeft;
00771     else if ( p.y() <= range && p.x() >= width()-range3)
00772         m = PositionTopRight;
00773     else if ( p.y() <= 4 )
00774         m = PositionTop;
00775     else if ( p.y() >= height()-border )
00776         m = PositionBottom;
00777     else if ( p.x() <= border_width )
00778         m = PositionLeft;
00779     else if ( p.x() >= width()-border )
00780         m = PositionRight;
00781     else
00782         m = PositionCenter;
00783 
00784     return m;
00785 }
00786 
00787 void ModernSys::resize( const QSize& s )
00788 {
00789     widget()->resize( s );
00790 }
00791 
00792 void ModernSys::iconChange()
00793 {
00794 }
00795 
00796 void ModernSys::shadeChange()
00797 {
00798     if (button[BtnShade]) {
00799         bool on = isShade();
00800         button[BtnShade]->turnOn(on);
00801         button[BtnShade]->repaint(false);
00802         QToolTip::remove( button[BtnShade] );
00803         QToolTip::add( button[BtnShade], on ? i18n("Unshade") : i18n("Shade"));
00804     }
00805 }
00806 
00807 QSize ModernSys::minimumSize() const
00808 {
00809     return QSize( 50, 50 ); // FRAME
00810 }
00811 
00812 void ModernSys::borders( int& left, int& right, int& top, int& bottom ) const
00813 {
00814     bool reverse = QApplication::reverseLayout();
00815     left = border_width + (reverse ? handle_width : 0);
00816     right = border_width + (reverse ? 0 : handle_width);
00817     top = 4 + titlebar->geometry().height(); // FRAME is this ok?
00818     bottom = border_width + handle_width;
00819 // FRAME this below needs doShape() changes
00820 //    if( isShade())
00821 //        bottom = 0;
00822 //    if( ( maximizeMode() & MaximizeHorizontal ) && !options()->moveResizeMaximizedWindows())
00823 //        left = right = 0;
00824 //    if( ( maximizeMode() & MaximizeVertical ) && !options()->moveResizeMaximizedWindows())
00825 //        bottom = 0;
00826 }
00827 
00828 bool ModernSys::eventFilter( QObject* o, QEvent* e )
00829 {
00830     if( o != widget())
00831     return false;
00832     switch( e->type())
00833     {
00834     case QEvent::Resize:
00835         resizeEvent( static_cast< QResizeEvent* >( e ));
00836         return true;
00837     case QEvent::Paint:
00838         paintEvent( static_cast< QPaintEvent* >( e ));
00839         return true;
00840     case QEvent::MouseButtonDblClick:
00841         mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
00842         return true;
00843     case QEvent::MouseButtonPress:
00844         processMousePressEvent( static_cast< QMouseEvent* >( e ));
00845         return true;
00846     case QEvent::Show:
00847         showEvent( static_cast< QShowEvent* >( e ));
00848         return true;
00849     default:
00850         break;
00851     }
00852     return false;
00853 }
00854 
00855 ModernSysFactory::ModernSysFactory()
00856 {
00857     button_pattern = new QString;
00858     read_config();
00859     create_pixmaps();
00860 }
00861 
00862 ModernSysFactory::~ModernSysFactory()
00863 {
00864     ModernSystem::delete_pixmaps();
00865     delete ModernSystem::button_pattern;
00866 }
00867 
00868 KDecoration* ModernSysFactory::createDecoration( KDecorationBridge* b )
00869 {
00870     return(new ModernSys(b, this));
00871 }
00872 
00873 bool ModernSysFactory::reset( unsigned long changed )
00874 {
00875     bool ret = read_config();
00876     if( changed & (SettingColors | SettingBorder) )
00877     {
00878         delete_pixmaps();
00879         create_pixmaps();
00880     }
00881     if( ret )
00882         return true;
00883     else
00884     {
00885         resetDecorations( changed );
00886         return false; // no recreating of decorations
00887     }
00888 }
00889 
00890 }
00891 
00892 // KWin extended plugin interface
00893 extern "C" KDecorationFactory* create_factory()
00894 {
00895     return new ModernSystem::ModernSysFactory();
00896 }
00897 
00898 
00899 
00900 #include "modernsys.moc"
00901 // vim:ts=4:sw=4
KDE Logo
This file is part of the documentation for kwin Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Sep 25 20:35:06 2004 by doxygen 1.3.8-20040913 written by Dimitri van Heesch, © 1997-2003