1 /*********************************************************************
3 KDE2 Default KWin client
5 Copyright (C) 1999, 2001 Daniel Duley <mosfet@kde.org>
6 Matthias Ettrich <ettrich@kde.org>
7 Karol Szwed <gallium@kde.org>
9 Draws mini titlebars for tool windows.
10 Many features are now customizable.
12 drawColorBitmaps orignally from kdefx:
13 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 *********************************************************************/
31 #include <kconfiggroup.h>
39 #include <QApplication>
49 static const unsigned char iconify_bits
[] = {
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00,
51 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
53 static const unsigned char close_bits
[] = {
54 0x00, 0x00, 0x84, 0x00, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00,
55 0xfc, 0x00, 0xce, 0x01, 0x84, 0x00, 0x00, 0x00};
57 static const unsigned char maximize_bits
[] = {
58 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x86, 0x01, 0x86, 0x01, 0x86, 0x01,
59 0x86, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00};
61 static const unsigned char minmax_bits
[] = {
62 0x7f, 0x00, 0x7f, 0x00, 0x63, 0x00, 0xfb, 0x03, 0xfb, 0x03, 0x1f, 0x03,
63 0x1f, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x03};
65 static const unsigned char question_bits
[] = {
66 0x00, 0x00, 0x78, 0x00, 0xcc, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00,
67 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};
69 static const unsigned char above_on_bits
[] = {
70 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00,
71 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
73 static const unsigned char above_off_bits
[] = {
74 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
77 static const unsigned char below_on_bits
[] = {
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00,
79 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00 };
81 static const unsigned char below_off_bits
[] = {
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01,
83 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00, 0x30, 0x00 };
85 static const unsigned char shade_on_bits
[] = {
86 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x02, 0x01, 0x02, 0x01,
87 0x02, 0x01, 0x02, 0x01, 0xfe, 0x01, 0x00, 0x00 };
89 static const unsigned char shade_off_bits
[] = {
90 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
93 static const unsigned char pindown_white_bits
[] = {
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0xa0, 0x03,
95 0xb0, 0x01, 0x30, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
98 static const unsigned char pindown_gray_bits
[] = {
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
100 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
103 static const unsigned char pindown_dgray_bits
[] = {
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x10, 0x70, 0x20, 0x50, 0x20,
105 0x48, 0x30, 0xc8, 0x38, 0x08, 0x1f, 0x08, 0x18, 0x10, 0x1c, 0x10, 0x0e,
106 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
108 static const unsigned char pindown_mask_bits
[] = {
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x1f, 0xf0, 0x3f, 0xf0, 0x3f,
110 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x0f,
111 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
113 static const unsigned char pinup_white_bits
[] = {
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x11,
115 0x3f, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
118 static const unsigned char pinup_gray_bits
[] = {
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x80, 0x0a, 0xbf, 0x0a, 0x80, 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
123 static const unsigned char pinup_dgray_bits
[] = {
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x40, 0x31, 0x40, 0x2e,
125 0x40, 0x20, 0x40, 0x20, 0x7f, 0x2a, 0x40, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
128 static const unsigned char pinup_mask_bits
[] = {
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0xc0, 0x31, 0xc0, 0x3f,
130 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xc0, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
133 void drawColorBitmaps(QPainter
*p
, const QPalette
&pal
, int x
, int y
, int w
, int h
,
134 const uchar
*lightColor
, const uchar
*midColor
, const uchar
*blackColor
)
136 const uchar
*data
[]={lightColor
, midColor
, blackColor
};
138 QColor colors
[]={pal
.color(QPalette::Light
), pal
.color(QPalette::Mid
), Qt::black
};
142 for(i
=0; i
< 3; ++i
){
143 QBitmap b
= QBitmap::fromData(s
, data
[i
], QImage::Format_MonoLSB
);
145 p
->setPen(colors
[i
]);
146 p
->drawPixmap(x
, y
, b
);
150 // ===========================================================================
152 static QPixmap
* titlePix
;
153 static QPixmap
* titleBuffer
;
154 static QPixmap
* aUpperGradient
;
155 static QPixmap
* iUpperGradient
;
157 static QPixmap
* pinDownPix
;
158 static QPixmap
* pinUpPix
;
159 static QPixmap
* ipinDownPix
;
160 static QPixmap
* ipinUpPix
;
162 static QPixmap
* rightBtnUpPix
[2];
163 static QPixmap
* rightBtnDownPix
[2];
164 static QPixmap
* irightBtnUpPix
[2];
165 static QPixmap
* irightBtnDownPix
[2];
167 static QPixmap
* leftBtnUpPix
[2];
168 static QPixmap
* leftBtnDownPix
[2];
169 static QPixmap
* ileftBtnUpPix
[2];
170 static QPixmap
* ileftBtnDownPix
[2];
172 static KDE2Handler
* clientHandler
;
173 static int toolTitleHeight
;
174 static int normalTitleHeight
;
175 static int borderWidth
;
176 static int grabBorderWidth
;
177 static bool KDE2_initialized
= false;
178 static bool useGradients
;
179 static bool showGrabBar
;
180 static bool showTitleBarStipple
;
183 // ===========================================================================
185 KDE2Handler::KDE2Handler()
187 clientHandler
= this;
190 KDE2_initialized
= true;
194 KDE2Handler::~KDE2Handler()
196 KDE2_initialized
= false;
198 clientHandler
= NULL
;
201 KDecoration
* KDE2Handler::createDecoration( KDecorationBridge
* b
)
203 return ( new KDE2Client( b
, this ))->decoration();
206 bool KDE2Handler::reset( unsigned long changed
)
208 KDE2_initialized
= false;
209 changed
|= readConfig( true );
210 if( changed
& SettingColors
)
211 { // pixmaps need to be recreated
215 KDE2_initialized
= true;
216 // SettingButtons is handled by KCommonDecoration
217 bool need_recreate
= ( changed
& ( SettingDecoration
| SettingFont
| SettingBorder
)) != 0;
218 if( need_recreate
) // something else than colors changed
220 resetDecorations( changed
);
225 unsigned long KDE2Handler::readConfig( bool update
)
227 unsigned long changed
= 0;
228 KConfig
c("kwinKDE2rc");
229 KConfigGroup
conf(&c
, "General");
231 bool new_showGrabBar
= conf
.readEntry("ShowGrabBar", true);
232 bool new_showTitleBarStipple
= conf
.readEntry("ShowTitleBarStipple", true);
233 bool new_useGradients
= conf
.readEntry("UseGradients", true);
234 int new_titleHeight
= QFontMetrics(options()->font(true)).height() - 2;
235 int new_toolTitleHeight
= QFontMetrics(options()->font(true, true)).height() - 4;
238 switch(options()->preferredBorderSize(this)) {
242 case BorderVeryLarge
:
243 new_borderWidth
= 12;
246 new_borderWidth
= 18;
249 new_borderWidth
= 27;
251 case BorderOversized
:
252 new_borderWidth
= 40;
260 if (new_titleHeight
< 16) new_titleHeight
= 16;
261 if (new_titleHeight
< new_borderWidth
) new_titleHeight
= new_borderWidth
;
262 if (new_toolTitleHeight
< 12) new_toolTitleHeight
= 12;
263 if (new_toolTitleHeight
< new_borderWidth
) new_toolTitleHeight
= new_borderWidth
;
267 if( new_showGrabBar
!= showGrabBar
268 || new_titleHeight
!= normalTitleHeight
269 || new_toolTitleHeight
!= toolTitleHeight
270 || new_borderWidth
!= borderWidth
)
271 changed
|= SettingDecoration
; // need recreating the decoration
272 if( new_showTitleBarStipple
!= showTitleBarStipple
273 || new_useGradients
!= useGradients
274 || new_titleHeight
!= normalTitleHeight
275 || new_toolTitleHeight
!= toolTitleHeight
)
276 changed
|= SettingColors
; // just recreate the pixmaps and repaint
279 showGrabBar
= new_showGrabBar
;
280 showTitleBarStipple
= new_showTitleBarStipple
;
281 useGradients
= new_useGradients
;
282 normalTitleHeight
= new_titleHeight
;
283 toolTitleHeight
= new_toolTitleHeight
;
284 borderWidth
= new_borderWidth
;
285 grabBorderWidth
= (borderWidth
> 15) ? borderWidth
+ 15 : 2*borderWidth
;
289 static void gradientFill(QPixmap
*pixmap
, const QColor
&color1
, const QColor
&color2
)
292 QLinearGradient
gradient(0, 0, 0, pixmap
->height());
293 gradient
.setColorAt(0.0, color1
);
294 gradient
.setColorAt(1.0, color2
);
295 QBrush
brush(gradient
);
296 p
.fillRect(pixmap
->rect(), brush
);
299 // This paints the button pixmaps upon loading the style.
300 void KDE2Handler::createPixmaps()
302 bool highcolor
= useGradients
&& (QPixmap::defaultDepth() > 8);
304 // Make the titlebar stipple optional
305 if (showTitleBarStipple
)
308 QPainter maskPainter
;
310 titlePix
= new QPixmap(132, normalTitleHeight
+2);
311 QBitmap
mask(132, normalTitleHeight
+2);
312 mask
.fill(Qt::color0
);
315 maskPainter
.begin(&mask
);
316 maskPainter
.setPen(Qt::color1
);
317 for(i
=0, y
=2; i
< 9; ++i
, y
+=4)
318 for(x
=1; x
<= 132; x
+=3)
320 p
.setPen(options()->color(ColorTitleBar
, true).light(150));
322 maskPainter
.drawPoint(x
, y
);
323 p
.setPen(options()->color(ColorTitleBar
, true).dark(150));
324 p
.drawPoint(x
+1, y
+1);
325 maskPainter
.drawPoint(x
+1, y
+1);
329 titlePix
->setMask(mask
);
333 QColor
activeTitleColor1(options()->color(ColorTitleBar
, true));
334 QColor
activeTitleColor2(options()->color(ColorTitleBlend
, true));
336 QColor
inactiveTitleColor1(options()->color(ColorTitleBar
, false));
337 QColor
inactiveTitleColor2(options()->color(ColorTitleBlend
, false));
339 // Create titlebar gradient images if required
340 aUpperGradient
= NULL
;
341 iUpperGradient
= NULL
;
345 QSize
s(128, normalTitleHeight
+ 2);
346 // Create the titlebar gradients
347 if (activeTitleColor1
!= activeTitleColor2
)
350 aUpperGradient
= new QPixmap(s
);
351 gradientFill(aUpperGradient
, activeTitleColor1
, activeTitleColor2
);
354 if (inactiveTitleColor1
!= inactiveTitleColor2
)
356 iUpperGradient
= new QPixmap(s
);
357 gradientFill(iUpperGradient
, inactiveTitleColor1
, inactiveTitleColor2
);
361 // Set the sticky pin pixmaps;
366 g
= options()->palette( ColorButtonBg
, true );
367 QImage pinUpImg
= QImage(16, 16, QImage::Format_ARGB32_Premultiplied
);
368 p
.begin( &pinUpImg
);
369 drawColorBitmaps( &p
, g
, 0, 0, 16, 16, pinup_white_bits
, pinup_gray_bits
, pinup_dgray_bits
);
371 pinUpPix
= new QPixmap(QPixmap::fromImage(pinUpImg
));
372 pinUpPix
->setMask( QBitmap::fromData(QSize( 16, 16 ), pinup_mask_bits
) );
374 QImage pinDownImg
= QImage(16, 16, QImage::Format_ARGB32_Premultiplied
);
375 p
.begin( &pinDownImg
);
376 drawColorBitmaps( &p
, g
, 0, 0, 16, 16, pindown_white_bits
, pindown_gray_bits
, pindown_dgray_bits
);
378 pinDownPix
= new QPixmap(QPixmap::fromImage(pinDownImg
));
379 pinDownPix
->setMask( QBitmap::fromData(QSize( 16, 16 ), pindown_mask_bits
) );
382 g
= options()->palette( ColorButtonBg
, false );
383 QImage ipinUpImg
= QImage(16, 16, QImage::Format_ARGB32_Premultiplied
);
384 p
.begin( &ipinUpImg
);
385 drawColorBitmaps( &p
, g
, 0, 0, 16, 16, pinup_white_bits
, pinup_gray_bits
, pinup_dgray_bits
);
387 ipinUpPix
= new QPixmap(QPixmap::fromImage(ipinUpImg
));
388 ipinUpPix
->setMask( QBitmap::fromData(QSize( 16, 16 ), pinup_mask_bits
) );
390 QImage ipinDownImg
= QImage(16, 16, QImage::Format_ARGB32_Premultiplied
);
391 p
.begin( &ipinDownImg
);
392 drawColorBitmaps( &p
, g
, 0, 0, 16, 16, pindown_white_bits
, pindown_gray_bits
, pindown_dgray_bits
);
394 ipinDownPix
= new QPixmap(QPixmap::fromImage(ipinDownImg
));
395 ipinDownPix
->setMask( QBitmap::fromData(QSize( 16, 16 ), pindown_mask_bits
) );
397 // Create a title buffer for flicker-free painting
398 titleBuffer
= new QPixmap();
400 // Cache all possible button states
401 leftBtnUpPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
402 leftBtnDownPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
403 ileftBtnUpPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
404 ileftBtnDownPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
406 rightBtnUpPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
407 rightBtnDownPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
408 irightBtnUpPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
409 irightBtnDownPix
[true] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
411 leftBtnUpPix
[false] = new QPixmap(toolTitleHeight
, normalTitleHeight
);
412 leftBtnDownPix
[false] = new QPixmap(toolTitleHeight
, normalTitleHeight
);
413 ileftBtnUpPix
[false] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
414 ileftBtnDownPix
[false] = new QPixmap(normalTitleHeight
, normalTitleHeight
);
416 rightBtnUpPix
[false] = new QPixmap(toolTitleHeight
, toolTitleHeight
);
417 rightBtnDownPix
[false] = new QPixmap(toolTitleHeight
, toolTitleHeight
);
418 irightBtnUpPix
[false] = new QPixmap(toolTitleHeight
, toolTitleHeight
);
419 irightBtnDownPix
[false] = new QPixmap(toolTitleHeight
, toolTitleHeight
);
421 // Draw the button state pixmaps
422 g
= options()->palette( ColorTitleBar
, true );
423 drawButtonBackground( leftBtnUpPix
[true], g
, false );
424 drawButtonBackground( leftBtnDownPix
[true], g
, true );
425 drawButtonBackground( leftBtnUpPix
[false], g
, false );
426 drawButtonBackground( leftBtnDownPix
[false], g
, true );
428 g
= options()->palette( ColorButtonBg
, true );
429 drawButtonBackground( rightBtnUpPix
[true], g
, false );
430 drawButtonBackground( rightBtnDownPix
[true], g
, true );
431 drawButtonBackground( rightBtnUpPix
[false], g
, false );
432 drawButtonBackground( rightBtnDownPix
[false], g
, true );
434 g
= options()->palette( ColorTitleBar
, false );
435 drawButtonBackground( ileftBtnUpPix
[true], g
, false );
436 drawButtonBackground( ileftBtnDownPix
[true], g
, true );
437 drawButtonBackground( ileftBtnUpPix
[false], g
, false );
438 drawButtonBackground( ileftBtnDownPix
[false], g
, true );
440 g
= options()->palette( ColorButtonBg
, false );
441 drawButtonBackground( irightBtnUpPix
[true], g
, false );
442 drawButtonBackground( irightBtnDownPix
[true], g
, true );
443 drawButtonBackground( irightBtnUpPix
[false], g
, false );
444 drawButtonBackground( irightBtnDownPix
[false], g
, true );
448 void KDE2Handler::freePixmaps()
450 // Free button pixmaps
451 if (rightBtnUpPix
[true])
452 delete rightBtnUpPix
[true];
453 if(rightBtnDownPix
[true])
454 delete rightBtnDownPix
[true];
455 if (irightBtnUpPix
[true])
456 delete irightBtnUpPix
[true];
457 if (irightBtnDownPix
[true])
458 delete irightBtnDownPix
[true];
460 if (leftBtnUpPix
[true])
461 delete leftBtnUpPix
[true];
462 if(leftBtnDownPix
[true])
463 delete leftBtnDownPix
[true];
464 if (ileftBtnUpPix
[true])
465 delete ileftBtnUpPix
[true];
466 if (ileftBtnDownPix
[true])
467 delete ileftBtnDownPix
[true];
469 if (rightBtnUpPix
[false])
470 delete rightBtnUpPix
[false];
471 if(rightBtnDownPix
[false])
472 delete rightBtnDownPix
[false];
473 if (irightBtnUpPix
[false])
474 delete irightBtnUpPix
[false];
475 if (irightBtnDownPix
[false])
476 delete irightBtnDownPix
[false];
478 if (leftBtnUpPix
[false])
479 delete leftBtnUpPix
[false];
480 if(leftBtnDownPix
[false])
481 delete leftBtnDownPix
[false];
482 if (ileftBtnUpPix
[false])
483 delete ileftBtnUpPix
[false];
484 if (ileftBtnDownPix
[false])
485 delete ileftBtnDownPix
[false];
493 delete aUpperGradient
;
495 delete iUpperGradient
;
509 void KDE2Handler::drawButtonBackground(QPixmap
*pix
,
510 const QPalette
&g
, bool sunken
)
513 int w
= pix
->width();
514 int h
= pix
->height();
518 bool highcolor
= useGradients
&& (QPixmap::defaultDepth() > 8);
519 QColor c
= g
.color( QPalette::Background
);
521 // Fill the background with a gradient if possible
523 gradientFill(pix
, c
.light(130), c
.dark(130));
529 p
.setPen(g
.color( QPalette::Mid
));
530 p
.drawLine(0, 0, x2
, 0);
531 p
.drawLine(0, 0, 0, y2
);
532 p
.setPen(g
.color( QPalette::Light
));
533 p
.drawLine(x2
, 0, x2
, y2
);
534 p
.drawLine(0, x2
, y2
, x2
);
535 p
.setPen(g
.color( QPalette::Dark
));
536 p
.drawRect(1, 1, w
-3, h
-3);
537 p
.setPen(sunken
? g
.color( QPalette::Mid
) : g
.color( QPalette::Light
));
538 p
.drawLine(2, 2, x2
-2, 2);
539 p
.drawLine(2, 2, 2, y2
-2);
540 p
.setPen(sunken
? g
.color( QPalette::Light
) : g
.color( QPalette::Mid
));
541 p
.drawLine(x2
-2, 2, x2
-2, y2
-2);
542 p
.drawLine(2, x2
-2, y2
-2, x2
-2);
545 QList
< KDE2Handler::BorderSize
> KDE2Handler::borderSizes() const
546 { // the list must be sorted
547 return QList
< BorderSize
>() << BorderNormal
<< BorderLarge
<<
548 BorderVeryLarge
<< BorderHuge
<< BorderVeryHuge
<< BorderOversized
;
551 bool KDE2Handler::supports( Ability ability
) const
556 case AbilityAnnounceButtons
:
557 case AbilityAnnounceColors
:
559 case AbilityButtonMenu
:
560 case AbilityButtonOnAllDesktops
:
561 case AbilityButtonSpacer
:
562 case AbilityButtonHelp
:
563 case AbilityButtonMinimize
:
564 case AbilityButtonMaximize
:
565 case AbilityButtonClose
:
566 case AbilityButtonAboveOthers
:
567 case AbilityButtonBelowOthers
:
568 case AbilityButtonShade
:
570 case AbilityColorTitleBack
:
571 case AbilityColorTitleBlend
:
572 case AbilityColorTitleFore
:
573 case AbilityColorFrame
:
574 case AbilityColorButtonBack
:
581 // ===========================================================================
583 KDE2Button::KDE2Button(ButtonType type
, KDE2Client
*parent
, const char *name
)
584 : KCommonDecorationButton(type
, parent
)
586 setObjectName( name
);
587 setAttribute( Qt::WA_NoBackground
);
591 large
= !decoration()->isToolWindow();
595 KDE2Button::~KDE2Button()
602 void KDE2Button::reset(unsigned long changed
)
604 if (changed
&DecorationReset
|| changed
&ManualReset
|| changed
&SizeChange
|| changed
&StateChange
) {
607 setBitmap(close_bits
);
610 setBitmap(question_bits
);
613 setBitmap(iconify_bits
);
616 setBitmap( isChecked() ? minmax_bits
: maximize_bits
);
618 case OnAllDesktopsButton
:
622 setBitmap( isChecked() ? shade_on_bits
: shade_off_bits
);
625 setBitmap( isChecked() ? above_on_bits
: above_off_bits
);
628 setBitmap( isChecked() ? below_on_bits
: below_off_bits
);
640 void KDE2Button::setBitmap(const unsigned char *bitmap
)
646 deco
= new QBitmap( QBitmap::fromData(QSize( 10, 10 ), bitmap
) );
647 deco
->setMask( *deco
);
651 void KDE2Button::paintEvent(QPaintEvent
*)
657 void KDE2Button::drawButton(QPainter
*p
)
659 if (!KDE2_initialized
)
662 const bool active
= decoration()->isActive();
665 // Fill the button background with an appropriate button image
671 *leftBtnDownPix
[large
] : *ileftBtnDownPix
[large
];
674 *leftBtnUpPix
[large
] : *ileftBtnUpPix
[large
];
678 *rightBtnDownPix
[large
] : *irightBtnDownPix
[large
];
681 *rightBtnUpPix
[large
] : *irightBtnUpPix
[large
];
684 p
->drawPixmap( 0, 0, btnbg
);
686 } else if ( isLeft() ) {
688 // Fill the button background with an appropriate color/gradient
689 // This is for sticky and menu buttons
690 QPixmap
* grad
= active
? aUpperGradient
: iUpperGradient
;
692 QColor c
= KDecoration::options()->color(KDecoration::ColorTitleBar
, active
);
693 p
->fillRect(0, 0, width(), height(), c
);
695 p
->drawPixmap( 0, 0, *grad
, 0,1, width(), height() );
698 // Draw a plain background for menus or sticky buttons on RHS
699 QColor c
= KDecoration::options()->color(KDecoration::ColorFrame
, active
);
700 p
->fillRect(0, 0, width(), height(), c
);
704 // If we have a decoration bitmap, then draw that
705 // otherwise we paint a menu button (with mini icon), or a sticky button.
707 // Select the appropriate button decoration color
708 bool darkDeco
= qGray( KDecoration::options()->color(
709 isLeft() ? KDecoration::ColorTitleBar
: KDecoration::ColorButtonBg
,
710 active
).rgb() ) > 127;
713 p
->setPen( darkDeco
? Qt::darkGray
: Qt::lightGray
);
715 p
->setPen( darkDeco
? Qt::black
: Qt::white
);
717 int xOff
= (width()-10)/2;
718 int yOff
= (height()-10)/2;
719 p
->drawPixmap(isDown() ? xOff
+1: xOff
, isDown() ? yOff
+1 : yOff
, *deco
);
724 if (type()==OnAllDesktopsButton
) {
726 btnpix
= isChecked() ? *pinDownPix
: *pinUpPix
;
728 btnpix
= isChecked() ? *ipinDownPix
: *ipinUpPix
;
730 btnpix
= decoration()->icon().pixmap( style()->pixelMetric( QStyle::PM_SmallIconSize
), QIcon::Normal
);
732 // Intensify the image if required
734 // XXX Find a suitable substitute for this.
735 // btnpix = KPixmapEffect::intensity(btnpix, 0.8);
738 // Smooth scale the pixmap for small titlebars
739 // This is slow, but we assume this isn't done too often
740 if ( width() < 16 ) {
741 btnpix
= btnpix
.scaled(12, 12);
742 p
->drawPixmap( 0, 0, btnpix
);
745 p
->drawPixmap( width()/2-8, height()/2-8, btnpix
);
750 void KDE2Button::enterEvent(QEvent
*e
)
754 KCommonDecorationButton::enterEvent(e
);
758 void KDE2Button::leaveEvent(QEvent
*e
)
762 KCommonDecorationButton::leaveEvent(e
);
766 // ===========================================================================
768 KDE2Client::KDE2Client( KDecorationBridge
* b
, KDecorationFactory
* f
)
769 : KCommonDecoration( b
, f
)/*,
774 QString
KDE2Client::visibleName() const
776 return i18n("KDE 2");
779 bool KDE2Client::decorationBehaviour(DecorationBehaviour behaviour
) const
790 return KCommonDecoration::decorationBehaviour(behaviour
);
794 int KDE2Client::layoutMetric(LayoutMetric lm
, bool respectWindowState
, const KCommonDecorationButton
*btn
) const
801 case LM_BorderBottom
:
802 return mustDrawHandle() ? grabBorderWidth
: borderWidth
;
804 case LM_TitleEdgeLeft
:
805 case LM_TitleEdgeRight
:
808 case LM_TitleEdgeTop
:
811 case LM_TitleEdgeBottom
:
814 case LM_TitleBorderLeft
:
815 case LM_TitleBorderRight
:
822 case LM_ButtonHeight
:
825 case LM_ButtonSpacing
:
829 return KCommonDecoration::layoutMetric(lm
, respectWindowState
, btn
);
833 KCommonDecorationButton
*KDE2Client::createButton(ButtonType type
)
837 return new KDE2Button(MenuButton
, this, "menu");
838 case OnAllDesktopsButton
:
839 return new KDE2Button(OnAllDesktopsButton
, this, "on_all_desktops");
841 return new KDE2Button(HelpButton
, this, "help");
843 return new KDE2Button(MinButton
, this, "minimize");
845 return new KDE2Button(MaxButton
, this, "maximize");
847 return new KDE2Button(CloseButton
, this, "close");
849 return new KDE2Button(AboveButton
, this, "above");
851 return new KDE2Button(BelowButton
, this, "below");
853 return new KDE2Button(ShadeButton
, this, "shade");
860 void KDE2Client::init()
862 // Finally, toolWindows look small
863 if ( isToolWindow() ) {
864 titleHeight
= toolTitleHeight
;
867 titleHeight
= normalTitleHeight
;
870 KCommonDecoration::init();
873 void KDE2Client::reset( unsigned long changed
)
877 KCommonDecoration::reset(changed
);
880 bool KDE2Client::mustDrawHandle() const
882 bool drawSmallBorders
= !options()->moveResizeMaximizedWindows();
883 if (drawSmallBorders
&& (maximizeMode() & MaximizeVertical
)) {
886 return showGrabBar
&& isResizable();
890 void KDE2Client::paintEvent( QPaintEvent
* )
892 if (!KDE2_initialized
)
898 QPixmap
* upperGradient
= isActive() ? aUpperGradient
: iUpperGradient
;
900 QPainter
p(widget());
902 // Obtain widget bounds.
903 QRect
r(widget()->rect());
906 int x2
= r
.width() - 1;
907 int y2
= r
.height() - 1;
911 // Determine where to place the extended left titlebar
912 int leftFrameStart
= (h
> 42) ? y
+titleHeight
+26: y
+titleHeight
;
914 // Determine where to make the titlebar color transition
916 int rightOffset
= r
.x()+r
.width()+1;
918 // Create a disposable pixmap buffer for the titlebar
919 // very early before drawing begins so there is no lag
920 // during painting pixels.
921 *titleBuffer
= QPixmap( rightOffset
-3, titleHeight
+1 );
923 // Draw an outer black frame
925 p
.drawRect(x
,y
,w
-1,h
-1);
927 // Draw part of the frame that is the titlebar color
928 g
= options()->palette(ColorTitleBar
, isActive());
929 p
.setPen(g
.color( QPalette::Light
));
930 p
.drawLine(x
+1, y
+1, rightOffset
-1, y
+1);
931 p
.drawLine(x
+1, y
+1, x
+1, leftFrameStart
+borderWidth
-4);
933 // Draw titlebar colour separator line
934 p
.setPen(g
.color( QPalette::Dark
));
935 p
.drawLine(rightOffset
-1, y
+1, rightOffset
-1, titleHeight
+2);
937 p
.fillRect(x
+2, y
+titleHeight
+3,
938 borderWidth
-4, leftFrameStart
+borderWidth
-y
-titleHeight
-8,
939 options()->color(ColorTitleBar
, isActive() ));
941 // Finish drawing the titlebar extension
943 p
.drawLine(x
+1, leftFrameStart
+borderWidth
-4, x
+borderWidth
-2, leftFrameStart
-1);
944 p
.setPen(g
.color( QPalette::Mid
));
945 p
.drawLine(x
+borderWidth
-2, y
+titleHeight
+3, x
+borderWidth
-2, leftFrameStart
-2);
947 // Fill out the border edges
948 g
= options()->palette(ColorFrame
, isActive());
949 p
.setPen(g
.color( QPalette::Light
));
950 p
.drawLine(rightOffset
, y
+1, x2
-1, y
+1);
951 p
.drawLine(x
+1, leftFrameStart
+borderWidth
-3, x
+1, y2
-1);
952 p
.setPen(g
.color( QPalette::Dark
));
953 p
.drawLine(x2
-1, y
+1, x2
-1, y2
-1);
954 p
.drawLine(x
+1, y2
-1, x2
-1, y2
-1);
956 p
.setPen(options()->color(ColorFrame
, isActive()));
958 QBrush
brush( options()->color(ColorFrame
, isActive()), Qt::SolidPattern
);
959 p
.setBrush( brush
); // use solid, yellow brush
960 a
.setPoints( 4, x
+2, leftFrameStart
+borderWidth
-4,
961 x
+borderWidth
-2, leftFrameStart
,
962 x
+borderWidth
-2, y2
-2,
965 p
.fillRect(x2
-borderWidth
+2, y
+titleHeight
+3,
966 borderWidth
-3, y2
-y
-titleHeight
-4,
967 options()->color(ColorFrame
, isActive() ));
969 // Draw the bottom handle if required
970 if (mustDrawHandle())
974 qDrawShadePanel(&p
, x
+1, y2
-grabBorderWidth
+3, 2*borderWidth
+12, grabBorderWidth
-3,
975 g
, false, 1, &g
.brush(QPalette::Mid
));
976 qDrawShadePanel(&p
, x
+2*borderWidth
+13, y2
-grabBorderWidth
+3, w
-4*borderWidth
-26, grabBorderWidth
-3,
977 g
, false, 1, isActive() ?
978 &g
.brush(QPalette::Background
) :
979 &g
.brush(QPalette::Mid
));
980 qDrawShadePanel(&p
, x2
-2*borderWidth
-12, y2
-grabBorderWidth
+3, 2*borderWidth
+12, grabBorderWidth
-3,
981 g
, false, 1, &g
.brush(QPalette::Mid
));
983 qDrawShadePanel(&p
, x
+1, y2
-grabBorderWidth
+3, w
-2, grabBorderWidth
-3,
984 g
, false, 1, isActive() ?
985 &g
.brush(QPalette::Background
) :
986 &g
.brush(QPalette::Mid
));
987 offset
= grabBorderWidth
;
990 p
.fillRect(x
+2, y2
-borderWidth
+2, w
-4, borderWidth
-3,
991 options()->color(ColorFrame
, isActive() ));
992 offset
= borderWidth
;
995 // Draw a frame around the wrapped widget.
996 p
.setPen( g
.color( QPalette::Dark
) );
997 p
.drawRect( x
+borderWidth
-1, y
+titleHeight
+3, w
-2*borderWidth
+1, h
-titleHeight
-offset
-2 );
999 // Draw the title bar.
1002 // Obtain titlebar blend colours
1003 QColor c1
= options()->color(ColorTitleBar
, isActive() );
1004 QColor c2
= options()->color(ColorFrame
, isActive() );
1006 // Fill with frame color behind RHS buttons
1007 p
.fillRect( rightOffset
, y
+2, x2
-rightOffset
-1, titleHeight
+1, c2
);
1009 QPainter
p2( titleBuffer
);
1010 p2
.initFrom( widget());
1012 // Draw the titlebar gradient
1014 p2
.drawTiledPixmap(0, 0, rightOffset
-3, titleHeight
+1, *upperGradient
);
1016 p2
.fillRect(0, 0, rightOffset
-3, titleHeight
+1, c1
);
1018 // Draw the title text on the pixmap, and with a smaller font
1019 // for toolwindows than the default.
1020 QFont fnt
= options()->font(true);
1022 if ( isToolWindow() )
1023 fnt
.setPointSize( fnt
.pointSize()-2 ); // Shrink font by 2pt
1027 // Draw the titlebar stipple if active and available
1028 if (isActive() && titlePix
)
1030 QFontMetrics
fm(fnt
);
1031 int captionWidth
= fm
.width(caption());
1032 if (caption().isRightToLeft())
1033 p2
.drawTiledPixmap( r
.x(), 0, r
.width()-captionWidth
-4,
1034 titleHeight
+1, *titlePix
);
1036 p2
.drawTiledPixmap( r
.x()+captionWidth
+3, 0, r
.width()-captionWidth
-4,
1037 titleHeight
+1, *titlePix
);
1040 p2
.setPen( options()->color(ColorFont
, isActive()) );
1041 p2
.drawText(r
.x(), 1, r
.width()-1, r
.height(),
1042 (caption().isRightToLeft() ? Qt::AlignRight
: Qt::AlignLeft
) | Qt::AlignVCenter
,
1047 p
.drawPixmap( 2, 2, *titleBuffer
);
1049 // Ensure a shaded window has no unpainted areas
1050 // Is this still needed?
1053 p
.drawLine(x
+borderWidth
, y
+titleHeight
+4, x2
-borderWidth
, y
+titleHeight
+4);
1057 QRegion
KDE2Client::cornerShape(WindowCorner corner
)
1061 return QRect(0, 0, 1, 1);
1064 return QRect(width()-1, 0, 1, 1);
1067 return QRect(0, height()-1, 1, 1);
1069 case WC_BottomRight
:
1070 return QRect(width()-1, height()-1, 1, 1);
1079 // Extended KWin plugin interface
1080 extern "C" KDE_EXPORT KDecorationFactory
* create_factory()
1082 return new KDE2::KDE2Handler();
1086 // kate: space-indent off; tab-width 4;