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 }
01005
01006 void KDEDefaultClient::resizeEvent( QResizeEvent* e)
01007 {
01008 doShape();
01009 calcHiddenButtons();
01010
01011 if ( widget()->isShown())
01012 {
01013 widget()->update( widget()->rect());
01014 #if 1 // what's the point of this, when paintEvent() repaints everything anyway?
01015 int dx = 0;
01016 int dy = 0;
01017
01018 if ( e->oldSize().width() != width() )
01019 dx = 32 + QABS( e->oldSize().width() - width() );
01020
01021 if ( e->oldSize().height() != height() )
01022 dy = 8 + QABS( e->oldSize().height() - height() );
01023
01024 if ( dy )
01025 widget()->update( 0, height() - dy + 1, width(), dy );
01026
01027 if ( dx )
01028 {
01029 widget()->update( width() - dx + 1, 0, dx, height() );
01030 widget()->update( QRect( QPoint(4,4), titlebar->geometry().bottomLeft() -
01031 QPoint(1,0) ) );
01032 widget()->update( QRect( titlebar->geometry().topRight(), QPoint(width() - 4,
01033 titlebar->geometry().bottom()) ) );
01034
01035 QApplication::postEvent( widget(), new QPaintEvent(titlebar->geometry(),
01036 FALSE) );
01037 }
01038 #endif
01039 }
01040 }
01041
01042
01043 void KDEDefaultClient::captionChange()
01044 {
01045 widget()->repaint( titlebar->geometry(), false );
01046 }
01047
01048
01049 void KDEDefaultClient::paintEvent( QPaintEvent* )
01050 {
01051 if (!KDEDefault_initialized)
01052 return;
01053
01054 QColorGroup g;
01055 int offset;
01056
01057 KPixmap* upperGradient = isActive() ? aUpperGradient : iUpperGradient;
01058
01059 QPainter p(widget());
01060
01061
01062 QRect r(widget()->rect());
01063 int x = r.x();
01064 int y = r.y();
01065 int x2 = r.width() - 1;
01066 int y2 = r.height() - 1;
01067 int w = r.width();
01068 int h = r.height();
01069
01070
01071 int leftFrameStart = (h > 42) ? y+titleHeight+26: y+titleHeight;
01072
01073
01074 r = titlebar->geometry();
01075 int rightOffset = r.x()+r.width()+1;
01076
01077
01078
01079
01080 titleBuffer->resize( rightOffset-3, titleHeight+1 );
01081
01082
01083 p.setPen(Qt::black);
01084 p.drawRect(x,y,w,h);
01085
01086
01087 g = options()->colorGroup(ColorTitleBar, isActive());
01088 p.setPen(g.light());
01089 p.drawLine(x+1, y+1, rightOffset-1, y+1);
01090 p.drawLine(x+1, y+1, x+1, leftFrameStart+borderWidth-4);
01091
01092
01093 p.setPen(g.dark());
01094 p.drawLine(rightOffset-1, y+1, rightOffset-1, titleHeight+2);
01095
01096 p.fillRect(x+2, y+titleHeight+3,
01097 borderWidth-4, leftFrameStart+borderWidth-y-titleHeight-8,
01098 options()->color(ColorTitleBar, isActive() ));
01099
01100
01101 p.setPen(Qt::black);
01102 p.drawLine(x+1, leftFrameStart+borderWidth-4, x+borderWidth-2, leftFrameStart-1);
01103 p.setPen(g.mid());
01104 p.drawLine(x+borderWidth-2, y+titleHeight+3, x+borderWidth-2, leftFrameStart-2);
01105
01106
01107 g = options()->colorGroup(ColorFrame, isActive());
01108 p.setPen(g.light());
01109 p.drawLine(rightOffset, y+1, x2-1, y+1);
01110 p.drawLine(x+1, leftFrameStart+borderWidth-3, x+1, y2-1);
01111 p.setPen(g.dark());
01112 p.drawLine(x2-1, y+1, x2-1, y2-1);
01113 p.drawLine(x+1, y2-1, x2-1, y2-1);
01114
01115 p.setPen(options()->color(ColorFrame, isActive()));
01116 QPointArray a;
01117 QBrush brush( options()->color(ColorFrame, isActive()), Qt::SolidPattern );
01118 p.setBrush( brush );
01119 a.setPoints( 4, x+2, leftFrameStart+borderWidth-4,
01120 x+borderWidth-2, leftFrameStart,
01121 x+borderWidth-2, y2-2,
01122 x+2, y2-2);
01123 p.drawPolygon( a );
01124 p.fillRect(x2-borderWidth+2, y+titleHeight+3,
01125 borderWidth-3, y2-y-titleHeight-4,
01126 options()->color(ColorFrame, isActive() ));
01127
01128
01129 if (mustDrawHandle())
01130 {
01131 if(w > 50)
01132 {
01133 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01134 g, false, 1, &g.brush(QColorGroup::Mid));
01135 qDrawShadePanel(&p, x+2*borderWidth+13, y2-grabBorderWidth+2, w-4*borderWidth-26, grabBorderWidth-2,
01136 g, false, 1, isActive() ?
01137 &g.brush(QColorGroup::Background) :
01138 &g.brush(QColorGroup::Mid));
01139 qDrawShadePanel(&p, x2-2*borderWidth-12, y2-grabBorderWidth+2, 2*borderWidth+12, grabBorderWidth-2,
01140 g, false, 1, &g.brush(QColorGroup::Mid));
01141 } else
01142 qDrawShadePanel(&p, x+1, y2-grabBorderWidth+2, w-2, grabBorderWidth-2,
01143 g, false, 1, isActive() ?
01144 &g.brush(QColorGroup::Background) :
01145 &g.brush(QColorGroup::Mid));
01146 offset = grabBorderWidth;
01147 } else
01148 {
01149 p.fillRect(x+2, y2-borderWidth+2, w-4, borderWidth-3,
01150 options()->color(ColorFrame, isActive() ));
01151 offset = borderWidth;
01152 }
01153
01154
01155 p.setPen( g.dark() );
01156 p.drawRect( x+borderWidth-1, y+titleHeight+3, w-2*borderWidth+2, h-titleHeight-offset-2 );
01157
01158
01159 r = titlebar->geometry();
01160
01161
01162 QColor c1 = options()->color(ColorTitleBar, isActive() );
01163 QColor c2 = options()->color(ColorFrame, isActive() );
01164
01165
01166 p.fillRect( rightOffset, y+2, x2-rightOffset-1, titleHeight+1, c2);
01167
01168 QPainter p2( titleBuffer, this );
01169
01170
01171 if (upperGradient)
01172 p2.drawTiledPixmap(0, 0, rightOffset-3, titleHeight+1, *upperGradient);
01173 else
01174 p2.fillRect(0, 0, rightOffset-3, titleHeight+1, c1);
01175
01176
01177
01178 QFont fnt = options()->font(true);
01179
01180 if ( isTool() )
01181 fnt.setPointSize( fnt.pointSize()-2 );
01182
01183 p2.setFont( fnt );
01184
01185
01186 if (isActive() && titlePix)
01187 {
01188 QFontMetrics fm(fnt);
01189 int captionWidth = fm.width(caption());
01190 if (caption().isRightToLeft())
01191 p2.drawTiledPixmap( r.x(), 0, r.width()-captionWidth-4,
01192 titleHeight+1, *titlePix );
01193 else
01194 p2.drawTiledPixmap( r.x()+captionWidth+3, 0, r.width()-captionWidth-4,
01195 titleHeight+1, *titlePix );
01196 }
01197
01198 p2.setPen( options()->color(ColorFont, isActive()) );
01199 p2.drawText(r.x(), 1, r.width()-1, r.height(),
01200 (caption().isRightToLeft() ? AlignRight : AlignLeft) | AlignVCenter,
01201 caption() );
01202
01203 bitBlt( widget(), 2, 2, titleBuffer );
01204
01205 p2.end();
01206
01207
01208
01209 #if 1
01210 p.setPen(c2);
01211 p.drawLine(x+borderWidth, y+titleHeight+4, x2-borderWidth, y+titleHeight+4);
01212 #endif
01213 }
01214
01215
01216 void KDEDefaultClient::doShape()
01217 {
01218 QRegion mask(QRect(0, 0, width(), height()));
01219 mask -= QRect(0, 0, 1, 1);
01220 mask -= QRect(width()-1, 0, 1, 1);
01221 mask -= QRect(0, height()-1, 1, 1);
01222 mask -= QRect(width()-1, height()-1, 1, 1);
01223 setMask(mask);
01224 }
01225
01226
01227 void KDEDefaultClient::showEvent(QShowEvent *)
01228 {
01229 calcHiddenButtons();
01230 doShape();
01231 }
01232
01233
01234 void KDEDefaultClient::mouseDoubleClickEvent( QMouseEvent * e )
01235 {
01236 if (titlebar->geometry().contains( e->pos() ) )
01237 titlebarDblClickOperation();
01238 }
01239
01240
01241 void KDEDefaultClient::maximizeChange()
01242 {
01243 if (button[BtnMax]) {
01244 bool m = maximizeMode() == MaximizeFull;
01245 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
01246 QToolTip::remove( button[ BtnMax ] );
01247 QToolTip::add( button[BtnMax], m ? i18n("Restore") : i18n("Maximize"));
01248 }
01249 spacer->changeSize(10, mustDrawHandle() ? 8 : 4,
01250 QSizePolicy::Expanding, QSizePolicy::Minimum);
01251 g->activate();
01252 }
01253
01254
01255 void KDEDefaultClient::activeChange()
01256 {
01257 for(int i=KDEDefaultClient::BtnHelp; i < KDEDefaultClient::BtnCount; i++)
01258 if(button[i])
01259 button[i]->repaint(false);
01260 widget()->repaint(false);
01261 }
01262
01263 void KDEDefaultClient::shadeChange()
01264 {
01265 if (button[BtnShade]) {
01266 bool on = isSetShade();
01267 button[BtnShade]->setBitmap( on ? shade_on_bits : shade_off_bits );
01268 button[BtnShade]->turnOn(on);
01269 button[BtnShade]->repaint(false);
01270 QToolTip::remove( button[BtnShade] );
01271 QToolTip::add( button[BtnShade], on ? i18n("Unshade") : i18n("Shade"));
01272 }
01273 }
01274
01275 QSize KDEDefaultClient::minimumSize() const
01276 {
01277 return QSize( 100, 50 );
01278 }
01279
01280 void KDEDefaultClient::resize( const QSize& s )
01281 {
01282 widget()->resize( s );
01283 }
01284
01285 void KDEDefaultClient::borders( int& left, int& right, int& top, int& bottom ) const
01286 {
01287 left = right = borderWidth;
01288
01289 top = titleHeight + 4;
01290 bottom = mustDrawHandle() ? grabBorderWidth : borderWidth;
01291 }
01292
01293
01294 void KDEDefaultClient::calcHiddenButtons()
01295 {
01296
01297
01298 KDEDefaultButton* btnArray[] = { button[ BtnShade ], button[ BtnBelow ],
01299 button[ BtnAbove ], button[BtnSticky], button[BtnHelp],
01300 button[BtnMax], button[BtnIconify], button[BtnClose],
01301 button[BtnMenu] };
01302 const int buttons_cnt = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
01303
01304 int minwidth = largeButtons ? 10 * normalTitleHeight : 10 * toolTitleHeight;
01305 int btn_width = largeButtons ? normalTitleHeight : toolTitleHeight;
01306 int current_width = width();
01307 int count = 0;
01308 int i;
01309
01310
01311 while (current_width < minwidth)
01312 {
01313 current_width += btn_width;
01314 count++;
01315 }
01316
01317
01318 if (count > buttons_cnt) count = buttons_cnt;
01319
01320
01321 for(i = 0; i < count; i++)
01322 {
01323 if (btnArray[i] && btnArray[i]->isVisible() )
01324 btnArray[i]->hide();
01325 }
01326
01327
01328 for(i = count; i < buttons_cnt; i++)
01329 {
01330 if (btnArray[i] && (!btnArray[i]->isVisible()) )
01331 btnArray[i]->show();
01332 }
01333 }
01334
01335
01336 KDecoration::Position KDEDefaultClient::mousePosition( const QPoint& p ) const
01337 {
01338 Position m = PositionCenter;
01339
01340 int bottomSize = mustDrawHandle() ? grabBorderWidth : borderWidth;
01341
01342 const int range = 14 + 3*borderWidth/2;
01343
01344 if ( ( p.x() > borderWidth && p.x() < width() - borderWidth )
01345 && ( p.y() > 4 && p.y() < height() - bottomSize ) )
01346 m = PositionCenter;
01347 else if ( p.y() <= range && p.x() <= range)
01348 m = PositionTopLeft;
01349 else if ( p.y() >= height()-range && p.x() >= width()-range)
01350 m = PositionBottomRight;
01351 else if ( p.y() >= height()-range && p.x() <= range)
01352 m = PositionBottomLeft;
01353 else if ( p.y() <= range && p.x() >= width()-range)
01354 m = PositionTopRight;
01355 else if ( p.y() <= 4 )
01356 m = PositionTop;
01357 else if ( p.y() >= height()-bottomSize )
01358 m = PositionBottom;
01359 else if ( p.x() <= borderWidth )
01360 m = PositionLeft;
01361 else if ( p.x() >= width()-borderWidth )
01362 m = PositionRight;
01363 else
01364 m = PositionCenter;
01365
01366
01367 if (mustDrawHandle())
01368 if (p.y() >= (height() - grabBorderWidth))
01369 {
01370 if (p.x() >= (width() - 2*borderWidth - 12))
01371 m = PositionBottomRight;
01372 else if (p.x() <= 2*borderWidth + 12)
01373 m = PositionBottomLeft;
01374 else
01375 m = PositionBottom;
01376 }
01377
01378 return m;
01379 }
01380
01381
01382
01383 void KDEDefaultClient::menuButtonPressed()
01384 {
01385 static QTime t;
01386 static KDEDefaultClient* lastClient = NULL;
01387 bool dbl = ( lastClient == this && t.elapsed() <= QApplication::doubleClickInterval());
01388 lastClient = this;
01389 t.start();
01390
01391 if (dbl)
01392 {
01393 m_closing = true;
01394 return;
01395 }
01396
01397 QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
01398 button[BtnMenu]->rect().bottomLeft().y()+2 );
01399 KDecorationFactory* f = factory();
01400 QRect menuRect = button[BtnMenu]->rect();
01401 QPoint menutop = button[BtnMenu]->mapToGlobal(menuRect.topLeft());
01402 QPoint menubottom = button[BtnMenu]->mapToGlobal(menuRect.bottomRight());
01403 showWindowMenu(QRect(menutop, menubottom));
01404 if( !f->exists( this ))
01405 return;
01406 button[BtnMenu]->setDown(false);
01407 }
01408
01409 void KDEDefaultClient::menuButtonReleased()
01410 {
01411 if (m_closing)
01412 closeWindow();
01413 }
01414
01415 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
01416 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
01417 | NET::UtilityMask | NET::SplashMask;
01418
01419 bool KDEDefaultClient::isTool() const
01420 {
01421 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
01422 return type == NET::Toolbar || type == NET::Utility || type == NET::Menu;
01423 }
01424
01425
01426 bool KDEDefaultClient::eventFilter( QObject* o, QEvent* e )
01427 {
01428 if( o != widget())
01429 return false;
01430 switch( e->type())
01431 {
01432 case QEvent::Resize:
01433 resizeEvent( static_cast< QResizeEvent* >( e ));
01434 return true;
01435 case QEvent::Paint:
01436 paintEvent( static_cast< QPaintEvent* >( e ));
01437 return true;
01438 case QEvent::MouseButtonDblClick:
01439 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
01440 return true;
01441 case QEvent::MouseButtonPress:
01442 processMousePressEvent( static_cast< QMouseEvent* >( e ));
01443 return true;
01444 case QEvent::Show:
01445 showEvent( static_cast< QShowEvent* >( e ));
01446 return true;
01447 default:
01448 break;
01449 }
01450 return false;
01451 }
01452
01453
01454 }
01455
01456
01457 extern "C" KDecorationFactory* create_factory()
01458 {
01459 return new Default::KDEDefaultHandler();
01460 }
01461
01462 #include "kdedefault.moc"
01463