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     int w2 = framePixmaps[FrameTopRight]->width();
00595     int h2 = framePixmaps[FrameTopRight]->height();
00596     if (w2 > width()/2) w2 = width()/2;
00597     if (h2 > height()/2) h2 = height()/2;
00598     if (framePixmaps[FrameTopRight]->mask())
00599         p.drawPixmap(width()-w2,0,*framePixmaps[FrameTopRight]->mask(),
00600              framePixmaps[FrameTopRight]->width()-w2,0,w2, h2);
00601 
00602     int w3 = framePixmaps[FrameBottomLeft]->width();
00603     int h3 = framePixmaps[FrameBottomLeft]->height();
00604     if (w3 > width()/2) w3 = width()/2;
00605     if (h3 > height()/2) h3 = height()/2;
00606     if (framePixmaps[FrameBottomLeft]->mask())
00607         p.drawPixmap(0,height()-h3,*framePixmaps[FrameBottomLeft]->mask(),
00608              0,framePixmaps[FrameBottomLeft]->height()-h3,w3, h3);
00609 
00610     int w4 = framePixmaps[FrameBottomRight]->width();
00611     int h4 = framePixmaps[FrameBottomRight]->height();
00612     if (w4 > width()/2) w4 = width()/2;
00613     if (h4 > height()/2) h4 = height()/2;
00614     if (framePixmaps[FrameBottomRight]->mask())
00615         p.drawPixmap(width()-w4,height()-h4,*framePixmaps[FrameBottomRight]->mask(),
00616              framePixmaps[FrameBottomRight]->width()-w4,
00617              framePixmaps[FrameBottomRight]->height()-h4,
00618              w4, h4);
00619 
00620     QPixmap pm;
00621     QWMatrix m;
00622     int n,s,w;
00623     //top
00624     if (framePixmaps[FrameTop]->mask())
00625     {
00626         pm = *framePixmaps[FrameTop]->mask();
00627 
00628         s = width()-w2-w1;
00629         n = s/pm.width();
00630         w = n>0?s/n:s;
00631         m.reset();
00632         m.scale(w/(float)pm.width(), 1);
00633         pm = pm.xForm(m);
00634 
00635         x = w1;
00636         while (1){
00637             if (pm.width() < width()-w2-x){
00638                 p.drawPixmap(x,maxExtent-pm.height()-1,
00639                      pm);
00640             x += pm.width();
00641             }
00642             else {
00643             p.drawPixmap(x,maxExtent-pm.height()-1,
00644                      pm,
00645                      0,0,width()-w2-x,pm.height());
00646             break;
00647             }
00648         }
00649     }
00650 
00651     //bottom
00652     if (framePixmaps[FrameBottom]->mask())
00653     {
00654         pm = *framePixmaps[FrameBottom]->mask();
00655 
00656         s = width()-w4-w3;
00657         n = s/pm.width();
00658         w = n>0?s/n:s;
00659         m.reset();
00660         m.scale(w/(float)pm.width(), 1);
00661         pm = pm.xForm(m);
00662 
00663         x = w3;
00664         while (1){
00665           if (pm.width() < width()-w4-x){
00666         p.drawPixmap(x,height()-maxExtent+1,pm);
00667         x += pm.width();
00668           }
00669           else {
00670         p.drawPixmap(x,height()-maxExtent+1,pm,
00671                  0,0,width()-w4-x,pm.height());
00672         break;
00673           }
00674         }
00675     }
00676 
00677     //left
00678     if (framePixmaps[FrameLeft]->mask())
00679     {
00680         pm = *framePixmaps[FrameLeft]->mask();
00681 
00682         s = height()-h3-h1;
00683         n = s/pm.height();
00684         w = n>0?s/n:s;
00685         m.reset();
00686         m.scale(1, w/(float)pm.height());
00687         pm = pm.xForm(m);
00688 
00689         y = h1;
00690         while (1){
00691           if (pm.height() < height()-h3-y){
00692         p.drawPixmap(maxExtent-pm.width()-1, y,
00693                  pm);
00694         y += pm.height();
00695           }
00696           else {
00697         p.drawPixmap(maxExtent-pm.width()-1, y,
00698                  pm,
00699                  0,0, pm.width(),
00700                  height()-h3-y);
00701         break;
00702           }
00703         }
00704     }
00705 
00706     //right
00707     if (framePixmaps[FrameRight]->mask())
00708     {
00709         pm = *framePixmaps[FrameRight]->mask();
00710 
00711         s = height()-h4-h2;
00712         n = s/pm.height();
00713         w = n>0?s/n:s;
00714         m.reset();
00715         m.scale(1, w/(float)pm.height());
00716         pm = pm.xForm(m);
00717 
00718         y = h2;
00719         while (1){
00720           if (pm.height() < height()-h4-y){
00721         p.drawPixmap(width()-maxExtent+1, y,
00722                  pm);
00723         y += pm.height();
00724           }
00725           else {
00726         p.drawPixmap(width()-maxExtent+1, y,
00727                  pm,
00728                  0,0, pm.width(),
00729                  height()-h4-y);
00730         break;
00731           }
00732         }
00733     }
00734     p.fillRect(maxExtent-1, maxExtent-1, width()-2*maxExtent+2, height()-2*maxExtent+2, color1);
00735     setMask(shapemask);
00736 }
00737 
00738 
00739 void KWMThemeClient::showEvent(QShowEvent *)
00740 {
00741     doShape();
00742     widget()->repaint(false);
00743 }
00744 
00745 void KWMThemeClient::mouseDoubleClickEvent( QMouseEvent * e )
00746 {
00747     if (titlebar->geometry().contains( e->pos() ) )
00748         titlebarDblClickOperation();
00749 }
00750 
00751 void KWMThemeClient::desktopChange()
00752 {
00753     if (stickyBtn) {
00754        bool on = isOnAllDesktops();
00755        stickyBtn->setPixmap(on ? *pindownPix : *pinupPix);
00756        QToolTip::remove( stickyBtn );
00757        QToolTip::add( stickyBtn, on ? i18n("Un-Sticky") : i18n("Sticky") );
00758     }
00759 }
00760 
00761 void KWMThemeClient::maximizeChange()
00762 {
00763     if (maxBtn) {
00764        bool m = maximizeMode() == MaximizeFull;
00765        maxBtn->setPixmap(m ? *minmaxPix : *maxPix);
00766        QToolTip::remove( maxBtn );
00767        QToolTip::add( maxBtn, m ? i18n("Restore") : i18n("Maximize"));
00768     }
00769 }
00770 
00771 void KWMThemeClient::slotMaximize()
00772 {
00773     maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );
00774 }
00775 
00776 void KWMThemeClient::activeChange()
00777 {
00778     widget()->update();
00779 }
00780 
00781 KDecoration::Position KWMThemeClient::mousePosition(const QPoint &p) const
00782 {
00783     Position m = KDecoration::mousePosition(p);
00784     // corners
00785     if(p.y() < framePixmaps[FrameTop]->height() &&
00786        p.x() < framePixmaps[FrameLeft]->width()){
00787         m = PositionTopLeft;
00788     }
00789     else if(p.y() < framePixmaps[FrameTop]->height() &&
00790             p.x() > width()-framePixmaps[FrameRight]->width()){
00791         m = PositionTopRight;
00792     }
00793     else if(p.y() > height()-framePixmaps[FrameBottom]->height() &&
00794             p.x() < framePixmaps[FrameLeft]->width()){
00795         m = PositionBottomLeft;
00796     }
00797     else if(p.y() > height()-framePixmaps[FrameBottom]->height() &&
00798             p.x() > width()-framePixmaps[FrameRight]->width()){
00799         m = PositionBottomRight;
00800     } // edges
00801     else if(p.y() < framePixmaps[FrameTop]->height())
00802         m = PositionTop;
00803     else if(p.y() > height()-framePixmaps[FrameBottom]->height())
00804         m = PositionBottom;
00805     else if(p.x()  < framePixmaps[FrameLeft]->width())
00806         m = PositionLeft;
00807     else if(p.x() > width()-framePixmaps[FrameRight]->width())
00808         m = PositionRight;
00809     return(m);
00810 }
00811 
00812 void KWMThemeClient::menuButtonPressed()
00813 {
00814     mnuBtn->setDown(false); // will stay down if I don't do this
00815     QPoint pos = mnuBtn->mapToGlobal(mnuBtn->rect().bottomLeft());
00816     showWindowMenu( pos );
00817 }
00818 
00819 void KWMThemeClient::iconChange()
00820 {
00821     if(mnuBtn){
00822         if( icon().pixmap( QIconSet::Small, QIconSet::Normal ).isNull()){
00823             mnuBtn->setPixmap(*menuPix);
00824         }
00825         else{
00826             mnuBtn->setPixmap(icon().pixmap( QIconSet::Small, QIconSet::Normal ));
00827         }
00828     }
00829 }
00830 
00831 bool KWMThemeClient::eventFilter( QObject* o, QEvent* e )
00832 {
00833     if ( o != widget() )
00834         return false;
00835 
00836     switch ( e->type() )
00837     {
00838         case QEvent::Resize:
00839             resizeEvent( static_cast< QResizeEvent* >( e ) );
00840             return true;
00841 
00842         case QEvent::Paint:
00843             paintEvent( static_cast< QPaintEvent* >( e ) );
00844             return true;
00845 
00846         case QEvent::MouseButtonDblClick:
00847             mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) );
00848             return true;
00849 
00850         case QEvent::MouseButtonPress:
00851             processMousePressEvent( static_cast< QMouseEvent* >( e ) );
00852             return true;
00853 
00854         case QEvent::Show:
00855             showEvent( static_cast< QShowEvent* >( e ) );
00856             return true;
00857 
00858         default:
00859                 return false;
00860     }
00861 }
00862 
00863 QSize KWMThemeClient::minimumSize() const
00864 {
00865     return widget()->minimumSize().expandedTo( QSize( 100, 50 ));
00866 }
00867 
00868 void KWMThemeClient::resize( const QSize& s )
00869 {
00870     widget()->resize( s );
00871 }
00872 
00873 void KWMThemeClient::borders( int& left, int& right, int& top, int& bottom ) const
00874 {
00875     left =
00876     right =
00877     top =
00878     bottom =
00879     
00880 TODO
00881 }
00882 
00883 KWMThemeFactory::KWMThemeFactory()
00884 {
00885     create_pixmaps();
00886 }
00887 
00888 KWMThemeFactory::~KWMThemeFactory()
00889 {
00890     delete_pixmaps();
00891 }
00892 
00893 KDecoration* KWMThemeFactory::createDecoration( KDecorationBridge* b )
00894 {
00895     return new KWMThemeClient( b, this );
00896 }
00897 
00898 bool KWMThemeFactory::reset( unsigned long mask )
00899 {
00900     bool needHardReset = false;
00901 
00902 TODO
00903 
00904     // doesn't obey the Border size setting
00905     if( mask & ( SettingFont | SettingButtons ))
00906         needHardReset = true;
00907 
00908     if( mask & ( SettingFont | SettingColors )) {
00909         KWMTheme::delete_pixmaps();
00910         KWMTheme::create_pixmaps();
00911     }
00912     
00913     if( !needHardReset )
00914         resetDecorations( mask );
00915     return needHardReset;
00916 }
00917 
00918 }
00919 
00920 extern "C"
00921 {
00922     KDecorationFactory *create_factory()
00923     {
00924                 return new KWMTheme::KWMThemeFactory();
00925     }
00926 }
00927 
00928 #include "kwmthemeclient.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.2.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Mar 5 04:41:14 2004 by doxygen 1.3.6-20040222 written by Dimitri van Heesch, © 1997-2003