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