00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "redmond.h"
00016
00017
#include <qlayout.h>
00018
#include <qdrawutil.h>
00019
#include <qdatetime.h>
00020
#include <kpixmapeffect.h>
00021
#include <kimageeffect.h>
00022
#include <kdrawutil.h>
00023
#include <klocale.h>
00024
00025
#include <qbitmap.h>
00026
#include <qtooltip.h>
00027
#include <qimage.h>
00028
#include <qlabel.h>
00029
#include <qapplication.h>
00030
00031
namespace Redmond {
00032
00033
static const char *kdelogo[] = {
00034
00035
"16 16 8 1",
00036
" c None",
00037
". c #000000",
00038
"+ c #A0A0A4",
00039
"@ c #FFFFFF",
00040
"# c #585858",
00041
"$ c #C0C0C0",
00042
"% c #808080",
00043
"& c #DCDCDC",
00044
" ",
00045
" .. .. ",
00046
" .+@. .@#. ",
00047
" .@@@. .@@@# ",
00048
" .@@@..$@@$. ",
00049
" .@@@.@@@$. ",
00050
" .@@@%@@$. ",
00051
" .@@@&@@. ",
00052
" .@@@@@@. ",
00053
" .@@@$@@&. ",
00054
" .@@@.@@@. ",
00055
" .@@@.+@@@. ",
00056
" .@@@..$@@&. ",
00057
" .@@%. .@@@. ",
00058
" .... ... ",
00059
" "};
00060
00061
static unsigned char iconify_bits[] = {
00062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00063 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00};
00064
00065
static unsigned char close_bits[] = {
00066 0x00, 0x00, 0x86, 0x01, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x78, 0x00,
00067 0xcc, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00};
00068
00069
static unsigned char maximize_bits[] = {
00070 0xff, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00071 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x00, 0x00};
00072
00073
static unsigned char minmax_bits[] = {
00074 0xfc, 0x00, 0xfc, 0x00, 0x84, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xe1, 0x00,
00075 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x00, 0x00};
00076
00077
static unsigned char question_bits[] = {
00078 0x00, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
00079 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00};
00080
00081
00082
00083
static KPixmap *btnPix1;
00084
static KPixmap *iBtnPix1;
00085
static KPixmap *btnDownPix1;
00086
static KPixmap *iBtnDownPix1;
00087
00088
static KPixmap *miniBtnPix1;
00089
static KPixmap *iMiniBtnPix1;
00090
static KPixmap *miniBtnDownPix1;
00091
static KPixmap *iMiniBtnDownPix1;
00092
00093
static QPixmap *defaultMenuPix;
00094
static QColor *btnForeground;
00095
static bool pixmaps_created =
false;
00096
00097
static int toolTitleHeight;
00098
static int normalTitleHeight;
00099
static int borderWidth;
00100
00101
static inline const KDecorationOptions *options()
00102 {
00103
return KDecoration::options();
00104 }
00105
00106
static void drawButtonFrame( KPixmap *pix,
const QColorGroup &g,
bool sunken )
00107 {
00108 QPainter p;
00109
int x2 = pix->width() - 1;
00110
int y2 = pix->height() - 1;
00111 p.begin(pix);
00112
00113
00114 p.setPen( sunken ? g.dark().dark(155) : g.light());
00115 p.drawLine(0, 0, x2-1, 0);
00116 p.drawLine(0, 0, 0, y2-1);
00117
00118
if (sunken)
00119 {
00120 p.setPen( g.mid().dark(135) );
00121 p.drawLine(1, 1, x2-2, 1);
00122 p.drawLine(1, 1, 1, y2-2);
00123 }
00124
00125 p.setPen( sunken ? g.light() : g.mid().dark(135));
00126 p.drawLine(1, y2-1, x2-1, y2-1);
00127 p.drawLine(x2-1, 1, x2-1, y2-1);
00128
00129 p.setPen( sunken ? g.light() : g.dark().dark(155));
00130 p.drawLine(0, y2, x2, y2);
00131 p.drawLine(x2, 0, x2, y2);
00132 }
00133
00134
00135
static void create_pixmaps ()
00136 {
00137
if (pixmaps_created)
00138
return;
00139
00140 pixmaps_created =
true;
00141
00142
bool highcolor = QPixmap::defaultDepth() > 8;
00143
00144 btnPix1 =
new KPixmap;
00145 btnDownPix1 =
new KPixmap;
00146 iBtnPix1 =
new KPixmap;
00147 iBtnDownPix1 =
new KPixmap;
00148 miniBtnPix1 =
new KPixmap;
00149 miniBtnDownPix1 =
new KPixmap;
00150 iMiniBtnPix1 =
new KPixmap;
00151 iMiniBtnDownPix1 =
new KPixmap;
00152 defaultMenuPix =
new QPixmap(kdelogo);
00153
00154
00155 QColorGroup g = options()->colorGroup(KDecoration::ColorButtonBg,
true);
00156 QColor c = g.background();
00157 btnPix1->resize(normalTitleHeight, normalTitleHeight-2);
00158 btnDownPix1->resize(normalTitleHeight, normalTitleHeight-2);
00159 iBtnPix1->resize(normalTitleHeight, normalTitleHeight-2);
00160 iBtnDownPix1->resize(normalTitleHeight, normalTitleHeight-2);
00161
00162 miniBtnPix1->resize(toolTitleHeight, toolTitleHeight);
00163 miniBtnDownPix1->resize(toolTitleHeight, toolTitleHeight);
00164 iMiniBtnPix1->resize(toolTitleHeight, toolTitleHeight);
00165 iMiniBtnDownPix1->resize(toolTitleHeight, toolTitleHeight);
00166
00167
if (highcolor &&
false) {
00168 KPixmapEffect::gradient(*btnPix1, c.light(130), c.dark(130),
00169 KPixmapEffect::VerticalGradient);
00170 KPixmapEffect::gradient(*btnDownPix1, c.dark(130), c.light(130),
00171 KPixmapEffect::VerticalGradient);
00172
00173 KPixmapEffect::gradient(*miniBtnPix1, c.light(130), c.dark(130),
00174 KPixmapEffect::VerticalGradient);
00175 KPixmapEffect::gradient(*miniBtnDownPix1, c.dark(130), c.light(130),
00176 KPixmapEffect::VerticalGradient);
00177
00178 g = options()->colorGroup(KDecoration::ColorButtonBg,
false);
00179 c = g.background();
00180 KPixmapEffect::gradient(*iBtnPix1, c.light(130), c.dark(130),
00181 KPixmapEffect::VerticalGradient);
00182 KPixmapEffect::gradient(*iBtnDownPix1, c.dark(130), c.light(130),
00183 KPixmapEffect::VerticalGradient);
00184 KPixmapEffect::gradient(*iMiniBtnPix1, c.light(130), c.dark(130),
00185 KPixmapEffect::VerticalGradient);
00186 KPixmapEffect::gradient(*iMiniBtnDownPix1, c.dark(130), c.light(130),
00187 KPixmapEffect::VerticalGradient);
00188 }
else {
00189 btnPix1->fill(c.rgb());
00190 btnDownPix1->fill(c.rgb());
00191 miniBtnPix1->fill(c.rgb());
00192 miniBtnDownPix1->fill(c.rgb());
00193
00194 g = options()->colorGroup(KDecoration::ColorButtonBg,
false);
00195 c = g.background();
00196 iBtnPix1->fill(c.rgb());
00197 iBtnDownPix1->fill(c.rgb());
00198 iMiniBtnPix1->fill(c.rgb());
00199 iMiniBtnDownPix1->fill(c.rgb());
00200 }
00201
00202 g = options()->colorGroup(KDecoration::ColorButtonBg,
true);
00203 drawButtonFrame(btnPix1, g,
false);
00204 drawButtonFrame(btnDownPix1, g,
true);
00205 drawButtonFrame(miniBtnPix1, g,
false);
00206 drawButtonFrame(miniBtnDownPix1, g,
true);
00207
00208 g = options()->colorGroup(KDecoration::ColorButtonBg,
false);
00209 drawButtonFrame(iBtnPix1, g,
false);
00210 drawButtonFrame(iBtnDownPix1, g,
true);
00211 drawButtonFrame(iMiniBtnPix1, g,
false);
00212 drawButtonFrame(iMiniBtnDownPix1, g,
true);
00213
00214
00215
if (qGray(options()->color(KDecoration::ColorButtonBg,
true).rgb()) > 127)
00216 btnForeground =
new QColor(Qt::black);
00217
else
00218 btnForeground =
new QColor(Qt::white);
00219 }
00220
00221
void delete_pixmaps()
00222 {
00223
delete btnPix1;
00224
delete btnDownPix1;
00225
delete iBtnPix1;
00226
delete iBtnDownPix1;
00227
delete miniBtnPix1;
00228
delete miniBtnDownPix1;
00229
delete iMiniBtnPix1;
00230
delete iMiniBtnDownPix1;
00231
delete defaultMenuPix;
00232
delete btnForeground;
00233 pixmaps_created =
false;
00234 }
00235
00236
00237 RedmondButton::RedmondButton(RedmondDeco *parent,
const char *name,
00238
const unsigned char *bitmap,
bool menuButton,
bool isMini,
int size,
const QString& tip,
const int realizeBtns)
00239 : QButton(parent->widget(), name),
00240 last_button( NoButton )
00241 {
00242
00243 setBackgroundMode( NoBackground );
00244 setCursor( arrowCursor );
00245
00246 menuBtn = menuButton;
00247 miniBtn = isMini;
00248 client = parent;
00249 this->size = size;
00250 realizeButtons = realizeBtns;
00251
00252
00253
if ( isMini || menuButton ) {
00254 setFixedSize(size, size);
00255 resize(size, size);
00256 }
else {
00257 setFixedSize(size, size-2);
00258 resize(size, size-2);
00259 }
00260
00261
if ( bitmap ) {
00262 setBitmap(bitmap);
00263 }
00264
00265 QToolTip::add(
this, tip);
00266 }
00267
00268
00269 QSize RedmondButton::sizeHint()
const
00270
{
00271
if ( miniBtn || menuBtn )
00272
return( QSize(size, size) );
00273
else
00274
return( QSize(size, size-2) );
00275 }
00276
00277
00278
void RedmondButton::reset()
00279 {
00280 repaint(
false);
00281 }
00282
00283
00284
void RedmondButton::setBitmap(
const unsigned char *bitmap)
00285 {
00286 pix.resize(0, 0);
00287 deco = QBitmap(10, 10, bitmap,
true);
00288 deco.setMask(deco);
00289 repaint(
false );
00290 }
00291
00292
00293
void RedmondButton::setPixmap(
const QPixmap &p )
00294 {
00295 deco.resize(0, 0);
00296 pix = p;
00297
00298
if (miniBtn || menuBtn)
00299 setMask(QRect(0, 0, size, size));
00300
else
00301 setMask(QRect(0, 0, size, size-2));
00302
00303 repaint(
false);
00304 }
00305
00306
00307
void RedmondButton::mousePressEvent( QMouseEvent* e )
00308 {
00309 last_button = e->button();
00310 QMouseEvent me(e->type(), e->pos(), e->globalPos(),
00311 (e->button()&realizeButtons)?LeftButton:NoButton, e->state());
00312 QButton::mousePressEvent( &me );
00313 }
00314
00315
00316
void RedmondButton::mouseReleaseEvent( QMouseEvent* e )
00317 {
00318 last_button = e->button();
00319 QMouseEvent me ( e->type(), e->pos(), e->globalPos(),
00320 (e->button()&realizeButtons)?LeftButton:NoButton, e->state() );
00321 QButton::mouseReleaseEvent( &me );
00322 }
00323
00324
00325
void RedmondButton::drawButton(QPainter *p)
00326 {
00327
if ( pix.isNull() ) {
00328
if ( client->isActive() ) {
00329
if ( isDown() )
00330 p->drawPixmap(0, 0, miniBtn ? *miniBtnDownPix1 : *btnDownPix1);
00331
else
00332 p->drawPixmap(0, 0, miniBtn ? *miniBtnPix1 : *btnPix1);
00333 }
else {
00334
if ( isDown() )
00335 p->drawPixmap(0, 0, miniBtn ? *iMiniBtnDownPix1 : *iBtnDownPix1);
00336
else
00337 p->drawPixmap(0, 0, miniBtn ? *iMiniBtnPix1 : *iBtnPix1);
00338 }
00339
00340 p->setPen( *btnForeground );
00341
int xOff = (width()-10)/2;
00342
int yOff = (height()-10)/2;
00343 p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, deco);
00344 }
else {
00345 p->fillRect(0, 0, width(), height(),
00346 options()->color(KDecoration::ColorTitleBar, client->isActive()));
00347
00348
if ( menuBtn && size < 16) {
00349 QPixmap tmpPix;
00350
00351
00352 tmpPix.convertFromImage(
00353 pix.convertToImage().smoothScale(size, size));
00354
00355 p->drawPixmap( 0, 0, tmpPix );
00356 }
else {
00357
int xOff = (width() -pix.width() )/2;
00358
int yOff = (height()-pix.height())/2;
00359 p->drawPixmap(xOff, yOff, pix );
00360 }
00361 }
00362 }
00363
00364
00365 RedmondDeco::RedmondDeco(KDecorationBridge *b, KDecorationFactory *f)
00366 :
KDecoration(b, f)
00367 {
00368 }
00369
00370
void RedmondDeco::init()
00371 {
00372 createMainWidget(WResizeNoErase);
00373 widget()->installEventFilter(
this);
00374
00375 widget()->setBackgroundMode(NoBackground);
00376
00377
00378
00379
00380
00381
00382
00383 titleHeight = normalTitleHeight+2;
00384 smallButtons =
false;
00385
00386
00387 lastButtonWidth = 0;
00388
00389 QGridLayout* g =
new QGridLayout(widget(), 0, 0, 0);
00390 g->setResizeMode(QLayout::FreeResize);
00391
if (isPreview()) {
00392 g->addWidget(
new QLabel(i18n(
"<center><b>Redmond preview</b></center>"), widget()), 3, 1);
00393 }
else {
00394 g->addItem(
new QSpacerItem( 0, 0 ), 3, 1);
00395 }
00396
00397 g->addRowSpacing(0, borderWidth);
00398
00399 g->addItem(
new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding));
00400 g->setRowStretch(3, 10);
00401 g->addRowSpacing(4, borderWidth);
00402 g->addRowSpacing(2, 1);
00403 g->addColSpacing(0, borderWidth);
00404 g->addColSpacing(2, borderWidth);
00405
00406 button[BtnMenu] =
new RedmondButton(
this,
"menu", NULL,
true, smallButtons, titleHeight-2, i18n(
"Menu"), LeftButton|RightButton);
00407 button[BtnClose] =
new RedmondButton(
this,
"close", close_bits,
false, smallButtons, titleHeight-2, i18n(
"Close"));
00408 button[BtnMin] =
new RedmondButton(
this,
"iconify", iconify_bits,
false, smallButtons, titleHeight-2, i18n(
"Minimize"));
00409 button[BtnMax] =
new RedmondButton(
this,
"maximize", maximize_bits,
false, smallButtons, titleHeight-2, i18n(
"Maximize"), LeftButton|MidButton|RightButton);
00410
00411
00412 connect(button[BtnMenu], SIGNAL(pressed()),
this, SLOT(menuButtonPressed()));
00413 connect(button[BtnClose], SIGNAL(clicked()),
this, SLOT(
closeWindow()));
00414 connect(button[BtnMin], SIGNAL(clicked()),
this, SLOT(
minimize()));
00415 connect(button[BtnMax], SIGNAL(clicked()),
this, SLOT(slotMaximize()));
00416
00417
00418 hb =
new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
00419 hb->setResizeMode(QLayout::FreeResize);
00420 hb->addSpacing(2);
00421 hb->addWidget(button[BtnMenu]);
00422 titlebar =
new QSpacerItem(10, titleHeight, QSizePolicy::Expanding, QSizePolicy::Minimum);
00423 hb->addItem(titlebar);
00424 hb->addSpacing(borderWidth/2);
00425
00426
if (
providesContextHelp() ) {
00427 button[BtnHelp] =
new RedmondButton(
this,
"help", question_bits,
false, smallButtons, titleHeight-2, i18n(
"Help"));
00428 connect( button[BtnHelp], SIGNAL( clicked() ),
this, SLOT(
showContextHelp() ));
00429 hb->addWidget( button[BtnHelp] );
00430 }
else {
00431 button[BtnHelp] = NULL;
00432 }
00433
00434 hb->addWidget(button[BtnMin]);
00435 hb->addWidget(button[BtnMax]);
00436 hb->addSpacing(borderWidth/2);
00437 hb->addWidget(button[BtnClose]);
00438 hb->addSpacing(2);
00439
00440 g->addLayout(hb, 1, 1);
00441
00442
00443
00444
if (!isMinimizable())
00445 button[BtnMin]->hide();
00446
if (!isMaximizable())
00447 button[BtnMax]->hide();
00448
if (!isCloseable())
00449 button[BtnClose]->hide();
00450
00451 hiddenItems =
false;
00452
00453
00454 iconChange();
00455 widget()->layout()->activate();
00456 }
00457
00458
00459
void RedmondDeco::slotReset()
00460 {
00461
00462
for(
int i = RedmondDeco::BtnHelp; i <= RedmondDeco::BtnClose; i++)
00463
if (button[i])
00464 button[i]->reset();
00465
00466
00467
00468 widget()->repaint(
false );
00469 }
00470
00471
00472
void RedmondDeco::iconChange()
00473 {
00474 QPixmap miniIcon = icon().pixmap(QIconSet::Small, QIconSet::Normal);
00475
00476
if (!miniIcon.isNull())
00477 button[BtnMenu]->setPixmap(miniIcon);
00478
else
00479 button[BtnMenu]->setPixmap(*defaultMenuPix);
00480
00481
if (button[BtnMenu]->isVisible())
00482 button[BtnMenu]->repaint(
false);
00483 }
00484
00485
00486
void RedmondDeco::slotMaximize()
00487 {
00488
if (button[BtnMax]) {
00489 maximize(button[BtnMax]->last_button);
00490 }
00491 }
00492
00493
00494
void RedmondDeco::resizeEvent(QResizeEvent *)
00495 {
00496 calcHiddenButtons();
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 }
00523
00524
00525
void RedmondDeco::captionChange(
const QString& )
00526 {
00527 widget()->repaint( titlebar->geometry(),
false );
00528 }
00529
00530
00531
void RedmondDeco::paintEvent( QPaintEvent* )
00532 {
00533
bool hicolor = QPixmap::defaultDepth() > 8;
00534
int fontoffset = 1;
00535
00536 QPainter p(widget());
00537
00538
00539 QRect r(widget()->rect());
00540
int x = r.x();
00541
int y = r.y();
00542
int x2 = r.width()-1;
00543
int y2 = r.height()-1;
00544
int w = r.width();
00545
int h = r.height();
00546
00547
00548
00549 QColorGroup g = options()->colorGroup(KDecoration::ColorFrame, isActive());
00550 p.setPen( g.background() );
00551 p.drawLine( x, y, x2-1, y );
00552 p.drawLine( x, y, x, y2-1 );
00553
00554
00555 p.drawLine( x+borderWidth, y+titleHeight+borderWidth, x2-borderWidth, y+titleHeight+borderWidth );
00556
00557 p.drawLine( x+borderWidth, y2-borderWidth, x2-borderWidth, y2-borderWidth );
00558
00559
00560
for (
int i = 1; i < borderWidth; i++)
00561 p.drawRect( x+i, y+i, w-2*i, h-2*i );
00562
00563
00564 p.setPen(g.light());
00565
for (
int i = 1; i <= borderWidth/3; i++) {
00566 p.drawLine( x+i, y+i, x2-i-1, y+i);
00567 p.drawLine( x+i, y+i, x+i, y2-i-1);
00568 }
00569
00570 p.setPen(g.mid().dark(135));
00571
for (
int i = 1; i <= borderWidth/3; i++) {
00572 p.drawLine( x2-i, y+i+1, x2-i, y2-i);
00573 p.drawLine( x+i+1, y2-i, x2-i, y2-i);
00574 }
00575
00576
00577 p.setPen( g.dark().dark(155) );
00578 p.drawLine(x2, y, x2, y2);
00579 p.drawLine(x, y2, x2, y2);
00580
00581
00582
00583 r = titlebar->geometry();
00584 QFontMetrics fm(options()->font(
true));
00585
00586
00587 QColor c1 = options()->color(KDecoration::ColorTitleBar, isActive() );
00588 QColor c2 = options()->color(KDecoration::ColorTitleBlend, isActive() );
00589
00590
00591
00592
if ((c1 != c2) && hicolor) {
00593
00594
00595
00596 KPixmap* titleBuffer =
new KPixmap;
00597 titleBuffer->resize(w-2*borderWidth, titleHeight);
00598
00599
if (titleBuffer->depth() > 16) {
00600 KPixmapEffect::gradient(*titleBuffer, c1, c2,
00601 KPixmapEffect::HorizontalGradient);
00602 }
else {
00603
00604
00605 QImage image = KImageEffect::gradient(titleBuffer->size(), c1, c2,
00606 KImageEffect::HorizontalGradient);
00607
00608 titleBuffer->convertFromImage(image, Qt::OrderedDither);
00609 }
00610
00611 QPainter p2( titleBuffer,
this );
00612
00613
00614
00615
00616
00617 QFont fnt = options()->font(
true);
00618
if ( smallButtons ) {
00619 fnt.setPointSize( fnt.pointSize() - 2 );
00620 fnt.setWeight( QFont::Normal );
00621 fontoffset = 0;
00622 }
00623 p2.setFont( fnt );
00624 p2.setPen( options()->color(KDecoration::ColorFont, isActive() ));
00625 p2.drawText( r.x(), fontoffset, r.width()-3, r.height()-1,
00626 AlignLeft | AlignVCenter,
caption() );
00627 p2.end();
00628
00629 p.drawPixmap( borderWidth, borderWidth, *titleBuffer );
00630
00631
delete titleBuffer;
00632
00633 }
else {
00634
00635
00636 p.fillRect( borderWidth, borderWidth, w-2*borderWidth, titleHeight, c1 );
00637
00638
00639 QFont fnt = options()->font(
true);
00640
if ( smallButtons )
00641 {
00642 fnt.setPointSize( fnt.pointSize() - 2 );
00643 fnt.setWeight( QFont::Normal );
00644 fontoffset = 0;
00645 }
00646 p.setFont( fnt );
00647 p.setPen(options()->color(KDecoration::ColorFont, isActive() ));
00648 p.drawText(r.x()+4, r.y()+fontoffset, r.width()-3, r.height()-1,
00649 AlignLeft | AlignVCenter,
caption() );
00650 }
00651
00652 }
00653
00654
void RedmondDeco::showEvent(QShowEvent *)
00655 {
00656 calcHiddenButtons();
00657 widget()->show();
00658 }
00659
00660
00661
void RedmondDeco::mouseDoubleClickEvent( QMouseEvent * e )
00662 {
00663
if (titlebar->geometry().contains( e->pos() ) )
00664 titlebarDblClickOperation();
00665 }
00666
00667
00668
void RedmondDeco::maximizeChange(
bool m)
00669 {
00670 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
00671 }
00672
00673
void RedmondDeco::calcHiddenButtons()
00674 {
00675
00676
int minWidth = (2 + 4 + (
providesContextHelp() ? 2 : 1 )) * normalTitleHeight;
00677
00678
if (lastButtonWidth > width()) {
00679 lastButtonWidth = width();
00680
if (width() < minWidth) {
00681 hiddenItems =
true;
00682
00683
for(
int i = RedmondDeco::BtnHelp; i <= RedmondDeco::BtnMenu; i++) {
00684
if (button[i]) {
00685
if ( !button[i]->isHidden() ) {
00686 button[i]->hide();
00687 }
00688 minWidth -= button[i]->sizeHint().width();
00689
if (width() >= minWidth) {
00690
return;
00691 }
00692 }
00693 }
00694 }
00695 }
else {
00696
if ( hiddenItems ) {
00697 lastButtonWidth = width();
00698
int totalSize = normalTitleHeight*3;
00699
00700
for (
int i = RedmondDeco::BtnMenu; i >= RedmondDeco::BtnHelp; i--) {
00701
if (button[i]) {
00702
if (button[i]->sizeHint().width() + totalSize <= width()) {
00703 totalSize += button[i]->sizeHint().width();
00704 button[i]->resize(button[i]->sizeHint());
00705 button[i]->show();
00706 }
else {
00707
return;
00708 }
00709 }
00710 }
00711
00712
00713 hiddenItems =
false;
00714 }
else {
00715 lastButtonWidth = width();
00716 }
00717 }
00718 }
00719
00720 RedmondDeco::Position RedmondDeco::mousePosition(
const QPoint &p)
const
00721
{
00722
Position m = PositionCenter;
00723
00724
const int range = 14 + 3*borderWidth/2;
00725
00726
if ( ( p.x() > borderWidth && p.x() < width() - borderWidth )
00727 && ( p.y() > borderWidth && p.y() < height() - borderWidth ) )
00728 m = PositionCenter;
00729
else if ( p.y() <= range && p.x() <= range)
00730 m = PositionTopLeft;
00731
else if ( p.y() >= height()-range && p.x() >= width()-range)
00732 m = PositionBottomRight;
00733
else if ( p.y() >= height()-range && p.x() <= range)
00734 m = PositionBottomLeft;
00735
else if ( p.y() <= range && p.x() >= width()-range)
00736 m = PositionTopRight;
00737
else if ( p.y() <= borderWidth )
00738 m = PositionTop;
00739
else if ( p.y() >= height()-borderWidth )
00740 m = PositionBottom;
00741
else if ( p.x() <= borderWidth )
00742 m = PositionLeft;
00743
else if ( p.x() >= width()-borderWidth )
00744 m = PositionRight;
00745
else
00746 m = PositionCenter;
00747
00748
return m;
00749 }
00750
00751
void RedmondDeco::borders(
int &l,
int &r,
int &t,
int &b)
const
00752
{
00753
00754 l = borderWidth;
00755 r = borderWidth;
00756 t = borderWidth + titlebar->geometry().height() + 1;
00757 b = borderWidth;
00758 }
00759
00760
void RedmondDeco::resize(
const QSize &s)
00761 {
00762 widget()->resize(s);
00763 }
00764
00765 QSize RedmondDeco::minimumSize()
const
00766
{
00767
return QSize(50, 50);
00768 }
00769
00770
void RedmondDeco::activeChange()
00771 {
00772 QPixmap miniIcon = icon().pixmap(QIconSet::Small, QIconSet::Normal);
00773
if (!miniIcon.isNull()) {
00774 button[BtnMenu]->setPixmap(miniIcon);
00775 }
else {
00776 button[BtnMenu]->setPixmap(kdelogo);
00777 }
00778
00779
00780
for (
int i = BtnHelp; i < BtnCount; i++) {
00781
if (button[i]) button[i]->reset();
00782 }
00783
00784 widget()->repaint(
false);
00785 }
00786
00787
void RedmondDeco::captionChange()
00788 {
00789 widget()->repaint(titlebar->geometry(),
false);
00790 }
00791
00792
void RedmondDeco::maximizeChange()
00793 {
00794
bool m = (maximizeMode() ==
MaximizeFull);
00795 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
00796 QToolTip::remove(button[BtnMax]);
00797 QToolTip::add(button[BtnMax], m ? i18n(
"Restore") : i18n(
"Maximize"));
00798 }
00799
00800
void RedmondDeco::desktopChange()
00801 {
00802 }
00803
00804
void RedmondDeco::shadeChange()
00805 {
00806 }
00807
00808
void RedmondDeco::menuButtonPressed()
00809 {
00810
static QTime* t = NULL;
00811
static RedmondDeco* lastClient = NULL;
00812
if (t == NULL) t =
new QTime;
00813
bool dbl = ( lastClient ==
this && t->elapsed() <= QApplication::doubleClickInterval());
00814 lastClient =
this;
00815 t->start();
00816
if (!dbl) {
00817 QRect menuRect = button[BtnMenu]->rect();
00818 QPoint menuTop = QPoint(menuRect.topLeft().x()-3,
00819 menuRect.topLeft().y());
00820 QPoint menuBottom = QPoint(menuRect.bottomRight().x()+3,
00821 menuRect.bottomRight().y()+4);
00822 KDecorationFactory* f = factory();
00823 showWindowMenu(QRect(button[BtnMenu]->mapToGlobal(menuTop),
00824 button[BtnMenu]->mapToGlobal(menuBottom)));
00825
if( !f->exists(
this ))
00826
return;
00827 button[BtnMenu]->setDown(
false);
00828 }
else {
00829
closeWindow();
00830 }
00831 }
00832
00833
bool RedmondDeco::eventFilter(QObject *o, QEvent *e)
00834 {
00835
if (o != widget()) {
return false; }
00836
switch (e->type()) {
00837
case QEvent::Resize: {
00838 resizeEvent(static_cast<QResizeEvent *>(e));
00839
return true;
00840 }
00841
case QEvent::Paint: {
00842 paintEvent(static_cast<QPaintEvent *>(e));
00843
return true;
00844 }
00845
case QEvent::Show: {
00846 showEvent(static_cast<QShowEvent *>(e));
00847
return true;
00848 }
00849
case QEvent::MouseButtonDblClick: {
00850 mouseDoubleClickEvent(static_cast<QMouseEvent *>(e));
00851
return true;
00852 }
00853
case QEvent::MouseButtonPress: {
00854 processMousePressEvent(static_cast<QMouseEvent *>(e));
00855
return true;
00856 }
00857
default: {
00858
break;
00859 }
00860 }
00861
00862
return false;
00863 }
00864
00865
void RedmondDecoFactory::readConfig() {
00866 normalTitleHeight = QFontMetrics(options()->font(
true)).height();
00867 toolTitleHeight = QFontMetrics(options()->font(
true,
true)).height();
00868
switch(options()->preferredBorderSize(
this)) {
00869
case BorderLarge:
00870 borderWidth = 8;
00871
if (normalTitleHeight < 20) normalTitleHeight = 20;
00872
if (toolTitleHeight < 20) toolTitleHeight = 20;
00873
break;
00874
case BorderVeryLarge:
00875 borderWidth = 12;
00876
if (normalTitleHeight < 24) normalTitleHeight = 24;
00877
if (toolTitleHeight < 24) toolTitleHeight = 24;
00878
break;
00879
case BorderHuge:
00880 borderWidth = 18;
00881
if (normalTitleHeight < 28) normalTitleHeight = 28;
00882
if (toolTitleHeight < 28) toolTitleHeight = 28;
00883
break;
00884
case BorderVeryHuge:
00885 borderWidth = 27;
00886
if (normalTitleHeight < 33) normalTitleHeight = 33;
00887
if (toolTitleHeight < 33) toolTitleHeight = 33;
00888
break;
00889
case BorderOversized:
00890 borderWidth = 40;
00891
if (normalTitleHeight < 40) normalTitleHeight = 40;
00892
if (toolTitleHeight < 40) toolTitleHeight = 40;
00893
break;
00894
case BorderTiny:
00895
case BorderNormal:
00896
default:
00897 borderWidth = 4;
00898
if (normalTitleHeight < 16) normalTitleHeight = 16;
00899
if (toolTitleHeight < 16) toolTitleHeight = 16;
00900 }
00901 }
00902
00903 RedmondDecoFactory::RedmondDecoFactory()
00904 {
00905 readConfig();
00906 create_pixmaps();
00907 }
00908
00909 RedmondDecoFactory::~RedmondDecoFactory()
00910 {
00911 Redmond::delete_pixmaps();
00912 }
00913
00914
KDecoration *RedmondDecoFactory::createDecoration( KDecorationBridge *b )
00915 {
00916
return new RedmondDeco(b,
this);
00917 }
00918
00919
bool RedmondDecoFactory::reset(
unsigned long changed )
00920 {
00921
if ( changed & (
SettingFont |
SettingBorder |
SettingColors ) ) {
00922 delete_pixmaps();
00923 readConfig();
00924 create_pixmaps();
00925 resetDecorations(changed);
00926
return true;
00927 }
else {
00928 resetDecorations(changed);
00929
return false;
00930 }
00931 }
00932
00933 QValueList< RedmondDecoFactory::BorderSize > RedmondDecoFactory::borderSizes()
const
00934
{
00935
return QValueList< BorderSize >() <<
BorderNormal <<
BorderLarge <<
00936
BorderVeryLarge <<
BorderHuge <<
BorderVeryHuge <<
BorderOversized;
00937 }
00938
00939 }
00940
00941
extern "C" KDecorationFactory *create_factory()
00942 {
00943
return new Redmond::RedmondDecoFactory();
00944 }
00945
00946
00947
#include "redmond.moc"
00948