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
00537
00538
00539 KDEDefaultButton::KDEDefaultButton(KDEDefaultClient *parent, const char *name,
00540 bool largeButton, bool isLeftButton, bool isStickyButton,
00541 const unsigned char *bitmap, const QString& tip, const int realizeBtns )
00542 : QButton(parent->widget(), name)
00543 {
00544 realizeButtons = realizeBtns;
00545
00546 QToolTip::add( this, tip );
00547 setCursor( arrowCursor );
00548 setBackgroundMode( QWidget::NoBackground );
00549 setToggleButton( isStickyButton );
00550
00551 isMouseOver = false;
00552 deco = NULL;
00553 large = largeButton;
00554 isLeft = isLeftButton;
00555 isSticky = isStickyButton;
00556 client = parent;
00557
00558 if (large)
00559 setFixedSize(normalTitleHeight, normalTitleHeight);
00560 else
00561 setFixedSize(toolTitleHeight, toolTitleHeight);
00562
00563 if (bitmap)
00564 setBitmap(bitmap);
00565 }
00566
00567
00568 KDEDefaultButton::~KDEDefaultButton()
00569 {
00570 if (deco)
00571 delete deco;
00572 }
00573
00574
00575 QSize KDEDefaultButton::sizeHint() const
00576 {
00577 if ( large )
00578 return( QSize(normalTitleHeight, normalTitleHeight) );
00579 else
00580 return( QSize(toolTitleHeight, toolTitleHeight) );
00581 }
00582
00583
00584 void KDEDefaultButton::setBitmap(const unsigned char *bitmap)
00585 {
00586 if (deco)
00587 delete deco;
00588
00589 deco = new QBitmap(10, 10, bitmap, true);
00590 deco->setMask( *deco );
00591 repaint( false );
00592 }
00593
00594
00595 void KDEDefaultButton::drawButton(QPainter *p)
00596 {
00597 if (!KDEDefault_initialized)
00598 return;
00599
00600 if (deco) {
00601
00602 KPixmap btnbg;
00603
00604 if (isLeft) {
00605 if (isDown())
00606 btnbg = client->isActive() ?
00607 *leftBtnDownPix[large] : *ileftBtnDownPix[large];
00608 else
00609 btnbg = client->isActive() ?
00610 *leftBtnUpPix[large] : *ileftBtnUpPix[large];
00611 } else {
00612 if (isDown())
00613 btnbg = client->isActive() ?
00614 *rightBtnDownPix[large] : *irightBtnDownPix[large];
00615 else
00616 btnbg = client->isActive() ?
00617 *rightBtnUpPix[large] : *irightBtnUpPix[large];
00618 }
00619
00620 p->drawPixmap( 0, 0, btnbg );
00621
00622 } else if ( isLeft ) {
00623
00624
00625
00626 KPixmap* grad = client->isActive() ? aUpperGradient : iUpperGradient;
00627 if (!grad) {
00628 QColor c = KDecoration::options()->color(ColorTitleBar, client->isActive());
00629 p->fillRect(0, 0, width(), height(), c );
00630 } else
00631 p->drawPixmap( 0, 0, *grad, 0,1, width(), height() );
00632
00633 } else {
00634
00635 QColor c = KDecoration::options()->color(ColorFrame, client->isActive());
00636 p->fillRect(0, 0, width(), height(), c);
00637 }
00638
00639
00640
00641
00642 if( deco ) {
00643
00644 bool darkDeco = qGray( KDecoration::options()->color(
00645 isLeft? ColorTitleBar : ColorButtonBg,
00646 client->isActive()).rgb() ) > 127;
00647
00648 if (isMouseOver)
00649 p->setPen( darkDeco ? Qt::darkGray : Qt::lightGray );
00650 else
00651 p->setPen( darkDeco ? Qt::black : Qt::white );
00652
00653 int xOff = (width()-10)/2;
00654 int yOff = (height()-10)/2;
00655 p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, *deco);
00656
00657 } else {
00658 KPixmap btnpix;
00659
00660 if (isSticky) {
00661 if (client->isActive())
00662 btnpix = isOn() ? *pinDownPix : *pinUpPix;
00663 else
00664 btnpix = isOn() ? *ipinDownPix : *ipinUpPix;
00665 } else
00666 btnpix = client->icon().pixmap( QIconSet::Small, QIconSet::Normal );
00667
00668
00669 if (isMouseOver) {
00670 btnpix = KPixmapEffect::intensity(btnpix, 0.8);
00671 }
00672
00673
00674
00675 if ( width() < 16 ) {
00676 btnpix.convertFromImage(btnpix.convertToImage().smoothScale(12, 12));
00677 p->drawPixmap( 0, 0, btnpix );
00678 }
00679 else
00680 p->drawPixmap( width()/2-8, height()/2-8, btnpix );
00681 }
00682 }
00683
00684
00685
00686 void KDEDefaultButton::turnOn( bool isOn )
00687 {
00688 if ( isToggleButton() )
00689 setOn( isOn );
00690 }
00691
00692
00693 void KDEDefaultButton::enterEvent(QEvent *e)
00694 {
00695 isMouseOver=true;
00696 repaint(false);
00697 QButton::enterEvent(e);
00698 }
00699
00700
00701 void KDEDefaultButton::leaveEvent(QEvent *e)
00702 {
00703 isMouseOver=false;
00704 repaint(false);
00705 QButton::leaveEvent(e);
00706 }
00707
00708
00709 void KDEDefaultButton::mousePressEvent( QMouseEvent* e )
00710 {
00711 last_button = e->button();
00712 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00713 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00714 QButton::mousePressEvent( &me );
00715 }
00716
00717
00718 void KDEDefaultButton::mouseReleaseEvent( QMouseEvent* e )
00719 {
00720 last_button = e->button();
00721 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00722 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00723 QButton::mouseReleaseEvent( &me );
00724 }
00725
00726
00727
00728
00729 KDEDefaultClient::KDEDefaultClient( KDecorationBridge* b, KDecorationFactory* f )
00730 : KDecoration( b, f ),
00731 m_closing(false)
00732 {
00733 }
00734
00735 void KDEDefaultClient::init()
00736 {
00737 connect( this, SIGNAL( keepAboveChanged( bool )), SLOT( keepAboveChange( bool )));
00738 connect( this, SIGNAL( keepBelowChanged( bool )), SLOT( keepBelowChange( bool )));
00739
00740 createMainWidget( WResizeNoErase | WStaticContents | WRepaintNoErase );
00741 widget()->installEventFilter( this );
00742
00743
00744 widget()->setBackgroundMode( QWidget::NoBackground );
00745
00746
00747 for(int i=0; i < KDEDefaultClient::BtnCount; i++)
00748 button[i] = NULL;
00749
00750
00751 if ( isTool() ) {
00752 titleHeight = toolTitleHeight;
00753 largeButtons = false;
00754 }
00755 else {
00756 titleHeight = normalTitleHeight;
00757 largeButtons = true;
00758 }
00759
00760
00761 g = new QGridLayout(widget(), 0, 0, 0);
00762 g->setResizeMode(QLayout::FreeResize);
00763 g->addRowSpacing(0, 3);
00764 g->addRowSpacing(2, 1);
00765 if( isPreview())
00766 g->addWidget( new QLabel( i18n( "<b><center>KDE2 preview</center></b>" ), widget()), 3, 1);
00767 else
00768 g->addItem( new QSpacerItem( 0, 0 ), 3, 1);
00769
00770
00771 g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed,
00772 QSizePolicy::Expanding ) );
00773 g->setRowStretch(3, 10);
00774
00775
00776 spacer = new QSpacerItem(10,
00777 mustDrawHandle() ? grabBorderWidth : borderWidth,
00778 QSizePolicy::Expanding, QSizePolicy::Minimum);
00779 g->addItem(spacer, 4, 1);
00780
00781 g->addColSpacing(0, borderWidth);
00782 g->addColSpacing(2, borderWidth);
00783
00784
00785 hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0 );
00786 hb->setResizeMode( QLayout::FreeResize );
00787 g->addLayout ( hb, 1, 1 );
00788
00789 addClientButtons( options()->titleButtonsLeft() );
00790 titlebar = new QSpacerItem( 10, titleHeight, QSizePolicy::Expanding,
00791 QSizePolicy::Minimum );
00792 hb->addItem(titlebar);
00793 hb->addSpacing(2);
00794 addClientButtons( options()->titleButtonsRight(), false );
00795 }
00796
00797
00798 void KDEDefaultClient::addClientButtons( const QString& s, bool isLeft )
00799 {
00800 if (s.length() > 0)
00801 for(unsigned int i = 0; i < s.length(); i++) {
00802 switch( s[i].latin1() )
00803 {
00804
00805 case 'M':
00806 if (!button[BtnMenu])
00807 {
00808 button[BtnMenu] = new KDEDefaultButton(this, "menu",
00809 largeButtons, isLeft, false, NULL, i18n("Menu"), LeftButton|RightButton);
00810 connect( button[BtnMenu], SIGNAL(pressed()),
00811 this, SLOT(menuButtonPressed()) );
00812 connect( button[BtnMenu], SIGNAL(released()),
00813 this, SLOT(menuButtonReleased()));
00814 hb->addWidget( button[BtnMenu] );
00815 }
00816 break;
00817
00818
00819 case 'S':
00820 if (!button[BtnSticky])
00821 {
00822 button[BtnSticky] = new KDEDefaultButton(this, "sticky",
00823 largeButtons, isLeft, true, NULL,
00824 isOnAllDesktops()?i18n("Not on all desktops"):i18n("On all desktops"));
00825 button[BtnSticky]->turnOn( isOnAllDesktops() );
00826 connect( button[BtnSticky], SIGNAL(clicked()),
00827 this, SLOT(toggleOnAllDesktops()) );
00828 hb->addWidget( button[BtnSticky] );
00829 }
00830 break;
00831
00832
00833 case 'H':
00834 if( providesContextHelp() && (!button[BtnHelp]) )
00835 {
00836 button[BtnHelp] = new KDEDefaultButton(this, "help",
00837 largeButtons, isLeft, true, question_bits,
00838 i18n("Help"));
00839 connect( button[BtnHelp], SIGNAL( clicked() ),
00840 this, SLOT( showContextHelp() ));
00841 hb->addWidget( button[BtnHelp] );
00842 }
00843 break;
00844
00845
00846 case 'I':
00847 if ( (!button[BtnIconify]) && isMinimizable())
00848 {
00849 button[BtnIconify] = new KDEDefaultButton(this, "iconify",
00850 largeButtons, isLeft, true, iconify_bits,
00851 i18n("Minimize"));
00852 connect( button[BtnIconify], SIGNAL( clicked()),
00853 this, SLOT(minimize()) );
00854 hb->addWidget( button[BtnIconify] );
00855 }
00856 break;
00857
00858
00859 case 'A':
00860 if ( (!button[BtnMax]) && isMaximizable())
00861 {
00862 button[BtnMax] = new KDEDefaultButton(this, "maximize",
00863 largeButtons, isLeft, true, maximize_bits,
00864 i18n("Maximize"), LeftButton|MidButton|RightButton);
00865 connect( button[BtnMax], SIGNAL( clicked()),
00866 this, SLOT(slotMaximize()) );
00867 hb->addWidget( button[BtnMax] );
00868 }
00869 break;
00870
00871
00872 case 'X':
00873 if (!button[BtnClose] && isCloseable())
00874 {
00875 button[BtnClose] = new KDEDefaultButton(this, "close",
00876 largeButtons, isLeft, true, close_bits,
00877 i18n("Close"));
00878 connect( button[BtnClose], SIGNAL( clicked()),
00879 this, SLOT(closeWindow()) );
00880 hb->addWidget( button[BtnClose] );
00881 }
00882 break;
00883
00884
00885 case 'F':
00886 if ( (!button[BtnAbove]))
00887 {
00888 button[BtnAbove] = new KDEDefaultButton(this, "above",
00889 largeButtons, isLeft, true,
00890 keepAbove() ? above_on_bits : above_off_bits,
00891 i18n("Keep Above Others"));
00892 connect( button[BtnAbove], SIGNAL( clicked()),
00893 this, SLOT(slotAbove()) );
00894 hb->addWidget( button[BtnAbove] );
00895 }
00896 break;
00897
00898
00899 case 'B':
00900 if ( (!button[BtnBelow]))
00901 {
00902 button[BtnBelow] = new KDEDefaultButton(this, "below",
00903 largeButtons, isLeft, true,
00904 keepBelow() ? below_on_bits : below_off_bits,
00905 i18n("Keep Below Others"));
00906 connect( button[BtnBelow], SIGNAL( clicked()),
00907 this, SLOT(slotBelow()) );
00908 hb->addWidget( button[BtnBelow] );
00909 }
00910 break;
00911
00912
00913 case 'L':
00914 if ( (!button[BtnShade]) && isShadeable())
00915 {
00916 button[BtnShade] = new KDEDefaultButton(this, "shade",
00917 largeButtons, isLeft, true,
00918 isSetShade() ? shade_on_bits : shade_off_bits,
00919 isSetShade() ? i18n( "Unshade" ) : i18n("Shade"));
00920 connect( button[BtnShade], SIGNAL( clicked()),
00921 this, SLOT(slotShade()) );
00922 hb->addWidget( button[BtnShade] );
00923 }
00924 break;
00925
00926
00927 case '_':
00928 if ( !isTool() )
00929 hb->addSpacing(borderWidth/2);
00930 }
00931 }
00932 }
00933
00934 void KDEDefaultClient::reset( unsigned long )
00935 {
00936 widget()->repaint();
00937 }
00938
00939 bool KDEDefaultClient::mustDrawHandle() const
00940 {
00941 bool drawSmallBorders = !options()->moveResizeMaximizedWindows();
00942 if (drawSmallBorders && (maximizeMode() & MaximizeVertical)) {
00943 return false;
00944 } else {
00945 return showGrabBar && isResizable();
00946 }
00947 }
00948
00949 void KDEDefaultClient::iconChange()
00950 {
00951 if (button[BtnMenu] && button[BtnMenu]->isVisible())
00952 button[BtnMenu]->repaint(false);
00953 }
00954
00955 void KDEDefaultClient::desktopChange()
00956 {
00957 if (button[BtnSticky]) {
00958 bool on = isOnAllDesktops();
00959 button[BtnSticky]->turnOn(on);
00960 button[BtnSticky]->repaint(false);
00961 QToolTip::remove( button[BtnSticky] );
00962 QToolTip::add( button[BtnSticky], on ? i18n("Not on all desktops") : i18n("On all desktops"));
00963 }
00964 }
00965
00966 void KDEDefaultClient::keepAboveChange( bool above )
00967 {
00968 if (button[BtnAbove]) {
00969 button[BtnAbove]->setBitmap( above ? above_on_bits : above_off_bits );
00970 button[BtnAbove]->repaint(false);
00971 }
00972 }
00973
00974 void KDEDefaultClient::keepBelowChange( bool below )
00975 {
00976 if (button[BtnBelow]) {
00977 button[BtnBelow]->setBitmap( below ? below_on_bits : below_off_bits );
00978 button[BtnBelow]->repaint(false);
00979 }
00980 }
00981
00982 void KDEDefaultClient::slotMaximize()
00983 {
00984 maximize( button[BtnMax]->last_button );
00985 }
00986
00987 void KDEDefaultClient::slotAbove()
00988 {
00989 setKeepAbove( !keepAbove());
00990 button[BtnAbove]->turnOn(keepAbove());
00991 button[BtnAbove]->repaint(true);
00992 }
00993
00994 void KDEDefaultClient::slotBelow()
00995 {
00996 setKeepBelow( !keepBelow());
00997 button[BtnBelow]->turnOn(keepBelow());
00998 button[BtnBelow]->repaint(true);
00999 }
01000
01001 void KDEDefaultClient::slotShade()
01002 {
01003 setShade( !isSetShade());
01004 button[BtnShade]->setBitmap(isSetShade() ? shade_on_bits : shade_off_bits );
01005 button[BtnShade]->repaint(true);
01006 }
01007
01008 void KDEDefaultClient::resizeEvent( QResizeEvent* e)
01009 {
01010 doShape();
01011 calcHiddenButtons();
01012
01013 if ( widget()->isShown())
01014 {
01015 widget()->update( widget()->rect());
01016 #if 1 // what's the point of this, when paintEvent() repaints everything anyway?
01017 int dx = 0;
01018 int dy = 0;
01019
01020 if ( e->oldSize().width() != width() )
01021 dx = 32 + QABS( e->oldSize().width() - width() );
01022
01023 if ( e->oldSize().height() != height() )
01024 dy = 8 + QABS( e->oldSize().height() - height() );
01025
01026 if ( dy )
01027 widget()->update( 0, height() - dy + 1, width(), dy );
01028
01029 if ( dx )
01030 {
01031 widget()->update( width() - dx + 1, 0, dx, height() );
01032 widget()->update( QRect( QPoint(4,4), titlebar->geometry().bottomLeft() -
01033 QPoint(1,0) ) );
01034 widget()->update( QRect( titlebar->geometry().topRight(), QPoint(width() - 4,
01035 titlebar->geometry().bottom()) ) );
01036
01037 QApplication::postEvent( widget(), new QPaintEvent(titlebar->geometry(),
01038 FALSE) );
01039 }
01040 #endif
01041 }
01042 }
01043
01044
01045 void KDEDefaultClient::captionChange()
01046 {
01047 widget()->repaint( titlebar->geometry(), false );
01048 }
01049
01050
01051 void KDEDefaultClient::paintEvent( QPaintEvent* )
01052 {
01053 if (!KDEDefault_initialized)
01054 return;
01055
01056 QColorGroup g;
01057 int offset;
01058
01059 KPixmap* upperGradient = isActive() ? aUpperGradient : iUpperGradient;
01060
01061 QPainter p(widget());
01062
01063
01064 QRect r(widget()->rect());
01065 int x = r.x();
01066 int y = r.y();
01067 int x2 = r.width() - 1;
01068 int y2 = r.height() - 1;
01069 int w = r.width();
01070 int h = r.height();
01071
01072
01073 int leftFrameStart = (h > 42) ? y+titleHeight+26: y+titleHeight;
01074
01075
01076 r = titlebar->geometry();
01077 int rightOffset = r.x()+r.width()+1;
01078
01079
01080
01081
01082 titleBuffer->resize( rightOffset-3, titleHeight+1 );
01083
01084
01085 p.setPen(Qt::black);
01086 p.drawRect(x,y,w,h);
01087
01088
01089 g = options()->colorGroup(ColorTitleBar, isActive());
01090 p.setPen(g.light());
01091 p.drawLine(x+1, y+1, rightOffset-1, y+1);
01092 p.drawLine(x+1, y+1, x+1, leftFrameStart+borderWidth-4);
01093
01094
01095 p.setPen(g.dark());
01096 p.drawLine(rightOffset-1, y+1, rightOffset-1, titleHeight+2);
01097
01098 p.fillRect(x+2, y+titleHeight+3,
01099 borderWidth-4, leftFrameStart+borderWidth-y-titleHeight-8,
01100 options()->color(ColorTitleBar, isActive() ));
01101
01102
01103 p.setPen(Qt::black);
01104 p.drawLine(x+1, leftFrameStart+borderWidth-4, x+borderWidth-2, leftFrameStart-1);
01105 p.setPen(g.mid());
01106 p.drawLine(x+borderWidth-2, y+titleHeight+3, x+borderWidth-2, leftFrameStart-2);
01107
01108
01109 g = options()->colorGroup(ColorFrame, isActive());
01110 p.setPen(g.light());
01111 p.drawLine(rightOffset, y+1, x2-1, y+1);
01112 p.drawLine(x+1, leftFrameStart+borderWidth-3, x+1, y2-1);
01113 p.setPen(g.dark());
01114 p.drawLine(x2-1, y+1, x2-1, y2-1);
01115 p.drawLine(x+1, y2-1, x2-1, y2-1);
01116
01117 p.setPen(options()->color(ColorFrame, isActive()));
01118 QPointArray a;
01119 QBrush brush( options()->color(ColorFrame, isActive()), Qt::SolidPattern );
01120 p.setBrush( brush );
01121 a.setPoints( 4, x+2, leftFrameStart+borderWidth-4,
01122 x+borderWidth-2, leftFrameStart,
01123 x+borderWidth-2, y2-2,
01124 x+2, y2-2);
01125 p.drawPolygon( a );
01126 p.fillRect(x2-borderWidth+2, y+titleHeight+3,
01127 borderWidth-3, y2-y-titleHeight-4,
01128 options()->color(ColorFrame, isActive() ));
01129
01130
01131 if (mustDrawHandle())
01132 {
01133 if(w > 50)
01134 {
01135 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01136 g, false, 1, &g.brush(QColorGroup::Mid));
01137 qDrawShadePanel(&p, x+2*borderWidth+13, y2-grabBorderWidth+2, w-4*borderWidth-26, grabBorderWidth-2,
01138 g, false, 1, isActive() ?
01139 &g.brush(QColorGroup::Background) :
01140 &g.brush(QColorGroup::Mid));
01141 qDrawShadePanel(&p, x2-2*borderWidth-12, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01142 g, false, 1, &g.brush(QColorGroup::Mid));
01143 } else
01144 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, w-2, grabBorderWidth-2,
01145 g, false, 1, isActive() ?
01146 &g.brush(QColorGroup::Background) :
01147 &g.brush(QColorGroup::Mid));
01148 offset = grabBorderWidth;
01149 } else
01150 {
01151 p.fillRect(x+2, y2-borderWidth+2, w-4, borderWidth-3,
01152 options()->color(ColorFrame, isActive() ));
01153 offset = borderWidth;
01154 }
01155
01156
01157 p.setPen( g.dark() );
01158 p.drawRect( x+borderWidth-1, y+titleHeight+3, w-2*borderWidth+2, h-titleHeight-offset-2 );
01159
01160
01161 r = titlebar->geometry();
01162
01163
01164 QColor c1 = options()->color(ColorTitleBar, isActive() );
01165 QColor c2 = options()->color(ColorFrame, isActive() );
01166
01167
01168 p.fillRect( rightOffset, y+2, x2-rightOffset-1, titleHeight+1, c2);
01169
01170 QPainter p2( titleBuffer, this );
01171
01172
01173 if (upperGradient)
01174 p2.drawTiledPixmap(0, 0, rightOffset-3, titleHeight+1, *upperGradient);
01175 else
01176 p2.fillRect(0, 0, rightOffset-3, titleHeight+1, c1);
01177
01178
01179
01180 QFont fnt = options()->font(true);
01181
01182 if ( isTool() )
01183 fnt.setPointSize( fnt.pointSize()-2 );
01184
01185 p2.setFont( fnt );
01186
01187
01188 if (isActive() && titlePix)
01189 {
01190 QFontMetrics fm(fnt);
01191 int captionWidth = fm.width(caption());
01192 if (caption().isRightToLeft())
01193 p2.drawTiledPixmap( r.x(), 0, r.width()-captionWidth-4,
01194 titleHeight+1, *titlePix );
01195 else
01196 p2.drawTiledPixmap( r.x()+captionWidth+3, 0, r.width()-captionWidth-4,
01197 titleHeight+1, *titlePix );
01198 }
01199
01200 p2.setPen( options()->color(ColorFont, isActive()) );
01201 p2.drawText(r.x(), 1, r.width()-1, r.height(),
01202 (caption().isRightToLeft() ? AlignRight : AlignLeft) | AlignVCenter,
01203 caption() );
01204
01205 bitBlt( widget(), 2, 2, titleBuffer );
01206
01207 p2.end();
01208
01209
01210
01211 #if 1
01212 p.setPen(c2);
01213 p.drawLine(x+borderWidth, y+titleHeight+4, x2-borderWidth, y+titleHeight+4);
01214 #endif
01215 }
01216
01217
01218 void KDEDefaultClient::doShape()
01219 {
01220 QRegion mask(QRect(0, 0, width(), height()));
01221 mask -= QRect(0, 0, 1, 1);
01222 mask -= QRect(width()-1, 0, 1, 1);
01223 mask -= QRect(0, height()-1, 1, 1);
01224 mask -= QRect(width()-1, height()-1, 1, 1);
01225 setMask(mask);
01226 }
01227
01228
01229 void KDEDefaultClient::showEvent(QShowEvent *)
01230 {
01231 calcHiddenButtons();
01232 doShape();
01233 }
01234
01235
01236 void KDEDefaultClient::mouseDoubleClickEvent( QMouseEvent * e )
01237 {
01238 if (titlebar->geometry().contains( e->pos() ) )
01239 titlebarDblClickOperation();
01240 }
01241
01242
01243 void KDEDefaultClient::maximizeChange()
01244 {
01245 if (button[BtnMax]) {
01246 bool m = maximizeMode() == MaximizeFull;
01247 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
01248 QToolTip::remove( button[ BtnMax ] );
01249 QToolTip::add( button[BtnMax], m ? i18n("Restore") : i18n("Maximize"));
01250 }
01251 spacer->changeSize(10, mustDrawHandle() ? 8 : 4,
01252 QSizePolicy::Expanding, QSizePolicy::Minimum);
01253 g->activate();
01254 }
01255
01256
01257 void KDEDefaultClient::activeChange()
01258 {
01259 for(int i=KDEDefaultClient::BtnHelp; i < KDEDefaultClient::BtnCount; i++)
01260 if(button[i])
01261 button[i]->repaint(false);
01262 widget()->repaint(false);
01263 }
01264
01265 void KDEDefaultClient::shadeChange()
01266 {
01267 if (button[BtnShade]) {
01268 bool on = isShade();
01269 button[BtnShade]->turnOn(on);
01270 button[BtnShade]->repaint(false);
01271 QToolTip::remove( button[BtnShade] );
01272 QToolTip::add( button[BtnShade], on ? i18n("Unshade") : i18n("Shade"));
01273 }
01274 }
01275
01276 QSize KDEDefaultClient::minimumSize() const
01277 {
01278 return QSize( 100, 50 );
01279 }
01280
01281 void KDEDefaultClient::resize( const QSize& s )
01282 {
01283 widget()->resize( s );
01284 }
01285
01286 void KDEDefaultClient::borders( int& left, int& right, int& top, int& bottom ) const
01287 {
01288 left = right = borderWidth;
01289
01290 top = titleHeight + 4;
01291 bottom = mustDrawHandle() ? grabBorderWidth : borderWidth;
01292 }
01293
01294
01295 void KDEDefaultClient::calcHiddenButtons()
01296 {
01297
01298
01299 KDEDefaultButton* btnArray[] = { button[ BtnShade ], button[ BtnBelow ],
01300 button[ BtnAbove ], button[BtnSticky], button[BtnHelp],
01301 button[BtnMax], button[BtnIconify], button[BtnClose],
01302 button[BtnMenu] };
01303 const int buttons_cnt = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
01304
01305 int minwidth = largeButtons ? 10 * normalTitleHeight : 10 * toolTitleHeight;
01306 int btn_width = largeButtons ? normalTitleHeight : toolTitleHeight;
01307 int current_width = width();
01308 int count = 0;
01309 int i;
01310
01311
01312 while (current_width < minwidth)
01313 {
01314 current_width += btn_width;
01315 count++;
01316 }
01317
01318
01319 if (count > buttons_cnt) count = buttons_cnt;
01320
01321
01322 for(i = 0; i < count; i++)
01323 {
01324 if (btnArray[i] && btnArray[i]->isVisible() )
01325 btnArray[i]->hide();
01326 }
01327
01328
01329 for(i = count; i < buttons_cnt; i++)
01330 {
01331 if (btnArray[i] && (!btnArray[i]->isVisible()) )
01332 btnArray[i]->show();
01333 }
01334 }
01335
01336
01337 KDecoration::Position KDEDefaultClient::mousePosition( const QPoint& p ) const
01338 {
01339 Position m = PositionCenter;
01340
01341 int bottomSize = mustDrawHandle() ? grabBorderWidth : borderWidth;
01342
01343 const int range = 14 + 3*borderWidth/2;
01344
01345 if ( ( p.x() > borderWidth && p.x() < width() - borderWidth )
01346 && ( p.y() > 4 && p.y() < height() - bottomSize ) )
01347 m = PositionCenter;
01348 else if ( p.y() <= range && p.x() <= range)
01349 m = PositionTopLeft;
01350 else if ( p.y() >= height()-range && p.x() >= width()-range)
01351 m = PositionBottomRight;
01352 else if ( p.y() >= height()-range && p.x() <= range)
01353 m = PositionBottomLeft;
01354 else if ( p.y() <= range && p.x() >= width()-range)
01355 m = PositionTopRight;
01356 else if ( p.y() <= 4 )
01357 m = PositionTop;
01358 else if ( p.y() >= height()-bottomSize )
01359 m = PositionBottom;
01360 else if ( p.x() <= borderWidth )
01361 m = PositionLeft;
01362 else if ( p.x() >= width()-borderWidth )
01363 m = PositionRight;
01364 else
01365 m = PositionCenter;
01366
01367
01368 if (mustDrawHandle())
01369 if (p.y() >= (height() - grabBorderWidth))
01370 {
01371 if (p.x() >= (width() - 2*borderWidth - 12))
01372 m = PositionBottomRight;
01373 else if (p.x() <= 2*borderWidth + 12)
01374 m = PositionBottomLeft;
01375 else
01376 m = PositionBottom;
01377 }
01378
01379 return m;
01380 }
01381
01382
01383
01384 void KDEDefaultClient::menuButtonPressed()
01385 {
01386 static QTime t;
01387 static KDEDefaultClient* lastClient = NULL;
01388 bool dbl = ( lastClient == this && t.elapsed() <= QApplication::doubleClickInterval());
01389 lastClient = this;
01390 t.start();
01391
01392 if (dbl)
01393 {
01394 m_closing = true;
01395 return;
01396 }
01397
01398 QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
01399 button[BtnMenu]->rect().bottomLeft().y()+2 );
01400 KDecorationFactory* f = factory();
01401 QRect menuRect = button[BtnMenu]->rect();
01402 QPoint menutop = button[BtnMenu]->mapToGlobal(menuRect.topLeft());
01403 QPoint menubottom = button[BtnMenu]->mapToGlobal(menuRect.bottomRight());
01404 showWindowMenu(QRect(menutop, menubottom));
01405 if( !f->exists( this ))
01406 return;
01407 button[BtnMenu]->setDown(false);
01408 }
01409
01410 void KDEDefaultClient::menuButtonReleased()
01411 {
01412 if (m_closing)
01413 closeWindow();
01414 }
01415
01416 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
01417 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
01418 | NET::UtilityMask | NET::SplashMask;
01419
01420 bool KDEDefaultClient::isTool() const
01421 {
01422 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
01423 return type == NET::Toolbar || type == NET::Utility || type == NET::Menu;
01424 }
01425
01426
01427 bool KDEDefaultClient::eventFilter( QObject* o, QEvent* e )
01428 {
01429 if( o != widget())
01430 return false;
01431 switch( e->type())
01432 {
01433 case QEvent::Resize:
01434 resizeEvent( static_cast< QResizeEvent* >( e ));
01435 return true;
01436 case QEvent::Paint:
01437 paintEvent( static_cast< QPaintEvent* >( e ));
01438 return true;
01439 case QEvent::MouseButtonDblClick:
01440 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
01441 return true;
01442 case QEvent::MouseButtonPress:
01443 processMousePressEvent( static_cast< QMouseEvent* >( e ));
01444 return true;
01445 case QEvent::Show:
01446 showEvent( static_cast< QShowEvent* >( e ));
01447 return true;
01448 default:
01449 break;
01450 }
01451 return false;
01452 }
01453
01454
01455 }
01456
01457
01458 extern "C" KDecorationFactory* create_factory()
01459 {
01460 return new Default::KDEDefaultHandler();
01461 }
01462
01463 #include "kdedefault.moc"
01464