00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "kdedefault.h"
00014
00015 #include <kconfig.h>
00016 #include <kglobal.h>
00017 #include <kpixmapeffect.h>
00018 #include <kimageeffect.h>
00019 #include <kdrawutil.h>
00020 #include <klocale.h>
00021 #include <qlayout.h>
00022 #include <qdrawutil.h>
00023 #include <qbitmap.h>
00024 #include <qimage.h>
00025 #include <qtooltip.h>
00026 #include <qapplication.h>
00027 #include <qlabel.h>
00028 #include <kdebug.h>
00029
00030 namespace Default
00031 {
00032
00033 static const unsigned char iconify_bits[] = {
00034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00,
00035 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00036
00037 static const unsigned char close_bits[] = {
00038 0x00, 0x00, 0x84, 0x00, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00,
00039 0xfc, 0x00, 0xce, 0x01, 0x84, 0x00, 0x00, 0x00};
00040
00041 static const unsigned char maximize_bits[] = {
00042 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x86, 0x01, 0x86, 0x01, 0x86, 0x01,
00043 0x86, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00};
00044
00045 static const unsigned char minmax_bits[] = {
00046 0x7f, 0x00, 0x7f, 0x00, 0x63, 0x00, 0xfb, 0x03, 0xfb, 0x03, 0x1f, 0x03,
00047 0x1f, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x03};
00048
00049 static const unsigned char question_bits[] = {
00050 0x00, 0x00, 0x78, 0x00, 0xcc, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00,
00051 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};
00052
00053 static const unsigned char above_on_bits[] = {
00054 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00,
00055 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00056
00057 static const unsigned char above_off_bits[] = {
00058 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01,
00059 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00060
00061 static const unsigned char below_on_bits[] = {
00062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00,
00063 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00 };
00064
00065 static const unsigned char below_off_bits[] = {
00066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01,
00067 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00, 0x30, 0x00 };
00068
00069 static const unsigned char shade_on_bits[] = {
00070 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x02, 0x01, 0x02, 0x01,
00071 0x02, 0x01, 0x02, 0x01, 0xfe, 0x01, 0x00, 0x00 };
00072
00073 static const unsigned char shade_off_bits[] = {
00074 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00,
00075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00076
00077 static const unsigned char pindown_white_bits[] = {
00078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0xa0, 0x03,
00079 0xb0, 0x01, 0x30, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00,
00080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00081
00082 static const unsigned char pindown_gray_bits[] = {
00083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
00084 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
00085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00086
00087 static const unsigned char pindown_dgray_bits[] = {
00088 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x10, 0x70, 0x20, 0x50, 0x20,
00089 0x48, 0x30, 0xc8, 0x38, 0x08, 0x1f, 0x08, 0x18, 0x10, 0x1c, 0x10, 0x0e,
00090 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00091
00092 static const unsigned char pindown_mask_bits[] = {
00093 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x1f, 0xf0, 0x3f, 0xf0, 0x3f,
00094 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x0f,
00095 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00096
00097 static const unsigned char pinup_white_bits[] = {
00098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x11,
00099 0x3f, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00101
00102 static const unsigned char pinup_gray_bits[] = {
00103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00104 0x80, 0x0a, 0xbf, 0x0a, 0x80, 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
00105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00106
00107 static const unsigned char pinup_dgray_bits[] = {
00108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x40, 0x31, 0x40, 0x2e,
00109 0x40, 0x20, 0x40, 0x20, 0x7f, 0x2a, 0x40, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
00110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00111
00112 static const unsigned char pinup_mask_bits[] = {
00113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0xc0, 0x31, 0xc0, 0x3f,
00114 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xc0, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
00115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00116
00117
00118
00119 static QPixmap* titlePix;
00120 static KPixmap* titleBuffer;
00121 static KPixmap* aUpperGradient;
00122 static KPixmap* iUpperGradient;
00123
00124 static KPixmap* pinDownPix;
00125 static KPixmap* pinUpPix;
00126 static KPixmap* ipinDownPix;
00127 static KPixmap* ipinUpPix;
00128
00129 static KPixmap* rightBtnUpPix[2];
00130 static KPixmap* rightBtnDownPix[2];
00131 static KPixmap* irightBtnUpPix[2];
00132 static KPixmap* irightBtnDownPix[2];
00133
00134 static KPixmap* leftBtnUpPix[2];
00135 static KPixmap* leftBtnDownPix[2];
00136 static KPixmap* ileftBtnUpPix[2];
00137 static KPixmap* ileftBtnDownPix[2];
00138
00139 static KDEDefaultHandler* clientHandler;
00140 static int toolTitleHeight;
00141 static int normalTitleHeight;
00142 static int borderWidth;
00143 static int grabBorderWidth;
00144 static bool KDEDefault_initialized = false;
00145 static bool useGradients;
00146 static bool showGrabBar;
00147 static bool showTitleBarStipple;
00148
00149
00150
00151
00152 KDEDefaultHandler::KDEDefaultHandler()
00153 {
00154 clientHandler = this;
00155 readConfig( false );
00156 createPixmaps();
00157 KDEDefault_initialized = true;
00158 }
00159
00160
00161 KDEDefaultHandler::~KDEDefaultHandler()
00162 {
00163 KDEDefault_initialized = false;
00164 freePixmaps();
00165 clientHandler = NULL;
00166 }
00167
00168 KDecoration* KDEDefaultHandler::createDecoration( KDecorationBridge* b )
00169 {
00170 return new KDEDefaultClient( b, this );
00171 }
00172
00173 bool KDEDefaultHandler::reset( unsigned long changed )
00174 {
00175 KDEDefault_initialized = false;
00176 changed |= readConfig( true );
00177 if( changed & SettingColors )
00178 {
00179 freePixmaps();
00180 createPixmaps();
00181 }
00182 KDEDefault_initialized = true;
00183 bool need_recreate = ( changed & ( SettingDecoration | SettingFont | SettingButtons | SettingBorder )) != 0;
00184 if( need_recreate )
00185 return true;
00186 resetDecorations( changed );
00187 return false;
00188 }
00189
00190
00191 unsigned long KDEDefaultHandler::readConfig( bool update )
00192 {
00193 unsigned long changed = 0;
00194 KConfig* conf = KGlobal::config();
00195 conf->setGroup("KDEDefault");
00196
00197 bool new_showGrabBar = conf->readBoolEntry("ShowGrabBar", true);
00198 bool new_showTitleBarStipple = conf->readBoolEntry("ShowTitleBarStipple", true);
00199 bool new_useGradients = conf->readBoolEntry("UseGradients", true);
00200 int new_titleHeight = QFontMetrics(options()->font(true)).height();
00201 int new_toolTitleHeight = QFontMetrics(options()->font(true, true)).height()-2;
00202
00203 int new_borderWidth;
00204 switch(options()->preferredBorderSize(this)) {
00205 case BorderLarge:
00206 new_borderWidth = 8;
00207 break;
00208 case BorderVeryLarge:
00209 new_borderWidth = 12;
00210 break;
00211 case BorderHuge:
00212 new_borderWidth = 18;
00213 break;
00214 case BorderVeryHuge:
00215 new_borderWidth = 27;
00216 break;
00217 case BorderOversized:
00218 new_borderWidth = 40;
00219 break;
00220 case BorderTiny:
00221 case BorderNormal:
00222 default:
00223 new_borderWidth = 4;
00224 }
00225
00226 if (new_titleHeight < 16) new_titleHeight = 16;
00227 if (new_titleHeight < new_borderWidth) new_titleHeight = new_borderWidth;
00228 if (new_toolTitleHeight < 12) new_toolTitleHeight = 12;
00229 if (new_toolTitleHeight < new_borderWidth) new_toolTitleHeight = new_borderWidth;
00230
00231 if( update )
00232 {
00233 if( new_showGrabBar != showGrabBar
00234 || new_titleHeight != normalTitleHeight
00235 || new_toolTitleHeight != toolTitleHeight
00236 || new_borderWidth != borderWidth )
00237 changed |= SettingDecoration;
00238 if( new_showTitleBarStipple != showTitleBarStipple
00239 || new_useGradients != useGradients
00240 || new_titleHeight != normalTitleHeight
00241 || new_toolTitleHeight != toolTitleHeight )
00242 changed |= SettingColors;
00243 }
00244
00245 showGrabBar = new_showGrabBar;
00246 showTitleBarStipple = new_showTitleBarStipple;
00247 useGradients = new_useGradients;
00248 normalTitleHeight = new_titleHeight;
00249 toolTitleHeight = new_toolTitleHeight;
00250 borderWidth = new_borderWidth;
00251 grabBorderWidth = (borderWidth > 15) ? borderWidth + 15 : 2*borderWidth;
00252 return changed;
00253 }
00254
00255
00256
00257 void KDEDefaultHandler::createPixmaps()
00258 {
00259 bool highcolor = useGradients && (QPixmap::defaultDepth() > 8);
00260
00261
00262 if (showTitleBarStipple)
00263 {
00264 QPainter p;
00265 QPainter maskPainter;
00266 int i, x, y;
00267 titlePix = new QPixmap(132, normalTitleHeight+2);
00268 QBitmap mask(132, normalTitleHeight+2);
00269 mask.fill(Qt::color0);
00270
00271 p.begin(titlePix);
00272 maskPainter.begin(&mask);
00273 maskPainter.setPen(Qt::color1);
00274 for(i=0, y=2; i < 9; ++i, y+=4)
00275 for(x=1; x <= 132; x+=3)
00276 {
00277 p.setPen(options()->color(ColorTitleBar, true).light(150));
00278 p.drawPoint(x, y);
00279 maskPainter.drawPoint(x, y);
00280 p.setPen(options()->color(ColorTitleBar, true).dark(150));
00281 p.drawPoint(x+1, y+1);
00282 maskPainter.drawPoint(x+1, y+1);
00283 }
00284 maskPainter.end();
00285 p.end();
00286 titlePix->setMask(mask);
00287 } else
00288 titlePix = NULL;
00289
00290 QColor activeTitleColor1(options()->color(ColorTitleBar, true));
00291 QColor activeTitleColor2(options()->color(ColorTitleBlend, true));
00292
00293 QColor inactiveTitleColor1(options()->color(ColorTitleBar, false));
00294 QColor inactiveTitleColor2(options()->color(ColorTitleBlend, false));
00295
00296
00297 aUpperGradient = NULL;
00298 iUpperGradient = NULL;
00299
00300 if(highcolor)
00301 {
00302
00303 if (activeTitleColor1 != activeTitleColor2)
00304 {
00305 aUpperGradient = new KPixmap;
00306 aUpperGradient->resize(128, normalTitleHeight+2);
00307 KPixmapEffect::gradient(*aUpperGradient,
00308 activeTitleColor1,
00309 activeTitleColor2,
00310 KPixmapEffect::VerticalGradient);
00311 }
00312
00313 if (inactiveTitleColor1 != inactiveTitleColor2)
00314 {
00315 iUpperGradient = new KPixmap;
00316 iUpperGradient->resize(128, normalTitleHeight+2);
00317
00318 KPixmapEffect::gradient(*iUpperGradient,
00319 inactiveTitleColor1,
00320 inactiveTitleColor2,
00321 KPixmapEffect::VerticalGradient);
00322 }
00323 }
00324
00325
00326 QColorGroup g;
00327 QPainter p;
00328
00329
00330 g = options()->colorGroup( ColorButtonBg, true );
00331 pinUpPix = new KPixmap();
00332 pinUpPix->resize(16, 16);
00333 p.begin( pinUpPix );
00334 kColorBitmaps( &p, g, 0, 0, 16, 16, true, pinup_white_bits,
00335 pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
00336 p.end();
00337 pinUpPix->setMask( QBitmap(16, 16, pinup_mask_bits, true) );
00338
00339 pinDownPix = new KPixmap();
00340 pinDownPix->resize(16, 16);
00341 p.begin( pinDownPix );
00342 kColorBitmaps( &p, g, 0, 0, 16, 16, true, pindown_white_bits,
00343 pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
00344 p.end();
00345 pinDownPix->setMask( QBitmap(16, 16, pindown_mask_bits, true) );
00346
00347
00348 g = options()->colorGroup( ColorButtonBg, false );
00349 ipinUpPix = new KPixmap();
00350 ipinUpPix->resize(16, 16);
00351 p.begin( ipinUpPix );
00352 kColorBitmaps( &p, g, 0, 0, 16, 16, true, pinup_white_bits,
00353 pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
00354 p.end();
00355 ipinUpPix->setMask( QBitmap(16, 16, pinup_mask_bits, true) );
00356
00357 ipinDownPix = new KPixmap();
00358 ipinDownPix->resize(16, 16);
00359 p.begin( ipinDownPix );
00360 kColorBitmaps( &p, g, 0, 0, 16, 16, true, pindown_white_bits,
00361 pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
00362 p.end();
00363 ipinDownPix->setMask( QBitmap(16, 16, pindown_mask_bits, true) );
00364
00365
00366 titleBuffer = new KPixmap();
00367
00368
00369 leftBtnUpPix[true] = new KPixmap();
00370 leftBtnUpPix[true]->resize(normalTitleHeight, normalTitleHeight);
00371 leftBtnDownPix[true] = new KPixmap();
00372 leftBtnDownPix[true]->resize(normalTitleHeight, normalTitleHeight);
00373 ileftBtnUpPix[true] = new KPixmap();
00374 ileftBtnUpPix[true]->resize(normalTitleHeight, normalTitleHeight);
00375 ileftBtnDownPix[true] = new KPixmap();
00376 ileftBtnDownPix[true]->resize(normalTitleHeight, normalTitleHeight);
00377
00378 rightBtnUpPix[true] = new KPixmap();
00379 rightBtnUpPix[true]->resize(normalTitleHeight, normalTitleHeight);
00380 rightBtnDownPix[true] = new KPixmap();
00381 rightBtnDownPix[true]->resize(normalTitleHeight, normalTitleHeight);
00382 irightBtnUpPix[true] = new KPixmap();
00383 irightBtnUpPix[true]->resize(normalTitleHeight, normalTitleHeight);
00384 irightBtnDownPix[true] = new KPixmap();
00385 irightBtnDownPix[true]->resize(normalTitleHeight, normalTitleHeight);
00386
00387 leftBtnUpPix[false] = new KPixmap();
00388 leftBtnUpPix[false]->resize(toolTitleHeight, normalTitleHeight);
00389 leftBtnDownPix[false] = new KPixmap();
00390 leftBtnDownPix[false]->resize(toolTitleHeight, normalTitleHeight);
00391 ileftBtnUpPix[false] = new KPixmap();
00392 ileftBtnUpPix[false]->resize(normalTitleHeight, normalTitleHeight);
00393 ileftBtnDownPix[false] = new KPixmap();
00394 ileftBtnDownPix[false]->resize(normalTitleHeight, normalTitleHeight);
00395
00396 rightBtnUpPix[false] = new KPixmap();
00397 rightBtnUpPix[false]->resize(toolTitleHeight, toolTitleHeight);
00398 rightBtnDownPix[false] = new KPixmap();
00399 rightBtnDownPix[false]->resize(toolTitleHeight, toolTitleHeight);
00400 irightBtnUpPix[false] = new KPixmap();
00401 irightBtnUpPix[false]->resize(toolTitleHeight, toolTitleHeight);
00402 irightBtnDownPix[false] = new KPixmap();
00403 irightBtnDownPix[false]->resize(toolTitleHeight, toolTitleHeight);
00404
00405
00406 g = options()->colorGroup( ColorTitleBar, true );
00407 drawButtonBackground( leftBtnUpPix[true], g, false );
00408 drawButtonBackground( leftBtnDownPix[true], g, true );
00409 drawButtonBackground( leftBtnUpPix[false], g, false );
00410 drawButtonBackground( leftBtnDownPix[false], g, true );
00411
00412 g = options()->colorGroup( ColorButtonBg, true );
00413 drawButtonBackground( rightBtnUpPix[true], g, false );
00414 drawButtonBackground( rightBtnDownPix[true], g, true );
00415 drawButtonBackground( rightBtnUpPix[false], g, false );
00416 drawButtonBackground( rightBtnDownPix[false], g, true );
00417
00418 g = options()->colorGroup( ColorTitleBar, false );
00419 drawButtonBackground( ileftBtnUpPix[true], g, false );
00420 drawButtonBackground( ileftBtnDownPix[true], g, true );
00421 drawButtonBackground( ileftBtnUpPix[false], g, false );
00422 drawButtonBackground( ileftBtnDownPix[false], g, true );
00423
00424 g = options()->colorGroup( ColorButtonBg, false );
00425 drawButtonBackground( irightBtnUpPix[true], g, false );
00426 drawButtonBackground( irightBtnDownPix[true], g, true );
00427 drawButtonBackground( irightBtnUpPix[false], g, false );
00428 drawButtonBackground( irightBtnDownPix[false], g, true );
00429 }
00430
00431
00432 void KDEDefaultHandler::freePixmaps()
00433 {
00434
00435 if (rightBtnUpPix[true])
00436 delete rightBtnUpPix[true];
00437 if(rightBtnDownPix[true])
00438 delete rightBtnDownPix[true];
00439 if (irightBtnUpPix[true])
00440 delete irightBtnUpPix[true];
00441 if (irightBtnDownPix[true])
00442 delete irightBtnDownPix[true];
00443
00444 if (leftBtnUpPix[true])
00445 delete leftBtnUpPix[true];
00446 if(leftBtnDownPix[true])
00447 delete leftBtnDownPix[true];
00448 if (ileftBtnUpPix[true])
00449 delete ileftBtnUpPix[true];
00450 if (ileftBtnDownPix[true])
00451 delete ileftBtnDownPix[true];
00452
00453 if (rightBtnUpPix[false])
00454 delete rightBtnUpPix[false];
00455 if(rightBtnDownPix[false])
00456 delete rightBtnDownPix[false];
00457 if (irightBtnUpPix[false])
00458 delete irightBtnUpPix[false];
00459 if (irightBtnDownPix[false])
00460 delete irightBtnDownPix[false];
00461
00462 if (leftBtnUpPix[false])
00463 delete leftBtnUpPix[false];
00464 if(leftBtnDownPix[false])
00465 delete leftBtnDownPix[false];
00466 if (ileftBtnUpPix[false])
00467 delete ileftBtnUpPix[false];
00468 if (ileftBtnDownPix[false])
00469 delete ileftBtnDownPix[false];
00470
00471
00472 if (titleBuffer)
00473 delete titleBuffer;
00474 if (titlePix)
00475 delete titlePix;
00476 if (aUpperGradient)
00477 delete aUpperGradient;
00478 if (iUpperGradient)
00479 delete iUpperGradient;
00480
00481
00482 if (pinUpPix)
00483 delete pinUpPix;
00484 if (ipinUpPix)
00485 delete ipinUpPix;
00486 if (pinDownPix)
00487 delete pinDownPix;
00488 if (ipinDownPix)
00489 delete ipinDownPix;
00490 }
00491
00492
00493 void KDEDefaultHandler::drawButtonBackground(KPixmap *pix,
00494 const QColorGroup &g, bool sunken)
00495 {
00496 QPainter p;
00497 int w = pix->width();
00498 int h = pix->height();
00499 int x2 = w-1;
00500 int y2 = h-1;
00501
00502 bool highcolor = useGradients && (QPixmap::defaultDepth() > 8);
00503 QColor c = g.background();
00504
00505
00506 if (highcolor)
00507 KPixmapEffect::gradient(*pix, c.light(130), c.dark(130),
00508 KPixmapEffect::VerticalGradient);
00509 else
00510 pix->fill(c);
00511
00512 p.begin(pix);
00513
00514 p.setPen(g.mid());
00515 p.drawLine(0, 0, x2, 0);
00516 p.drawLine(0, 0, 0, y2);
00517 p.setPen(g.light());
00518 p.drawLine(x2, 0, x2, y2);
00519 p.drawLine(0, x2, y2, x2);
00520 p.setPen(g.dark());
00521 p.drawRect(1, 1, w-2, h-2);
00522 p.setPen(sunken ? g.mid() : g.light());
00523 p.drawLine(2, 2, x2-2, 2);
00524 p.drawLine(2, 2, 2, y2-2);
00525 p.setPen(sunken ? g.light() : g.mid());
00526 p.drawLine(x2-2, 2, x2-2, y2-2);
00527 p.drawLine(2, x2-2, y2-2, x2-2);
00528 }
00529
00530 QValueList< KDEDefaultHandler::BorderSize > KDEDefaultHandler::borderSizes() const
00531 {
00532 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00533 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
00534 }
00535
00536 bool KDEDefaultHandler::supports( Ability ability )
00537 {
00538 switch( ability )
00539 {
00540 case AbilityAnnounceButtons:
00541 case AbilityButtonMenu:
00542 case AbilityButtonOnAllDesktops:
00543 case AbilityButtonSpacer:
00544 case AbilityButtonHelp:
00545 case AbilityButtonMinimize:
00546 case AbilityButtonMaximize:
00547 case AbilityButtonClose:
00548 case AbilityButtonAboveOthers:
00549 case AbilityButtonBelowOthers:
00550 case AbilityButtonShade:
00551 return true;
00552 default:
00553 return false;
00554 };
00555 }
00556
00557
00558
00559 KDEDefaultButton::KDEDefaultButton(KDEDefaultClient *parent, const char *name,
00560 bool largeButton, bool isLeftButton, bool isStickyButton,
00561 const unsigned char *bitmap, const QString& tip, const int realizeBtns )
00562 : QButton(parent->widget(), name)
00563 {
00564 realizeButtons = realizeBtns;
00565
00566 QToolTip::add( this, tip );
00567 setCursor( arrowCursor );
00568 setBackgroundMode( QWidget::NoBackground );
00569 setToggleButton( isStickyButton );
00570
00571 isMouseOver = false;
00572 deco = NULL;
00573 large = largeButton;
00574 isLeft = isLeftButton;
00575 isSticky = isStickyButton;
00576 client = parent;
00577
00578 if (large)
00579 setFixedSize(normalTitleHeight, normalTitleHeight);
00580 else
00581 setFixedSize(toolTitleHeight, toolTitleHeight);
00582
00583 if (bitmap)
00584 setBitmap(bitmap);
00585 }
00586
00587
00588 KDEDefaultButton::~KDEDefaultButton()
00589 {
00590 if (deco)
00591 delete deco;
00592 }
00593
00594
00595 QSize KDEDefaultButton::sizeHint() const
00596 {
00597 if ( large )
00598 return( QSize(normalTitleHeight, normalTitleHeight) );
00599 else
00600 return( QSize(toolTitleHeight, toolTitleHeight) );
00601 }
00602
00603
00604 void KDEDefaultButton::setBitmap(const unsigned char *bitmap)
00605 {
00606 if (deco)
00607 delete deco;
00608
00609 deco = new QBitmap(10, 10, bitmap, true);
00610 deco->setMask( *deco );
00611 repaint( false );
00612 }
00613
00614
00615 void KDEDefaultButton::drawButton(QPainter *p)
00616 {
00617 if (!KDEDefault_initialized)
00618 return;
00619
00620 if (deco) {
00621
00622 KPixmap btnbg;
00623
00624 if (isLeft) {
00625 if (isDown())
00626 btnbg = client->isActive() ?
00627 *leftBtnDownPix[large] : *ileftBtnDownPix[large];
00628 else
00629 btnbg = client->isActive() ?
00630 *leftBtnUpPix[large] : *ileftBtnUpPix[large];
00631 } else {
00632 if (isDown())
00633 btnbg = client->isActive() ?
00634 *rightBtnDownPix[large] : *irightBtnDownPix[large];
00635 else
00636 btnbg = client->isActive() ?
00637 *rightBtnUpPix[large] : *irightBtnUpPix[large];
00638 }
00639
00640 p->drawPixmap( 0, 0, btnbg );
00641
00642 } else if ( isLeft ) {
00643
00644
00645
00646 KPixmap* grad = client->isActive() ? aUpperGradient : iUpperGradient;
00647 if (!grad) {
00648 QColor c = KDecoration::options()->color(ColorTitleBar, client->isActive());
00649 p->fillRect(0, 0, width(), height(), c );
00650 } else
00651 p->drawPixmap( 0, 0, *grad, 0,1, width(), height() );
00652
00653 } else {
00654
00655 QColor c = KDecoration::options()->color(ColorFrame, client->isActive());
00656 p->fillRect(0, 0, width(), height(), c);
00657 }
00658
00659
00660
00661
00662 if( deco ) {
00663
00664 bool darkDeco = qGray( KDecoration::options()->color(
00665 isLeft? ColorTitleBar : ColorButtonBg,
00666 client->isActive()).rgb() ) > 127;
00667
00668 if (isMouseOver)
00669 p->setPen( darkDeco ? Qt::darkGray : Qt::lightGray );
00670 else
00671 p->setPen( darkDeco ? Qt::black : Qt::white );
00672
00673 int xOff = (width()-10)/2;
00674 int yOff = (height()-10)/2;
00675 p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, *deco);
00676
00677 } else {
00678 KPixmap btnpix;
00679
00680 if (isSticky) {
00681 if (client->isActive())
00682 btnpix = isOn() ? *pinDownPix : *pinUpPix;
00683 else
00684 btnpix = isOn() ? *ipinDownPix : *ipinUpPix;
00685 } else
00686 btnpix = client->icon().pixmap( QIconSet::Small, QIconSet::Normal );
00687
00688
00689 if (isMouseOver) {
00690 btnpix = KPixmapEffect::intensity(btnpix, 0.8);
00691 }
00692
00693
00694
00695 if ( width() < 16 ) {
00696 btnpix.convertFromImage(btnpix.convertToImage().smoothScale(12, 12));
00697 p->drawPixmap( 0, 0, btnpix );
00698 }
00699 else
00700 p->drawPixmap( width()/2-8, height()/2-8, btnpix );
00701 }
00702 }
00703
00704
00705
00706 void KDEDefaultButton::turnOn( bool isOn )
00707 {
00708 if ( isToggleButton() )
00709 setOn( isOn );
00710 }
00711
00712
00713 void KDEDefaultButton::enterEvent(QEvent *e)
00714 {
00715 isMouseOver=true;
00716 repaint(false);
00717 QButton::enterEvent(e);
00718 }
00719
00720
00721 void KDEDefaultButton::leaveEvent(QEvent *e)
00722 {
00723 isMouseOver=false;
00724 repaint(false);
00725 QButton::leaveEvent(e);
00726 }
00727
00728
00729 void KDEDefaultButton::mousePressEvent( QMouseEvent* e )
00730 {
00731 last_button = e->button();
00732 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00733 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00734 QButton::mousePressEvent( &me );
00735 }
00736
00737
00738 void KDEDefaultButton::mouseReleaseEvent( QMouseEvent* e )
00739 {
00740 last_button = e->button();
00741 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00742 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00743 QButton::mouseReleaseEvent( &me );
00744 }
00745
00746
00747
00748
00749 KDEDefaultClient::KDEDefaultClient( KDecorationBridge* b, KDecorationFactory* f )
00750 : KDecoration( b, f ),
00751 m_closing(false)
00752 {
00753 }
00754
00755 void KDEDefaultClient::init()
00756 {
00757 connect( this, SIGNAL( keepAboveChanged( bool )), SLOT( keepAboveChange( bool )));
00758 connect( this, SIGNAL( keepBelowChanged( bool )), SLOT( keepBelowChange( bool )));
00759
00760 createMainWidget( WResizeNoErase | WStaticContents | WRepaintNoErase );
00761 widget()->installEventFilter( this );
00762
00763
00764 widget()->setBackgroundMode( QWidget::NoBackground );
00765
00766
00767 for(int i=0; i < KDEDefaultClient::BtnCount; i++)
00768 button[i] = NULL;
00769
00770
00771 if ( isTool() ) {
00772 titleHeight = toolTitleHeight;
00773 largeButtons = false;
00774 }
00775 else {
00776 titleHeight = normalTitleHeight;
00777 largeButtons = true;
00778 }
00779
00780
00781 g = new QGridLayout(widget(), 0, 0, 0);
00782 g->setResizeMode(QLayout::FreeResize);
00783 g->addRowSpacing(0, 3);
00784 g->addRowSpacing(2, 1);
00785 if( isPreview())
00786 g->addWidget( new QLabel( i18n( "<b><center>KDE2 preview</center></b>" ), widget()), 3, 1);
00787 else
00788 g->addItem( new QSpacerItem( 0, 0 ), 3, 1);
00789
00790
00791 g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed,
00792 QSizePolicy::Expanding ) );
00793 g->setRowStretch(3, 10);
00794
00795
00796 spacer = new QSpacerItem(10,
00797 mustDrawHandle() ? grabBorderWidth : borderWidth,
00798 QSizePolicy::Expanding, QSizePolicy::Minimum);
00799 g->addItem(spacer, 4, 1);
00800
00801 g->addColSpacing(0, borderWidth);
00802 g->addColSpacing(2, borderWidth);
00803
00804
00805 hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0 );
00806 hb->setResizeMode( QLayout::FreeResize );
00807 g->addLayout ( hb, 1, 1 );
00808
00809 addClientButtons( options()->titleButtonsLeft() );
00810 titlebar = new QSpacerItem( 10, titleHeight, QSizePolicy::Expanding,
00811 QSizePolicy::Minimum );
00812 hb->addItem(titlebar);
00813 hb->addSpacing(2);
00814 addClientButtons( options()->titleButtonsRight(), false );
00815 }
00816
00817
00818 void KDEDefaultClient::addClientButtons( const QString& s, bool isLeft )
00819 {
00820 if (s.length() > 0)
00821 for(unsigned int i = 0; i < s.length(); i++) {
00822 switch( s[i].latin1() )
00823 {
00824
00825 case 'M':
00826 if (!button[BtnMenu])
00827 {
00828 button[BtnMenu] = new KDEDefaultButton(this, "menu",
00829 largeButtons, isLeft, false, NULL, i18n("Menu"), LeftButton|RightButton);
00830 connect( button[BtnMenu], SIGNAL(pressed()),
00831 this, SLOT(menuButtonPressed()) );
00832 connect( button[BtnMenu], SIGNAL(released()),
00833 this, SLOT(menuButtonReleased()));
00834 hb->addWidget( button[BtnMenu] );
00835 }
00836 break;
00837
00838
00839 case 'S':
00840 if (!button[BtnSticky])
00841 {
00842 button[BtnSticky] = new KDEDefaultButton(this, "sticky",
00843 largeButtons, isLeft, true, NULL,
00844 isOnAllDesktops()?i18n("Not on all desktops"):i18n("On all desktops"));
00845 button[BtnSticky]->turnOn( isOnAllDesktops() );
00846 connect( button[BtnSticky], SIGNAL(clicked()),
00847 this, SLOT(toggleOnAllDesktops()) );
00848 hb->addWidget( button[BtnSticky] );
00849 }
00850 break;
00851
00852
00853 case 'H':
00854 if( providesContextHelp() && (!button[BtnHelp]) )
00855 {
00856 button[BtnHelp] = new KDEDefaultButton(this, "help",
00857 largeButtons, isLeft, true, question_bits,
00858 i18n("Help"));
00859 connect( button[BtnHelp], SIGNAL( clicked() ),
00860 this, SLOT( showContextHelp() ));
00861 hb->addWidget( button[BtnHelp] );
00862 }
00863 break;
00864
00865
00866 case 'I':
00867 if ( (!button[BtnIconify]) && isMinimizable())
00868 {
00869 button[BtnIconify] = new KDEDefaultButton(this, "iconify",
00870 largeButtons, isLeft, true, iconify_bits,
00871 i18n("Minimize"));
00872 connect( button[BtnIconify], SIGNAL( clicked()),
00873 this, SLOT(minimize()) );
00874 hb->addWidget( button[BtnIconify] );
00875 }
00876 break;
00877
00878
00879 case 'A':
00880 if ( (!button[BtnMax]) && isMaximizable())
00881 {
00882 button[BtnMax] = new KDEDefaultButton(this, "maximize",
00883 largeButtons, isLeft, true, maximize_bits,
00884 i18n("Maximize"), LeftButton|MidButton|RightButton);
00885 connect( button[BtnMax], SIGNAL( clicked()),
00886 this, SLOT(slotMaximize()) );
00887 hb->addWidget( button[BtnMax] );
00888 }
00889 break;
00890
00891
00892 case 'X':
00893 if (!button[BtnClose] && isCloseable())
00894 {
00895 button[BtnClose] = new KDEDefaultButton(this, "close",
00896 largeButtons, isLeft, true, close_bits,
00897 i18n("Close"));
00898 connect( button[BtnClose], SIGNAL( clicked()),
00899 this, SLOT(closeWindow()) );
00900 hb->addWidget( button[BtnClose] );
00901 }
00902 break;
00903
00904
00905 case 'F':
00906 if ( (!button[BtnAbove]))
00907 {
00908 button[BtnAbove] = new KDEDefaultButton(this, "above",
00909 largeButtons, isLeft, true,
00910 keepAbove() ? above_on_bits : above_off_bits,
00911 i18n("Keep Above Others"));
00912 connect( button[BtnAbove], SIGNAL( clicked()),
00913 this, SLOT(slotAbove()) );
00914 hb->addWidget( button[BtnAbove] );
00915 }
00916 break;
00917
00918
00919 case 'B':
00920 if ( (!button[BtnBelow]))
00921 {
00922 button[BtnBelow] = new KDEDefaultButton(this, "below",
00923 largeButtons, isLeft, true,
00924 keepBelow() ? below_on_bits : below_off_bits,
00925 i18n("Keep Below Others"));
00926 connect( button[BtnBelow], SIGNAL( clicked()),
00927 this, SLOT(slotBelow()) );
00928 hb->addWidget( button[BtnBelow] );
00929 }
00930 break;
00931
00932
00933 case 'L':
00934 if ( (!button[BtnShade]) && isShadeable())
00935 {
00936 button[BtnShade] = new KDEDefaultButton(this, "shade",
00937 largeButtons, isLeft, true,
00938 isSetShade() ? shade_on_bits : shade_off_bits,
00939 isSetShade() ? i18n( "Unshade" ) : i18n("Shade"));
00940 connect( button[BtnShade], SIGNAL( clicked()),
00941 this, SLOT(slotShade()) );
00942 hb->addWidget( button[BtnShade] );
00943 }
00944 break;
00945
00946
00947 case '_':
00948 if ( !isTool() )
00949 hb->addSpacing(borderWidth/2);
00950 }
00951 }
00952 }
00953
00954 void KDEDefaultClient::reset( unsigned long )
00955 {
00956 widget()->repaint();
00957 }
00958
00959 bool KDEDefaultClient::mustDrawHandle() const
00960 {
00961 bool drawSmallBorders = !options()->moveResizeMaximizedWindows();
00962 if (drawSmallBorders && (maximizeMode() & MaximizeVertical)) {
00963 return false;
00964 } else {
00965 return showGrabBar && isResizable();
00966 }
00967 }
00968
00969 void KDEDefaultClient::iconChange()
00970 {
00971 if (button[BtnMenu] && button[BtnMenu]->isVisible())
00972 button[BtnMenu]->repaint(false);
00973 }
00974
00975 void KDEDefaultClient::desktopChange()
00976 {
00977 if (button[BtnSticky]) {
00978 bool on = isOnAllDesktops();
00979 button[BtnSticky]->turnOn(on);
00980 button[BtnSticky]->repaint(false);
00981 QToolTip::remove( button[BtnSticky] );
00982 QToolTip::add( button[BtnSticky], on ? i18n("Not on all desktops") : i18n("On all desktops"));
00983 }
00984 }
00985
00986 void KDEDefaultClient::keepAboveChange( bool above )
00987 {
00988 if (button[BtnAbove]) {
00989 button[BtnAbove]->setBitmap( above ? above_on_bits : above_off_bits );
00990 button[BtnAbove]->repaint(false);
00991 }
00992 }
00993
00994 void KDEDefaultClient::keepBelowChange( bool below )
00995 {
00996 if (button[BtnBelow]) {
00997 button[BtnBelow]->setBitmap( below ? below_on_bits : below_off_bits );
00998 button[BtnBelow]->repaint(false);
00999 }
01000 }
01001
01002 void KDEDefaultClient::slotMaximize()
01003 {
01004 maximize( button[BtnMax]->last_button );
01005 }
01006
01007 void KDEDefaultClient::slotAbove()
01008 {
01009 setKeepAbove( !keepAbove());
01010 button[BtnAbove]->turnOn(keepAbove());
01011 button[BtnAbove]->repaint(true);
01012 }
01013
01014 void KDEDefaultClient::slotBelow()
01015 {
01016 setKeepBelow( !keepBelow());
01017 button[BtnBelow]->turnOn(keepBelow());
01018 button[BtnBelow]->repaint(true);
01019 }
01020
01021 void KDEDefaultClient::slotShade()
01022 {
01023 setShade( !isSetShade());
01024 }
01025
01026 void KDEDefaultClient::resizeEvent( QResizeEvent* e)
01027 {
01028 doShape();
01029 calcHiddenButtons();
01030
01031 if ( widget()->isShown())
01032 {
01033 widget()->update( widget()->rect());
01034 #if 1 // what's the point of this, when paintEvent() repaints everything anyway?
01035 int dx = 0;
01036 int dy = 0;
01037
01038 if ( e->oldSize().width() != width() )
01039 dx = 32 + QABS( e->oldSize().width() - width() );
01040
01041 if ( e->oldSize().height() != height() )
01042 dy = 8 + QABS( e->oldSize().height() - height() );
01043
01044 if ( dy )
01045 widget()->update( 0, height() - dy + 1, width(), dy );
01046
01047 if ( dx )
01048 {
01049 widget()->update( width() - dx + 1, 0, dx, height() );
01050 widget()->update( QRect( QPoint(4,4), titlebar->geometry().bottomLeft() -
01051 QPoint(1,0) ) );
01052 widget()->update( QRect( titlebar->geometry().topRight(), QPoint(width() - 4,
01053 titlebar->geometry().bottom()) ) );
01054
01055 QApplication::postEvent( widget(), new QPaintEvent(titlebar->geometry(),
01056 FALSE) );
01057 }
01058 #endif
01059 }
01060 }
01061
01062
01063 void KDEDefaultClient::captionChange()
01064 {
01065 widget()->repaint( titlebar->geometry(), false );
01066 }
01067
01068
01069 void KDEDefaultClient::paintEvent( QPaintEvent* )
01070 {
01071 if (!KDEDefault_initialized)
01072 return;
01073
01074 QColorGroup g;
01075 int offset;
01076
01077 KPixmap* upperGradient = isActive() ? aUpperGradient : iUpperGradient;
01078
01079 QPainter p(widget());
01080
01081
01082 QRect r(widget()->rect());
01083 int x = r.x();
01084 int y = r.y();
01085 int x2 = r.width() - 1;
01086 int y2 = r.height() - 1;
01087 int w = r.width();
01088 int h = r.height();
01089
01090
01091 int leftFrameStart = (h > 42) ? y+titleHeight+26: y+titleHeight;
01092
01093
01094 r = titlebar->geometry();
01095 int rightOffset = r.x()+r.width()+1;
01096
01097
01098
01099
01100 titleBuffer->resize( rightOffset-3, titleHeight+1 );
01101
01102
01103 p.setPen(Qt::black);
01104 p.drawRect(x,y,w,h);
01105
01106
01107 g = options()->colorGroup(ColorTitleBar, isActive());
01108 p.setPen(g.light());
01109 p.drawLine(x+1, y+1, rightOffset-1, y+1);
01110 p.drawLine(x+1, y+1, x+1, leftFrameStart+borderWidth-4);
01111
01112
01113 p.setPen(g.dark());
01114 p.drawLine(rightOffset-1, y+1, rightOffset-1, titleHeight+2);
01115
01116 p.fillRect(x+2, y+titleHeight+3,
01117 borderWidth-4, leftFrameStart+borderWidth-y-titleHeight-8,
01118 options()->color(ColorTitleBar, isActive() ));
01119
01120
01121 p.setPen(Qt::black);
01122 p.drawLine(x+1, leftFrameStart+borderWidth-4, x+borderWidth-2, leftFrameStart-1);
01123 p.setPen(g.mid());
01124 p.drawLine(x+borderWidth-2, y+titleHeight+3, x+borderWidth-2, leftFrameStart-2);
01125
01126
01127 g = options()->colorGroup(ColorFrame, isActive());
01128 p.setPen(g.light());
01129 p.drawLine(rightOffset, y+1, x2-1, y+1);
01130 p.drawLine(x+1, leftFrameStart+borderWidth-3, x+1, y2-1);
01131 p.setPen(g.dark());
01132 p.drawLine(x2-1, y+1, x2-1, y2-1);
01133 p.drawLine(x+1, y2-1, x2-1, y2-1);
01134
01135 p.setPen(options()->color(ColorFrame, isActive()));
01136 QPointArray a;
01137 QBrush brush( options()->color(ColorFrame, isActive()), Qt::SolidPattern );
01138 p.setBrush( brush );
01139 a.setPoints( 4, x+2, leftFrameStart+borderWidth-4,
01140 x+borderWidth-2, leftFrameStart,
01141 x+borderWidth-2, y2-2,
01142 x+2, y2-2);
01143 p.drawPolygon( a );
01144 p.fillRect(x2-borderWidth+2, y+titleHeight+3,
01145 borderWidth-3, y2-y-titleHeight-4,
01146 options()->color(ColorFrame, isActive() ));
01147
01148
01149 if (mustDrawHandle())
01150 {
01151 if(w > 50)
01152 {
01153 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01154 g, false, 1, &g.brush(QColorGroup::Mid));
01155 qDrawShadePanel(&p, x+2*borderWidth+13, y2-grabBorderWidth+2, w-4*borderWidth-26, grabBorderWidth-2,
01156 g, false, 1, isActive() ?
01157 &g.brush(QColorGroup::Background) :
01158 &g.brush(QColorGroup::Mid));
01159 qDrawShadePanel(&p, x2-2*borderWidth-12, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01160 g, false, 1, &g.brush(QColorGroup::Mid));
01161 } else
01162 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, w-2, grabBorderWidth-2,
01163 g, false, 1, isActive() ?
01164 &g.brush(QColorGroup::Background) :
01165 &g.brush(QColorGroup::Mid));
01166 offset = grabBorderWidth;
01167 } else
01168 {
01169 p.fillRect(x+2, y2-borderWidth+2, w-4, borderWidth-3,
01170 options()->color(ColorFrame, isActive() ));
01171 offset = borderWidth;
01172 }
01173
01174
01175 p.setPen( g.dark() );
01176 p.drawRect( x+borderWidth-1, y+titleHeight+3, w-2*borderWidth+2, h-titleHeight-offset-2 );
01177
01178
01179 r = titlebar->geometry();
01180
01181
01182 QColor c1 = options()->color(ColorTitleBar, isActive() );
01183 QColor c2 = options()->color(ColorFrame, isActive() );
01184
01185
01186 p.fillRect( rightOffset, y+2, x2-rightOffset-1, titleHeight+1, c2);
01187
01188 QPainter p2( titleBuffer, this );
01189
01190
01191 if (upperGradient)
01192 p2.drawTiledPixmap(0, 0, rightOffset-3, titleHeight+1, *upperGradient);
01193 else
01194 p2.fillRect(0, 0, rightOffset-3, titleHeight+1, c1);
01195
01196
01197
01198 QFont fnt = options()->font(true);
01199
01200 if ( isTool() )
01201 fnt.setPointSize( fnt.pointSize()-2 );
01202
01203 p2.setFont( fnt );
01204
01205
01206 if (isActive() && titlePix)
01207 {
01208 QFontMetrics fm(fnt);
01209 int captionWidth = fm.width(caption());
01210 if (caption().isRightToLeft())
01211 p2.drawTiledPixmap( r.x(), 0, r.width()-captionWidth-4,
01212 titleHeight+1, *titlePix );
01213 else
01214 p2.drawTiledPixmap( r.x()+captionWidth+3, 0, r.width()-captionWidth-4,
01215 titleHeight+1, *titlePix );
01216 }
01217
01218 p2.setPen( options()->color(ColorFont, isActive()) );
01219 p2.drawText(r.x(), 1, r.width()-1, r.height(),
01220 (caption().isRightToLeft() ? AlignRight : AlignLeft) | AlignVCenter,
01221 caption() );
01222
01223 bitBlt( widget(), 2, 2, titleBuffer );
01224
01225 p2.end();
01226
01227
01228
01229 #if 1
01230 p.setPen(c2);
01231 p.drawLine(x+borderWidth, y+titleHeight+4, x2-borderWidth, y+titleHeight+4);
01232 #endif
01233 }
01234
01235
01236 void KDEDefaultClient::doShape()
01237 {
01238 QRegion mask(QRect(0, 0, width(), height()));
01239 mask -= QRect(0, 0, 1, 1);
01240 mask -= QRect(width()-1, 0, 1, 1);
01241 mask -= QRect(0, height()-1, 1, 1);
01242 mask -= QRect(width()-1, height()-1, 1, 1);
01243 setMask(mask);
01244 }
01245
01246
01247 void KDEDefaultClient::showEvent(QShowEvent *)
01248 {
01249 calcHiddenButtons();
01250 doShape();
01251 }
01252
01253
01254 void KDEDefaultClient::mouseDoubleClickEvent( QMouseEvent * e )
01255 {
01256 if (e->button() == LeftButton && titlebar->geometry().contains( e->pos() ) )
01257 titlebarDblClickOperation();
01258 }
01259
01260
01261 void KDEDefaultClient::maximizeChange()
01262 {
01263 if (button[BtnMax]) {
01264 bool m = maximizeMode() == MaximizeFull;
01265 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
01266 QToolTip::remove( button[ BtnMax ] );
01267 QToolTip::add( button[BtnMax], m ? i18n("Restore") : i18n("Maximize"));
01268 }
01269 spacer->changeSize(10, mustDrawHandle() ? 8 : 4,
01270 QSizePolicy::Expanding, QSizePolicy::Minimum);
01271 g->activate();
01272 }
01273
01274
01275 void KDEDefaultClient::activeChange()
01276 {
01277 for(int i=KDEDefaultClient::BtnHelp; i < KDEDefaultClient::BtnCount; i++)
01278 if(button[i])
01279 button[i]->repaint(false);
01280 widget()->repaint(false);
01281 }
01282
01283 void KDEDefaultClient::shadeChange()
01284 {
01285 if (button[BtnShade]) {
01286 bool on = isSetShade();
01287 button[BtnShade]->setBitmap( on ? shade_on_bits : shade_off_bits );
01288 button[BtnShade]->turnOn(on);
01289 button[BtnShade]->repaint(false);
01290 QToolTip::remove( button[BtnShade] );
01291 QToolTip::add( button[BtnShade], on ? i18n("Unshade") : i18n("Shade"));
01292 }
01293 }
01294
01295 QSize KDEDefaultClient::minimumSize() const
01296 {
01297 return QSize( 100, 50 );
01298 }
01299
01300 void KDEDefaultClient::resize( const QSize& s )
01301 {
01302 widget()->resize( s );
01303 }
01304
01305 void KDEDefaultClient::borders( int& left, int& right, int& top, int& bottom ) const
01306 {
01307 left = right = borderWidth;
01308
01309 top = titleHeight + 4;
01310 bottom = mustDrawHandle() ? grabBorderWidth : borderWidth;
01311 }
01312
01313
01314 void KDEDefaultClient::calcHiddenButtons()
01315 {
01316
01317
01318 KDEDefaultButton* btnArray[] = { button[ BtnShade ], button[ BtnBelow ],
01319 button[ BtnAbove ], button[BtnSticky], button[BtnHelp],
01320 button[BtnMax], button[BtnIconify], button[BtnClose],
01321 button[BtnMenu] };
01322 const int buttons_cnt = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
01323
01324 int minwidth = largeButtons ? 10 * normalTitleHeight : 10 * toolTitleHeight;
01325 int btn_width = largeButtons ? normalTitleHeight : toolTitleHeight;
01326 int current_width = width();
01327 int count = 0;
01328 int i;
01329
01330
01331 while (current_width < minwidth)
01332 {
01333 current_width += btn_width;
01334 count++;
01335 }
01336
01337
01338 if (count > buttons_cnt) count = buttons_cnt;
01339
01340
01341 for(i = 0; i < count; i++)
01342 {
01343 if (btnArray[i] && btnArray[i]->isVisible() )
01344 btnArray[i]->hide();
01345 }
01346
01347
01348 for(i = count; i < buttons_cnt; i++)
01349 {
01350 if (btnArray[i] && (!btnArray[i]->isVisible()) )
01351 btnArray[i]->show();
01352 }
01353 }
01354
01355
01356 KDecoration::Position KDEDefaultClient::mousePosition( const QPoint& p ) const
01357 {
01358 Position m = PositionCenter;
01359
01360 int bottomSize = mustDrawHandle() ? grabBorderWidth : borderWidth;
01361
01362 const int range = 14 + 3*borderWidth/2;
01363
01364 if ( ( p.x() > borderWidth && p.x() < width() - borderWidth )
01365 && ( p.y() > 4 && p.y() < height() - bottomSize ) )
01366 m = PositionCenter;
01367 else if ( p.y() <= range && p.x() <= range)
01368 m = PositionTopLeft;
01369 else if ( p.y() >= height()-range && p.x() >= width()-range)
01370 m = PositionBottomRight;
01371 else if ( p.y() >= height()-range && p.x() <= range)
01372 m = PositionBottomLeft;
01373 else if ( p.y() <= range && p.x() >= width()-range)
01374 m = PositionTopRight;
01375 else if ( p.y() <= 4 )
01376 m = PositionTop;
01377 else if ( p.y() >= height()-bottomSize )
01378 m = PositionBottom;
01379 else if ( p.x() <= borderWidth )
01380 m = PositionLeft;
01381 else if ( p.x() >= width()-borderWidth )
01382 m = PositionRight;
01383 else
01384 m = PositionCenter;
01385
01386
01387 if (mustDrawHandle())
01388 if (p.y() >= (height() - grabBorderWidth))
01389 {
01390 if (p.x() >= (width() - 2*borderWidth - 12))
01391 m = PositionBottomRight;
01392 else if (p.x() <= 2*borderWidth + 12)
01393 m = PositionBottomLeft;
01394 else
01395 m = PositionBottom;
01396 }
01397
01398 return m;
01399 }
01400
01401
01402
01403 void KDEDefaultClient::menuButtonPressed()
01404 {
01405 static QTime t;
01406 static KDEDefaultClient* lastClient = NULL;
01407 bool dbl = ( lastClient == this && t.elapsed() <= QApplication::doubleClickInterval());
01408 lastClient = this;
01409 t.start();
01410
01411 if (dbl)
01412 {
01413 m_closing = true;
01414 return;
01415 }
01416
01417 QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
01418 button[BtnMenu]->rect().bottomLeft().y()+2 );
01419 KDecorationFactory* f = factory();
01420 QRect menuRect = button[BtnMenu]->rect();
01421 QPoint menutop = button[BtnMenu]->mapToGlobal(menuRect.topLeft());
01422 QPoint menubottom = button[BtnMenu]->mapToGlobal(menuRect.bottomRight());
01423 showWindowMenu(QRect(menutop, menubottom));
01424 if( !f->exists( this ))
01425 return;
01426 button[BtnMenu]->setDown(false);
01427 }
01428
01429 void KDEDefaultClient::menuButtonReleased()
01430 {
01431 if (m_closing)
01432 closeWindow();
01433 }
01434
01435 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
01436 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
01437 | NET::UtilityMask | NET::SplashMask;
01438
01439 bool KDEDefaultClient::isTool() const
01440 {
01441 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
01442 return type == NET::Toolbar || type == NET::Utility || type == NET::Menu;
01443 }
01444
01445
01446 bool KDEDefaultClient::eventFilter( QObject* o, QEvent* e )
01447 {
01448 if( o != widget())
01449 return false;
01450 switch( e->type())
01451 {
01452 case QEvent::Resize:
01453 resizeEvent( static_cast< QResizeEvent* >( e ));
01454 return true;
01455 case QEvent::Paint:
01456 paintEvent( static_cast< QPaintEvent* >( e ));
01457 return true;
01458 case QEvent::MouseButtonDblClick:
01459 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
01460 return true;
01461 case QEvent::MouseButtonPress:
01462 processMousePressEvent( static_cast< QMouseEvent* >( e ));
01463 return true;
01464 case QEvent::Show:
01465 showEvent( static_cast< QShowEvent* >( e ));
01466 return true;
01467 default:
01468 break;
01469 }
01470 return false;
01471 }
01472
01473
01474 }
01475
01476
01477 extern "C" KDE_EXPORT KDecorationFactory* create_factory()
01478 {
01479 return new Default::KDEDefaultHandler();
01480 }
01481
01482 #include "kdedefault.moc"
01483