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