00001
00002
00003
00004 #include <kconfig.h>
00005 #include <kglobal.h>
00006 #include <klocale.h>
00007 #include <qlayout.h>
00008 #include <qdrawutil.h>
00009 #include <kpixmapeffect.h>
00010 #include <kdrawutil.h>
00011 #include <qbitmap.h>
00012 #include <qtooltip.h>
00013 #include <qapplication.h>
00014 #include <qlabel.h>
00015 #include "modernsys.h"
00016
00017 #include "buttondata.h"
00018 #include "btnhighcolor.h"
00019 #include <qimage.h>
00020
00021 namespace ModernSystem {
00022
00023 static unsigned char iconify_bits[] = {
00024 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00};
00025
00026 static unsigned char close_bits[] = {
00027 0x00, 0x66, 0x7e, 0x3c, 0x3c, 0x7e, 0x66, 0x00};
00028
00029 static unsigned char maximize_bits[] = {
00030 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00};
00031
00032 static unsigned char minmax_bits[] = {
00033 0x0c, 0x18, 0x33, 0x67, 0xcf, 0x9f, 0x3f, 0x3f};
00034
00035 static unsigned char unsticky_bits[] = {
00036 0x3c, 0x42, 0x99, 0xbd, 0xbd, 0x99, 0x42, 0x3c};
00037
00038 static unsigned char sticky_bits[] = {
00039 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c};
00040
00041 static unsigned char question_bits[] = {
00042 0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18};
00043
00044 static unsigned char above_on_bits[] = {
00045 0x7e, 0x00, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00};
00046
00047 static unsigned char above_off_bits[] = {
00048 0x18, 0x3c, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00};
00049
00050 static unsigned char below_off_bits[] = {
00051 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x3c, 0x18};
00052
00053 static unsigned char below_on_bits[] = {
00054 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x00, 0x7e};
00055
00056 static unsigned char shade_off_bits[] = {
00057 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00};
00058
00059 static unsigned char shade_on_bits[] = {
00060 0x00, 0x7e, 0x7e, 0x42, 0x42, 0x42, 0x7e, 0x00};
00061
00062 static unsigned char btnhighcolor_mask_bits[] = {
00063 0xe0,0x41,0xf8,0x07,0xfc,0x0f,0xfe,0xdf,0xfe,0x1f,0xff,0x3f,0xff,0xff,0xff,
00064 0x3f,0xff,0x3f,0xff,0xff,0xff,0xff,0xfe,0x9f,0xfe,0x1f,0xfc,0x0f,0xf0,0x03,
00065 0x00,0x40,0x80,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x20,0x99,0x0f,0x08,0xc4,
00066 0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x58,0x5f,0x43,0x68,0x61,0x6e,0x67,0x65 };
00067
00068 static KPixmap *aUpperGradient=0;
00069 static KPixmap *iUpperGradient=0;
00070 static QPixmap *buttonPix=0;
00071 static QPixmap *buttonPixDown=0;
00072 static QPixmap *iButtonPix=0;
00073 static QPixmap *iButtonPixDown=0;
00074
00075 static QColor *buttonFg;
00076 static bool pixmaps_created = false;
00077
00078 static QBitmap *lcDark1;
00079 static QBitmap *lcDark2;
00080 static QBitmap *lcDark3;
00081 static QBitmap *lcLight1;
00082 static QImage *btnSource;
00083
00084 static QString *button_pattern = NULL;
00085 static bool show_handle;
00086 static int handle_size;
00087 static int handle_width;
00088 static int border_width;
00089 static int title_height;
00090
00091 static inline const KDecorationOptions* options()
00092 {
00093 return KDecoration::options();
00094 }
00095
00096 static void make_button_fx(const QColorGroup &g, QPixmap *pix, bool light=false)
00097 {
00098 pix->fill(g.background());
00099 QPainter p(pix);
00100
00101 if(QPixmap::defaultDepth() > 8){
00102 int i, destH, destS, destV, srcH, srcS, srcV;
00103 QColor btnColor = g.background();
00104
00105 if(btnSource->depth() < 32)
00106 *btnSource = btnSource->convertDepth(32);
00107 if(light)
00108 btnColor = btnColor.light(120);
00109 btnColor.hsv(&destH, &destS, &destV);
00110 QImage btnDest(14, 15, 32);
00111
00112 unsigned int *srcData = (unsigned int *)btnSource->bits();
00113 unsigned int *destData = (unsigned int *)btnDest.bits();
00114 QColor srcColor;
00115 for(i=0; i < btnSource->width()*btnSource->height(); ++i){
00116 srcColor.setRgb(srcData[i]);
00117 srcColor.hsv(&srcH, &srcS, &srcV);
00118 srcColor.setHsv(destH, destS, srcV);
00119 destData[i] = srcColor.rgb();
00120 }
00121 pix->convertFromImage(btnDest);
00122
00123 }
00124 else{
00125 if(!lcDark1->mask()){
00126 lcDark1->setMask(*lcDark1);
00127 lcDark2->setMask(*lcDark2);
00128 lcDark3->setMask(*lcDark3);
00129 lcLight1->setMask(*lcLight1);
00130 }
00131 p.setPen(g.dark());
00132 p.drawPixmap(0, 0, *lcDark2);
00133 p.drawPixmap(0, 0, *lcDark1);
00134 p.setPen(g.mid());
00135 p.drawPixmap(0, 0, *lcDark3);
00136 p.setPen(g.light());
00137 p.drawPixmap(0, 0, *lcLight1);
00138 }
00139 }
00140
00141
00142 static void create_pixmaps()
00143 {
00144 if(pixmaps_created)
00145 return;
00146 pixmaps_created = true;
00147
00148 lcDark1 = new QBitmap(14, 15, lowcolor_6a696a_bits, true);
00149 lcDark2 = new QBitmap(14, 15, lowcolor_949194_bits, true);
00150 lcDark3 = new QBitmap(14, 15, lowcolor_b4b6b4_bits, true);
00151 lcLight1 = new QBitmap(14, 15, lowcolor_e6e6e6_bits, true);
00152 btnSource = new QImage(btnhighcolor_xpm);
00153
00154 if(QPixmap::defaultDepth() > 8){
00155 aUpperGradient = new KPixmap;
00156 aUpperGradient->resize(32, title_height+2);
00157 iUpperGradient = new KPixmap;
00158 iUpperGradient->resize(32, title_height+2);
00159 KPixmapEffect::gradient(*aUpperGradient,
00160 options()->color(KDecoration::ColorTitleBar, true).light(130),
00161 options()->color(KDecoration::ColorTitleBlend, true),
00162 KPixmapEffect::VerticalGradient);
00163 KPixmapEffect::gradient(*iUpperGradient,
00164 options()->color(KDecoration::ColorTitleBar, false).light(130),
00165 options()->color(KDecoration::ColorTitleBlend, false),
00166 KPixmapEffect::VerticalGradient);
00167 }
00168
00169 QColorGroup btnColor(options()->colorGroup(KDecoration::ColorButtonBg, true));
00170 buttonPix = new QPixmap(14, 15);
00171 make_button_fx(btnColor, buttonPix);
00172 buttonPixDown = new QPixmap(14, 15);
00173 make_button_fx(btnColor, buttonPixDown, true);
00174
00175 btnColor = options()->colorGroup(KDecoration::ColorButtonBg, false);
00176 iButtonPix = new QPixmap(14, 15);
00177 make_button_fx(btnColor, iButtonPix);
00178 iButtonPixDown = new QPixmap(14, 15);
00179 make_button_fx(btnColor, iButtonPixDown, true);
00180
00181
00182 if(qGray(btnColor.background().rgb()) < 150)
00183 buttonFg = new QColor(Qt::white);
00184 else
00185 buttonFg = new QColor(Qt::black);
00186
00187 delete lcDark1;
00188 delete lcDark2;
00189 delete lcDark3;
00190 delete lcLight1;
00191 delete btnSource;
00192 }
00193
00194 static void delete_pixmaps()
00195 {
00196 if(aUpperGradient){
00197 delete aUpperGradient;
00198 delete iUpperGradient;
00199 }
00200 delete buttonPix;
00201 delete buttonPixDown;
00202 delete iButtonPix;
00203 delete iButtonPixDown;
00204
00205 delete buttonFg;
00206
00207 pixmaps_created = false;
00208 }
00209
00210 bool ModernSysFactory::read_config()
00211 {
00212 bool showh;
00213 int hsize, hwidth, bwidth, theight;
00214 QString bpatt;
00215
00216 KConfig c("kwinmodernsysrc");
00217 c.setGroup("General");
00218 showh = c.readBoolEntry("ShowHandle", true);
00219
00220 hwidth = c.readUnsignedNumEntry("HandleWidth", 6);
00221 hsize = c.readUnsignedNumEntry("HandleSize", 30);
00222 if (!(showh && hsize && hwidth)) {
00223 showh = false;
00224 hwidth = hsize = 0;
00225 }
00226
00227 switch(options()->preferredBorderSize( this )) {
00228 case BorderLarge:
00229 bwidth = 8;
00230 hwidth = hwidth * 7/5;
00231 hsize = hsize * 7/5;
00232 break;
00233 case BorderVeryLarge:
00234 bwidth = 12;
00235 hwidth = hwidth * 17/10 + 2;
00236 hsize = hsize * 17/10;
00237 break;
00238 case BorderHuge:
00239 bwidth = 18;
00240 hwidth = hwidth * 2 + 6;
00241 hsize = hsize * 2;
00242 break;
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 case BorderNormal:
00258 default:
00259 bwidth = 4;
00260 }
00261
00262 theight = QFontMetrics(options()->font(true)).height() + 2;
00263 if (theight < 16)
00264 theight = 16;
00265 if (theight < bwidth)
00266 theight = bwidth;
00267
00268 if (options()->customButtonPositions()) {
00269 bpatt = "2" + options()->titleButtonsLeft() + "3t3"
00270 + options()->titleButtonsRight() + "2";
00271 }
00272 else
00273 bpatt = "2X3t3HSIA2";
00274
00275 if (showh == show_handle && hwidth == handle_width && hsize == handle_size
00276 && bwidth == border_width && theight == title_height
00277 && bpatt == *button_pattern)
00278 return false;
00279
00280 show_handle = showh;
00281 handle_width = hwidth;
00282 handle_size = hsize;
00283 border_width = bwidth;
00284 title_height = theight;
00285 *button_pattern = bpatt;
00286 return true;
00287 }
00288
00289 QValueList< ModernSysFactory::BorderSize > ModernSysFactory::borderSizes() const
00290 {
00291 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00292 BorderVeryLarge << BorderHuge;
00293
00294
00295 }
00296
00297 ModernButton::ModernButton(ModernSys *parent, const char *name, bool toggle,
00298 const unsigned char *bitmap, const QString& tip, const int realizeBtns)
00299 : QButton(parent->widget(), name),
00300 last_button( NoButton )
00301 {
00302 setBackgroundMode( NoBackground );
00303
00304 setToggleButton(toggle);
00305
00306 setCursor( arrowCursor );
00307 realizeButtons = realizeBtns;
00308 QBitmap mask(14, 15, QPixmap::defaultDepth() > 8 ?
00309 btnhighcolor_mask_bits : lowcolor_mask_bits, true);
00310 resize(14, 15);
00311
00312 if(bitmap)
00313 setBitmap(bitmap);
00314 setMask(mask);
00315 hide();
00316 client = parent;
00317 QToolTip::add( this, tip );
00318
00319 }
00320
00321 QSize ModernButton::sizeHint() const
00322 {
00323 return(QSize(14, 15));
00324 }
00325
00326
00327 void ModernButton::turnOn( bool isOn )
00328 {
00329 if ( isToggleButton() )
00330 setOn( isOn );
00331 }
00332
00333 void ModernButton::reset()
00334 {
00335 repaint(false);
00336 }
00337
00338 void ModernButton::setBitmap(const unsigned char *bitmap)
00339 {
00340 deco = QBitmap(8, 8, bitmap, true);
00341 deco.setMask(deco);
00342 repaint();
00343 }
00344
00345 void ModernButton::drawButton(QPainter *p)
00346 {
00347 if(client->isActive()){
00348 if(buttonPix)
00349 p->drawPixmap(0, 0, isDown() ? *buttonPixDown : *buttonPix);
00350 }
00351 else{
00352 if(iButtonPix)
00353 p->drawPixmap(0, 0, isDown() ? *iButtonPixDown : *iButtonPix);
00354 }
00355 if(!deco.isNull()){
00356 p->setPen(*buttonFg);
00357 p->drawPixmap(isDown() ? 4 : 3, isDown() ? 5 : 4, deco);
00358 }
00359 }
00360
00361 void ModernButton::mousePressEvent( QMouseEvent* e )
00362 {
00363 last_button = e->button();
00364 QMouseEvent me ( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00365 QButton::mousePressEvent( &me );
00366 }
00367
00368 void ModernButton::mouseReleaseEvent( QMouseEvent* e )
00369 {
00370 QMouseEvent me ( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00371 QButton::mouseReleaseEvent( &me );
00372 }
00373
00374
00375 void ModernSys::reset( unsigned long )
00376 {
00377 titleBuffer.resize(0, 0);
00378 recalcTitleBuffer();
00379 for (int i = 0; i < 5; button[i++]->reset());
00380 widget()->repaint();
00381 }
00382
00383 ModernSys::ModernSys( KDecorationBridge* b, KDecorationFactory* f )
00384 : KDecoration( b, f )
00385 {
00386 }
00387
00388 void ModernSys::init()
00389 {
00390 connect( this, SIGNAL( keepAboveChanged( bool )), SLOT( keepAboveChange( bool )));
00391 connect( this, SIGNAL( keepBelowChanged( bool )), SLOT( keepBelowChange( bool )));
00392
00393 createMainWidget( WResizeNoErase );
00394 widget()->installEventFilter( this );
00395 bool reverse = QApplication::reverseLayout();
00396
00397 bool help = providesContextHelp();
00398
00399 QGridLayout* g = new QGridLayout(widget(), 0, 0, 2);
00400 if( isPreview())
00401 g->addWidget( new QLabel( i18n( "<center><b>Modern System preview</b></center>" ), widget()), 1, 1 );
00402 else
00403 g->addItem( new QSpacerItem( 0, 0 ), 1, 1 );
00404 g->setRowStretch(1, 10);
00405 g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
00406
00407 g->addColSpacing(0, border_width-2 + (reverse ? handle_width : 0));
00408 g->addColSpacing(2, border_width-2 + (reverse ? 0 : handle_width));
00409
00410 g->addRowSpacing(2, border_width-2 + handle_width);
00411
00412 QBoxLayout* hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00413 hb->setResizeMode(QLayout::FreeResize);
00414 titlebar = new QSpacerItem(10, title_height, QSizePolicy::Expanding,
00415 QSizePolicy::Minimum);
00416
00417 button[BtnClose] = new ModernButton(this, "close", false, close_bits, i18n("Close"));
00418 button[BtnSticky] = new ModernButton(this, "sticky", false, NULL, isOnAllDesktops()?i18n("Unsticky"):i18n("Sticky"));
00419 button[BtnMinimize] = new ModernButton(this, "iconify", false, iconify_bits, i18n("Minimize"));
00420 button[BtnMaximize] = new ModernButton(this, "maximize", false, maximize_bits, i18n("Maximize"), LeftButton|MidButton|RightButton);
00421 button[BtnHelp] = new ModernButton(this, "help", false, question_bits, i18n("Help"));
00422 button[BtnAbove] = new ModernButton(this, "above", true, above_off_bits, i18n("Keep above others"));
00423 button[BtnBelow] = new ModernButton(this, "below", true, below_off_bits, i18n("Keep below others"));
00424 button[BtnShade] = new ModernButton(this, "shade", true, shade_off_bits, isSetShade()?i18n("Unshade"):i18n("Shade") );
00425
00426 connect( button[BtnClose], SIGNAL(clicked()), this, SLOT( closeWindow() ) );
00427 connect( button[BtnSticky], SIGNAL(clicked()), this, SLOT( toggleOnAllDesktops() ) );
00428 connect( button[BtnMinimize], SIGNAL(clicked()), this, SLOT( minimize() ) );
00429 connect( button[BtnMaximize], SIGNAL(clicked()), this, SLOT( maxButtonClicked() ) );
00430 connect( button[BtnHelp], SIGNAL(clicked()), this, SLOT( showContextHelp() ) );
00431 connect( button[BtnAbove], SIGNAL( clicked()), this, SLOT(slotAbove()) );
00432 connect( button[BtnBelow], SIGNAL( clicked()), this, SLOT(slotBelow()) );
00433 connect( button[BtnShade], SIGNAL( clicked()), this, SLOT(slotShade()) );
00434
00435 for (int i = 0; i < (int)button_pattern->length();) {
00436 QChar c = (*button_pattern)[i++];
00437 if (c == '_')
00438 c = '3';
00439
00440 if (c.isDigit()) {
00441 hb->addSpacing(int(c - '0'));
00442 continue;
00443 }
00444 else if (c == 'X' && isCloseable()) {
00445 hb->addWidget(button[BtnClose]);
00446 button[BtnClose]->show();
00447 }
00448 else if (c == 'S') {
00449 if(isOnAllDesktops())
00450 button[BtnSticky]->setBitmap(unsticky_bits);
00451 else
00452 button[BtnSticky]->setBitmap(sticky_bits);
00453 hb->addWidget(button[BtnSticky]);
00454 button[BtnSticky]->show();
00455 }
00456 else if (c == 'I' && isMinimizable()) {
00457 hb->addWidget(button[BtnMinimize]);
00458 button[BtnMinimize]->show();
00459 }
00460 else if (c == 'A' && isMaximizable()) {
00461 hb->addWidget(button[BtnMaximize]);
00462 button[BtnMaximize]->show();
00463 }
00464 else if (help && c == 'H') {
00465 hb->addWidget(button[BtnHelp]);
00466 button[BtnHelp]->show();
00467 }
00468 else if (c == 'F') {
00469 button[BtnAbove]->setBitmap(keepAbove()?above_on_bits:above_off_bits);
00470 hb->addWidget(button[BtnAbove]);
00471 button[BtnAbove]->show();
00472 }
00473 else if (c == 'B') {
00474 button[BtnBelow]->setBitmap(keepBelow()?below_on_bits:below_off_bits);
00475 hb->addWidget(button[BtnBelow]);
00476 button[BtnBelow]->show();
00477 }
00478 else if (c == 'L' && isShadeable()) {
00479 button[BtnShade]->setBitmap(isSetShade()?shade_on_bits:shade_off_bits);
00480 hb->addWidget(button[BtnShade]);
00481 button[BtnShade]->show();
00482 }
00483 else if (c == 't')
00484 hb->addItem(titlebar);
00485
00486 if ((*button_pattern)[i] >= 'A' && (*button_pattern)[i] <= 'Z')
00487 hb->addSpacing(1);
00488 }
00489
00490 g->addLayout( hb, 0, 1 );
00491 widget()->setBackgroundMode(NoBackground);
00492 recalcTitleBuffer();
00493 widget()->layout()->activate();
00494 }
00495
00496
00497 void ModernSys::maxButtonClicked( )
00498 {
00499 if (button[BtnMaximize]) {
00500 maximize(button[BtnMaximize]->last_button);
00501 }
00502 }
00503
00504 void ModernSys::slotAbove()
00505 {
00506 setKeepAbove( !keepAbove());
00507 if (button[BtnAbove]) {
00508 button[BtnAbove]->turnOn(keepAbove());
00509 button[BtnAbove]->repaint(true);
00510 }
00511 }
00512
00513
00514 void ModernSys::slotBelow()
00515 {
00516 setKeepBelow( !keepBelow());
00517 if (button[BtnBelow]) {
00518 button[BtnBelow]->turnOn(keepBelow());
00519 button[BtnBelow]->repaint(true);
00520 }
00521 }
00522
00523
00524 void ModernSys::slotShade()
00525 {
00526 setShade( !isSetShade());
00527 }
00528
00529 void ModernSys::resizeEvent( QResizeEvent* )
00530 {
00531 recalcTitleBuffer();
00532 doShape();
00533 }
00534
00535 void ModernSys::recalcTitleBuffer()
00536 {
00537 if(oldTitle == caption() && width() == titleBuffer.width())
00538 return;
00539
00540 QFontMetrics fm(options()->font(true));
00541 titleBuffer.resize(width(), title_height+2);
00542 QPainter p;
00543 p.begin(&titleBuffer);
00544 if(aUpperGradient)
00545 p.drawTiledPixmap(0, 0, width(), title_height+2, *aUpperGradient);
00546 else
00547 p.fillRect(0, 0, width(), title_height+2,
00548 options()->colorGroup(ColorTitleBar, true).
00549 brush(QColorGroup::Button));
00550
00551 QRect t = titlebar->geometry();
00552 t.setTop( 2 );
00553 t.setLeft( t.left() );
00554 t.setRight( t.right() - 2 );
00555
00556 QRegion r(t.x(), 0, t.width(), title_height+2);
00557 r -= QRect(t.x()+((t.width()-fm.width(caption()))/2)-4,
00558 0, fm.width(caption())+8, title_height+2);
00559 p.setClipRegion(r);
00560 int i, ly;
00561 ly = (title_height % 3 == 0) ? 3 : 4;
00562 for(i=0; i < (title_height-2)/3; ++i, ly+=3){
00563 p.setPen(options()->color(ColorTitleBar, true).light(150));
00564 p.drawLine(0, ly, width()-1, ly);
00565 p.setPen(options()->color(ColorTitleBar, true).dark(120));
00566 p.drawLine(0, ly+1, width()-1, ly+1);
00567 }
00568 p.setClipRect(t);
00569 p.setPen(options()->color(ColorFont, true));
00570 p.setFont(options()->font(true));
00571
00572 p.drawText(t.x()+((t.width()-fm.width(caption()))/2)-4,
00573 0, fm.width(caption())+8, title_height+2, AlignCenter, caption());
00574 p.setClipping(false);
00575 p.end();
00576 oldTitle = caption();
00577 }
00578
00579 void ModernSys::captionChange()
00580 {
00581 recalcTitleBuffer();
00582 widget()->repaint( titlebar->geometry(), false );
00583 }
00584
00585 void ModernSys::drawRoundFrame(QPainter &p, int x, int y, int w, int h)
00586 {
00587 kDrawRoundButton(&p, x, y, w, h,
00588 options()->colorGroup(ColorFrame, isActive()), false);
00589
00590 }
00591
00592 void ModernSys::paintEvent( QPaintEvent* )
00593 {
00594 int hs = handle_size;
00595 int hw = handle_width;
00596
00597 QPainter p( widget() );
00598 QRect t = titlebar->geometry();
00599
00600 QBrush fillBrush(widget()->colorGroup().brush(QColorGroup::Background).pixmap() ?
00601 widget()->colorGroup().brush(QColorGroup::Background) :
00602 options()->colorGroup(ColorFrame, isActive()).
00603 brush(QColorGroup::Button));
00604
00605 p.fillRect(1, 16, width()-2, height()-16, fillBrush);
00606 p.fillRect(width()-6, 0, width()-1, height(), fillBrush);
00607
00608 t.setTop( 2 );
00609 t.setLeft( t.left() );
00610 t.setRight( t.right() - 2 );
00611
00612 int w = width() - hw;
00613 int h = height() - hw;
00614
00615
00616 QColorGroup g = options()->colorGroup(ColorTitleBar, isActive());
00617 if(isActive()){
00618 p.drawPixmap(1, 1, titleBuffer, 0, 0, w-2, title_height+2);
00619 }
00620 else{
00621 if(iUpperGradient)
00622 p.drawTiledPixmap(1, 1, w-2, title_height+2, *iUpperGradient);
00623 else
00624 p.fillRect(1, 1, w-2, title_height+2, fillBrush);
00625 p.setPen(options()->color(ColorFont, isActive()));
00626 p.setFont(options()->font(isActive()));
00627 p.drawText(t, AlignCenter, caption() );
00628 }
00629
00630
00631 p.setPen(g.light());
00632 p.drawLine(1, 1, 1, title_height+3);
00633 p.drawLine(1, 1, w-3, 1);
00634 p.setPen(g.dark());
00635 p.drawLine(w-2, 1, w-2, title_height+3);
00636 p.drawLine(0, title_height+2, w-2, title_height+2);
00637
00638
00639 g = options()->colorGroup(ColorFrame, isActive());
00640 p.setPen(g.light());
00641 p.drawLine(1, title_height+3, 1, h-2);
00642 p.setPen(g.dark());
00643 p.drawLine(2, h-2, w-2, h-2);
00644 p.drawLine(w-2, title_height+3, w-2, h-2);
00645
00646
00647
00648 qDrawShadePanel(&p, border_width-1, title_height+3, w-2*border_width+2, h-title_height-border_width-2, g, true);
00649
00650 if (show_handle) {
00651 p.setPen(g.dark());
00652 p.drawLine(width()-3, height()-hs-1, width()-3, height()-3);
00653 p.drawLine(width()-hs-1, height()-3, width()-3, height()-3);
00654
00655 p.setPen(g.light());
00656 p.drawLine(width()-hw, height()-hs-1, width()-hw, height()-hw);
00657 p.drawLine(width()-hs-1, height()-hw, width()-hw, height()-hw);
00658 p.drawLine(width()-hw, height()-hs-1, width()-4, height()-hs-1);
00659 p.drawLine(width()-hs-1, height()-hw, width()-hs-1, height()-4);
00660
00661 p.setPen(Qt::black);
00662 p.drawRect(0, 0, w, h);
00663
00664
00665 p.drawLine(width()-hw, height()-hs, width(), height()-hs);
00666 p.drawLine(width()-2, height()-hs, width()-2, height()-2);
00667 p.drawLine(width()-hs, height()-2, width()-2, height()-2);
00668 p.drawLine(width()-hs, height()-hw, width()-hs, height()-2);
00669 } else {
00670 p.setPen(Qt::black);
00671 p.drawRect(0, 0, w, h);
00672 }
00673 }
00674
00675 void ModernSys::doShape()
00676 {
00677 int hs = handle_size;
00678 int hw = handle_width;
00679 QRegion mask;
00680 mask += QRect(0, 0, width()-hw, height()-hw);
00681
00682 mask -= QRect(0, 0, 1, 1);
00683 mask -= QRect(width()-hw-1, 0, 1, 1);
00684 mask -= QRect(0, height()-hw-1, 1, 1);
00685
00686 if (show_handle) {
00687 mask += QRect(width()-hs, height()-hs, hs-1, hs-1);
00688 mask -= QRect(width()-2, height()-2, 1, 1);
00689 mask -= QRect(width()-2, height()-hs, 1, 1);
00690 mask -= QRect(width()-hs, height()-2, 1, 1);
00691 } else
00692 mask -= QRect(width()-1, height()-1, 1, 1);
00693
00694 setMask(mask);
00695 }
00696
00697 void ModernSys::showEvent(QShowEvent *)
00698 {
00699 doShape();
00700 widget()->repaint();
00701 }
00702
00703 void ModernSys::mouseDoubleClickEvent( QMouseEvent * e )
00704 {
00705 if (titlebar->geometry().contains( e->pos() ) )
00706 titlebarDblClickOperation();
00707 }
00708
00709 void ModernSys::desktopChange()
00710 {
00711 bool sticky_on = isOnAllDesktops();
00712 button[BtnSticky]->setBitmap(sticky_on ? unsticky_bits : sticky_bits);
00713 QToolTip::remove( button[BtnSticky] );
00714 QToolTip::add( button[BtnSticky], sticky_on ? i18n("Unsticky") : i18n("Sticky"));
00715 }
00716
00717 void ModernSys::maximizeChange()
00718 {
00719 bool m = ( maximizeMode() == MaximizeFull );
00720 button[BtnMaximize]->setBitmap(m ? minmax_bits : maximize_bits);
00721 QToolTip::remove( button[BtnMaximize] );
00722 QToolTip::add( button[BtnMaximize], m ? i18n("Restore") : i18n("Maximize"));
00723 }
00724
00725 void ModernSys::activeChange()
00726 {
00727 widget()->repaint(false);
00728 for (int i = 0; i < 5; button[i++]->reset());
00729 }
00730
00731
00732 void ModernSys::keepAboveChange( bool above )
00733 {
00734 if (button[BtnAbove]) {
00735 button[BtnAbove]->setBitmap( above ? above_on_bits : above_off_bits );
00736 button[BtnAbove]->repaint(false);
00737 }
00738 }
00739
00740 void ModernSys::keepBelowChange( bool below )
00741 {
00742 if (button[BtnBelow]) {
00743 button[BtnBelow]->setBitmap( below ? below_on_bits : below_off_bits );
00744 button[BtnBelow]->repaint(false);
00745 }
00746 }
00747
00748
00749 ModernSys::Position ModernSys::mousePosition( const QPoint& p) const
00750 {
00751 Position m = KDecoration::mousePosition( p );
00752
00753 const int range = 14 + 3*border_width/2;
00754 const int border = show_handle ? handle_width + border_width : border_width;
00755 const int range2 = show_handle ? handle_width + border_width : range;
00756 const int range3 = show_handle ? handle_width + range : range;
00757
00758 if ( ( p.x() > border_width && p.x() < width() - border )
00759 && ( p.y() > 4 && p.y() < height() - border ) )
00760 m = PositionCenter;
00761 else if ( p.y() <= range && p.x() <= range)
00762 m = PositionTopLeft;
00763 else if ( p.y() >= height()-range2 && p.x() >= width()-range2)
00764 m = PositionBottomRight;
00765 else if ( p.y() >= height()-range3 && p.x() <= range)
00766 m = PositionBottomLeft;
00767 else if ( p.y() <= range && p.x() >= width()-range3)
00768 m = PositionTopRight;
00769 else if ( p.y() <= 4 )
00770 m = PositionTop;
00771 else if ( p.y() >= height()-border )
00772 m = PositionBottom;
00773 else if ( p.x() <= border_width )
00774 m = PositionLeft;
00775 else if ( p.x() >= width()-border )
00776 m = PositionRight;
00777 else
00778 m = PositionCenter;
00779
00780 return m;
00781 }
00782
00783 void ModernSys::resize( const QSize& s )
00784 {
00785 widget()->resize( s );
00786 }
00787
00788 void ModernSys::iconChange()
00789 {
00790 }
00791
00792 void ModernSys::shadeChange()
00793 {
00794 if (button[BtnShade]) {
00795 bool on = isSetShade();
00796 button[BtnShade]->turnOn(on);
00797 button[BtnShade]->setBitmap(isSetShade() ? shade_on_bits : shade_off_bits );
00798 button[BtnShade]->repaint(false);
00799 QToolTip::remove( button[BtnShade] );
00800 QToolTip::add( button[BtnShade], on ? i18n("Unshade") : i18n("Shade"));
00801 }
00802 }
00803
00804 QSize ModernSys::minimumSize() const
00805 {
00806 return QSize( 50, 50 );
00807 }
00808
00809 void ModernSys::borders( int& left, int& right, int& top, int& bottom ) const
00810 {
00811 bool reverse = QApplication::reverseLayout();
00812 left = border_width + (reverse ? handle_width : 0);
00813 right = border_width + (reverse ? 0 : handle_width);
00814 top = 4 + titlebar->geometry().height();
00815 bottom = border_width + handle_width;
00816
00817
00818
00819
00820
00821
00822
00823 }
00824
00825 bool ModernSys::eventFilter( QObject* o, QEvent* e )
00826 {
00827 if( o != widget())
00828 return false;
00829 switch( e->type())
00830 {
00831 case QEvent::Resize:
00832 resizeEvent( static_cast< QResizeEvent* >( e ));
00833 return true;
00834 case QEvent::Paint:
00835 paintEvent( static_cast< QPaintEvent* >( e ));
00836 return true;
00837 case QEvent::MouseButtonDblClick:
00838 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
00839 return true;
00840 case QEvent::MouseButtonPress:
00841 processMousePressEvent( static_cast< QMouseEvent* >( e ));
00842 return true;
00843 case QEvent::Show:
00844 showEvent( static_cast< QShowEvent* >( e ));
00845 return true;
00846 default:
00847 break;
00848 }
00849 return false;
00850 }
00851
00852 ModernSysFactory::ModernSysFactory()
00853 {
00854 button_pattern = new QString;
00855 read_config();
00856 create_pixmaps();
00857 }
00858
00859 ModernSysFactory::~ModernSysFactory()
00860 {
00861 ModernSystem::delete_pixmaps();
00862 delete ModernSystem::button_pattern;
00863 }
00864
00865 KDecoration* ModernSysFactory::createDecoration( KDecorationBridge* b )
00866 {
00867 return(new ModernSys(b, this));
00868 }
00869
00870 bool ModernSysFactory::reset( unsigned long changed )
00871 {
00872 bool ret = read_config();
00873 if( changed & (SettingColors | SettingBorder) )
00874 {
00875 delete_pixmaps();
00876 create_pixmaps();
00877 }
00878 if( ret )
00879 return true;
00880 else
00881 {
00882 resetDecorations( changed );
00883 return false;
00884 }
00885 }
00886
00887 bool ModernSysFactory::supports( Ability ability )
00888 {
00889 switch( ability )
00890 {
00891 case AbilityAnnounceButtons:
00892 case AbilityButtonOnAllDesktops:
00893 case AbilityButtonSpacer:
00894 case AbilityButtonHelp:
00895 case AbilityButtonMinimize:
00896 case AbilityButtonMaximize:
00897 case AbilityButtonClose:
00898 case AbilityButtonAboveOthers:
00899 case AbilityButtonBelowOthers:
00900 case AbilityButtonShade:
00901 return true;
00902 default:
00903 return false;
00904 };
00905 }
00906
00907 }
00908
00909
00910 extern "C" KDE_EXPORT KDecorationFactory* create_factory()
00911 {
00912 return new ModernSystem::ModernSysFactory();
00913 }
00914
00915
00916
00917 #include "modernsys.moc"
00918