kwin Library API Documentation

laptopclient.cpp

00001 /* 00002 * Laptop KWin Decoration 00003 * 00004 * Port of this decoration to KDE 3.2, accessibility enhancement are 00005 * Copyright (c) 2003 Luciano Montanaro <mikelima@virgilio.it> 00006 */ 00007 00008 #include <kconfig.h> // up here to avoid X11 header conflict :P 00009 #include "laptopclient.h" 00010 #include <qlayout.h> 00011 #include <qdrawutil.h> 00012 #include <kpixmapeffect.h> 00013 #include <kdrawutil.h> 00014 #include <kglobal.h> 00015 #include <kapplication.h> 00016 #include <klocale.h> 00017 #include <qbitmap.h> 00018 #include <qtooltip.h> 00019 #include <qlabel.h> 00020 00021 namespace Laptop { 00022 00023 static const unsigned char iconify_bits[] = { 00024 0xff, 0xff, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18}; 00025 00026 static const unsigned char close_bits[] = { 00027 0x42, 0xe7, 0x7e, 0x3c, 0x3c, 0x7e, 0xe7, 0x42}; 00028 00029 static const unsigned char maximize_bits[] = { 00030 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0xff, 0xff }; 00031 00032 static const unsigned char minmax_bits[] = { 00033 0x0c, 0x18, 0x33, 0x67, 0xcf, 0x9f, 0x3f, 0x3f}; 00034 00035 static const unsigned char question_bits[] = { 00036 0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18}; 00037 00038 static const unsigned char unsticky_bits[] = { 00039 0x3c, 0x42, 0x99, 0xbd, 0xbd, 0x99, 0x42, 0x3c}; 00040 00041 static const unsigned char sticky_bits[] = { 00042 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c}; 00043 00044 static QPixmap *titlePix; 00045 static KPixmap *aUpperGradient; 00046 static KPixmap *iUpperGradient; 00047 // buttons active, inactive, up, down, and 2 sizes :P 00048 static KPixmap *btnPix1; 00049 static KPixmap *iBtnPix1; 00050 static KPixmap *btnDownPix1; 00051 static KPixmap *iBtnDownPix1; 00052 static KPixmap *btnPix2; 00053 static KPixmap *btnDownPix2; 00054 static KPixmap *iBtnPix2; 00055 static KPixmap *iBtnDownPix2; 00056 static QColor btnForeground; 00057 00058 static int titleHeight = 14; 00059 static int btnWidth1 = 17; 00060 static int btnWidth2 = 27; 00061 00062 static int handleSize = 8; // the resize handle size in pixels 00063 00064 static bool pixmaps_created = false; 00065 00066 // ===================================== 00067 00068 extern "C" KDecorationFactory* create_factory() 00069 { 00070 return new Laptop::LaptopClientFactory(); 00071 } 00072 00073 // ===================================== 00074 00075 static inline const KDecorationOptions* options() 00076 { 00077 return KDecoration::options(); 00078 } 00079 00080 static void drawButtonFrame(KPixmap *pix, const QColorGroup &g, bool sunken) 00081 { 00082 QPainter p; 00083 int w = pix->width(); 00084 int h = pix->height(); 00085 int x2 = w-1; 00086 int y2 = h-1; 00087 p.begin(pix); 00088 00089 if(sunken){ 00090 qDrawShadePanel(&p, 0, 0, w, h, g, true, 2); 00091 } 00092 else{ 00093 p.setPen(g.dark()); 00094 p.drawRect(0, 0, w-1, h-1); 00095 p.setPen(g.light()); 00096 p.drawLine(x2, 0, x2, y2); 00097 p.drawLine(0, y2, x2, y2); 00098 p.drawLine(1, 1, x2-2, 1); 00099 p.drawLine(1, 1, 1, y2-2); 00100 p.end(); 00101 } 00102 } 00103 00104 static void create_pixmaps() 00105 { 00106 if(pixmaps_created) 00107 return; 00108 pixmaps_created = true; 00109 00110 titleHeight = QFontMetrics(options()->font(true)).height() + 2; 00111 if (titleHeight < handleSize) titleHeight = handleSize; 00112 titleHeight &= ~1; // Make title height even 00113 if (titleHeight < 14) titleHeight = 14; 00114 00115 btnWidth1 = titleHeight + 3; 00116 btnWidth2 = 3*titleHeight/2 + 6; 00117 00118 // titlebar 00119 QPainter p; 00120 QPainter maskPainter; 00121 int i, x, y; 00122 titlePix = new QPixmap(33, 12); 00123 QBitmap mask(33, 12); 00124 mask.fill(Qt::color0); 00125 00126 p.begin(titlePix); 00127 maskPainter.begin(&mask); 00128 maskPainter.setPen(Qt::color1); 00129 for(i=0, y=2; i < 3; ++i, y+=4){ 00130 for(x=1; x <= 33; x+=3){ 00131 p.setPen(options()->color(KDecoration::ColorTitleBar, true).light(150)); 00132 p.drawPoint(x, y); 00133 maskPainter.drawPoint(x, y); 00134 p.setPen(options()->color(KDecoration::ColorTitleBar, true).dark(150)); 00135 p.drawPoint(x+1, y+1); 00136 maskPainter.drawPoint(x+1, y+1); 00137 } 00138 } 00139 p.end(); 00140 maskPainter.end(); 00141 titlePix->setMask(mask); 00142 00143 if(QPixmap::defaultDepth() > 8){ 00144 aUpperGradient = new KPixmap; 00145 aUpperGradient->resize(32, titleHeight+2); 00146 iUpperGradient = new KPixmap; 00147 iUpperGradient->resize(32, titleHeight+2); 00148 QColor bgColor = options()->color(KDecoration::ColorTitleBar, true); 00149 KPixmapEffect::gradient(*aUpperGradient, 00150 bgColor.light(120), 00151 bgColor.dark(120), 00152 KPixmapEffect::VerticalGradient); 00153 bgColor = options()->color(KDecoration::ColorTitleBar, false); 00154 KPixmapEffect::gradient(*iUpperGradient, 00155 bgColor.light(120), 00156 bgColor.dark(120), 00157 KPixmapEffect::VerticalGradient); 00158 } 00159 // buttons (active/inactive, sunken/unsunken, 2 sizes each) 00160 QColorGroup g = options()->colorGroup(KDecoration::ColorButtonBg, true); 00161 QColor c = g.background(); 00162 btnPix1 = new KPixmap; 00163 btnPix1->resize(btnWidth1, titleHeight); 00164 btnDownPix1 = new KPixmap; 00165 btnDownPix1->resize(btnWidth1, titleHeight); 00166 btnPix2 = new KPixmap; 00167 btnPix2->resize(btnWidth2, titleHeight); 00168 btnDownPix2 = new KPixmap; 00169 btnDownPix2->resize(btnWidth2, titleHeight); 00170 iBtnPix1 = new KPixmap; 00171 iBtnPix1->resize(btnWidth1, titleHeight); 00172 iBtnDownPix1 = new KPixmap; 00173 iBtnDownPix1->resize(btnWidth1, titleHeight); 00174 iBtnPix2 = new KPixmap; 00175 iBtnPix2->resize(btnWidth2, titleHeight); 00176 iBtnDownPix2 = new KPixmap; 00177 iBtnDownPix2->resize(btnWidth2, titleHeight); 00178 if(QPixmap::defaultDepth() > 8){ 00179 KPixmapEffect::gradient(*btnPix1, c.light(120), c.dark(130), 00180 KPixmapEffect::DiagonalGradient); 00181 KPixmapEffect::gradient(*btnDownPix1, c.dark(130), c.light(120), 00182 KPixmapEffect::DiagonalGradient); 00183 KPixmapEffect::gradient(*btnPix2, c.light(120), c.dark(130), 00184 KPixmapEffect::DiagonalGradient); 00185 KPixmapEffect::gradient(*btnDownPix2, c.dark(130), c.light(120), 00186 KPixmapEffect::DiagonalGradient); 00187 g = options()->colorGroup(KDecoration::ColorButtonBg, false); 00188 c = g.background(); 00189 KPixmapEffect::gradient(*iBtnPix1, c.light(120), c.dark(130), 00190 KPixmapEffect::DiagonalGradient); 00191 KPixmapEffect::gradient(*iBtnDownPix1, c.dark(130), c.light(120), 00192 KPixmapEffect::DiagonalGradient); 00193 KPixmapEffect::gradient(*iBtnPix2, c.light(120), c.dark(130), 00194 KPixmapEffect::DiagonalGradient); 00195 KPixmapEffect::gradient(*iBtnDownPix2, c.dark(130), c.light(120), 00196 KPixmapEffect::DiagonalGradient); 00197 } 00198 else{ 00199 btnPix1->fill(c.rgb()); 00200 btnDownPix1->fill(c.rgb()); 00201 btnPix2->fill(c.rgb()); 00202 btnDownPix2->fill(c.rgb()); 00203 g = options()->colorGroup(KDecoration::ColorButtonBg, false); 00204 c = g.background(); 00205 iBtnPix1->fill(c.rgb()); 00206 iBtnDownPix1->fill(c.rgb()); 00207 iBtnPix2->fill(c.rgb()); 00208 iBtnDownPix2->fill(c.rgb()); 00209 } 00210 g = options()->colorGroup(KDecoration::ColorButtonBg, true); 00211 c = g.background(); 00212 drawButtonFrame(btnPix1, g, false); 00213 drawButtonFrame(btnDownPix1, g, true); 00214 drawButtonFrame(btnPix2, g, false); 00215 drawButtonFrame(btnDownPix2, g, true); 00216 g = options()->colorGroup(KDecoration::ColorButtonBg, false); 00217 c = g.background(); 00218 drawButtonFrame(iBtnPix1, g, false); 00219 drawButtonFrame(iBtnDownPix1, g, true); 00220 drawButtonFrame(iBtnPix2, g, false); 00221 drawButtonFrame(iBtnDownPix2, g, true); 00222 00223 if(qGray(options()->color(KDecoration::ColorButtonBg, true).rgb()) > 128) 00224 btnForeground = Qt::black; 00225 else 00226 btnForeground = Qt::white; 00227 } 00228 00229 static void delete_pixmaps() 00230 { 00231 delete titlePix; 00232 if(aUpperGradient){ 00233 delete aUpperGradient; 00234 delete iUpperGradient; 00235 delete btnPix1; 00236 delete btnDownPix1; 00237 delete iBtnPix1; 00238 delete iBtnDownPix1; 00239 delete btnPix2; 00240 delete btnDownPix2; 00241 delete iBtnPix2; 00242 delete iBtnDownPix2; 00243 } 00244 pixmaps_created = false; 00245 } 00246 00247 // ===================================== 00248 00249 LaptopButton::LaptopButton(int w, int h, LaptopClient *parent, 00250 const char *name, const unsigned char *bitmap, 00251 const QString& tip, const int realizeBtns) 00252 : QButton(parent->widget(), name), client(parent) 00253 { 00254 realizeButtons = realizeBtns; 00255 00256 setCursor( arrowCursor ); 00257 defaultSize = QSize(w, h); 00258 setFixedHeight(h); 00259 resize(defaultSize); 00260 if(bitmap) 00261 setBitmap(bitmap); 00262 00263 //setBackgroundMode(QWidget::NoBackground); 00264 00265 QToolTip::add(this, tip); 00266 } 00267 00268 QSize LaptopButton::sizeHint() const 00269 { 00270 return(defaultSize); 00271 } 00272 00273 void LaptopButton::reset() 00274 { 00275 repaint(false); 00276 } 00277 00278 void LaptopButton::setBitmap(const unsigned char *bitmap) 00279 { 00280 deco = QBitmap(8, 8, bitmap, true); 00281 deco.setMask(deco); 00282 repaint(); 00283 } 00284 00285 void LaptopButton::drawButton(QPainter *p) 00286 { 00287 bool smallBtn = width() == btnWidth1; 00288 if(btnPix1){ 00289 if(client->isActive()){ 00290 if(isDown()) 00291 p->drawPixmap(0, 0, smallBtn ? *btnDownPix1 : *btnDownPix2); 00292 else 00293 p->drawPixmap(0, 0, smallBtn ? *btnPix1 : *btnPix2); 00294 } 00295 else{ 00296 if(isDown()) 00297 p->drawPixmap(0, 0, smallBtn ? *iBtnDownPix1 : *iBtnDownPix2); 00298 else 00299 p->drawPixmap(0, 0, smallBtn ? *iBtnPix1 : *iBtnPix2); 00300 } 00301 } 00302 else{ 00303 QColorGroup g = options()->colorGroup(KDecoration::ColorButtonBg, 00304 client->isActive()); 00305 int w = width(); 00306 int h = height(); 00307 p->fillRect(1, 1, w-2, h-2, isDown() ? g.mid() : g.button()); 00308 p->setPen(isDown() ? g.dark() : g.light()); 00309 p->drawLine(0, 0, w-1, 0); 00310 p->drawLine(0, 0, 0, w-1); 00311 p->setPen(isDown() ? g.light() : g.dark()); 00312 p->drawLine(w-1, 0, w-1, h-1); 00313 p->drawLine(0, h-1, w-1, h-1); 00314 } 00315 00316 p->setPen(btnForeground); 00317 int xOff = (width()-8)/2; 00318 int yOff = (height()-8)/2; 00319 p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, deco); 00320 } 00321 00322 // ===================================== 00323 00324 void LaptopClient::reset(unsigned long) 00325 { 00326 for (int i = 0; i < 5; ++i) { 00327 if (button[i]) 00328 button[i]->reset(); 00329 } 00330 widget()->repaint(); 00331 } 00332 00333 LaptopClient::LaptopClient(KDecorationBridge *b, KDecorationFactory *f) 00334 : KDecoration(b, f) 00335 { 00336 } 00337 00338 void LaptopClient::init() 00339 { 00340 createMainWidget(WResizeNoErase | WStaticContents); 00341 widget()->installEventFilter(this); 00342 00343 lastButtonWidth = 0; 00344 lastBufferWidth = 0; 00345 00346 // XXX Check how to do this... 00347 // connect(options(), SIGNAL(resetClients()), this, SLOT(slotReset())); 00348 bool help = providesContextHelp(); 00349 00350 g = new QGridLayout(widget(), 0, 0, 0); 00351 g->setResizeMode(QLayout::FreeResize); 00352 g->addRowSpacing(0, 3); 00353 g->addRowSpacing(2, 1); 00354 if (isPreview()) 00355 g->addWidget(new QLabel(i18n("<center><b></b>Laptop preview</center>"), 00356 widget()), 3, 1); 00357 else 00358 g->addItem( new QSpacerItem( 0, 0 ), 3, 1); // no widget in the middle 00359 00360 g->setRowStretch(3, 10); 00361 spacer = new QSpacerItem(10, isResizable() ? handleSize : 4, 00362 QSizePolicy::Expanding, QSizePolicy::Minimum); 00363 g->addItem(spacer, 4, 1); 00364 g->addColSpacing(0, 4); 00365 g->addColSpacing(2, 4); 00366 00367 int th = titleHeight; 00368 if ( isTool() ) 00369 th -= 2; 00370 00371 button[BtnClose] = new LaptopButton(btnWidth2, th, this, "close", 00372 close_bits, i18n("Close")); 00373 button[BtnSticky] = new LaptopButton(btnWidth1, th, this, "sticky", 00374 NULL, isOnAllDesktops()?i18n("Not On All Desktops"):i18n("On All Desktops")); 00375 if(isOnAllDesktops()) 00376 button[BtnSticky]->setBitmap(unsticky_bits); 00377 else 00378 button[BtnSticky]->setBitmap(sticky_bits); 00379 button[BtnIconify] = new LaptopButton(btnWidth2, th, this, "iconify", 00380 iconify_bits, i18n("Minimize")); 00381 button[BtnMax] = new LaptopButton(btnWidth2, th, this, "maximize", 00382 maximize_bits, i18n("Maximize"), LeftButton|MidButton|RightButton); 00383 if (help) { 00384 button[BtnHelp] = new LaptopButton(btnWidth1, th, this, "help", 00385 question_bits, i18n("Help")); 00386 connect(button[BtnHelp], SIGNAL( clicked() ), this, SLOT( showContextHelp() ) ); 00387 } 00388 else 00389 button[BtnHelp] = NULL; 00390 00391 connect( button[BtnClose], SIGNAL( clicked() ), this, SLOT( closeWindow() ) ); 00392 connect( button[BtnSticky], SIGNAL( clicked() ), this, SLOT( toggleOnAllDesktops() ) ); 00393 connect( button[BtnIconify], SIGNAL( clicked() ), this, SLOT( minimize() ) ); 00394 connect( button[BtnMax], SIGNAL( clicked() ), this, SLOT( slotMaximize() ) ); 00395 00396 hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0); 00397 hb->setResizeMode(QLayout::FreeResize); 00398 g->addLayout( hb, 1, 1 ); 00399 hb->addWidget( button[BtnClose]); 00400 hb->addSpacing(1); 00401 titlebar = new QSpacerItem(10, th, QSizePolicy::Expanding, 00402 QSizePolicy::Minimum); 00403 hb->addItem(titlebar); 00404 hb->addSpacing(1); 00405 if (help) { 00406 hb->addWidget(button[BtnHelp]); 00407 } 00408 hb->addWidget( button[BtnSticky]); 00409 hb->addWidget( button[BtnIconify]); 00410 hb->addWidget( button[BtnMax]); 00411 00412 if ( isTransient() || isTool() ) 00413 button[BtnSticky]->hide(); 00414 if ( !isMinimizable() ) 00415 button[BtnIconify]->hide(); 00416 if ( !isMaximizable() ) 00417 button[BtnMax]->hide(); 00418 if ( !isCloseable() ) 00419 button[BtnClose]->hide(); 00420 00421 hiddenItems = false; 00422 bufferDirty = true; 00423 } 00424 00425 void LaptopClient::slotMaximize() 00426 { 00427 switch (button[BtnMax]->last_button) { 00428 case MidButton: 00429 maximize( maximizeMode() ^ MaximizeVertical ); 00430 break; 00431 case RightButton: 00432 maximize( maximizeMode() ^ MaximizeHorizontal ); 00433 break; 00434 case LeftButton: 00435 default: 00436 maximize(maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull); 00437 break; 00438 } 00439 } 00440 00441 void LaptopClient::resizeEvent(QResizeEvent* e) 00442 { 00443 doShape(); 00444 calcHiddenButtons(); 00445 if ( widget()->isVisibleToTLW() ) { 00446 int dx = 0; 00447 int dy = 0; 00448 if ( e->oldSize().width() != width() ) 00449 dx = 32 + QABS( e->oldSize().width() - width() ); 00450 if ( e->oldSize().height() != height() ) 00451 dy = isResizable() ? handleSize : 4 + 00452 QABS( e->oldSize().height() - height() ); 00453 if ( dy ) 00454 widget()->update( 0, height() - dy + 1, width(), dy ); 00455 if ( dx ) { 00456 widget()->update( width() - dx + 1, 0, dx, height() ); 00457 widget()->update( QRect( QPoint(4,4), 00458 titlebar->geometry().bottomLeft() - QPoint(1,0) ) ); 00459 widget()->update( QRect( titlebar->geometry().topRight(), 00460 QPoint( width() - 4, titlebar->geometry().bottom() ) ) ); 00461 widget()->update(titlebar->geometry()); 00462 } 00463 } 00464 } 00465 00466 void LaptopClient::captionChange() 00467 { 00468 bufferDirty = true; 00469 widget()->repaint(titlebar->geometry(), false); 00470 } 00471 00472 void LaptopClient::paintEvent( QPaintEvent* ) 00473 { 00474 QPainter p(widget()); 00475 QColorGroup g = options()->colorGroup(KDecoration::ColorFrame, isActive()); 00476 00477 QRect r(widget()->rect()); 00478 p.setPen(Qt::black); 00479 p.drawRect(r); 00480 // outer frame 00481 p.setPen(g.light()); 00482 p.drawLine(r.x()+1, r.y()+1, r.right()-1, r.y()+1); 00483 p.drawLine(r.x()+1, r.y()+1, r.x()+1, r.bottom()-1); 00484 p.setPen(g.dark()); 00485 p.drawLine(r.right()-1, r.y()+1, r.right()-1, r.bottom()-1); 00486 p.drawLine(r.x()+1, r.bottom()-1, r.right()-1, r.bottom()-1); 00487 00488 int th = titleHeight; 00489 int bb = handleSize + 2; // Bottom border 00490 int bs = handleSize - 2; // inner size of bottom border 00491 if (!isResizable()) { 00492 bb = 6; 00493 bs = 0; 00494 } 00495 if ( isTool() ) 00496 th -= 2; 00497 00498 // inner rect 00499 p.drawRect(r.x() + 3, r.y() + th + 3, r.width() - 6, r.height() - th - bb); 00500 00501 // handles 00502 if (!isResizable()) { 00503 } else if (r.width() > 3*handleSize + 20) { 00504 int range = 8 + 3*handleSize/2; 00505 qDrawShadePanel(&p, r.x() + 1, r.bottom() - bs, range, 00506 handleSize - 2, g, false, 1, &g.brush(QColorGroup::Mid)); 00507 qDrawShadePanel(&p, r.x() + range + 1, r.bottom() - bs, 00508 r.width() - 2*range - 2, handleSize - 2, g, false, 1, 00509 isActive() ? &g.brush(QColorGroup::Background) : 00510 &g.brush(QColorGroup::Mid)); 00511 qDrawShadePanel(&p, r.right() - range, r.bottom() - bs, 00512 range, bs, g, false, 1, &g.brush(QColorGroup::Mid)); 00513 } 00514 else 00515 qDrawShadePanel(&p, r.x() + 1, r.bottom() - bs, 00516 r.width() - 2, bs, g, false, 1, 00517 isActive() ? &g.brush(QColorGroup::Background) : 00518 &g.brush(QColorGroup::Mid)); 00519 00520 r = titlebar->geometry(); 00521 r.setRight(r.right()-1); 00522 00523 if(isActive()){ 00524 updateActiveBuffer(); 00525 p.drawPixmap(r.x(), r.y(), activeBuffer); 00526 } 00527 else{ 00528 if(iUpperGradient) 00529 p.drawTiledPixmap(r.x(), r.y(), r.width(), r.height()-1, 00530 *iUpperGradient); 00531 else 00532 p.fillRect(r.x(), r.y(), r.width(), r.height()-1, 00533 options()->color(KDecoration::ColorTitleBar, false)); 00534 00535 p.setFont(options()->font(false, isTool() )); 00536 QFontMetrics fm(options()->font(false)); 00537 g = options()->colorGroup(KDecoration::ColorTitleBar, false); 00538 if(iUpperGradient) 00539 p.drawTiledPixmap(r.x()+((r.width()-fm.width(caption()))/2)-4, 00540 r.y(), fm.width(caption())+8, r.height()-1, 00541 *iUpperGradient); 00542 else 00543 p.fillRect(r.x()+((r.width()-fm.width(caption()))/2)-4, r.y(), 00544 fm.width(caption())+8, r.height()-1, 00545 g.brush(QColorGroup::Background)); 00546 p.setPen(g.mid()); 00547 p.drawLine(r.x(), r.y(), r.right(), r.y()); 00548 p.drawLine(r.x(), r.y(), r.x(), r.bottom()); 00549 p.setPen(g.button()); 00550 p.drawLine(r.right(), r.y(), r.right(), r.bottom()); 00551 p.drawLine(r.x(), r.bottom(), r.right(), r.bottom()); 00552 p.setPen(options()->color(KDecoration::ColorFont, false)); 00553 p.drawText(r.x(), r.y(), r.width(), r.height()-1, 00554 AlignCenter, caption() ); 00555 g = options()->colorGroup(KDecoration::ColorFrame, true); 00556 p.setPen(g.background()); 00557 p.drawPoint(r.x(), r.y()); 00558 p.drawPoint(r.right(), r.y()); 00559 p.drawLine(r.right()+1, r.y(), r.right()+1, r.bottom()); 00560 } 00561 } 00562 00563 #define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) 00564 00565 void LaptopClient::doShape() 00566 { 00567 QRegion mask(QRect(0, 0, width(), height())); 00568 mask -= QRect(0, 0, 1, 1); 00569 mask -= QRect(width()-1, 0, 1, 1); 00570 mask -= QRect(0, height()-1, 1, 1); 00571 mask -= QRect(width()-1, height()-1, 1, 1); 00572 00573 setMask(mask); 00574 } 00575 00576 void LaptopClient::showEvent(QShowEvent *) 00577 { 00578 doShape(); 00579 widget()->repaint(); 00580 } 00581 00582 void LaptopClient::mouseDoubleClickEvent( QMouseEvent * e ) 00583 { 00584 if (titlebar->geometry().contains( e->pos() ) ) 00585 titlebarDblClickOperation(); 00586 } 00587 00588 void LaptopClient::iconChange() 00589 { 00590 // There is no icon support in this theme 00591 } 00592 00593 void LaptopClient::desktopChange() 00594 { 00595 bool on = isOnAllDesktops(); 00596 button[BtnSticky]->setBitmap(on ? unsticky_bits : sticky_bits); 00597 QToolTip::remove(button[BtnSticky]); 00598 QToolTip::add(button[BtnSticky], 00599 on ? i18n("Not On All Desktops") : i18n("On All Desktops")); 00600 } 00601 00602 void LaptopClient::maximizeChange() 00603 { 00604 bool m = (maximizeMode() == MaximizeFull); 00605 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits); 00606 QToolTip::remove(button[BtnMax]); 00607 QToolTip::add(button[BtnMax], m ? i18n("Restore") : i18n("Maximize")); 00608 spacer->changeSize(10, isResizable() ? handleSize : 4, 00609 QSizePolicy::Expanding, QSizePolicy::Minimum); 00610 g->activate(); 00611 doShape(); 00612 widget()->repaint(false); 00613 } 00614 00615 void LaptopClient::activeChange() 00616 { 00617 widget()->repaint(false); 00618 int i; 00619 for(i=0; i < 5; ++i){ 00620 if(button[i]) 00621 button[i]->reset(); 00622 } 00623 } 00624 00625 00626 void LaptopClient::calcHiddenButtons() 00627 { 00628 // order of hiding is help, sticky, maximize, minimize, close; 00629 // buttons can have 00630 int minWidth = 32 + btnWidth2*3 + (providesContextHelp() ? btnWidth1*2 : 00631 btnWidth1); 00632 00633 if(lastButtonWidth > width()){ // shrinking 00634 lastButtonWidth = width(); 00635 if(width() < minWidth){ 00636 hiddenItems = true; 00637 int i; 00638 for(i=0; i<5; ++i){ 00639 if(button[i]){ 00640 if( !button[i]->isHidden() ) { 00641 button[i]->hide(); 00642 } 00643 minWidth-=button[i]->sizeHint().width(); 00644 if(width() >= minWidth) 00645 return; 00646 } 00647 } 00648 } 00649 } 00650 else if(hiddenItems){ // expanding 00651 lastButtonWidth = width(); 00652 int i; 00653 int totalSize=32; 00654 for(i=4; i>=0; --i){ 00655 if(button[i]){ 00656 if(button[i]->sizeHint().width() + totalSize <= width()){ 00657 totalSize+=button[i]->sizeHint().width(); 00658 if(button[i]->isHidden() && 00659 ( !isTransient() || i != BtnSticky ) && 00660 ( isMinimizable() || i != BtnIconify ) && 00661 ( isMaximizable() || ( i != BtnIconify && i != BtnSticky && i != BtnMax ) ) 00662 00663 ) { 00664 button[i]->resize(button[i]->sizeHint()); 00665 button[i]->show(); 00666 } 00667 } 00668 else 00669 return; 00670 } 00671 } 00672 // all items shown now 00673 hiddenItems = false; 00674 } 00675 else 00676 lastButtonWidth = width(); 00677 } 00678 00679 void LaptopClient::updateActiveBuffer( ) 00680 { 00681 if( !bufferDirty && (lastBufferWidth == titlebar->geometry().width())) 00682 return; 00683 if ( titlebar->geometry().width() <= 0 || titlebar->geometry().height() <= 0 ) 00684 return; 00685 lastBufferWidth = titlebar->geometry().width(); 00686 bufferDirty = false; 00687 00688 activeBuffer.resize(titlebar->geometry().width(), 00689 titlebar->geometry().height()); 00690 QPainter p; 00691 QRect r(0, 0, activeBuffer.width()-1, activeBuffer.height()); 00692 p.begin(&activeBuffer); 00693 if(aUpperGradient){ 00694 p.drawTiledPixmap(r, *aUpperGradient); 00695 } 00696 else{ 00697 p.fillRect(r, options()->color(KDecoration::ColorTitleBar, true)); 00698 } 00699 if(titlePix) 00700 p.drawTiledPixmap(r, *titlePix); 00701 00702 p.setFont(options()->font(true, isTool() )); 00703 QFontMetrics fm(options()->font(true)); 00704 QColorGroup g = options()->colorGroup(KDecoration::ColorTitleBar, true); 00705 if(aUpperGradient) 00706 p.drawTiledPixmap(r.x()+((r.width()-fm.width(caption()))/2)-4, 00707 r.y(), fm.width(caption())+8, r.height()-1, 00708 *aUpperGradient); 00709 else 00710 p.fillRect(r.x()+((r.width()-fm.width(caption()))/2)-4, 0, 00711 fm.width(caption())+8, r.height(), 00712 g.brush(QColorGroup::Background)); 00713 p.setPen(g.mid()); 00714 p.drawLine(r.x(), r.y(), r.right(), r.y()); 00715 p.drawLine(r.x(), r.y(), r.x(), r.bottom()); 00716 p.setPen(g.button()); 00717 p.drawLine(r.right(), r.y(), r.right(), r.bottom()); 00718 p.drawLine(r.x(), r.bottom(), r.right(), r.bottom()); 00719 p.setPen(options()->color(KDecoration::ColorFont, true)); 00720 p.drawText(r.x(), r.y(), r.width(), r.height()-1, 00721 AlignCenter, caption() ); 00722 g = options()->colorGroup(KDecoration::ColorFrame, true); 00723 p.setPen(g.background()); 00724 p.drawPoint(r.x(), r.y()); 00725 p.drawPoint(r.right(), r.y()); 00726 p.drawLine(r.right()+1, r.y(), r.right()+1, r.bottom()); 00727 p.end(); 00728 } 00729 00730 LaptopClient::Position LaptopClient::mousePosition(const QPoint & p) const 00731 { 00732 Position m = PositionCenter; 00733 int range = 8 + 3*handleSize/2; 00734 00735 if (p.y() < (height() - handleSize + 1)) 00736 m = KDecoration::mousePosition(p); 00737 00738 else { 00739 if (p.x() >= (width() - range)) 00740 m = PositionBottomRight; 00741 else if (p.x() <= range) 00742 m = PositionBottomLeft; 00743 else 00744 m = PositionBottom; 00745 } 00746 00747 return m; 00748 } 00749 00750 void LaptopClient::borders(int &left, int &right, int &top, int &bottom) const 00751 { 00752 left = right = 4; 00753 top = titleHeight + 4; 00754 bottom = isResizable() ? handleSize : 4; 00755 } 00756 00757 void LaptopClient::shadeChange() 00758 { 00759 } 00760 00761 QSize LaptopClient::minimumSize() const 00762 { 00763 return QSize(4 * handleSize, handleSize); 00764 } 00765 00766 void LaptopClient::resize(const QSize& s) 00767 { 00768 widget()->resize(s); 00769 widget()->repaint(); //there is some strange wrong repaint of the frame without 00770 } 00771 00772 static const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | 00773 NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | 00774 NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | 00775 NET::UtilityMask | NET::SplashMask; 00776 00777 bool LaptopClient::isTransient() const 00778 { 00779 NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK); 00780 return type == NET::Dialog; 00781 } 00782 00783 bool LaptopClient::isTool() const 00784 { 00785 NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK); 00786 return type == NET::Toolbar || type == NET::Utility || type == NET::Menu; 00787 } 00788 00789 bool LaptopClient::eventFilter(QObject *o, QEvent *e) 00790 { 00791 if (o != widget()) 00792 return false; 00793 switch (e->type()) { 00794 case QEvent::Resize: 00795 resizeEvent(static_cast< QResizeEvent* >( e )); 00796 return true; 00797 case QEvent::Paint: 00798 paintEvent(static_cast< QPaintEvent* >( e )); 00799 return true; 00800 case QEvent::MouseButtonDblClick: 00801 mouseDoubleClickEvent(static_cast< QMouseEvent* >( e )); 00802 return true; 00803 case QEvent::MouseButtonPress: 00804 processMousePressEvent(static_cast< QMouseEvent* >( e )); 00805 return true; 00806 case QEvent::Show: 00807 showEvent(static_cast< QShowEvent* >( e )); 00808 return true; 00809 default: 00810 break; 00811 } 00812 return false; 00813 } 00814 00815 // ===================================== 00816 00817 LaptopClientFactory::LaptopClientFactory() 00818 { 00819 create_pixmaps(); 00820 } 00821 00822 LaptopClientFactory::~LaptopClientFactory() 00823 { 00824 delete_pixmaps(); 00825 } 00826 00827 KDecoration *LaptopClientFactory::createDecoration(KDecorationBridge *b) 00828 { 00829 findPreferredHandleSize(); 00830 return new Laptop::LaptopClient(b, this); 00831 } 00832 00833 bool LaptopClientFactory::reset(unsigned long /*changed*/) 00834 { 00835 findPreferredHandleSize(); 00836 00837 // TODO Do not recreate decorations if it is not needed. Look at 00838 // ModernSystem for how to do that 00839 Laptop::delete_pixmaps(); 00840 Laptop::create_pixmaps(); 00841 // For now just return true. 00842 return true; 00843 } 00844 00845 QValueList< LaptopClientFactory::BorderSize > 00846 LaptopClientFactory::borderSizes() const 00847 { 00848 // the list must be sorted 00849 return QValueList< BorderSize >() << BorderNormal << BorderLarge << 00850 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized; 00851 } 00852 00853 void LaptopClientFactory::findPreferredHandleSize() 00854 { 00855 switch (options()->preferredBorderSize(this)) { 00856 case KDecoration::BorderLarge: 00857 handleSize = 11; 00858 break; 00859 case KDecoration::BorderVeryLarge: 00860 handleSize = 16; 00861 break; 00862 case KDecoration::BorderHuge: 00863 handleSize = 24; 00864 break; 00865 case KDecoration::BorderVeryHuge: 00866 handleSize = 32; 00867 break; 00868 case KDecoration::BorderOversized: 00869 handleSize = 40; 00870 break; 00871 case KDecoration::BorderTiny: 00872 case KDecoration::BorderNormal: 00873 default: 00874 handleSize = 8; 00875 } 00876 } 00877 00878 } // Laptop namespace 00879 00880 #include "laptopclient.moc" 00881 00882 // vim: 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 Sep 16 15:59:32 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003