kwin Library API Documentation

kwmthemeclient.cpp

00001 #include <kconfig.h> 00002 #include "kwmthemeclient.h" 00003 #include <kglobal.h> 00004 #include <qlayout.h> 00005 #include <qdrawutil.h> 00006 #include <qpainter.h> 00007 #include <kpixmapeffect.h> 00008 #include <kstandarddirs.h> 00009 #include <kdebug.h> 00010 #include <klocale.h> 00011 #include <qbitmap.h> 00012 #include <qstyle.h> 00013 #include <qlabel.h> 00014 #include <qtooltip.h> 00015 00016 namespace KWMTheme { 00017 00018 00019 /* static QPixmap stretchPixmap(QPixmap& src, bool stretchVert){ 00020 QPixmap dest; 00021 QBitmap *srcMask, *destMask; 00022 int w, h, w2, h2; 00023 QPainter p; 00024 00025 if (src.isNull()) return src; 00026 00027 w = src.width(); 00028 h = src.height(); 00029 00030 if (stretchVert){ 00031 w2 = w; 00032 for (h2=h; h2<100; h2=h2<<1) 00033 ; 00034 } 00035 else{ 00036 h2 = h; 00037 for (w2=w; w2<100; w2=w2<<1) 00038 ; 00039 } 00040 if (w2==w && h2==h) return src; 00041 00042 dest = src; 00043 dest.resize(w2, h2); 00044 00045 p.begin(&dest); 00046 p.drawTiledPixmap(0, 0, w2, h2, src); 00047 p.end(); 00048 00049 srcMask = (QBitmap*)src.mask(); 00050 if (srcMask){ 00051 destMask = (QBitmap*)dest.mask(); 00052 p.begin(destMask); 00053 p.drawTiledPixmap(0, 0, w2, h2, *srcMask); 00054 p.end(); 00055 } 00056 return dest; 00057 } */ 00058 00059 00060 inline const KDecorationOptions* options() { return KDecoration::options(); } 00061 00062 enum FramePixmap{FrameTop=0, FrameBottom, FrameLeft, FrameRight, FrameTopLeft, 00063 FrameTopRight, FrameBottomLeft, FrameBottomRight}; 00064 00065 static QPixmap *framePixmaps[8]; 00066 static QPixmap *menuPix, *iconifyPix, *closePix, *maxPix, *minmaxPix, 00067 *pinupPix, *pindownPix; 00068 static KPixmap *aTitlePix = 0; 00069 static KPixmap *iTitlePix = 0; 00070 static KPixmapEffect::GradientType grType; 00071 static int maxExtent, titleAlign; 00072 static bool titleGradient = true; 00073 static bool pixmaps_created = false; 00074 static bool titleSunken = false; 00075 static bool titleTransparent; 00076 00077 static void create_pixmaps() 00078 { 00079 const char *keys[] = {"wm_top", "wm_bottom", "wm_left", "wm_right", 00080 "wm_topleft", "wm_topright", "wm_bottomleft", "wm_bottomright"}; 00081 00082 if(pixmaps_created) 00083 return; 00084 pixmaps_created = true; 00085 00086 KConfig *config = KGlobal::config(); 00087 config->setGroup("General"); 00088 QString tmpStr; 00089 00090 for(int i=0; i < 8; ++i) 00091 { 00092 framePixmaps[i] = new QPixmap(locate("data", 00093 "kwin/pics/"+config->readEntry(keys[i], " "))); 00094 if(framePixmaps[i]->isNull()) 00095 kdWarning() << "Unable to load frame pixmap for " << keys[i] << endl; 00096 } 00097 /* 00098 *framePixmaps[FrameTop] = stretchPixmap(*framePixmaps[FrameTop], false); 00099 *framePixmaps[FrameBottom] = stretchPixmap(*framePixmaps[FrameBottom], false); 00100 *framePixmaps[FrameLeft] = stretchPixmap(*framePixmaps[FrameLeft], true); 00101 *framePixmaps[FrameRight] = stretchPixmap(*framePixmaps[FrameRight], true); 00102 */ 00103 maxExtent = framePixmaps[FrameTop]->height(); 00104 if(framePixmaps[FrameBottom]->height() > maxExtent) 00105 maxExtent = framePixmaps[FrameBottom]->height(); 00106 if(framePixmaps[FrameLeft]->width() > maxExtent) 00107 maxExtent = framePixmaps[FrameLeft]->width(); 00108 if(framePixmaps[FrameRight]->width() > maxExtent) 00109 maxExtent = framePixmaps[FrameRight]->width(); 00110 00111 maxExtent++; 00112 00113 menuPix = new QPixmap(locate("data", 00114 "kwin/pics/"+config->readEntry("menu", " "))); 00115 iconifyPix = new QPixmap(locate("data", 00116 "kwin/pics/"+config->readEntry("iconify", " "))); 00117 maxPix = new QPixmap(locate("appdata", 00118 "pics/"+config->readEntry("maximize", " "))); 00119 minmaxPix = new QPixmap(locate("data", 00120 "kwin/pics/"+config->readEntry("maximizedown", " "))); 00121 closePix = new QPixmap(locate("data", 00122 "kwin/pics/"+config->readEntry("close", " "))); 00123 pinupPix = new QPixmap(locate("data", 00124 "kwin/pics/"+config->readEntry("pinup", " "))); 00125 pindownPix = new QPixmap(locate("data", 00126 "kwin/pics/"+config->readEntry("pindown", " "))); 00127 if(menuPix->isNull()) 00128 menuPix->load(locate("data", "kwin/pics/menu.png")); 00129 if(iconifyPix->isNull()) 00130 iconifyPix->load(locate("data", "kwin/pics/iconify.png")); 00131 if(maxPix->isNull()) 00132 maxPix->load(locate("data", "kwin/pics/maximize.png")); 00133 if(minmaxPix->isNull()) 00134 minmaxPix->load(locate("data", "kwin/pics/maximizedown.png")); 00135 if(closePix->isNull()) 00136 closePix->load(locate("data", "kwin/pics/close.png")); 00137 if(pinupPix->isNull()) 00138 pinupPix->load(locate("data", "kwin/pics/pinup.png")); 00139 if(pindownPix->isNull()) 00140 pindownPix->load(locate("data", "kwin/pics/pindown.png")); 00141 00142 tmpStr = config->readEntry("TitleAlignment"); 00143 if(tmpStr == "right") 00144 titleAlign = Qt::AlignRight | Qt::AlignVCenter; 00145 else if(tmpStr == "middle") 00146 titleAlign = Qt::AlignCenter; 00147 else 00148 titleAlign = Qt::AlignLeft | Qt::AlignVCenter; 00149 titleSunken = config->readBoolEntry("TitleFrameShaded", true); 00150 // titleSunken = true; // is this fixed? 00151 titleTransparent = config->readBoolEntry("PixmapUnderTitleText", true); 00152 00153 tmpStr = config->readEntry("TitlebarLook"); 00154 if(tmpStr == "shadedVertical"){ 00155 aTitlePix = new KPixmap; 00156 aTitlePix->resize(32, 20); 00157 KPixmapEffect::gradient(*aTitlePix, 00158 options()->color(KDecorationOptions::ColorTitleBar, true), 00159 options()->color(KDecorationOptions::ColorTitleBlend, true), 00160 KPixmapEffect::VerticalGradient); 00161 iTitlePix = new KPixmap; 00162 iTitlePix->resize(32, 20); 00163 KPixmapEffect::gradient(*iTitlePix, 00164 options()->color(KDecorationOptions::ColorTitleBar, false), 00165 options()->color(KDecorationOptions::ColorTitleBlend, false), 00166 KPixmapEffect::VerticalGradient); 00167 titleGradient = false; // we can just tile this 00168 00169 } 00170 else if(tmpStr == "shadedHorizontal") 00171 grType = KPixmapEffect::HorizontalGradient; 00172 else if(tmpStr == "shadedDiagonal") 00173 grType = KPixmapEffect::DiagonalGradient; 00174 else if(tmpStr == "shadedCrossDiagonal") 00175 grType = KPixmapEffect::CrossDiagonalGradient; 00176 else if(tmpStr == "shadedPyramid") 00177 grType = KPixmapEffect::PyramidGradient; 00178 else if(tmpStr == "shadedRectangle") 00179 grType = KPixmapEffect::RectangleGradient; 00180 else if(tmpStr == "shadedPipeCross") 00181 grType = KPixmapEffect::PipeCrossGradient; 00182 else if(tmpStr == "shadedElliptic") 00183 grType = KPixmapEffect::EllipticGradient; 00184 else{ 00185 titleGradient = false; 00186 tmpStr = config->readEntry("TitlebarPixmapActive", ""); 00187 if(!tmpStr.isEmpty()){ 00188 aTitlePix = new KPixmap; 00189 aTitlePix->load(locate("data", "kwin/pics/" + tmpStr)); 00190 } 00191 else 00192 aTitlePix = NULL; 00193 tmpStr = config->readEntry("TitlebarPixmapInactive", ""); 00194 if(!tmpStr.isEmpty()){ 00195 iTitlePix = new KPixmap; 00196 iTitlePix->load(locate("data", "kwin/pics/" + tmpStr)); 00197 } 00198 else 00199 iTitlePix = NULL; 00200 } 00201 } 00202 00203 static void delete_pixmaps() 00204 { 00205 for(int i=0; i < 8; ++i) 00206 delete framePixmaps[i]; 00207 00208 delete menuPix; 00209 delete iconifyPix; 00210 delete closePix; 00211 delete maxPix; 00212 delete minmaxPix; 00213 delete pinupPix; 00214 delete pindownPix; 00215 delete aTitlePix; 00216 aTitlePix = 0; 00217 delete iTitlePix; 00218 iTitlePix = 0; 00219 00220 titleGradient = true; 00221 pixmaps_created = false; 00222 titleSunken = false; 00223 } 00224 00225 void MyButton::drawButtonLabel(QPainter *p) 00226 { 00227 if(pixmap()){ 00228 // If we have a theme who's button covers the entire width or 00229 // entire height, we shift down/right by 1 pixel so we have 00230 // some visual notification of button presses. i.e. for MGBriezh 00231 int offset = (isDown() && ((pixmap()->width() >= width()) || 00232 (pixmap()->height() >= height()))) ? 1 : 0; 00233 style().drawItem(p, QRect( offset, offset, width(), height() ), 00234 AlignCenter, colorGroup(), 00235 true, pixmap(), QString::null); 00236 } 00237 } 00238 00239 KWMThemeClient::KWMThemeClient( KDecorationBridge* b, KDecorationFactory* f ) 00240 : KDecoration( b, f ) 00241 { 00242 } 00243 00244 void KWMThemeClient::init() 00245 { 00246 createMainWidget( WResizeNoErase | WStaticContents ); 00247 widget()->installEventFilter( this ); 00248 00249 stickyBtn = maxBtn = mnuBtn = 0; 00250 layout = new QGridLayout(widget()); 00251 layout->addColSpacing(0, maxExtent); 00252 layout->addColSpacing(2, maxExtent); 00253 00254 layout->addRowSpacing(0, maxExtent); 00255 00256 layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, 00257 QSizePolicy::Expanding)); 00258 00259 if( isPreview()) 00260 layout->addWidget( new QLabel( i18n( "<center><b>KWMTheme</b></center>" ), widget()), 2, 1); 00261 else 00262 layout->addItem( new QSpacerItem( 0, 0 ), 2, 1); 00263 00264 // Without the next line, shading flickers 00265 layout->addItem( new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding) ); 00266 layout->addRowSpacing(3, maxExtent); 00267 layout->setRowStretch(2, 10); 00268 layout->setColStretch(1, 10); 00269 00270 QBoxLayout* hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0); 00271 layout->addLayout( hb, 1, 1 ); 00272 00273 KConfig *config = KGlobal::config(); 00274 config->setGroup("Buttons"); 00275 QString val; 00276 MyButton *btn; 00277 int i; 00278 static const char *defaultButtons[]={"Menu","Sticky","Off","Iconify", 00279 "Maximize","Close"}; 00280 static const char keyOffsets[]={"ABCDEF"}; 00281 for(i=0; i < 6; ++i){ 00282 if(i == 3){ 00283 titlebar = new QSpacerItem(10, 20, QSizePolicy::Expanding, 00284 QSizePolicy::Minimum ); 00285 hb->addItem( titlebar ); 00286 } 00287 QString key("Button"); 00288 key += QChar(keyOffsets[i]); 00289 val = config->readEntry(key, defaultButtons[i]); 00290 if(val == "Menu"){ 00291 mnuBtn = new MyButton(widget(), "menu"); 00292 QToolTip::add( mnuBtn, i18n("Menu")); 00293 iconChange(); 00294 hb->addWidget(mnuBtn); 00295 mnuBtn->setFixedSize(20, 20); 00296 connect(mnuBtn, SIGNAL(pressed()), this, 00297 SLOT(menuButtonPressed())); 00298 } 00299 else if(val == "Sticky"){ 00300 stickyBtn = new MyButton(widget(), "sticky"); 00301 QToolTip::add( stickyBtn, i18n("Sticky")); 00302 if (isOnAllDesktops()) 00303 stickyBtn->setPixmap(*pindownPix); 00304 else 00305 stickyBtn->setPixmap(*pinupPix); 00306 connect(stickyBtn, SIGNAL( clicked() ), this, SLOT(toggleOnAllDesktops())); 00307 hb->addWidget(stickyBtn); 00308 stickyBtn->setFixedSize(20, 20); 00309 } 00310 else if((val == "Iconify") && isMinimizable()){ 00311 btn = new MyButton(widget(), "iconify"); 00312 QToolTip::add( btn, i18n("Minimize")); 00313 btn->setPixmap(*iconifyPix); 00314 connect(btn, SIGNAL(clicked()), this, SLOT(minimize())); 00315 hb->addWidget(btn); 00316 btn->setFixedSize(20, 20); 00317 } 00318 else if((val == "Maximize") && isMaximizable()){ 00319 maxBtn = new MyButton(widget(), "max"); 00320 QToolTip::add( maxBtn, i18n("Maximize")); 00321 maxBtn->setPixmap(*maxPix); 00322 connect(maxBtn, SIGNAL(clicked()), this, SLOT(maximize())); 00323 hb->addWidget(maxBtn); 00324 maxBtn->setFixedSize(20, 20); 00325 } 00326 else if((val == "Close") && isCloseable()){ 00327 btn = new MyButton(widget(), "close"); 00328 QToolTip::add( btn, i18n("Close")); 00329 btn->setPixmap(*closePix); 00330 connect(btn, SIGNAL(clicked()), this, SLOT(closeWindow())); 00331 hb->addWidget(btn); 00332 btn->setFixedSize(20, 20); 00333 } 00334 else{ 00335 if((val != "Off") && 00336 ((val == "Iconify") && !isMinimizable()) && 00337 ((val == "Maximize") && !isMaximizable())) 00338 kdWarning() << "KWin: Unrecognized button value: " << val << endl; 00339 00340 } 00341 } 00342 if(titleGradient){ 00343 aGradient = new KPixmap; 00344 iGradient = new KPixmap; 00345 } 00346 else{ 00347 aGradient = 0; 00348 iGradient = 0; 00349 } 00350 widget()->setBackgroundMode(NoBackground); 00351 } 00352 00353 void KWMThemeClient::drawTitle(QPainter &dest) 00354 { 00355 QRect titleRect = titlebar->geometry(); 00356 QRect r(0, 0, titleRect.width(), titleRect.height()); 00357 QPixmap buffer; 00358 00359 if(buffer.width() == r.width()) 00360 return; 00361 00362 buffer.resize(r.size()); 00363 QPainter p; 00364 p.begin(&buffer); 00365 00366 if(titleSunken){ 00367 qDrawShadeRect(&p, r, options()->colorGroup(KDecorationOptions::ColorFrame, isActive()), 00368 true, 1, 0); 00369 r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); 00370 } 00371 00372 KPixmap *fill = isActive() ? aTitlePix : iTitlePix; 00373 if(fill) 00374 p.drawTiledPixmap(r, *fill); 00375 else if(titleGradient){ 00376 fill = isActive() ? aGradient : iGradient; 00377 if(fill->width() != r.width()){ 00378 fill->resize(r.width(), 20); 00379 KPixmapEffect::gradient(*fill, 00380 options()->color(KDecorationOptions::ColorTitleBar, isActive()), 00381 options()->color(KDecorationOptions::ColorTitleBlend, isActive()), 00382 grType); 00383 } 00384 p.drawTiledPixmap(r, *fill); 00385 } 00386 else{ 00387 p.fillRect(r, options()->colorGroup(KDecorationOptions::ColorTitleBar, isActive()). 00388 brush(QColorGroup::Button)); 00389 } 00390 p.setFont(options()->font(isActive())); 00391 p.setPen(options()->color(KDecorationOptions::ColorFont, isActive())); 00392 // Add left & right margin 00393 r.setLeft(r.left()+5); 00394 r.setRight(r.right()-5); 00395 p.drawText(r, titleAlign, caption()); 00396 p.end(); 00397 00398 dest.drawPixmap(titleRect.x(), titleRect.y(), buffer); 00399 } 00400 00401 00402 void KWMThemeClient::resizeEvent( QResizeEvent* ) 00403 { 00404 doShape(); 00405 widget()->repaint(); 00406 } 00407 00408 void KWMThemeClient::captionChange() 00409 { 00410 widget()->repaint( titlebar->geometry(), false ); 00411 } 00412 00413 void KWMThemeClient::paintEvent( QPaintEvent *) 00414 { 00415 QPainter p; 00416 p.begin(widget()); 00417 int x,y; 00418 // first the corners 00419 int w1 = framePixmaps[FrameTopLeft]->width(); 00420 int h1 = framePixmaps[FrameTopLeft]->height(); 00421 if (w1 > width()/2) w1 = width()/2; 00422 if (h1 > height()/2) h1 = height()/2; 00423 p.drawPixmap(0,0,*framePixmaps[FrameTopLeft], 00424 0,0,w1, h1); 00425 int w2 = framePixmaps[FrameTopRight]->width(); 00426 int h2 = framePixmaps[FrameTopRight]->height(); 00427 if (w2 > width()/2) w2 = width()/2; 00428 if (h2 > height()/2) h2 = height()/2; 00429 p.drawPixmap(width()-w2,0,*framePixmaps[FrameTopRight], 00430 framePixmaps[FrameTopRight]->width()-w2,0,w2, h2); 00431 00432 int w3 = framePixmaps[FrameBottomLeft]->width(); 00433 int h3 = framePixmaps[FrameBottomLeft]->height(); 00434 if (w3 > width()/2) w3 = width()/2; 00435 if (h3 > height()/2) h3 = height()/2; 00436 p.drawPixmap(0,height()-h3,*framePixmaps[FrameBottomLeft], 00437 0,framePixmaps[FrameBottomLeft]->height()-h3,w3, h3); 00438 00439 int w4 = framePixmaps[FrameBottomRight]->width(); 00440 int h4 = framePixmaps[FrameBottomRight]->height(); 00441 if (w4 > width()/2) w4 = width()/2; 00442 if (h4 > height()/2) h4 = height()/2; 00443 p.drawPixmap(width()-w4,height()-h4,*(framePixmaps[FrameBottomRight]), 00444 framePixmaps[FrameBottomRight]->width()-w4, 00445 framePixmaps[FrameBottomRight]->height()-h4, 00446 w4, h4); 00447 00448 QPixmap pm; 00449 QWMatrix m; 00450 int n,s,w; 00451 //top 00452 pm = *framePixmaps[FrameTop]; 00453 00454 if (pm.width() > 0){ 00455 s = width()-w2-w1; 00456 n = s/pm.width(); 00457 w = n>0?s/n:s; 00458 m.reset(); 00459 m.scale(w/(float)pm.width(), 1); 00460 pm = pm.xForm(m); 00461 00462 x = w1; 00463 while (1){ 00464 if (pm.width() < width()-w2-x){ 00465 p.drawPixmap(x,maxExtent-pm.height()-1, 00466 pm); 00467 x += pm.width(); 00468 } 00469 else { 00470 p.drawPixmap(x,maxExtent-pm.height()-1, 00471 pm, 00472 0,0,width()-w2-x,pm.height()); 00473 break; 00474 } 00475 } 00476 } 00477 00478 //bottom 00479 pm = *framePixmaps[FrameBottom]; 00480 00481 if (pm.width() > 0){ 00482 s = width()-w4-w3; 00483 n = s/pm.width(); 00484 w = n>0?s/n:s; 00485 m.reset(); 00486 m.scale(w/(float)pm.width(), 1); 00487 pm = pm.xForm(m); 00488 00489 x = w3; 00490 while (1){ 00491 if (pm.width() < width()-w4-x){ 00492 p.drawPixmap(x,height()-maxExtent+1,pm); 00493 x += pm.width(); 00494 } 00495 else { 00496 p.drawPixmap(x,height()-maxExtent+1,pm, 00497 0,0,width()-w4-x,pm.height()); 00498 break; 00499 } 00500 } 00501 } 00502 00503 //left 00504 pm = *framePixmaps[FrameLeft]; 00505 00506 if (pm.height() > 0){ 00507 s = height()-h3-h1; 00508 n = s/pm.height(); 00509 w = n>0?s/n:s; 00510 m.reset(); 00511 m.scale(1, w/(float)pm.height()); 00512 pm = pm.xForm(m); 00513 00514 y = h1; 00515 while (1){ 00516 if (pm.height() < height()-h3-y){ 00517 p.drawPixmap(maxExtent-pm.width()-1, y, 00518 pm); 00519 y += pm.height(); 00520 } 00521 else { 00522 p.drawPixmap(maxExtent-pm.width()-1, y, 00523 pm, 00524 0,0, pm.width(), 00525 height()-h3-y); 00526 break; 00527 } 00528 } 00529 } 00530 00531 //right 00532 pm = *framePixmaps[FrameRight]; 00533 00534 if (pm.height() > 0){ 00535 s = height()-h4-h2; 00536 n = s/pm.height(); 00537 w = n>0?s/n:s; 00538 m.reset(); 00539 m.scale(1, w/(float)pm.height()); 00540 pm = pm.xForm(m); 00541 00542 y = h2; 00543 while (1){ 00544 if (pm.height() < height()-h4-y){ 00545 p.drawPixmap(width()-maxExtent+1, y, 00546 pm); 00547 y += pm.height(); 00548 } 00549 else { 00550 p.drawPixmap(width()-maxExtent+1, y, 00551 pm, 00552 0,0, pm.width(), 00553 height()-h4-y); 00554 break; 00555 } 00556 } 00557 } 00558 drawTitle(p); 00559 00560 QColor c = widget()->colorGroup().background(); 00561 00562 // KWM evidently had a 1 pixel border around the client window. We 00563 // emulate it here, but should be removed at some point in order to 00564 // seamlessly mesh widget themes 00565 p.setPen(c); 00566 p.drawRect(maxExtent-1, maxExtent-1, width()-(maxExtent-1)*2, 00567 height()-(maxExtent-1)*2); 00568 00569 // We fill the area behind the wrapped widget to ensure that 00570 // shading animation is drawn as smoothly as possible 00571 QRect r(layout->cellGeometry(2, 1)); 00572 p.fillRect( r.x(), r.y(), r.width(), r.height(), c); 00573 p.end(); 00574 } 00575 00576 void KWMThemeClient::doShape() 00577 { 00578 00579 QBitmap shapemask(width(), height()); 00580 shapemask.fill(color0); 00581 QPainter p; 00582 p.begin(&shapemask); 00583 p.setBrush(color1); 00584 p.setPen(color1); 00585 int x,y; 00586 // first the corners 00587 int w1 = framePixmaps[FrameTopLeft]->width(); 00588 int h1 = framePixmaps[FrameTopLeft]->height(); 00589 if (w1 > width()/2) w1 = width()/2; 00590 if (h1 > height()/2) h1 = height()/2; 00591 if (framePixmaps[FrameTopLeft]->mask()) 00592 p.drawPixmap(0,0,*framePixmaps[FrameTopLeft]->mask(), 00593 0,0,w1, h1); 00594 else 00595 p.fillRect(0,0,w1,h1,color1); 00596 int w2 = framePixmaps[FrameTopRight]->width(); 00597 int h2 = framePixmaps[FrameTopRight]->height(); 00598 if (w2 > width()/2) w2 = width()/2; 00599 if (h2 > height()/2) h2 = height()/2; 00600 if (framePixmaps[FrameTopRight]->mask()) 00601 p.drawPixmap(width()-w2,0,*framePixmaps[FrameTopRight]->mask(), 00602 framePixmaps[FrameTopRight]->width()-w2,0,w2, h2); 00603 else 00604 p.fillRect(width()-w2,0,w2, h2,color1); 00605 00606 int w3 = framePixmaps[FrameBottomLeft]->width(); 00607 int h3 = framePixmaps[FrameBottomLeft]->height(); 00608 if (w3 > width()/2) w3 = width()/2; 00609 if (h3 > height()/2) h3 = height()/2; 00610 if (framePixmaps[FrameBottomLeft]->mask()) 00611 p.drawPixmap(0,height()-h3,*framePixmaps[FrameBottomLeft]->mask(), 00612 0,framePixmaps[FrameBottomLeft]->height()-h3,w3, h3); 00613 else 00614 p.fillRect(0,height()-h3,w3,h3,color1); 00615 00616 int w4 = framePixmaps[FrameBottomRight]->width(); 00617 int h4 = framePixmaps[FrameBottomRight]->height(); 00618 if (w4 > width()/2) w4 = width()/2; 00619 if (h4 > height()/2) h4 = height()/2; 00620 if (framePixmaps[FrameBottomRight]->mask()) 00621 p.drawPixmap(width()-w4,height()-h4,*framePixmaps[FrameBottomRight]->mask(), 00622 framePixmaps[FrameBottomRight]->width()-w4, 00623 framePixmaps[FrameBottomRight]->height()-h4, 00624 w4, h4); 00625 else 00626 p.fillRect(width()-w4,height()-h4,w4,h4,color1); 00627 00628 QPixmap pm; 00629 QWMatrix m; 00630 int n,s,w; 00631 //top 00632 if (framePixmaps[FrameTop]->mask()) 00633 { 00634 pm = *framePixmaps[FrameTop]->mask(); 00635 00636 s = width()-w2-w1; 00637 n = s/pm.width(); 00638 w = n>0?s/n:s; 00639 m.reset(); 00640 m.scale(w/(float)pm.width(), 1); 00641 pm = pm.xForm(m); 00642 00643 x = w1; 00644 while (1){ 00645 if (pm.width() < width()-w2-x){ 00646 p.drawPixmap(x,maxExtent-pm.height()-1, 00647 pm); 00648 x += pm.width(); 00649 } 00650 else { 00651 p.drawPixmap(x,maxExtent-pm.height()-1, 00652 pm, 00653 0,0,width()-w2-x,pm.height()); 00654 break; 00655 } 00656 } 00657 } 00658 00659 //bottom 00660 if (framePixmaps[FrameBottom]->mask()) 00661 { 00662 pm = *framePixmaps[FrameBottom]->mask(); 00663 00664 s = width()-w4-w3; 00665 n = s/pm.width(); 00666 w = n>0?s/n:s; 00667 m.reset(); 00668 m.scale(w/(float)pm.width(), 1); 00669 pm = pm.xForm(m); 00670 00671 x = w3; 00672 while (1){ 00673 if (pm.width() < width()-w4-x){ 00674 p.drawPixmap(x,height()-maxExtent+1,pm); 00675 x += pm.width(); 00676 } 00677 else { 00678 p.drawPixmap(x,height()-maxExtent+1,pm, 00679 0,0,width()-w4-x,pm.height()); 00680 break; 00681 } 00682 } 00683 } 00684 00685 //left 00686 if (framePixmaps[FrameLeft]->mask()) 00687 { 00688 pm = *framePixmaps[FrameLeft]->mask(); 00689 00690 s = height()-h3-h1; 00691 n = s/pm.height(); 00692 w = n>0?s/n:s; 00693 m.reset(); 00694 m.scale(1, w/(float)pm.height()); 00695 pm = pm.xForm(m); 00696 00697 y = h1; 00698 while (1){ 00699 if (pm.height() < height()-h3-y){ 00700 p.drawPixmap(maxExtent-pm.width()-1, y, 00701 pm); 00702 y += pm.height(); 00703 } 00704 else { 00705 p.drawPixmap(maxExtent-pm.width()-1, y, 00706 pm, 00707 0,0, pm.width(), 00708 height()-h3-y); 00709 break; 00710 } 00711 } 00712 } 00713 00714 //right 00715 if (framePixmaps[FrameRight]->mask()) 00716 { 00717 pm = *framePixmaps[FrameRight]->mask(); 00718 00719 s = height()-h4-h2; 00720 n = s/pm.height(); 00721 w = n>0?s/n:s; 00722 m.reset(); 00723 m.scale(1, w/(float)pm.height()); 00724 pm = pm.xForm(m); 00725 00726 y = h2; 00727 while (1){ 00728 if (pm.height() < height()-h4-y){ 00729 p.drawPixmap(width()-maxExtent+1, y, 00730 pm); 00731 y += pm.height(); 00732 } 00733 else { 00734 p.drawPixmap(width()-maxExtent+1, y, 00735 pm, 00736 0,0, pm.width(), 00737 height()-h4-y); 00738 break; 00739 } 00740 } 00741 } 00742 p.fillRect(maxExtent-1, maxExtent-1, width()-2*maxExtent+2, height()-2*maxExtent+2, color1); 00743 setMask(shapemask); 00744 } 00745 00746 00747 void KWMThemeClient::showEvent(QShowEvent *) 00748 { 00749 doShape(); 00750 widget()->repaint(false); 00751 } 00752 00753 void KWMThemeClient::mouseDoubleClickEvent( QMouseEvent * e ) 00754 { 00755 if (titlebar->geometry().contains( e->pos() ) ) 00756 titlebarDblClickOperation(); 00757 } 00758 00759 void KWMThemeClient::desktopChange() 00760 { 00761 if (stickyBtn) { 00762 bool on = isOnAllDesktops(); 00763 stickyBtn->setPixmap(on ? *pindownPix : *pinupPix); 00764 QToolTip::remove( stickyBtn ); 00765 QToolTip::add( stickyBtn, on ? i18n("Un-Sticky") : i18n("Sticky") ); 00766 } 00767 } 00768 00769 void KWMThemeClient::maximizeChange() 00770 { 00771 if (maxBtn) { 00772 bool m = maximizeMode() == MaximizeFull; 00773 maxBtn->setPixmap(m ? *minmaxPix : *maxPix); 00774 QToolTip::remove( maxBtn ); 00775 QToolTip::add( maxBtn, m ? i18n("Restore") : i18n("Maximize")); 00776 } 00777 } 00778 00779 void KWMThemeClient::slotMaximize() 00780 { 00781 maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull ); 00782 } 00783 00784 void KWMThemeClient::activeChange() 00785 { 00786 widget()->update(); 00787 } 00788 00789 KDecoration::Position KWMThemeClient::mousePosition(const QPoint &p) const 00790 { 00791 Position m = KDecoration::mousePosition(p); 00792 // corners 00793 if(p.y() < framePixmaps[FrameTop]->height() && 00794 p.x() < framePixmaps[FrameLeft]->width()){ 00795 m = PositionTopLeft; 00796 } 00797 else if(p.y() < framePixmaps[FrameTop]->height() && 00798 p.x() > width()-framePixmaps[FrameRight]->width()){ 00799 m = PositionTopRight; 00800 } 00801 else if(p.y() > height()-framePixmaps[FrameBottom]->height() && 00802 p.x() < framePixmaps[FrameLeft]->width()){ 00803 m = PositionBottomLeft; 00804 } 00805 else if(p.y() > height()-framePixmaps[FrameBottom]->height() && 00806 p.x() > width()-framePixmaps[FrameRight]->width()){ 00807 m = PositionBottomRight; 00808 } // edges 00809 else if(p.y() < framePixmaps[FrameTop]->height()) 00810 m = PositionTop; 00811 else if(p.y() > height()-framePixmaps[FrameBottom]->height()) 00812 m = PositionBottom; 00813 else if(p.x() < framePixmaps[FrameLeft]->width()) 00814 m = PositionLeft; 00815 else if(p.x() > width()-framePixmaps[FrameRight]->width()) 00816 m = PositionRight; 00817 return(m); 00818 } 00819 00820 void KWMThemeClient::menuButtonPressed() 00821 { 00822 mnuBtn->setDown(false); // will stay down if I don't do this 00823 QPoint pos = mnuBtn->mapToGlobal(mnuBtn->rect().bottomLeft()); 00824 showWindowMenu( pos ); 00825 } 00826 00827 void KWMThemeClient::iconChange() 00828 { 00829 if(mnuBtn){ 00830 if( icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull()){ 00831 mnuBtn->setPixmap(*menuPix); 00832 } 00833 else{ 00834 mnuBtn->setPixmap(icon().pixmap( QIconSet::Small, QIconSet::Normal )); 00835 } 00836 } 00837 } 00838 00839 bool KWMThemeClient::eventFilter( QObject* o, QEvent* e ) 00840 { 00841 if ( o != widget() ) 00842 return false; 00843 00844 switch ( e->type() ) 00845 { 00846 case QEvent::Resize: 00847 resizeEvent( static_cast< QResizeEvent* >( e ) ); 00848 return true; 00849 00850 case QEvent::Paint: 00851 paintEvent( static_cast< QPaintEvent* >( e ) ); 00852 return true; 00853 00854 case QEvent::MouseButtonDblClick: 00855 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) ); 00856 return true; 00857 00858 case QEvent::MouseButtonPress: 00859 processMousePressEvent( static_cast< QMouseEvent* >( e ) ); 00860 return true; 00861 00862 case QEvent::Show: 00863 showEvent( static_cast< QShowEvent* >( e ) ); 00864 return true; 00865 00866 default: 00867 return false; 00868 } 00869 } 00870 00871 QSize KWMThemeClient::minimumSize() const 00872 { 00873 return widget()->minimumSize().expandedTo( QSize( 100, 50 )); 00874 } 00875 00876 void KWMThemeClient::resize( const QSize& s ) 00877 { 00878 widget()->resize( s ); 00879 } 00880 00881 void KWMThemeClient::borders( int& left, int& right, int& top, int& bottom ) const 00882 { 00883 left = 00884 right = 00885 top = 00886 bottom = 00887 00888 TODO 00889 } 00890 00891 KWMThemeFactory::KWMThemeFactory() 00892 { 00893 create_pixmaps(); 00894 } 00895 00896 KWMThemeFactory::~KWMThemeFactory() 00897 { 00898 delete_pixmaps(); 00899 } 00900 00901 KDecoration* KWMThemeFactory::createDecoration( KDecorationBridge* b ) 00902 { 00903 return new KWMThemeClient( b, this ); 00904 } 00905 00906 bool KWMThemeFactory::reset( unsigned long mask ) 00907 { 00908 bool needHardReset = false; 00909 00910 TODO 00911 00912 // doesn't obey the Border size setting 00913 if( mask & ( SettingFont | SettingButtons )) 00914 needHardReset = true; 00915 00916 if( mask & ( SettingFont | SettingColors )) { 00917 KWMTheme::delete_pixmaps(); 00918 KWMTheme::create_pixmaps(); 00919 } 00920 00921 if( !needHardReset ) 00922 resetDecorations( mask ); 00923 return needHardReset; 00924 } 00925 00926 } 00927 00928 extern "C" 00929 { 00930 KDecorationFactory *create_factory() 00931 { 00932 return new KWMTheme::KWMThemeFactory(); 00933 } 00934 } 00935 00936 #include "kwmthemeclient.moc"
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 Dec 16 19:08:41 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003