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@cirulla.net> 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, mustDrawHandle() ? 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 maximize(button[BtnMax]->last_button); 00428 } 00429 00430 void LaptopClient::resizeEvent(QResizeEvent* e) 00431 { 00432 doShape(); 00433 calcHiddenButtons(); 00434 if ( widget()->isVisibleToTLW() ) { 00435 int dx = 0; 00436 int dy = 0; 00437 if ( e->oldSize().width() != width() ) 00438 dx = 32 + QABS( e->oldSize().width() - width() ); 00439 if ( e->oldSize().height() != height() ) 00440 dy = mustDrawHandle() ? handleSize : 4 + 00441 QABS( e->oldSize().height() - height() ); 00442 if ( dy ) 00443 widget()->update( 0, height() - dy + 1, width(), dy ); 00444 if ( dx ) { 00445 widget()->update( width() - dx + 1, 0, dx, height() ); 00446 widget()->update( QRect( QPoint(4,4), 00447 titlebar->geometry().bottomLeft() - QPoint(1,0) ) ); 00448 widget()->update( QRect( titlebar->geometry().topRight(), 00449 QPoint( width() - 4, titlebar->geometry().bottom() ) ) ); 00450 widget()->update(titlebar->geometry()); 00451 } 00452 } 00453 } 00454 00455 void LaptopClient::captionChange() 00456 { 00457 bufferDirty = true; 00458 widget()->repaint(titlebar->geometry(), false); 00459 } 00460 00461 void LaptopClient::paintEvent( QPaintEvent* ) 00462 { 00463 QPainter p(widget()); 00464 QColorGroup g = options()->colorGroup(KDecoration::ColorFrame, isActive()); 00465 00466 QRect r(widget()->rect()); 00467 p.setPen(Qt::black); 00468 p.drawRect(r); 00469 // outer frame 00470 p.setPen(g.light()); 00471 p.drawLine(r.x()+1, r.y()+1, r.right()-1, r.y()+1); 00472 p.drawLine(r.x()+1, r.y()+1, r.x()+1, r.bottom()-1); 00473 p.setPen(g.dark()); 00474 p.drawLine(r.right()-1, r.y()+1, r.right()-1, r.bottom()-1); 00475 p.drawLine(r.x()+1, r.bottom()-1, r.right()-1, r.bottom()-1); 00476 00477 int th = titleHeight; 00478 int bb = handleSize + 2; // Bottom border 00479 int bs = handleSize - 2; // inner size of bottom border 00480 if (!mustDrawHandle()) { 00481 bb = 6; 00482 bs = 0; 00483 } 00484 if ( isTool() ) 00485 th -= 2; 00486 00487 // inner rect 00488 p.drawRect(r.x() + 3, r.y() + th + 3, r.width() - 6, r.height() - th - bb); 00489 00490 // handles 00491 if (mustDrawHandle()) { 00492 if (r.width() > 3*handleSize + 20) { 00493 int range = 8 + 3*handleSize/2; 00494 qDrawShadePanel(&p, r.x() + 1, r.bottom() - bs, range, 00495 handleSize - 2, g, false, 1, &g.brush(QColorGroup::Mid)); 00496 qDrawShadePanel(&p, r.x() + range + 1, r.bottom() - bs, 00497 r.width() - 2*range - 2, handleSize - 2, g, false, 1, 00498 isActive() ? &g.brush(QColorGroup::Background) : 00499 &g.brush(QColorGroup::Mid)); 00500 qDrawShadePanel(&p, r.right() - range, r.bottom() - bs, 00501 range, bs, g, false, 1, &g.brush(QColorGroup::Mid)); 00502 } else { 00503 qDrawShadePanel(&p, r.x() + 1, r.bottom() - bs, 00504 r.width() - 2, bs, g, false, 1, 00505 isActive() ? &g.brush(QColorGroup::Background) : 00506 &g.brush(QColorGroup::Mid)); 00507 } 00508 } 00509 r = titlebar->geometry(); 00510 r.setRight(r.right()-1); 00511 00512 if(isActive()){ 00513 updateActiveBuffer(); 00514 p.drawPixmap(r.x(), r.y(), activeBuffer); 00515 } 00516 else{ 00517 if(iUpperGradient) 00518 p.drawTiledPixmap(r.x(), r.y(), r.width(), r.height()-1, 00519 *iUpperGradient); 00520 else 00521 p.fillRect(r.x(), r.y(), r.width(), r.height()-1, 00522 options()->color(KDecoration::ColorTitleBar, false)); 00523 00524 p.setFont(options()->font(false, isTool() )); 00525 QFontMetrics fm(options()->font(false)); 00526 g = options()->colorGroup(KDecoration::ColorTitleBar, false); 00527 if(iUpperGradient) 00528 p.drawTiledPixmap(r.x()+((r.width()-fm.width(caption()))/2)-4, 00529 r.y(), fm.width(caption())+8, r.height()-1, 00530 *iUpperGradient); 00531 else 00532 p.fillRect(r.x()+((r.width()-fm.width(caption()))/2)-4, r.y(), 00533 fm.width(caption())+8, r.height()-1, 00534 g.brush(QColorGroup::Background)); 00535 p.setPen(g.mid()); 00536 p.drawLine(r.x(), r.y(), r.right(), r.y()); 00537 p.drawLine(r.x(), r.y(), r.x(), r.bottom()); 00538 p.setPen(g.button()); 00539 p.drawLine(r.right(), r.y(), r.right(), r.bottom()); 00540 p.drawLine(r.x(), r.bottom(), r.right(), r.bottom()); 00541 p.setPen(options()->color(KDecoration::ColorFont, false)); 00542 p.drawText(r.x(), r.y(), r.width(), r.height()-1, 00543 AlignCenter, caption() ); 00544 g = options()->colorGroup(KDecoration::ColorFrame, true); 00545 p.setPen(g.background()); 00546 p.drawPoint(r.x(), r.y()); 00547 p.drawPoint(r.right(), r.y()); 00548 p.drawLine(r.right()+1, r.y(), r.right()+1, r.bottom()); 00549 } 00550 } 00551 00552 #define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) 00553 00554 void LaptopClient::doShape() 00555 { 00556 QRegion mask(QRect(0, 0, width(), height())); 00557 mask -= QRect(0, 0, 1, 1); 00558 mask -= QRect(width()-1, 0, 1, 1); 00559 mask -= QRect(0, height()-1, 1, 1); 00560 mask -= QRect(width()-1, height()-1, 1, 1); 00561 00562 setMask(mask); 00563 } 00564 00565 void LaptopClient::showEvent(QShowEvent *) 00566 { 00567 doShape(); 00568 widget()->repaint(); 00569 } 00570 00571 void LaptopClient::mouseDoubleClickEvent( QMouseEvent * e ) 00572 { 00573 if (titlebar->geometry().contains( e->pos() ) ) 00574 titlebarDblClickOperation(); 00575 } 00576 00577 bool LaptopClient::mustDrawHandle() const 00578 { 00579 bool drawSmallBorders = !options()->moveResizeMaximizedWindows(); 00580 if (drawSmallBorders && (maximizeMode() & MaximizeVertical)) { 00581 return false; 00582 } else { 00583 return isResizable(); 00584 } 00585 } 00586 00587 void LaptopClient::iconChange() 00588 { 00589 // There is no icon support in this theme 00590 } 00591 00592 void LaptopClient::desktopChange() 00593 { 00594 bool on = isOnAllDesktops(); 00595 button[BtnSticky]->setBitmap(on ? unsticky_bits : sticky_bits); 00596 QToolTip::remove(button[BtnSticky]); 00597 QToolTip::add(button[BtnSticky], 00598 on ? i18n("Not on all desktops") : i18n("On all desktops")); 00599 } 00600 00601 void LaptopClient::maximizeChange() 00602 { 00603 bool m = (maximizeMode() == MaximizeFull); 00604 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits); 00605 QToolTip::remove(button[BtnMax]); 00606 QToolTip::add(button[BtnMax], m ? i18n("Restore") : i18n("Maximize")); 00607 spacer->changeSize(10, mustDrawHandle() ? handleSize : 4, 00608 QSizePolicy::Expanding, QSizePolicy::Minimum); 00609 g->activate(); 00610 doShape(); 00611 widget()->repaint(false); 00612 } 00613 00614 void LaptopClient::activeChange() 00615 { 00616 widget()->repaint(false); 00617 int i; 00618 for(i=0; i < 5; ++i){ 00619 if(button[i]) 00620 button[i]->reset(); 00621 } 00622 } 00623 00624 00625 void LaptopClient::calcHiddenButtons() 00626 { 00627 // order of hiding is help, sticky, maximize, minimize, close; 00628 // buttons can have 00629 int minWidth = 32 + btnWidth2*3 + (providesContextHelp() ? btnWidth1*2 : 00630 btnWidth1); 00631 00632 if(lastButtonWidth > width()){ // shrinking 00633 lastButtonWidth = width(); 00634 if(width() < minWidth){ 00635 hiddenItems = true; 00636 int i; 00637 for(i=0; i<5; ++i){ 00638 if(button[i]){ 00639 if( !button[i]->isHidden() ) { 00640 button[i]->hide(); 00641 } 00642 minWidth-=button[i]->sizeHint().width(); 00643 if(width() >= minWidth) 00644 return; 00645 } 00646 } 00647 } 00648 } 00649 else if(hiddenItems){ // expanding 00650 lastButtonWidth = width(); 00651 int i; 00652 int totalSize=32; 00653 for(i=4; i>=0; --i){ 00654 if(button[i]){ 00655 if(button[i]->sizeHint().width() + totalSize <= width()){ 00656 totalSize+=button[i]->sizeHint().width(); 00657 if(button[i]->isHidden() && 00658 ( !isTransient() || i != BtnSticky ) && 00659 ( isMinimizable() || i != BtnIconify ) && 00660 ( isMaximizable() || ( i != BtnIconify && i != BtnSticky && i != BtnMax ) ) 00661 00662 ) { 00663 button[i]->resize(button[i]->sizeHint()); 00664 button[i]->show(); 00665 } 00666 } 00667 else 00668 return; 00669 } 00670 } 00671 // all items shown now 00672 hiddenItems = false; 00673 } 00674 else 00675 lastButtonWidth = width(); 00676 } 00677 00678 void LaptopClient::updateActiveBuffer( ) 00679 { 00680 if( !bufferDirty && (lastBufferWidth == titlebar->geometry().width())) 00681 return; 00682 if ( titlebar->geometry().width() <= 0 || titlebar->geometry().height() <= 0 ) 00683 return; 00684 lastBufferWidth = titlebar->geometry().width(); 00685 bufferDirty = false; 00686 00687 activeBuffer.resize(titlebar->geometry().width(), 00688 titlebar->geometry().height()); 00689 QPainter p; 00690 QRect r(0, 0, activeBuffer.width()-1, activeBuffer.height()); 00691 p.begin(&activeBuffer); 00692 if(aUpperGradient){ 00693 p.drawTiledPixmap(r, *aUpperGradient); 00694 } 00695 else{ 00696 p.fillRect(r, options()->color(KDecoration::ColorTitleBar, true)); 00697 } 00698 if(titlePix) 00699 p.drawTiledPixmap(r, *titlePix); 00700 00701 p.setFont(options()->font(true, isTool() )); 00702 QFontMetrics fm(options()->font(true)); 00703 QColorGroup g = options()->colorGroup(KDecoration::ColorTitleBar, true); 00704 if(aUpperGradient) 00705 p.drawTiledPixmap(r.x()+((r.width()-fm.width(caption()))/2)-4, 00706 r.y(), fm.width(caption())+8, r.height()-1, 00707 *aUpperGradient); 00708 else 00709 p.fillRect(r.x()+((r.width()-fm.width(caption()))/2)-4, 0, 00710 fm.width(caption())+8, r.height(), 00711 g.brush(QColorGroup::Background)); 00712 p.setPen(g.mid()); 00713 p.drawLine(r.x(), r.y(), r.right(), r.y()); 00714 p.drawLine(r.x(), r.y(), r.x(), r.bottom()); 00715 p.setPen(g.button()); 00716 p.drawLine(r.right(), r.y(), r.right(), r.bottom()); 00717 p.drawLine(r.x(), r.bottom(), r.right(), r.bottom()); 00718 p.setPen(options()->color(KDecoration::ColorFont, true)); 00719 p.drawText(r.x(), r.y(), r.width(), r.height()-1, 00720 AlignCenter, caption() ); 00721 g = options()->colorGroup(KDecoration::ColorFrame, true); 00722 p.setPen(g.background()); 00723 p.drawPoint(r.x(), r.y()); 00724 p.drawPoint(r.right(), r.y()); 00725 p.drawLine(r.right()+1, r.y(), r.right()+1, r.bottom()); 00726 p.end(); 00727 } 00728 00729 LaptopClient::Position LaptopClient::mousePosition(const QPoint & p) const 00730 { 00731 Position m = PositionCenter; 00732 int range = 8 + 3*handleSize/2; 00733 00734 if (p.y() < (height() - handleSize + 1)) 00735 m = KDecoration::mousePosition(p); 00736 00737 else { 00738 if (p.x() >= (width() - range)) 00739 m = PositionBottomRight; 00740 else if (p.x() <= range) 00741 m = PositionBottomLeft; 00742 else 00743 m = PositionBottom; 00744 } 00745 00746 return m; 00747 } 00748 00749 void LaptopClient::borders(int &left, int &right, int &top, int &bottom) const 00750 { 00751 left = right = 4; 00752 top = titleHeight + 4; 00753 bottom = mustDrawHandle() ? handleSize : 4; 00754 } 00755 00756 void LaptopClient::shadeChange() 00757 { 00758 } 00759 00760 QSize LaptopClient::minimumSize() const 00761 { 00762 return QSize(4 * handleSize, handleSize); 00763 } 00764 00765 void LaptopClient::resize(const QSize& s) 00766 { 00767 widget()->resize(s); 00768 widget()->repaint(); //there is some strange wrong repaint of the frame without 00769 } 00770 00771 static const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | 00772 NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | 00773 NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | 00774 NET::UtilityMask | NET::SplashMask; 00775 00776 bool LaptopClient::isTransient() const 00777 { 00778 NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK); 00779 return type == NET::Dialog; 00780 } 00781 00782 bool LaptopClient::isTool() const 00783 { 00784 NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK); 00785 return type == NET::Toolbar || type == NET::Utility || type == NET::Menu; 00786 } 00787 00788 bool LaptopClient::eventFilter(QObject *o, QEvent *e) 00789 { 00790 if (o != widget()) 00791 return false; 00792 switch (e->type()) { 00793 case QEvent::Resize: 00794 resizeEvent(static_cast< QResizeEvent* >( e )); 00795 return true; 00796 case QEvent::Paint: 00797 paintEvent(static_cast< QPaintEvent* >( e )); 00798 return true; 00799 case QEvent::MouseButtonDblClick: 00800 mouseDoubleClickEvent(static_cast< QMouseEvent* >( e )); 00801 return true; 00802 case QEvent::MouseButtonPress: 00803 processMousePressEvent(static_cast< QMouseEvent* >( e )); 00804 return true; 00805 case QEvent::Show: 00806 showEvent(static_cast< QShowEvent* >( e )); 00807 return true; 00808 default: 00809 break; 00810 } 00811 return false; 00812 } 00813 00814 // ===================================== 00815 00816 LaptopClientFactory::LaptopClientFactory() 00817 { 00818 create_pixmaps(); 00819 } 00820 00821 LaptopClientFactory::~LaptopClientFactory() 00822 { 00823 delete_pixmaps(); 00824 } 00825 00826 KDecoration *LaptopClientFactory::createDecoration(KDecorationBridge *b) 00827 { 00828 findPreferredHandleSize(); 00829 return new Laptop::LaptopClient(b, this); 00830 } 00831 00832 bool LaptopClientFactory::reset(unsigned long /*changed*/) 00833 { 00834 findPreferredHandleSize(); 00835 00836 // TODO Do not recreate decorations if it is not needed. Look at 00837 // ModernSystem for how to do that 00838 Laptop::delete_pixmaps(); 00839 Laptop::create_pixmaps(); 00840 // For now just return true. 00841 return true; 00842 } 00843 00844 QValueList< LaptopClientFactory::BorderSize > 00845 LaptopClientFactory::borderSizes() const 00846 { 00847 // the list must be sorted 00848 return QValueList< BorderSize >() << BorderNormal << BorderLarge << 00849 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized; 00850 } 00851 00852 void LaptopClientFactory::findPreferredHandleSize() 00853 { 00854 switch (options()->preferredBorderSize(this)) { 00855 case KDecoration::BorderLarge: 00856 handleSize = 11; 00857 break; 00858 case KDecoration::BorderVeryLarge: 00859 handleSize = 16; 00860 break; 00861 case KDecoration::BorderHuge: 00862 handleSize = 24; 00863 break; 00864 case KDecoration::BorderVeryHuge: 00865 handleSize = 32; 00866 break; 00867 case KDecoration::BorderOversized: 00868 handleSize = 40; 00869 break; 00870 case KDecoration::BorderTiny: 00871 case KDecoration::BorderNormal: 00872 default: 00873 handleSize = 8; 00874 } 00875 } 00876 00877 } // Laptop namespace 00878 00879 #include "laptopclient.moc" 00880 00881 // vim: 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