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("Unsticky") : 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     KDE_EXPORT 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.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Apr 6 02:41:06 2005 by doxygen 1.4.0 written by Dimitri van Heesch, © 1997-2003