00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <kconfig.h>
00017 #include <kdrawutil.h>
00018 #include <kglobal.h>
00019 #include <klocale.h>
00020 #include <kpixmapeffect.h>
00021 #include <qbitmap.h>
00022 #include <qcursor.h>
00023 #include <qdrawutil.h>
00024 #include <qimage.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qtooltip.h>
00028 #include <qapplication.h>
00029
00030 #include "quartz.h"
00031
00032
00033 namespace Quartz {
00034
00035 static unsigned char iconify_bits[] = {
00036 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00,
00037 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00038
00039 static unsigned char close_bits[] = {
00040 0x00, 0x00, 0x86, 0x01, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x78, 0x00,
00041 0xcc, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00};
00042
00043 static unsigned char maximize_bits[] = {
00044 0xff, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00045 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x00, 0x00};
00046
00047 static unsigned char minmax_bits[] = {
00048 0xfc, 0x00, 0xfc, 0x00, 0x84, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xe1, 0x00,
00049 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x00, 0x00};
00050
00051 static unsigned char question_bits[] = {
00052 0x00, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
00053 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00};
00054
00055 static unsigned char pindown_white_bits[] = {
00056 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0xa0, 0x03,
00057 0xb0, 0x01, 0x30, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00,
00058 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00059
00060 static unsigned char pindown_gray_bits[] = {
00061 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
00062 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00064
00065 static unsigned char pindown_dgray_bits[] = {
00066 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x10, 0x70, 0x20, 0x50, 0x20,
00067 0x48, 0x30, 0xc8, 0x38, 0x08, 0x1f, 0x08, 0x18, 0x10, 0x1c, 0x10, 0x0e,
00068 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00069
00070 static unsigned char pinup_white_bits[] = {
00071 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x11,
00072 0x3f, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00074
00075 static unsigned char pinup_gray_bits[] = {
00076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00077 0x80, 0x0a, 0xbf, 0x0a, 0x80, 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
00078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00079
00080 static unsigned char pinup_dgray_bits[] = {
00081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x40, 0x31, 0x40, 0x2e,
00082 0x40, 0x20, 0x40, 0x20, 0x7f, 0x2a, 0x40, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
00083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00084
00085
00087
00088
00089 bool onAllDesktopsButtonOnLeft = true;
00090 bool coloredFrame = true;
00091
00092 KPixmap* titleBlocks = NULL;
00093 KPixmap* ititleBlocks = NULL;
00094 KPixmap* pinDownPix = NULL;
00095 KPixmap* pinUpPix = NULL;
00096 KPixmap* ipinDownPix = NULL;
00097 KPixmap* ipinUpPix = NULL;
00098 static int normalTitleHeight;
00099 static int toolTitleHeight;
00100 static int borderWidth;
00101
00102 bool quartz_initialized = false;
00103 QuartzHandler* clientHandler;
00104
00106
00107
00108 QuartzHandler::QuartzHandler()
00109 {
00110 quartz_initialized = false;
00111 readConfig();
00112 createPixmaps();
00113 quartz_initialized = true;
00114 }
00115
00116
00117 QuartzHandler::~QuartzHandler()
00118 {
00119 quartz_initialized = false;
00120 freePixmaps();
00121 }
00122
00123
00124 KDecoration* QuartzHandler::createDecoration( KDecorationBridge* bridge )
00125 {
00126 return new QuartzClient( bridge, this );
00127 }
00128
00129
00130 bool QuartzHandler::reset(unsigned long changed)
00131 {
00132 quartz_initialized = false;
00133 freePixmaps();
00134 readConfig();
00135 createPixmaps();
00136 quartz_initialized = true;
00137
00138
00139 bool needHardReset = true;
00140 if (changed & SettingColors)
00141 {
00142 needHardReset = false;
00143 }
00144
00145 if (needHardReset) {
00146 return true;
00147 } else {
00148 resetDecorations(changed);
00149 return false;
00150 }
00151 return true;
00152 }
00153
00154
00155 void QuartzHandler::readConfig()
00156 {
00157 KConfig conf("kwinquartzrc");
00158 conf.setGroup("General");
00159 coloredFrame = conf.readBoolEntry( "UseTitleBarBorderColors", true );
00160
00161
00162 onAllDesktopsButtonOnLeft = KDecoration::options()->titleButtonsLeft().contains( 'S' );
00163 if ( QApplication::reverseLayout() )
00164 onAllDesktopsButtonOnLeft = !onAllDesktopsButtonOnLeft;
00165 switch(options()->preferredBorderSize(this)) {
00166 case BorderLarge:
00167 borderWidth = 8;
00168 break;
00169 case BorderVeryLarge:
00170 borderWidth = 12;
00171 break;
00172 case BorderHuge:
00173 borderWidth = 18;
00174 break;
00175 case BorderVeryHuge:
00176 borderWidth = 27;
00177 break;
00178 case BorderOversized:
00179 borderWidth = 40;
00180 break;
00181 case BorderTiny:
00182 case BorderNormal:
00183 default:
00184 borderWidth = 4;
00185 }
00186
00187 normalTitleHeight = QFontMetrics(options()->font(true)).height();
00188 if (normalTitleHeight < 18) normalTitleHeight = 18;
00189 if (normalTitleHeight < borderWidth) normalTitleHeight = borderWidth;
00190
00191 toolTitleHeight = QFontMetrics(options()->font(true, true)).height();
00192 if (toolTitleHeight < 12) toolTitleHeight = 12;
00193 if (toolTitleHeight < borderWidth) toolTitleHeight = borderWidth;
00194 }
00195
00196
00197
00198
00199 void QuartzHandler::drawBlocks( KPixmap *pi, KPixmap &p, const QColor &c1, const QColor &c2 )
00200 {
00201 QPainter px;
00202
00203 px.begin( pi );
00204
00205
00206 KPixmapEffect::gradient(p, c1, c2, KPixmapEffect::HorizontalGradient);
00207
00208 int factor = (pi->height()-2)/4;
00209 int square = factor - (factor+2)/4;
00210
00211 int x = pi->width() - 5*factor - square;
00212 int y = (pi->height() - 4*factor)/2;
00213
00214 px.fillRect( x, y, square, square, c1.light(120) );
00215 px.fillRect( x, y+factor, square, square, c1 );
00216 px.fillRect( x, y+2*factor, square, square, c1.light(110) );
00217 px.fillRect( x, y+3*factor, square, square, c1 );
00218
00219 px.fillRect( x+factor, y, square, square, c1.light(110) );
00220 px.fillRect( x+factor, y+factor, square, square, c2.light(110) );
00221 px.fillRect( x+factor, y+2*factor, square, square, c1.light(120) );
00222 px.fillRect( x+factor, y+3*factor, square, square, c2.light(130) );
00223
00224 px.fillRect( x+2*factor, y+factor, square, square, c1.light(110) );
00225 px.fillRect( x+2*factor, y+2*factor, square, square, c2.light(120) );
00226 px.fillRect( x+2*factor, y+3*factor, square, square, c2.light(150) );
00227
00228 px.fillRect( x+3*factor, y, square, square, c1.dark(110) );
00229 px.fillRect( x+3*factor, y+2*factor, square, square, c2.light(120) );
00230 px.fillRect( x+3*factor, y+3*factor, square, square, c1.dark(120) );
00231
00232 px.fillRect( x+4*factor, y+factor, square, square, c1.light(110) );
00233 px.fillRect( x+4*factor, y+3*factor, square, square, c1.dark(110) );
00234
00235 px.fillRect( x+5*factor, y+2*factor, square, square, c2.light(120));
00236 px.fillRect( x+5*factor, y+3*factor, square, square, c2.light(110) );
00237 }
00238
00239
00240
00241 void QuartzHandler::createPixmaps()
00242 {
00243
00244 QColorGroup g2 = options()->colorGroup(ColorTitleBlend, true);
00245 QColor c2 = g2.background();
00246 g2 = options()->colorGroup(ColorTitleBar, true );
00247 QColor c = g2.background().light(130);
00248
00249 titleBlocks = new KPixmap();
00250 titleBlocks->resize( normalTitleHeight*25/18, normalTitleHeight );
00251 drawBlocks( titleBlocks, *titleBlocks, c, c2 );
00252
00253 g2 = options()->colorGroup(ColorTitleBlend, false);
00254 c2 = g2.background();
00255 g2 = options()->colorGroup(ColorTitleBar, false );
00256 c = g2.background().light(130);
00257
00258 ititleBlocks = new KPixmap();
00259 ititleBlocks->resize( normalTitleHeight*25/18, normalTitleHeight );
00260 drawBlocks( ititleBlocks, *ititleBlocks, c, c2 );
00261
00262
00263 QColorGroup g;
00264 QPainter p;
00265
00266 g = options()->colorGroup( onAllDesktopsButtonOnLeft ? ColorTitleBar : ColorTitleBlend, true );
00267 c = onAllDesktopsButtonOnLeft ? g.background().light(130) : g.background();
00268 g2 = options()->colorGroup( ColorButtonBg, true );
00269
00270 pinUpPix = new KPixmap();
00271 pinUpPix->resize(16, 16);
00272 p.begin( pinUpPix );
00273 p.fillRect( 0, 0, 16, 16, c);
00274 kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pinup_white_bits,
00275 pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
00276 p.end();
00277
00278 pinDownPix = new KPixmap();
00279 pinDownPix->resize(16, 16);
00280 p.begin( pinDownPix );
00281 p.fillRect( 0, 0, 16, 16, c);
00282 kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pindown_white_bits,
00283 pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
00284 p.end();
00285
00286
00287
00288 g = options()->colorGroup( onAllDesktopsButtonOnLeft ? ColorTitleBar : ColorTitleBlend, false );
00289 c = onAllDesktopsButtonOnLeft ? g.background().light(130) : g.background();
00290 g2 = options()->colorGroup( ColorButtonBg, false );
00291
00292 ipinUpPix = new KPixmap();
00293 ipinUpPix->resize(16, 16);
00294 p.begin( ipinUpPix );
00295 p.fillRect( 0, 0, 16, 16, c);
00296 kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pinup_white_bits,
00297 pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
00298 p.end();
00299
00300 ipinDownPix = new KPixmap();
00301 ipinDownPix->resize(16, 16);
00302 p.begin( ipinDownPix );
00303 p.fillRect( 0, 0, 16, 16, c);
00304 kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pindown_white_bits,
00305 pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
00306 p.end();
00307 }
00308
00309
00310 void QuartzHandler::freePixmaps()
00311 {
00312 delete titleBlocks;
00313 delete ititleBlocks;
00314
00315
00316 delete pinUpPix;
00317 delete ipinUpPix;
00318 delete pinDownPix;
00319 delete ipinDownPix;
00320 }
00321
00322
00323 QValueList< QuartzHandler::BorderSize > QuartzHandler::borderSizes() const
00324 {
00325 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00326 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
00327 }
00328
00329
00330 QuartzButton::QuartzButton(QuartzClient *parent, const char *name, bool largeButton,
00331 bool isLeftButton, bool isOnAllDesktopsButton, const unsigned char *bitmap,
00332 const QString& tip, const int realizeBtns)
00333 : QButton(parent->widget(), name)
00334 {
00335 setTipText(tip);
00336 setCursor(ArrowCursor);
00337
00338
00339 setBackgroundMode( QWidget::NoBackground );
00340 setToggleButton( isOnAllDesktopsButton );
00341
00342 realizeButtons = realizeBtns;
00343
00344 deco = NULL;
00345 large = largeButton;
00346 if ( QApplication::reverseLayout() )
00347 isLeft = !isLeftButton;
00348 else
00349 isLeft = isLeftButton;
00350 isOnAllDesktops = isOnAllDesktopsButton;
00351 client = parent;
00352
00353 if ( large )
00354 setFixedSize(normalTitleHeight-2, normalTitleHeight-2);
00355 else
00356 setFixedSize(toolTitleHeight-2, toolTitleHeight-2);
00357
00358 if(bitmap)
00359 setBitmap(bitmap);
00360 }
00361
00362
00363 QuartzButton::~QuartzButton()
00364 {
00365 delete deco;
00366 }
00367
00368
00369 QSize QuartzButton::sizeHint() const
00370 {
00371 if ( large )
00372 return( QSize(normalTitleHeight-2, normalTitleHeight-2) );
00373 else
00374 return( QSize(toolTitleHeight-2, toolTitleHeight-2) );
00375 }
00376
00377
00378 void QuartzButton::setBitmap(const unsigned char *bitmap)
00379 {
00380 delete deco;
00381
00382 deco = new QBitmap(10, 10, bitmap, true);
00383 deco->setMask( *deco );
00384 repaint( false );
00385 }
00386
00387
00388 void QuartzButton::setTipText(const QString &tip) {
00389 if(KDecoration::options()->showTooltips()) {
00390 QToolTip::remove(this );
00391 QToolTip::add(this, tip );
00392 }
00393 }
00394
00395
00396 void QuartzButton::drawButton(QPainter *p)
00397 {
00398
00399 if (!quartz_initialized)
00400 return;
00401
00402 QColor c;
00403
00404 if (isLeft)
00405 c = KDecoration::options()->color(KDecoration::ColorTitleBar, client->isActive()).light(130);
00406 else
00407 c = KDecoration::options()->color(KDecoration::ColorTitleBlend, client->isActive());
00408
00409
00410 p->fillRect(0, 0, width(), height(), c );
00411
00412
00413
00414 if( deco )
00415 {
00416 int xOff = (width()-10)/2;
00417 int yOff = (height()-10)/2;
00418 p->setPen( Qt::black );
00419 p->drawPixmap(isDown() ? xOff+2: xOff+1, isDown() ? yOff+2 : yOff+1, *deco);
00420 p->setPen( KDecoration::options()->color(KDecoration::ColorButtonBg, client->isActive()).light(150) );
00421 p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, *deco);
00422 } else
00423 {
00424 QPixmap btnpix;
00425 int Offset = 0;
00426
00427 if (isOnAllDesktops)
00428 {
00429 if (isDown())
00430 Offset = 1;
00431
00432
00433 if (client->isActive())
00434 btnpix = isOn() ? *pinDownPix : *pinUpPix;
00435 else
00436 btnpix = isOn() ? *ipinDownPix : *ipinUpPix;
00437
00438 } else
00439 btnpix = client->icon().pixmap( QIconSet::Small, QIconSet::Normal);
00440
00441
00442 if ( height() < 16)
00443 {
00444 QPixmap tmpPix;
00445
00446
00447 tmpPix.convertFromImage( btnpix.convertToImage().smoothScale(height(), height()));
00448 p->drawPixmap( 0, 0, tmpPix );
00449 } else {
00450 Offset += (height() - 16)/2;
00451 p->drawPixmap( Offset, Offset, btnpix );
00452 }
00453 }
00454 }
00455
00456
00457
00458 void QuartzButton::turnOn( bool isOn )
00459 {
00460 if ( isToggleButton() )
00461 setOn( isOn );
00462 }
00463
00464
00465 void QuartzButton::mousePressEvent( QMouseEvent* e )
00466 {
00467 last_button = e->button();
00468 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00469 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00470 QButton::mousePressEvent( &me );
00471 }
00472
00473
00474 void QuartzButton::mouseReleaseEvent( QMouseEvent* e )
00475 {
00476 last_button = e->button();
00477 QMouseEvent me( e->type(), e->pos(), e->globalPos(),
00478 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00479 QButton::mouseReleaseEvent( &me );
00480 }
00481
00482
00484
00485 QuartzClient::QuartzClient(KDecorationBridge* bridge, KDecorationFactory* factory)
00486 : KDecoration (bridge, factory)
00487 {
00488 }
00489
00490
00491 void QuartzClient::init()
00492 {
00493 createMainWidget(WNoAutoErase | WStaticContents);
00494
00495 widget()->installEventFilter( this );
00496
00497
00498 widget()->setBackgroundMode( QWidget::NoBackground );
00499
00500
00501 for(int i=0; i < QuartzClient::BtnCount; i++)
00502 button[i] = NULL;
00503
00504
00505 if ( isTool() ) {
00506 titleHeight = toolTitleHeight;
00507 largeButtons = false;
00508 }
00509 else {
00510 titleHeight = normalTitleHeight;
00511 largeButtons = true;
00512 }
00513
00514 borderSize = borderWidth;
00515
00516
00517 QGridLayout* g = new QGridLayout(widget(), 0, 0, 0);
00518 g->setResizeMode(QLayout::FreeResize);
00519 g->addRowSpacing(0, borderSize-1);
00520 if( isPreview())
00521 g->addWidget(new QLabel( i18n( "<center><b>Quartz</b></center>" ), widget()), 3, 1);
00522 else
00523 g->addItem(new QSpacerItem( 0, 0 ), 3, 1);
00524
00525
00526 g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed,
00527 QSizePolicy::Expanding ) );
00528 g->setRowStretch(3, 10);
00529 g->addRowSpacing(2, 1);
00530 g->addRowSpacing(4, borderSize);
00531 g->addColSpacing(0, borderSize);
00532 g->addColSpacing(2, borderSize);
00533
00534
00535 hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00536 hb->setResizeMode( QLayout::FreeResize );
00537 g->addLayout ( hb, 1, 1 );
00538
00539 addClientButtons( options()->titleButtonsLeft() );
00540
00541 titlebar = new QSpacerItem( 10, titleHeight, QSizePolicy::Expanding, QSizePolicy::Minimum );
00542 hb->addItem(titlebar);
00543 hb->addSpacing(2);
00544
00545 addClientButtons( options()->titleButtonsRight(), false );
00546
00547 hb->addSpacing(2);
00548 }
00549
00550 void QuartzClient::reset( unsigned long changed )
00551 {
00552 if (changed & SettingColors || changed & SettingFont)
00553 {
00554
00555 widget()->repaint(false);
00556 }
00557 }
00558
00559 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00560 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00561 | NET::UtilityMask | NET::SplashMask;
00562
00563 bool QuartzClient::isTool()
00564 {
00565 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
00566 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
00567 }
00568
00569
00570 void QuartzClient::addClientButtons( const QString& s, bool isLeft )
00571 {
00572 if (s.length() > 0)
00573 for(unsigned int i = 0; i < s.length(); i++)
00574 {
00575 switch( s[i].latin1() )
00576 {
00577
00578 case 'M':
00579 if (!button[BtnMenu])
00580 {
00581 button[BtnMenu] = new QuartzButton(this, "menu",
00582 largeButtons, isLeft, false, NULL, i18n("Menu"), LeftButton|RightButton);
00583 connect( button[BtnMenu], SIGNAL(pressed()),
00584 this, SLOT(menuButtonPressed()) );
00585 hb->addWidget( button[BtnMenu] );
00586 }
00587 break;
00588
00589
00590 case 'S':
00591 if (!button[BtnOnAllDesktops])
00592 {
00593 button[BtnOnAllDesktops] = new QuartzButton(this, "on_all_desktops",
00594 largeButtons, isLeft, true, NULL, isOnAllDesktops()?i18n("Not On All Desktops"):i18n("On All Desktops"));
00595 button[BtnOnAllDesktops]->turnOn( isOnAllDesktops() );
00596 connect( button[BtnOnAllDesktops], SIGNAL(clicked()),
00597 this, SLOT(toggleOnAllDesktops()) );
00598 hb->addSpacing(1);
00599 hb->addWidget( button[BtnOnAllDesktops] );
00600 hb->addSpacing(1);
00601 }
00602 break;
00603
00604
00605 case 'H':
00606 if( providesContextHelp() && (!button[BtnHelp]) )
00607 {
00608 button[BtnHelp] = new QuartzButton(this, "help",
00609 largeButtons, isLeft, true, question_bits, i18n("Help"));
00610 connect( button[BtnHelp], SIGNAL( clicked() ),
00611 this, SLOT(showContextHelp()));
00612 hb->addWidget( button[BtnHelp] );
00613 }
00614 break;
00615
00616
00617 case 'I':
00618 if ( (!button[BtnIconify]) && isMinimizable())
00619 {
00620 button[BtnIconify] = new QuartzButton(this, "iconify",
00621 largeButtons, isLeft, true, iconify_bits, i18n("Minimize"));
00622 connect( button[BtnIconify], SIGNAL( clicked()),
00623 this, SLOT(minimize()) );
00624 hb->addWidget( button[BtnIconify] );
00625 }
00626 break;
00627
00628
00629 case 'A':
00630 if ( (!button[BtnMax]) && isMaximizable())
00631 {
00632 button[BtnMax] = new QuartzButton(this, "maximize",
00633 largeButtons, isLeft, true, maximize_bits, i18n("Maximize"), LeftButton|MidButton|RightButton);
00634 connect( button[BtnMax], SIGNAL( clicked()),
00635 this, SLOT(slotMaximize()) );
00636 hb->addWidget( button[BtnMax] );
00637 }
00638 break;
00639
00640
00641 case 'X':
00642 if (!button[BtnClose] && isCloseable())
00643 {
00644 button[BtnClose] = new QuartzButton(this, "close",
00645 largeButtons, isLeft, true, close_bits, i18n("Close"));
00646 connect( button[BtnClose], SIGNAL( clicked()),
00647 this, SLOT(closeWindow()) );
00648 hb->addWidget( button[BtnClose] );
00649 }
00650 }
00651 }
00652 }
00653
00654
00655 void QuartzClient::iconChange()
00656 {
00657 if (button[BtnMenu] && button[BtnMenu]->isVisible())
00658 button[BtnMenu]->repaint(false);
00659 }
00660
00661
00662 void QuartzClient::desktopChange()
00663 {
00664 if (button[BtnOnAllDesktops])
00665 {
00666 button[BtnOnAllDesktops]->turnOn(isOnAllDesktops());
00667 button[BtnOnAllDesktops]->repaint(false);
00668 button[BtnOnAllDesktops]->setTipText(isOnAllDesktops() ? i18n("Not On All Desktops") : i18n("On All Desktops"));
00669 }
00670 }
00671
00672
00673 void QuartzClient::slotMaximize()
00674 {
00675 if (button[BtnMax])
00676 {
00677 switch (button[BtnMax]->last_button)
00678 {
00679 case MidButton:
00680 maximize(maximizeMode() ^ MaximizeVertical );
00681 break;
00682 case RightButton:
00683 maximize(maximizeMode() ^ MaximizeHorizontal );
00684 break;
00685 default:
00686 maximize(maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );
00687 }
00688 }
00689 }
00690
00691
00692 void QuartzClient::resizeEvent( QResizeEvent* e)
00693 {
00694 calcHiddenButtons();
00695
00696 if (widget()->isVisibleToTLW())
00697 {
00698 widget()->update(widget()->rect());
00699 int dx = 0;
00700 int dy = 0;
00701
00702 if ( e->oldSize().width() != width() )
00703 dx = 32 + QABS( e->oldSize().width() - width() );
00704
00705 if ( e->oldSize().height() != height() )
00706 dy = 8 + QABS( e->oldSize().height() - height() );
00707
00708 if ( dy )
00709 widget()->update( 0, height() - dy + 1, width(), dy );
00710
00711 if ( dx )
00712 {
00713 widget()->update( width() - dx + 1, 0, dx, height() );
00714 widget()->update( QRect( QPoint(4,4), titlebar->geometry().bottomLeft() - QPoint(1,0) ) );
00715 widget()->update( QRect( titlebar->geometry().topRight(), QPoint( width() - 4, titlebar->geometry().bottom() ) ) );
00716
00717 widget()->repaint(titlebar->geometry(), false);
00718 }
00719 }
00720 }
00721
00722
00723 void QuartzClient::captionChange()
00724 {
00725 widget()->repaint( titlebar->geometry(), false );
00726 }
00727
00728
00729
00730 void QuartzClient::paintEvent( QPaintEvent* )
00731 {
00732
00733 if (!quartz_initialized)
00734 return;
00735
00736 const bool maxFull = (maximizeMode()==MaximizeFull) && !options()->moveResizeMaximizedWindows();
00737
00738 QColorGroup g;
00739 QPainter p(widget());
00740
00741
00742 QRect r(widget()->rect());
00743 int x = r.x();
00744 int y = r.y();
00745 int x2 = r.width() - 1;
00746 int y2 = r.height() - 1;
00747 int w = r.width();
00748 int h = r.height();
00749
00750
00751
00752 if( coloredFrame )
00753 g = options()->colorGroup(ColorTitleBar, isActive());
00754 else
00755 g = options()->colorGroup(ColorFrame, isActive());
00756
00757
00758 p.setPen( g.light().light(120) );
00759 p.drawLine( x, y, x2-1, y );
00760 p.drawLine( x, y+1, x, y2-1 );
00761 p.setPen( g.dark().light(120) );
00762 p.drawLine( x2, y, x2, y2 );
00763 p.drawLine( x, y2, x2, y2 );
00764
00765
00766 QColor frameColor;
00767 if ( coloredFrame)
00768 frameColor = g.background().light(130);
00769 else
00770 frameColor = g.background();
00771 if (borderSize > 2) {
00772 p.fillRect(x+1, y+1, w-2, borderSize-2, frameColor);
00773 if (!maxFull) {
00774 p.fillRect(x+1, y+h-(borderSize-1), w-2, borderSize-2, frameColor);
00775 p.fillRect(x+1, y+borderSize-1, borderSize-1, h-2*(borderSize-1), frameColor);
00776 p.fillRect(x+w-(borderSize), y+borderSize-1, borderSize-1, h-2*(borderSize-1), frameColor);
00777 }
00778 }
00779
00780
00781 p.setPen( g.background() );
00782 if (maxFull) {
00783 p.drawLine(x+1, y+titleHeight+(borderSize-1), w-2, y+titleHeight+(borderSize-1));
00784 } else {
00785 p.drawRect( x+(borderSize-1), y+titleHeight+(borderSize-1), w-2*(borderSize-1), h-titleHeight-2*(borderSize-1) );
00786 }
00787
00788
00789 p.drawLine( x+borderSize, y2-borderSize, x2-borderSize, y2-borderSize);
00790
00791
00792 p.setPen( g.light().light(160) );
00793 p.drawPoint( x, y );
00794 p.setPen( g.light().light(140) );
00795 p.drawPoint( x+1, y );
00796 p.drawPoint( x, y+1 );
00797
00798
00799
00800 r = titlebar->geometry();
00801
00802
00803 QColor c1 = options()->color(ColorTitleBar, isActive() ).light(130);
00804 QColor c2 = options()->color(ColorTitleBlend, isActive() );
00805
00806
00807 KPixmap* titleBuffer = new KPixmap;
00808 titleBuffer->resize( maxFull?w-2:(w-2*(borderSize-1)), titleHeight );
00809
00810 QPainter p2( titleBuffer, this );
00811
00812
00813 int rightoffset = r.x()+r.width()-titleBlocks->width()-borderSize;
00814
00815 p2.fillRect( 0, 0, w, r.height(), c1 );
00816 p2.fillRect( rightoffset, 0, maxFull?w-rightoffset:w-rightoffset-2*(borderSize-1), r.height(), c2 );
00817
00818
00819 if ( isActive() )
00820 p2.drawPixmap( rightoffset, 0, *titleBlocks );
00821 else
00822 p2.drawPixmap( rightoffset, 0, *ititleBlocks );
00823
00824
00825
00826 QFont fnt;
00827 if ( largeButtons ) {
00828 fnt = options()->font(true, false);
00829 } else {
00830 fnt = options()->font(true, true);
00831 fnt.setWeight( QFont::Normal );
00832 }
00833 p2.setFont( fnt );
00834
00835 p2.setPen( options()->color(ColorFont, isActive() ));
00836 p2.drawText(r.x()+4-borderSize, 0, r.width()-3, r.height(),
00837 AlignLeft | AlignVCenter, caption() );
00838 p2.end();
00839
00840 p.drawPixmap( maxFull?1:borderSize-1, borderSize-1, *titleBuffer );
00841
00842 delete titleBuffer;
00843 }
00844
00845
00846 void QuartzClient::showEvent(QShowEvent *)
00847 {
00848 calcHiddenButtons();
00849 widget()->show();
00850 }
00851
00852
00853 void QuartzClient::mouseDoubleClickEvent( QMouseEvent * e )
00854 {
00855 if (titlebar->geometry().contains( e->pos() ) )
00856 titlebarDblClickOperation();
00857 }
00858
00859
00860 void QuartzClient::maximizeChange()
00861 {
00862 if (button[BtnMax]) {
00863 button[BtnMax]->setBitmap((maximizeMode()==MaximizeFull) ? minmax_bits : maximize_bits);
00864 button[BtnMax]->setTipText((maximizeMode()==MaximizeFull) ? i18n("Restore") : i18n("Maximize"));
00865 }
00866 }
00867
00868
00869 void QuartzClient::activeChange()
00870 {
00871 for(int i=QuartzClient::BtnHelp; i < QuartzClient::BtnCount; i++)
00872 if(button[i])
00873 button[i]->repaint(false);
00874
00875 widget()->repaint(false);
00876 }
00877
00878
00879 QuartzClient::Position QuartzClient::mousePosition(const QPoint &point) const
00880 {
00881 const int corner = 3*borderSize/2 + 18;
00882 Position pos = PositionCenter;
00883
00884 QRect r(widget()->rect());
00885
00886 if(point.y() < (borderSize-1)) {
00887 if(point.x() < corner) return PositionTopLeft;
00888 else if(point.x() > (r.right()-corner)) return PositionTopRight;
00889 else return PositionTop;
00890 } else if(point.y() > (r.bottom()-borderSize)) {
00891 if(point.x() < corner) return PositionBottomLeft;
00892 else if(point.x() > (r.right()-corner)) return PositionBottomRight;
00893 else return PositionBottom;
00894 } else if(point.x() < borderSize) {
00895 if(point.y() < corner) return PositionTopLeft;
00896 else if(point.y() > (r.bottom()-corner)) return PositionBottomLeft;
00897 else return PositionLeft;
00898 } else if(point.x() > (r.right()-borderSize)) {
00899 if(point.y() < corner) return PositionTopRight;
00900 else if(point.y() > (r.bottom()-corner)) return PositionBottomRight;
00901 else return PositionRight;
00902 }
00903
00904 return pos;
00905 }
00906
00907
00908 void QuartzClient::borders(int& left, int& right, int& top, int& bottom) const
00909 {
00910 left = borderSize;
00911 right = borderSize;
00912 top = 1 + titleHeight + (borderSize-1);
00913 bottom = borderSize;
00914
00915 if ((maximizeMode()==MaximizeFull) && !options()->moveResizeMaximizedWindows()) {
00916 left = right = bottom = 0;
00917 top = 1 + titleHeight + (borderSize-1);
00918 }
00919 }
00920
00921
00922 void QuartzClient::resize( const QSize& s )
00923 {
00924 widget()->resize( s );
00925 }
00926
00927
00928 QSize QuartzClient::minimumSize() const
00929 {
00930 return widget()->minimumSize();
00931 }
00932
00933
00934
00935 void QuartzClient::calcHiddenButtons()
00936 {
00937
00938 QuartzButton* btnArray[] = { button[BtnOnAllDesktops], button[BtnHelp], button[BtnMax],
00939 button[BtnMenu], button[BtnIconify], button[BtnClose] };
00940
00941 int minwidth = largeButtons ? 180 : 140;
00942 int btn_width = largeButtons ? 16 : 10;
00943 int current_width = width();
00944 int count = 0;
00945 int i;
00946
00947
00948 while (current_width < minwidth)
00949 {
00950 current_width += btn_width;
00951 count++;
00952 }
00953
00954
00955 if (count > 6) count = 6;
00956
00957
00958 for(i = 0; i < count; i++)
00959 {
00960 if (btnArray[i] && btnArray[i]->isVisible() )
00961 btnArray[i]->hide();
00962 }
00963
00964
00965 for(i = count; i < 6; i++)
00966 {
00967 if (btnArray[i] && (!btnArray[i]->isVisible()) )
00968 btnArray[i]->show();
00969 }
00970 }
00971
00972
00973
00974 void QuartzClient::menuButtonPressed()
00975 {
00976 QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
00977 button[BtnMenu]->rect().bottomLeft().y()+2 );
00978 menupoint = button[BtnMenu]->mapToGlobal( menupoint );
00979 KDecorationFactory* f = factory();
00980 showWindowMenu(menupoint);
00981 if( !f->exists( this ))
00982 return;
00983 button[BtnMenu]->setDown(false);
00984 }
00985
00986 bool QuartzClient::eventFilter( QObject* o, QEvent* e )
00987 {
00988 if( o != widget())
00989 return false;
00990 switch( e->type())
00991 {
00992 case QEvent::Resize:
00993 resizeEvent(static_cast< QResizeEvent* >( e ) );
00994 return true;
00995 case QEvent::Paint:
00996 paintEvent(static_cast< QPaintEvent* >( e ) );
00997 return true;
00998 case QEvent::MouseButtonDblClick:
00999 mouseDoubleClickEvent(static_cast< QMouseEvent* >( e ) );
01000 return true;
01001 case QEvent::MouseButtonPress:
01002 processMousePressEvent(static_cast< QMouseEvent* >( e ) );
01003 return true;
01004 default:
01005 break;
01006 }
01007 return false;
01008 }
01009
01010 }
01011
01012
01014 extern "C"
01015 {
01016 KDecorationFactory *create_factory()
01017 {
01018 Quartz::clientHandler = new Quartz::QuartzHandler();
01019 return Quartz::clientHandler;
01020 }
01021 }
01022
01023
01024
01025 #include "quartz.moc"
01026