kwin Library API Documentation

modernsys.cpp

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