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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Aug 31 00:02:14 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003