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 Fri Aug 13 21:47:05 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003