00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "redmond.h"
00017
00018 #include <qlayout.h>
00019 #include <qdrawutil.h>
00020 #include <qdatetime.h>
00021 #include <kpixmapeffect.h>
00022 #include <kimageeffect.h>
00023 #include <kdrawutil.h>
00024 #include <klocale.h>
00025
00026 #include <qbitmap.h>
00027 #include <qtooltip.h>
00028 #include <qimage.h>
00029 #include <qlabel.h>
00030 #include <qapplication.h>
00031
00032 namespace Redmond {
00033
00034 static const char *kdelogo[] = {
00035
00036 "16 16 8 1",
00037 " c None",
00038 ". c #000000",
00039 "+ c #A0A0A4",
00040 "@ c #FFFFFF",
00041 "# c #585858",
00042 "$ c #C0C0C0",
00043 "% c #808080",
00044 "& c #DCDCDC",
00045 " ",
00046 " .. .. ",
00047 " .+@. .@#. ",
00048 " .@@@. .@@@# ",
00049 " .@@@..$@@$. ",
00050 " .@@@.@@@$. ",
00051 " .@@@%@@$. ",
00052 " .@@@&@@. ",
00053 " .@@@@@@. ",
00054 " .@@@$@@&. ",
00055 " .@@@.@@@. ",
00056 " .@@@.+@@@. ",
00057 " .@@@..$@@&. ",
00058 " .@@%. .@@@. ",
00059 " .... ... ",
00060 " "};
00061
00062 static unsigned char iconify_bits[] = {
00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00064 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00};
00065
00066 static unsigned char close_bits[] = {
00067 0x00, 0x00, 0x86, 0x01, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x78, 0x00,
00068 0xcc, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00};
00069
00070 static unsigned char maximize_bits[] = {
00071 0xff, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00072 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x00, 0x00};
00073
00074 static unsigned char minmax_bits[] = {
00075 0xfc, 0x00, 0xfc, 0x00, 0x84, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xe1, 0x00,
00076 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x00, 0x00};
00077
00078 static unsigned char question_bits[] = {
00079 0x00, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
00080 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00};
00081
00082
00083
00084 static KPixmap *btnPix1;
00085 static KPixmap *iBtnPix1;
00086 static KPixmap *btnDownPix1;
00087 static KPixmap *iBtnDownPix1;
00088
00089 static KPixmap *miniBtnPix1;
00090 static KPixmap *iMiniBtnPix1;
00091 static KPixmap *miniBtnDownPix1;
00092 static KPixmap *iMiniBtnDownPix1;
00093
00094 static QPixmap *defaultMenuPix;
00095 static QColor *btnForeground;
00096 static bool pixmaps_created = false;
00097
00098 static int toolTitleHeight;
00099 static int normalTitleHeight;
00100 static int borderWidth;
00101
00102 static inline const KDecorationOptions *options()
00103 {
00104 return KDecoration::options();
00105 }
00106
00107 static void drawButtonFrame( KPixmap *pix, const QColorGroup &g, bool sunken )
00108 {
00109 QPainter p;
00110 int x2 = pix->width() - 1;
00111 int y2 = pix->height() - 1;
00112 p.begin(pix);
00113
00114
00115 p.setPen( sunken ? g.dark().dark(155) : g.light());
00116 p.drawLine(0, 0, x2-1, 0);
00117 p.drawLine(0, 0, 0, y2-1);
00118
00119 if (sunken)
00120 {
00121 p.setPen( g.mid().dark(135) );
00122 p.drawLine(1, 1, x2-2, 1);
00123 p.drawLine(1, 1, 1, y2-2);
00124 }
00125
00126 p.setPen( sunken ? g.light() : g.mid().dark(135));
00127 p.drawLine(1, y2-1, x2-1, y2-1);
00128 p.drawLine(x2-1, 1, x2-1, y2-1);
00129
00130 p.setPen( sunken ? g.light() : g.dark().dark(155));
00131 p.drawLine(0, y2, x2, y2);
00132 p.drawLine(x2, 0, x2, y2);
00133 }
00134
00135
00136 static void create_pixmaps ()
00137 {
00138 if (pixmaps_created)
00139 return;
00140
00141 pixmaps_created = true;
00142
00143 bool highcolor = QPixmap::defaultDepth() > 8;
00144
00145 btnPix1 = new KPixmap;
00146 btnDownPix1 = new KPixmap;
00147 iBtnPix1 = new KPixmap;
00148 iBtnDownPix1 = new KPixmap;
00149 miniBtnPix1 = new KPixmap;
00150 miniBtnDownPix1 = new KPixmap;
00151 iMiniBtnPix1 = new KPixmap;
00152 iMiniBtnDownPix1 = new KPixmap;
00153 defaultMenuPix = new QPixmap(kdelogo);
00154
00155
00156 QColorGroup g = options()->colorGroup(KDecoration::ColorButtonBg, true);
00157 QColor c = g.background();
00158 btnPix1->resize(normalTitleHeight, normalTitleHeight-2);
00159 btnDownPix1->resize(normalTitleHeight, normalTitleHeight-2);
00160 iBtnPix1->resize(normalTitleHeight, normalTitleHeight-2);
00161 iBtnDownPix1->resize(normalTitleHeight, normalTitleHeight-2);
00162
00163 miniBtnPix1->resize(toolTitleHeight, toolTitleHeight);
00164 miniBtnDownPix1->resize(toolTitleHeight, toolTitleHeight);
00165 iMiniBtnPix1->resize(toolTitleHeight, toolTitleHeight);
00166 iMiniBtnDownPix1->resize(toolTitleHeight, toolTitleHeight);
00167
00168 if (highcolor && false) {
00169 KPixmapEffect::gradient(*btnPix1, c.light(130), c.dark(130),
00170 KPixmapEffect::VerticalGradient);
00171 KPixmapEffect::gradient(*btnDownPix1, c.dark(130), c.light(130),
00172 KPixmapEffect::VerticalGradient);
00173
00174 KPixmapEffect::gradient(*miniBtnPix1, c.light(130), c.dark(130),
00175 KPixmapEffect::VerticalGradient);
00176 KPixmapEffect::gradient(*miniBtnDownPix1, c.dark(130), c.light(130),
00177 KPixmapEffect::VerticalGradient);
00178
00179 g = options()->colorGroup(KDecoration::ColorButtonBg, false);
00180 c = g.background();
00181 KPixmapEffect::gradient(*iBtnPix1, c.light(130), c.dark(130),
00182 KPixmapEffect::VerticalGradient);
00183 KPixmapEffect::gradient(*iBtnDownPix1, c.dark(130), c.light(130),
00184 KPixmapEffect::VerticalGradient);
00185 KPixmapEffect::gradient(*iMiniBtnPix1, c.light(130), c.dark(130),
00186 KPixmapEffect::VerticalGradient);
00187 KPixmapEffect::gradient(*iMiniBtnDownPix1, c.dark(130), c.light(130),
00188 KPixmapEffect::VerticalGradient);
00189 } else {
00190 btnPix1->fill(c.rgb());
00191 btnDownPix1->fill(c.rgb());
00192 miniBtnPix1->fill(c.rgb());
00193 miniBtnDownPix1->fill(c.rgb());
00194
00195 g = options()->colorGroup(KDecoration::ColorButtonBg, false);
00196 c = g.background();
00197 iBtnPix1->fill(c.rgb());
00198 iBtnDownPix1->fill(c.rgb());
00199 iMiniBtnPix1->fill(c.rgb());
00200 iMiniBtnDownPix1->fill(c.rgb());
00201 }
00202
00203 g = options()->colorGroup(KDecoration::ColorButtonBg, true);
00204 drawButtonFrame(btnPix1, g, false);
00205 drawButtonFrame(btnDownPix1, g, true);
00206 drawButtonFrame(miniBtnPix1, g, false);
00207 drawButtonFrame(miniBtnDownPix1, g, true);
00208
00209 g = options()->colorGroup(KDecoration::ColorButtonBg, false);
00210 drawButtonFrame(iBtnPix1, g, false);
00211 drawButtonFrame(iBtnDownPix1, g, true);
00212 drawButtonFrame(iMiniBtnPix1, g, false);
00213 drawButtonFrame(iMiniBtnDownPix1, g, true);
00214
00215
00216 if (qGray(options()->color(KDecoration::ColorButtonBg, true).rgb()) > 127)
00217 btnForeground = new QColor(Qt::black);
00218 else
00219 btnForeground = new QColor(Qt::white);
00220 }
00221
00222 void delete_pixmaps()
00223 {
00224 delete btnPix1;
00225 delete btnDownPix1;
00226 delete iBtnPix1;
00227 delete iBtnDownPix1;
00228 delete miniBtnPix1;
00229 delete miniBtnDownPix1;
00230 delete iMiniBtnPix1;
00231 delete iMiniBtnDownPix1;
00232 delete defaultMenuPix;
00233 delete btnForeground;
00234 pixmaps_created = false;
00235 }
00236
00237
00238 RedmondButton::RedmondButton(RedmondDeco *parent, const char *name,
00239 const unsigned char *bitmap, bool menuButton, bool isMini, int size, const QString& tip, const int realizeBtns)
00240 : QButton(parent->widget(), name)
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]->last_button == MidButton )
00489 maximize( maximizeMode() ^ MaximizeVertical );
00490 else if ( button[BtnMax]->last_button == RightButton )
00491 maximize( maximizeMode() ^ MaximizeHorizontal );
00492 else
00493 maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );
00494 }
00495
00496
00497 void RedmondDeco::resizeEvent(QResizeEvent *)
00498 {
00499 calcHiddenButtons();
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 }
00526
00527
00528 void RedmondDeco::captionChange( const QString& )
00529 {
00530 widget()->repaint( titlebar->geometry(), false );
00531 }
00532
00533
00534 void RedmondDeco::paintEvent( QPaintEvent* )
00535 {
00536 bool hicolor = QPixmap::defaultDepth() > 8;
00537 int fontoffset = 1;
00538
00539 QPainter p(widget());
00540
00541
00542 QRect r(widget()->rect());
00543 int x = r.x();
00544 int y = r.y();
00545 int x2 = r.width()-1;
00546 int y2 = r.height()-1;
00547 int w = r.width();
00548 int h = r.height();
00549
00550
00551
00552 QColorGroup g = options()->colorGroup(KDecoration::ColorFrame, isActive());
00553 p.setPen( g.background() );
00554 p.drawLine( x, y, x2-1, y );
00555 p.drawLine( x, y, x, y2-1 );
00556
00557
00558 p.drawLine( x+borderWidth, y+titleHeight+borderWidth, x2-borderWidth, y+titleHeight+borderWidth );
00559
00560 p.drawLine( x+borderWidth, y2-borderWidth, x2-borderWidth, y2-borderWidth );
00561
00562
00563 for (int i = 1; i < borderWidth; i++)
00564 p.drawRect( x+i, y+i, w-2*i, h-2*i );
00565
00566
00567 p.setPen(g.light());
00568 for (int i = 1; i <= borderWidth/3; i++) {
00569 p.drawLine( x+i, y+i, x2-i-1, y+i);
00570 p.drawLine( x+i, y+i, x+i, y2-i-1);
00571 }
00572
00573 p.setPen(g.mid().dark(135));
00574 for (int i = 1; i <= borderWidth/3; i++) {
00575 p.drawLine( x2-i, y+i+1, x2-i, y2-i);
00576 p.drawLine( x+i+1, y2-i, x2-i, y2-i);
00577 }
00578
00579
00580 p.setPen( g.dark().dark(155) );
00581 p.drawLine(x2, y, x2, y2);
00582 p.drawLine(x, y2, x2, y2);
00583
00584
00585
00586 r = titlebar->geometry();
00587 QFontMetrics fm(options()->font(true));
00588
00589
00590 QColor c1 = options()->color(KDecoration::ColorTitleBar, isActive() );
00591 QColor c2 = options()->color(KDecoration::ColorTitleBlend, isActive() );
00592
00593
00594
00595 if ((c1 != c2) && hicolor) {
00596
00597
00598
00599 KPixmap* titleBuffer = new KPixmap;
00600 titleBuffer->resize(w-2*borderWidth, titleHeight);
00601
00602 if (titleBuffer->depth() > 16) {
00603 KPixmapEffect::gradient(*titleBuffer, c1, c2,
00604 KPixmapEffect::HorizontalGradient);
00605 } else {
00606
00607
00608 QImage image = KImageEffect::gradient(titleBuffer->size(), c1, c2,
00609 KImageEffect::HorizontalGradient);
00610
00611 titleBuffer->convertFromImage(image, Qt::OrderedDither);
00612 }
00613
00614 QPainter p2( titleBuffer, this );
00615
00616
00617
00618
00619
00620 QFont fnt = options()->font(true);
00621 if ( smallButtons ) {
00622 fnt.setPointSize( fnt.pointSize() - 2 );
00623 fnt.setWeight( QFont::Normal );
00624 fontoffset = 0;
00625 }
00626 p2.setFont( fnt );
00627 p2.setPen( options()->color(KDecoration::ColorFont, isActive() ));
00628 p2.drawText( r.x(), fontoffset, r.width()-3, r.height()-1,
00629 AlignLeft | AlignVCenter, caption() );
00630 p2.end();
00631
00632 p.drawPixmap( borderWidth, borderWidth, *titleBuffer );
00633
00634 delete titleBuffer;
00635
00636 } else {
00637
00638
00639 p.fillRect( borderWidth, borderWidth, w-2*borderWidth, titleHeight, c1 );
00640
00641
00642 QFont fnt = options()->font(true);
00643 if ( smallButtons )
00644 {
00645 fnt.setPointSize( fnt.pointSize() - 2 );
00646 fnt.setWeight( QFont::Normal );
00647 fontoffset = 0;
00648 }
00649 p.setFont( fnt );
00650 p.setPen(options()->color(KDecoration::ColorFont, isActive() ));
00651 p.drawText(r.x()+4, r.y()+fontoffset, r.width()-3, r.height()-1,
00652 AlignLeft | AlignVCenter, caption() );
00653 }
00654
00655 }
00656
00657 void RedmondDeco::showEvent(QShowEvent *)
00658 {
00659 calcHiddenButtons();
00660 widget()->show();
00661 }
00662
00663
00664 void RedmondDeco::mouseDoubleClickEvent( QMouseEvent * e )
00665 {
00666 if (titlebar->geometry().contains( e->pos() ) )
00667 titlebarDblClickOperation();
00668 }
00669
00670
00671 void RedmondDeco::maximizeChange(bool m)
00672 {
00673 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
00674 }
00675
00676 void RedmondDeco::calcHiddenButtons()
00677 {
00678
00679 int minWidth = (2 + 4 + (providesContextHelp() ? 2 : 1 )) * normalTitleHeight;
00680
00681 if (lastButtonWidth > width()) {
00682 lastButtonWidth = width();
00683 if (width() < minWidth) {
00684 hiddenItems = true;
00685
00686 for(int i = RedmondDeco::BtnHelp; i <= RedmondDeco::BtnMenu; i++) {
00687 if (button[i]) {
00688 if ( !button[i]->isHidden() ) {
00689 button[i]->hide();
00690 }
00691 minWidth -= button[i]->sizeHint().width();
00692 if (width() >= minWidth) {
00693 return;
00694 }
00695 }
00696 }
00697 }
00698 } else {
00699 if ( hiddenItems ) {
00700 lastButtonWidth = width();
00701 int totalSize = normalTitleHeight*3;
00702
00703 for (int i = RedmondDeco::BtnMenu; i >= RedmondDeco::BtnHelp; i--) {
00704 if (button[i]) {
00705 if (button[i]->sizeHint().width() + totalSize <= width()) {
00706 totalSize += button[i]->sizeHint().width();
00707 button[i]->resize(button[i]->sizeHint());
00708 button[i]->show();
00709 } else {
00710 return;
00711 }
00712 }
00713 }
00714
00715
00716 hiddenItems = false;
00717 } else {
00718 lastButtonWidth = width();
00719 }
00720 }
00721 }
00722
00723 RedmondDeco::Position RedmondDeco::mousePosition(const QPoint &p) const
00724 {
00725 Position m = PositionCenter;
00726
00727 const int range = 14 + 3*borderWidth/2;
00728
00729 if ( ( p.x() > borderWidth && p.x() < width() - borderWidth )
00730 && ( p.y() > borderWidth && p.y() < height() - borderWidth ) )
00731 m = PositionCenter;
00732 else if ( p.y() <= range && p.x() <= range)
00733 m = PositionTopLeft;
00734 else if ( p.y() >= height()-range && p.x() >= width()-range)
00735 m = PositionBottomRight;
00736 else if ( p.y() >= height()-range && p.x() <= range)
00737 m = PositionBottomLeft;
00738 else if ( p.y() <= range && p.x() >= width()-range)
00739 m = PositionTopRight;
00740 else if ( p.y() <= borderWidth )
00741 m = PositionTop;
00742 else if ( p.y() >= height()-borderWidth )
00743 m = PositionBottom;
00744 else if ( p.x() <= borderWidth )
00745 m = PositionLeft;
00746 else if ( p.x() >= width()-borderWidth )
00747 m = PositionRight;
00748 else
00749 m = PositionCenter;
00750
00751 return m;
00752 }
00753
00754 void RedmondDeco::borders(int &l, int &r, int &t, int &b) const
00755 {
00756
00757 l = borderWidth;
00758 r = borderWidth;
00759 t = borderWidth + titlebar->geometry().height() + 1;
00760 b = borderWidth;
00761 }
00762
00763 void RedmondDeco::resize(const QSize &s)
00764 {
00765 widget()->resize(s);
00766 }
00767
00768 QSize RedmondDeco::minimumSize() const
00769 {
00770 return QSize(50, 50);
00771 }
00772
00773 void RedmondDeco::activeChange()
00774 {
00775 QPixmap miniIcon = icon().pixmap(QIconSet::Small, QIconSet::Normal);
00776 if (!miniIcon.isNull()) {
00777 button[BtnMenu]->setPixmap(miniIcon);
00778 } else {
00779 button[BtnMenu]->setPixmap(kdelogo);
00780 }
00781
00782
00783 for (int i = BtnHelp; i < BtnCount; i++) {
00784 if (button[i]) button[i]->reset();
00785 }
00786
00787 widget()->repaint(false);
00788 }
00789
00790 void RedmondDeco::captionChange()
00791 {
00792 widget()->repaint(titlebar->geometry(), false);
00793 }
00794
00795 void RedmondDeco::maximizeChange()
00796 {
00797 bool m = (maximizeMode() == MaximizeFull);
00798 button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
00799 QToolTip::remove(button[BtnMax]);
00800 QToolTip::add(button[BtnMax], m ? i18n("Restore") : i18n("Maximize"));
00801 }
00802
00803 void RedmondDeco::desktopChange()
00804 {
00805 }
00806
00807 void RedmondDeco::shadeChange()
00808 {
00809 }
00810
00811 void RedmondDeco::menuButtonPressed()
00812 {
00813 static QTime* t = NULL;
00814 static RedmondDeco* lastClient = NULL;
00815 if (t == NULL) t = new QTime;
00816 bool dbl = ( lastClient == this && t->elapsed() <= QApplication::doubleClickInterval());
00817 lastClient = this;
00818 t->start();
00819 if (!dbl) {
00820 QPoint menupoint(button[BtnMenu]->rect().bottomLeft().x()-3,
00821 button[BtnMenu]->rect().bottomLeft().y()+4);
00822 KDecorationFactory* f = factory();
00823 showWindowMenu(button[BtnMenu]->mapToGlobal(menupoint));
00824 if( !f->exists( this ))
00825 return;
00826 button[BtnMenu]->setDown(false);
00827 } else {
00828 closeWindow();
00829 }
00830 }
00831
00832 bool RedmondDeco::eventFilter(QObject *o, QEvent *e)
00833 {
00834 if (o != widget()) { return false; }
00835 switch (e->type()) {
00836 case QEvent::Resize: {
00837 resizeEvent(static_cast<QResizeEvent *>(e));
00838 return true;
00839 }
00840 case QEvent::Paint: {
00841 paintEvent(static_cast<QPaintEvent *>(e));
00842 return true;
00843 }
00844 case QEvent::Show: {
00845 showEvent(static_cast<QShowEvent *>(e));
00846 return true;
00847 }
00848 case QEvent::MouseButtonDblClick: {
00849 mouseDoubleClickEvent(static_cast<QMouseEvent *>(e));
00850 return true;
00851 }
00852 case QEvent::MouseButtonPress: {
00853 processMousePressEvent(static_cast<QMouseEvent *>(e));
00854 return true;
00855 }
00856 default: {
00857 break;
00858 }
00859 }
00860
00861 return false;
00862 }
00863
00864 void RedmondDecoFactory::readConfig() {
00865 normalTitleHeight = QFontMetrics(options()->font(true)).height();
00866 toolTitleHeight = QFontMetrics(options()->font(true, true)).height();
00867 switch(options()->preferredBorderSize(this)) {
00868 case BorderLarge:
00869 borderWidth = 8;
00870 if (normalTitleHeight < 20) normalTitleHeight = 20;
00871 if (toolTitleHeight < 20) toolTitleHeight = 20;
00872 break;
00873 case BorderVeryLarge:
00874 borderWidth = 12;
00875 if (normalTitleHeight < 24) normalTitleHeight = 24;
00876 if (toolTitleHeight < 24) toolTitleHeight = 24;
00877 break;
00878 case BorderHuge:
00879 borderWidth = 18;
00880 if (normalTitleHeight < 28) normalTitleHeight = 28;
00881 if (toolTitleHeight < 28) toolTitleHeight = 28;
00882 break;
00883 case BorderVeryHuge:
00884 borderWidth = 27;
00885 if (normalTitleHeight < 33) normalTitleHeight = 33;
00886 if (toolTitleHeight < 33) toolTitleHeight = 33;
00887 break;
00888 case BorderOversized:
00889 borderWidth = 40;
00890 if (normalTitleHeight < 40) normalTitleHeight = 40;
00891 if (toolTitleHeight < 40) toolTitleHeight = 40;
00892 break;
00893 case BorderTiny:
00894 case BorderNormal:
00895 default:
00896 borderWidth = 4;
00897 if (normalTitleHeight < 16) normalTitleHeight = 16;
00898 if (toolTitleHeight < 16) toolTitleHeight = 16;
00899 }
00900 }
00901
00902 RedmondDecoFactory::RedmondDecoFactory()
00903 {
00904 readConfig();
00905 create_pixmaps();
00906 }
00907
00908 RedmondDecoFactory::~RedmondDecoFactory()
00909 {
00910 Redmond::delete_pixmaps();
00911 }
00912
00913 KDecoration *RedmondDecoFactory::createDecoration( KDecorationBridge *b )
00914 {
00915 return new RedmondDeco(b, this);
00916 }
00917
00918 bool RedmondDecoFactory::reset( unsigned long changed )
00919 {
00920 if ( changed & ( SettingFont | SettingBorder | SettingColors ) ) {
00921 delete_pixmaps();
00922 readConfig();
00923 create_pixmaps();
00924 resetDecorations(changed);
00925 return true;
00926 } else {
00927 resetDecorations(changed);
00928 return false;
00929 }
00930 }
00931
00932 QValueList< RedmondDecoFactory::BorderSize > RedmondDecoFactory::borderSizes() const
00933 {
00934 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00935 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
00936 }
00937
00938 }
00939
00940 extern "C" KDecorationFactory *create_factory()
00941 {
00942 return new Redmond::RedmondDecoFactory();
00943 }
00944
00945
00946 #include "redmond.moc"
00947