Qt3to4
[kdeartwork.git] / styles / phase / phasestyle.cpp
blobbdef487f4cbf0bf44c79a81aa1f4ef55d0152137
1 //////////////////////////////////////////////////////////////////////////////
2 // phasestyle.cpp
3 // -------------------
4 // Qt/KDE widget style
5 // -------------------
6 // Copyright (c) 2004 David Johnson
7 // Please see the header file for copyright and license information.
8 //////////////////////////////////////////////////////////////////////////////
9 //
10 // Some miscellaneous notes
12 // Reimplemented scrollbar metric and drawing routines from KStyle to allow
13 // better placement of subcontrols. This is because the subcontrols slightly
14 // overlap to share part of their border.
16 // Menu and toolbars are painted with the background color by default. This
17 // differs from the Qt default of giving them PaletteButton backgrounds.
18 // Menubars have normal gradients, toolbars have reverse.
20 // Some toolbars are not part of a QMainWindows, such as in a KDE file dialog.
21 // In these cases we treat the toolbar as "floating" and paint it flat.
23 //////////////////////////////////////////////////////////////////////////////
25 #include <kdrawutil.h>
26 #include <kpixmap.h>
27 #include <kpixmapeffect.h>
29 #include <qapplication.h>
30 #include <q3intdict.h>
31 #include <qpainter.h>
32 #include <q3pointarray.h>
33 #include <qsettings.h>
34 #include <qstyleplugin.h>
36 #include <qcheckbox.h>
37 #include <qcombobox.h>
38 #include <q3header.h>
39 #include <q3mainwindow.h>
40 #include <qmenubar.h>
41 #include <q3popupmenu.h>
42 #include <q3progressbar.h>
43 #include <qpushbutton.h>
44 #include <qradiobutton.h>
45 #include <qscrollbar.h>
46 #include <qslider.h>
47 #include <qsplitter.h>
48 #include <qtabbar.h>
49 #include <qtabwidget.h>
50 #include <q3toolbar.h>
51 #include <qtoolbox.h>
52 #include <qtoolbutton.h>
53 //Added by qt3to4:
54 #include <QMouseEvent>
55 #include <Q3Frame>
56 #include <QEvent>
57 #include <QPixmap>
59 #include "phasestyle.h"
60 #include "bitmaps.h"
62 static const char* QSPLITTERHANDLE = "QSplitterHandle";
63 static const char* QTOOLBAREXTENSION = "QToolBarExtensionWidget";
64 static const char* KTOOLBARWIDGET = "kde toolbar widget";
66 // some convenient constants
67 static const int ITEMFRAME = 1; // menu stuff
68 static const int ITEMHMARGIN = 3;
69 static const int ITEMVMARGIN = 0;
70 static const int ARROWMARGIN = 6;
71 static const int RIGHTBORDER = 6;
72 static const int MINICONSIZE = 16;
73 static const int CHECKSIZE = 9;
74 static const int MAXGRADIENTSIZE = 64;
76 static unsigned contrast = 110;
78 QMap<unsigned int, Q3IntDict<GradientSet> > gradients; // gradients[color][size]
80 //////////////////////////////////////////////////////////////////////////////
81 // Construction, Destruction, Initialization //
82 //////////////////////////////////////////////////////////////////////////////
84 //////////////////////////////////////////////////////////////////////////////
85 // PhaseStyle()
86 // -----------
87 // Constructor
89 PhaseStyle::PhaseStyle()
90 : KStyle(FilledFrameWorkaround | AllowMenuTransparency,
91 ThreeButtonScrollBar), hover_(0), hovertab_(0),
92 gradients_(QPixmap::defaultDepth() > 8), kicker_(false)
94 QSettings settings;
95 if (gradients_) { // don't bother setting if already false
96 gradients_ =
97 settings.readBoolEntry("/phasestyle/Settings/gradients", true);
98 contrast = 100 + settings.readNumEntry("/Qt/KDE/contrast", 5);
100 highlights_ =
101 settings.readBoolEntry("/phasestyle/Settings/highlights", true);
103 reverse_ = QApplication::reverseLayout();
105 // create bitmaps
106 uarrow = QBitmap(6, 6, uarrow_bits, true);
107 uarrow.setMask(uarrow);
108 darrow = QBitmap(6, 6, darrow_bits, true);
109 darrow.setMask(darrow);
110 larrow = QBitmap(6, 6, larrow_bits, true);
111 larrow.setMask(larrow);
112 rarrow = QBitmap(6, 6, rarrow_bits, true);
113 rarrow.setMask(rarrow);
114 bplus = QBitmap(6, 6, bplus_bits, true);
115 bplus.setMask(bplus);
116 bminus = QBitmap(6, 6, bminus_bits, true);
117 bminus.setMask(bminus);
118 bcheck = QBitmap(9, 9, bcheck_bits, true);
119 bcheck.setMask(bcheck);
120 dexpand = QBitmap(9, 9, dexpand_bits, true);
121 dexpand.setMask(dexpand);
122 rexpand = QBitmap(9, 9, rexpand_bits, true);
123 rexpand.setMask(rexpand);
124 doodad_mid = QBitmap(4, 4, doodad_mid_bits, true);
125 doodad_light = QBitmap(4, 4, doodad_light_bits, true);
128 PhaseStyle::~PhaseStyle() { ; }
130 //////////////////////////////////////////////////////////////////////////////
131 // Polishing //
132 //////////////////////////////////////////////////////////////////////////////
134 //////////////////////////////////////////////////////////////////////////////
135 // polish()
136 // --------
137 // Initialize application specific
139 void PhaseStyle::polish(QApplication* app)
141 if (!qstrcmp(app->argv()[0], "kicker")) kicker_ = true;
144 //////////////////////////////////////////////////////////////////////////////
145 // polish()
146 // --------
147 // Initialize the appearance of a widget
149 void PhaseStyle::polish(QWidget *widget)
151 if (::qt_cast<QMenuBar*>(widget) ||
152 ::qt_cast<Q3PopupMenu*>(widget)) {
153 // anti-flicker optimization
154 widget->setBackgroundMode(Qt::NoBackground);
155 } else if (::qt_cast<Q3Frame*>(widget) ||
156 widget->inherits(QTOOLBAREXTENSION) ||
157 (!qstrcmp(widget->name(), KTOOLBARWIDGET))) {
158 // needs special handling on paint events
159 widget->installEventFilter(this);
160 } else if (highlights_ &&
161 (::qt_cast<QPushButton*>(widget) ||
162 ::qt_cast<QComboBox*>(widget) ||
163 ::qt_cast<Q3SpinWidget*>(widget) ||
164 ::qt_cast<QCheckBox*>(widget) ||
165 ::qt_cast<QRadioButton*>(widget) ||
166 ::qt_cast<QSlider*>(widget) ||
167 widget->inherits(QSPLITTERHANDLE))) {
168 // mouseover highlighting
169 widget->installEventFilter(this);
170 } else if (highlights_ && ::qt_cast<QTabBar*>(widget)) {
171 // highlighting needing mouse tracking
172 widget->setMouseTracking(true);
173 widget->installEventFilter(this);
176 KStyle::polish(widget);
179 //////////////////////////////////////////////////////////////////////////////
180 // polish()
181 // --------
182 // Initialize the palette
184 void PhaseStyle::polish(QPalette &pal)
186 // clear out gradients on a color change
187 gradients.clear();
189 // lighten up a bit, so the look is not so "crisp"
190 if (QPixmap::defaultDepth() > 8) { // but not on low color displays
191 pal.setColor(QPalette::Disabled, QColorGroup::Dark,
192 pal.color(QPalette::Disabled, QColorGroup::Dark).light(contrast));
193 pal.setColor(QPalette::Active, QColorGroup::Dark,
194 pal.color(QPalette::Active, QColorGroup::Dark).light(contrast));
195 pal.setColor(QPalette::Inactive, QColorGroup::Dark,
196 pal.color(QPalette::Inactive, QColorGroup::Dark).light(contrast));
199 QStyle::polish(pal);
202 //////////////////////////////////////////////////////////////////////////////
203 // unPolish()
204 // ----------
205 // Undo the initialization of a widget's appearance
207 void PhaseStyle::unPolish(QWidget *widget)
209 if (::qt_cast<QMenuBar*>(widget) ||
210 ::qt_cast<Q3PopupMenu*>(widget)) {
211 widget->setBackgroundMode(PaletteBackground);
212 } else if (::qt_cast<Q3Frame*>(widget) ||
213 widget->inherits(QTOOLBAREXTENSION) ||
214 (!qstrcmp(widget->name(), KTOOLBARWIDGET))) {
215 widget->removeEventFilter(this);
216 } else if (highlights_ && // highlighting
217 (::qt_cast<QPushButton*>(widget) ||
218 ::qt_cast<QComboBox*>(widget) ||
219 ::qt_cast<Q3SpinWidget*>(widget) ||
220 ::qt_cast<QCheckBox*>(widget) ||
221 ::qt_cast<QRadioButton*>(widget) ||
222 ::qt_cast<QSlider*>(widget) ||
223 widget->inherits(QSPLITTERHANDLE))) {
224 widget->removeEventFilter(this);
225 } else if (highlights_ && ::qt_cast<QTabBar*>(widget)) {
226 widget->setMouseTracking(false);
227 widget->removeEventFilter(this);
230 KStyle::unPolish(widget);
233 //////////////////////////////////////////////////////////////////////////////
234 // Drawing //
235 //////////////////////////////////////////////////////////////////////////////
237 //////////////////////////////////////////////////////////////////////////////
238 // drawPhaseGradient()
239 // ------------------
240 // Draw gradient
242 void PhaseStyle::drawPhaseGradient(QPainter *painter,
243 const QRect &rect,
244 QColor color,
245 bool horizontal,
246 int px, int py,
247 int pw, int ph,
248 bool reverse) const
250 if (!gradients_) {
251 painter->fillRect(rect, color);
252 return;
255 // px, py, pw, ph used for parent-relative pixmaps
256 int size;
257 if (horizontal)
258 size = (pw > 0) ? pw : rect.width();
259 else
260 size = (ph > 0) ? ph : rect.height();
262 if (size > MAXGRADIENTSIZE) { // keep it sensible
263 painter->fillRect(rect, color);
264 } else {
265 // lazy allocation
266 GradientSet *set = gradients[color.rgb()][size];
267 if (!set) {
268 set = new GradientSet(color, size);
269 gradients[color.rgb()].setAutoDelete(true);
270 gradients[color.rgb()].insert(size, set);
272 painter->drawTiledPixmap(rect, *set->gradient(horizontal, reverse),
273 QPoint(px, py));
277 //////////////////////////////////////////////////////////////////////////////
278 // drawPhaseBevel()
279 // ----------------
280 // Draw the basic Phase bevel
282 void PhaseStyle::drawPhaseBevel(QPainter *painter,
283 int x, int y, int w, int h,
284 const QColorGroup &group,
285 const QColor &fill,
286 bool sunken,
287 bool horizontal,
288 bool reverse) const
290 int x2 = x + w - 1;
291 int y2 = y + h - 1;
292 painter->save();
294 painter->setPen(group.dark());
295 painter->drawRect(x, y, w, h);
297 painter->setPen(sunken ? group.mid() : group.midlight());
298 painter->drawLine(x+1, y+1, x2-2, y+1);
299 painter->drawLine(x+1, y+2, x+1, y2-2);
301 painter->setPen(sunken ? group.midlight() : group.mid());
302 painter->drawLine(x+2, y2-1, x2-1, y2-1);
303 painter->drawLine(x2-1, y+2, x2-1, y2-2);
305 painter->setPen(group.button());
306 painter->drawPoint(x+1, y2-1);
307 painter->drawPoint(x2-1, y+1);
309 if (sunken) {
310 // sunken bevels don't get gradients
311 painter->fillRect(x+2, y+2, w-4, h-4, fill);
312 } else {
313 drawPhaseGradient(painter, QRect(x+2, y+2, w-4, h-4), fill,
314 horizontal, 0, 0, w-4, h-4, reverse);
316 painter->restore();
319 //////////////////////////////////////////////////////////////////////////////
320 // drawPhaseButton()
321 // ----------------
322 // Draw the basic Phase button
324 void PhaseStyle::drawPhaseButton(QPainter *painter,
325 int x, int y, int w, int h,
326 const QColorGroup &group,
327 const QColor &fill,
328 bool sunken) const
330 int x2 = x + w - 1;
331 int y2 = y + h - 1;
333 painter->setPen(group.midlight());
334 painter->drawLine(x+1, y2, x2, y2);
335 painter->drawLine(x2, y+1, x2, y2-1);
337 painter->setPen(group.mid());
338 painter->drawLine(x, y, x2-1, y);
339 painter->drawLine(x, y+1, x, y2-1);
341 painter->setPen(group.button());
342 painter->drawPoint(x, y2);
343 painter->drawPoint(x2, y);
345 drawPhaseBevel(painter, x+1, y+1, w-2, h-2, group, fill,
346 sunken, false, false);
349 //////////////////////////////////////////////////////////////////////////////
350 // drawPhasePanel()
351 // ----------------
352 // Draw the basic Phase panel
354 void PhaseStyle::drawPhasePanel(QPainter *painter,
355 int x, int y, int w, int h,
356 const QColorGroup &group,
357 bool sunken,
358 const QBrush *fill) const
360 int x2 = x + w - 1;
361 int y2 = y + h - 1;
362 painter->save();
364 if (sunken) {
365 painter->setPen(group.dark());
366 painter->drawRect(x+1, y+1, w-2, h-2);
367 painter->setPen(group.midlight());
368 painter->drawLine(x+1, y2, x2, y2);
369 painter->drawLine(x2, y+1, x2, y2-1);
370 painter->setPen(group.mid());
371 painter->drawLine(x, y, x, y2-1);
372 painter->drawLine(x+1, y, x2-1, y);
373 painter->setPen(group.background());
374 painter->drawPoint(x, y2);
375 painter->drawPoint(x2, y);
376 } else {
377 painter->setPen(group.dark());
378 painter->drawRect(x, y, w, h);
379 painter->setPen(group.midlight());
380 painter->drawLine(x+1, y+1, x2-2, y+1);
381 painter->drawLine(x+1, y+2, x+1, y2-2);
382 painter->setPen(group.mid());
383 painter->drawLine(x+2, y2-1, x2-1, y2-1);
384 painter->drawLine(x2-1, y+2, x2-1, y2-2);
385 painter->setPen(group.background());
386 painter->drawPoint(x+1, y2-1);
387 painter->drawPoint(x2-1, y+1);
390 if (fill) {
391 painter->fillRect(x+2, y+2, w-4, h-4, fill->color());
393 painter->restore();
396 //////////////////////////////////////////////////////////////////////////////
397 // drawPhaseTab()
398 // -------------
399 // Draw a Phase style tab
401 void PhaseStyle::drawPhaseTab(QPainter *painter,
402 int x, int y, int w, int h,
403 const QColorGroup &group,
404 const QTabBar *bar,
405 const QStyleOption &option,
406 SFlags flags) const
408 const QTabWidget *tabwidget;
409 bool selected = (flags & Style_Selected);
410 bool edge; // tab is at edge of bar
411 const int x2 = x + w - 1;
412 const int y2 = y + h - 1;
414 painter->save();
416 // what position is the tab?
417 if ((bar->count() == 1)
418 || (bar->indexOf(option.tab()->identifier()) == 0)) {
419 edge = true;
420 } else {
421 edge = false;
424 switch (QTabBar::Shape(bar->shape())) {
425 case QTabBar::RoundedNorth:
426 case QTabBar:: TriangularNorth: {
427 // is there a corner widget?
428 tabwidget = dynamic_cast<QTabWidget*>(bar->parent());
429 if (edge && tabwidget
430 && tabwidget->cornerWidget(reverse_ ?
431 Qt::TopRightCorner : Qt::TopLeftCorner)) {
432 edge = false;
435 if (!selected) { // shorten
436 y += 2; h -= 2;
438 if (selected) {
439 painter->setPen(Qt::NoPen);
440 painter->fillRect(x+1, y+1, w-1, h-1,
441 group.brush(QColorGroup::Background));
442 } else {
443 drawPhaseGradient(painter, QRect(x+1, y+1, w-1, h-2),
444 (flags & Style_MouseOver)
445 ? group.background()
446 : group.background().dark(contrast),
447 false, 0, 0, 0, h*2, false);
450 // draw tab
451 painter->setPen(group.dark());
452 painter->drawLine(x, y, x, y2-2);
453 painter->drawLine(x+1, y, x2, y);
454 painter->drawLine(x2, y+1, x2, y2-2);
456 painter->setPen(group.mid());
457 painter->drawLine(x2-1, y+2, x2-1, y2-2);
459 painter->setPen(group.midlight());
460 painter->drawLine(x+1, y+1, x2-2, y+1);
461 if ((selected) || edge) painter->drawLine(x+1, y+2, x+1, y2-2);
463 // finish off bottom
464 if (selected) {
465 painter->setPen(group.dark());
466 painter->drawPoint(x, y2-1);
467 painter->drawPoint(x2, y2-1);
469 painter->setPen(group.midlight());
470 painter->drawPoint(x, y2);
471 painter->drawLine(x+1, y2-1, x+1, y2);
472 painter->drawPoint(x2, y2);
474 painter->setPen(group.mid());
475 painter->drawPoint(x2-1, y2-1);
477 if (!reverse_ && edge) {
478 painter->setPen(group.dark());
479 painter->drawLine(x, y2-1, x, y2);
480 painter->setPen(group.midlight());
481 painter->drawPoint(x+1, y2);
483 } else {
484 painter->setPen(group.dark());
485 painter->drawLine(x, y2-1, x2, y2-1);
487 painter->setPen(group.midlight());
488 painter->drawLine(x, y2, x2, y2);
490 if (!reverse_ && edge) {
491 painter->setPen(group.dark());
492 painter->drawLine(x, y2-1, x, y2);
495 if (reverse_ && edge) {
496 painter->setPen(group.dark());
497 painter->drawPoint(x2, y2);
498 painter->setPen(selected ? group.mid() : group.background());
499 painter->drawPoint(x2-1, y2);
501 break;
504 case QTabBar:: RoundedSouth:
505 case QTabBar:: TriangularSouth: {
506 // is there a corner widget?
507 tabwidget = dynamic_cast<QTabWidget*>(bar->parent());
508 if (edge && tabwidget
509 && tabwidget->cornerWidget(reverse_ ?
510 Qt::BottomRightCorner : Qt::BottomLeftCorner)) {
511 edge = false;
514 painter->setBrush((selected || (flags & Style_MouseOver))
515 ? group.background()
516 : group.background().dark(contrast));
517 painter->setPen(Qt::NoPen);
518 painter->fillRect(x+1, y+1, w-1, h-1, painter->brush());
520 // draw tab
521 painter->setPen(group.dark());
522 painter->drawLine(x, y+1, x, y2);
523 painter->drawLine(x+1, y2, x2, y2);
524 painter->drawLine(x2, y+1, x2, y2-1);
526 painter->setPen(group.mid());
527 painter->drawLine(x2-1, y+1, x2-1, y2-1);
528 painter->drawLine(x+2, y2-1, x2-1, y2-1);
529 painter->drawPoint(x, y);
530 painter->drawPoint(x2, y);
532 if ((selected) || edge) {
533 painter->setPen(group.midlight());
534 painter->drawLine(x+1, y+1, x+1, y2-2);
537 // finish off top
538 if (selected) {
539 if (!reverse_ && edge) {
540 painter->setPen(group.dark());
541 painter->drawPoint(x, y);
542 painter->setPen(group.midlight());
543 painter->drawPoint(x+1, y);
545 } else {
546 painter->setPen(group.dark());
547 painter->drawLine(x, y+1, x2, y+1);
549 painter->setPen(group.mid());
550 painter->drawLine(x, y, x2, y);
552 if (!reverse_ && edge) {
553 painter->setPen(group.dark());
554 painter->drawPoint(x, y);
557 if (reverse_ && edge) {
558 painter->setPen(group.dark());
559 painter->drawPoint(x2, y);
560 painter->setPen(group.mid());
561 painter->drawPoint(x2-1, y);
563 break;
566 painter->restore();
569 //////////////////////////////////////////////////////////////////////////////
570 // drawPrimitive()
571 // ---------------
572 // Draw the primitive element
574 void PhaseStyle::drawPrimitive(PrimitiveElement element,
575 QPainter *painter,
576 const QRect &rect,
577 const QColorGroup &group,
578 SFlags flags,
579 const QStyleOption &option) const
581 // common locals
582 bool down = flags & Style_Down;
583 bool on = flags & Style_On;
584 bool depress = (down || on);
585 bool enabled = flags & Style_Enabled;
586 bool horiz = flags & Style_Horizontal;
587 bool mouseover = highlights_ && (flags & Style_MouseOver);
588 int x, y, w, h, x2, y2, n, cx, cy;
589 Q3PointArray parray;
590 QWidget* widget;
592 rect.rect(&x, &y, &w, &h);
593 x2 = rect.right();
594 y2 = rect.bottom();
596 switch(element) {
597 case PE_ButtonBevel:
598 case PE_ButtonDefault:
599 case PE_ButtonDropDown:
600 case PE_ButtonTool:
601 drawPhaseBevel(painter, x,y,w,h, group, group.button(),
602 depress, false, false);
603 break;
605 case PE_ButtonCommand:
606 drawPhaseButton(painter, x, y, w, h, group,
607 mouseover ?
608 group.button().light(contrast) :
609 group.button(), depress);
610 break;
612 case PE_FocusRect: {
613 QPen old = painter->pen();
614 painter->setPen(group.highlight().dark(contrast));
616 painter->drawRect(rect);
618 painter->setPen(old);
619 break;
622 case PE_HeaderSection: {
623 // covers kicker taskbar buttons and menu titles
624 Q3Header* header = dynamic_cast<Q3Header*>(painter->device());
625 widget = dynamic_cast<QWidget*>(painter->device());
627 if (header) {
628 horiz = (header->orientation() == Horizontal);
629 } else {
630 horiz = true;
633 if ((widget) && ((widget->inherits("QPopupMenu")) ||
634 (widget->inherits("KPopupTitle")))) {
635 // kicker/kdesktop menu titles
636 drawPhaseBevel(painter, x,y,w,h,
637 group, group.background(), depress, !horiz);
638 } else if (kicker_) {
639 // taskbar buttons (assuming no normal headers used in kicker)
640 if (depress) {
641 painter->setPen(group.dark());
642 painter->setBrush(group.brush(QColorGroup::Mid));
643 painter->drawRect(x-1, y-1, w+1, h+1);
645 else {
646 drawPhaseBevel(painter, x-1, y-1, w+1, h+1,
647 group, group.button(), false, !horiz, true);
649 } else {
650 // other headers
651 if (depress) {
652 painter->setPen(group.dark());
653 painter->setBrush(group.brush(QColorGroup::Mid));
654 painter->drawRect(x-1, y-1, w+1, h+1);
656 else {
657 drawPhaseBevel(painter, x-1, y-1, w+1, h+1, group,
658 group.background(), false, !horiz, true);
661 break;
664 case PE_HeaderArrow:
665 if (flags & Style_Up)
666 drawPrimitive(PE_ArrowUp, painter, rect, group, Style_Enabled);
667 else
668 drawPrimitive(PE_ArrowDown, painter, rect, group, Style_Enabled);
669 break;
671 case PE_ScrollBarAddPage:
672 case PE_ScrollBarSubPage:
673 if (h) { // has a height, thus visible
674 painter->fillRect(rect, group.mid());
675 painter->setPen(group.dark());
676 if (horiz) { // vertical
677 painter->drawLine(x, y, x2, y);
678 painter->drawLine(x, y2, x2, y2);
679 } else { // horizontal
680 painter->drawLine(x, y, x, y2);
681 painter->drawLine(x2, y, x2, y2);
684 break;
686 case PE_ScrollBarAddLine:
687 case PE_ScrollBarSubLine: {
688 drawPhaseBevel(painter, x, y, w, h,
689 group, group.button(), down, !horiz, true);
691 PrimitiveElement arrow = ((horiz) ?
692 ((element == PE_ScrollBarAddLine) ?
693 PE_ArrowRight : PE_ArrowLeft) :
694 ((element == PE_ScrollBarAddLine) ?
695 PE_ArrowDown : PE_ArrowUp));
696 if (down) { // shift arrow
697 switch (arrow) {
698 case PE_ArrowRight: x++; break;
699 case PE_ArrowLeft: x--; break;
700 case PE_ArrowDown: y++; break;
701 case PE_ArrowUp: y--; break;
702 default: break;
706 drawPrimitive(arrow, painter, QRect(x,y,h,w), group, flags);
707 break;
710 case PE_ScrollBarSlider:
711 drawPhaseBevel(painter, x, y, w, h, group, group.button(),
712 false, !horiz, true);
713 // draw doodads
714 cx = x + w/2 - 2; cy = y + h/2 - 2;
715 if (horiz && (w >=20)) {
716 for (n = -5; n <= 5; n += 5) {
717 kColorBitmaps(painter, group, cx+n, cy,
718 0, &doodad_mid, &doodad_light, 0, 0, 0);
720 } else if (!horiz && (h >= 20)) {
721 for (n = -5; n <= 5; n += 5) {
722 kColorBitmaps(painter, group, cx, cy+n,
723 0, &doodad_mid, &doodad_light, 0, 0, 0);
726 break;
728 case PE_Indicator:
729 drawPhasePanel(painter, x+1, y+1, w-2, h-2, group, true, enabled ?
730 &group.brush(QColorGroup::Base) :
731 &group.brush(QColorGroup::Background));
733 if (on) {
734 painter->setPen(mouseover
735 ? group.highlight().dark(contrast)
736 : group.dark());
737 painter->drawRect(x+4, y+4, w-8, h-8);
738 painter->fillRect(x+5, y+5, w-10, h-10,
739 group.brush(QColorGroup::Highlight));
740 } else if (mouseover) {
741 painter->setPen(group.highlight().dark(contrast));
742 painter->drawRect(x+4, y+4, w-8, h-8);
744 break;
746 case PE_IndicatorMask:
747 painter->fillRect(x+1, y+1, w-2, h-2, Qt::color1);
748 painter->setPen(Qt::color0);
749 break;
751 case PE_ExclusiveIndicator: {
752 // note that this requires an even size from pixelMetric
753 cx = (x + x2) / 2;
754 cy = (y + y2) / 2;
756 painter->setBrush(enabled
757 ? group.brush(QColorGroup::Base)
758 : group.brush(QColorGroup::Background));
760 painter->setPen(group.dark());
761 parray.putPoints(0, 8,
762 x+1,cy+1, x+1,cy, cx,y+1, cx+1,y+1,
763 x2-1,cy, x2-1,cy+1, cx+1,y2-1, cx,y2-1);
764 painter->drawConvexPolygon(parray, 0, 8);
766 painter->setPen(group.mid());
767 parray.putPoints(0, 4, x,cy, cx,y, cx+1,y, x2,cy);
768 painter->drawPolyline(parray, 0, 4);
769 painter->setPen(group.midlight());
770 parray.putPoints(0, 4, x2,cy+1, cx+1,y2, cx,y2, x,cy+1);
771 painter->drawPolyline(parray, 0, 4);
773 if (on) {
774 painter->setBrush(group.brush(QColorGroup::Highlight));
775 painter->setPen(mouseover
776 ? group.highlight().dark(contrast)
777 : group.dark());
778 parray.putPoints(0, 8,
779 x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
780 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4);
781 painter->drawConvexPolygon(parray, 0, 8);
782 } else if (mouseover) {
783 painter->setPen(group.highlight().dark(contrast));
784 parray.putPoints(0, 9,
785 x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
786 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4,
787 x+4,cy+1);
788 painter->drawPolyline(parray, 0, 9);
790 break;
793 case PE_ExclusiveIndicatorMask:
794 cx = (x + x2) / 2;
795 cy = (y + y2) / 2;
796 painter->setBrush(Qt::color1);
797 painter->setPen(Qt::color1);
798 parray.putPoints(0, 8,
799 x,cy+1, x,cy, cx,y, cx+1,y,
800 x2,cy, x2,cy+1, cx+1,y2, cx,y2);
801 painter->drawConvexPolygon(parray, 0, 8);
802 painter->setPen(Qt::color0);
803 break;
805 case PE_DockWindowResizeHandle:
806 drawPhasePanel(painter, x, y, w, h, group, false,
807 &group.brush(QColorGroup::Background));
808 break;
810 case PE_Splitter:
811 cx = x + w/2 - 2; cy = y + h/2 - 2;
812 painter->fillRect(rect,
813 (hover_ == painter->device())
814 ? group.background().light(contrast)
815 : group.background());
817 if (!horiz && (w >=20)) {
818 for (n = -5; n <= 5; n += 5) {
819 kColorBitmaps(painter, group, cx+n, cy,
820 0, &doodad_mid, &doodad_light, 0, 0, 0);
822 } else if (horiz && (h >= 20)) {
823 for (n = -5; n <= 5; n += 5) {
824 kColorBitmaps(painter, group, cx, cy+n,
825 0, &doodad_mid, &doodad_light, 0, 0, 0);
828 break;
830 case PE_Panel:
831 case PE_PanelLineEdit:
832 case PE_PanelTabWidget:
833 case PE_TabBarBase:
834 drawPhasePanel(painter, x, y, w, h, group, flags & Style_Sunken);
835 break;
837 case PE_PanelPopup:
838 case PE_WindowFrame:
839 drawPhasePanel(painter, x, y, w, h, group, false);
840 break;
842 case PE_GroupBoxFrame:
843 case PE_PanelGroupBox:
844 painter->setPen(group.dark());
845 painter->drawRect(rect);
846 break;
848 case PE_Separator:
849 painter->setPen(group.dark());
850 if (w < h)
851 painter->drawLine(w/2, y, w/2, y2);
852 else
853 painter->drawLine(x, h/2, x2, h/2);
854 break;
856 case PE_StatusBarSection:
857 painter->setPen(group.mid());
858 painter->drawLine(x, y, x2-1, y);
859 painter->drawLine(x, y+1, x, y2-1);
860 painter->setPen(group.midlight());
861 painter->drawLine(x+1, y2, x2, y2);
862 painter->drawLine(x2, y+1, x2, y2-1);
863 break;
865 case PE_PanelMenuBar:
866 case PE_PanelDockWindow:
867 if (kicker_ && (w == 2)) { // kicker handle separator
868 painter->setPen(group.mid());
869 painter->drawLine(x, y, x, y2);
870 painter->setPen(group.midlight());
871 painter->drawLine(x+1, y, x+1, y2);
872 } else if (kicker_ && (h == 2)) { // kicker handle separator
873 painter->setPen(group.mid());
874 painter->drawLine(x, y, x2, y);
875 painter->setPen(group.midlight());
876 painter->drawLine(x, y+1, x2, y+1);
877 } else {
878 --x; --y; ++w; ++h; // adjust rect so we can use bevel
879 drawPhaseBevel(painter, x, y, w, h,
880 group, group.background(), false, (w < h),
881 (element==PE_PanelDockWindow) ? true : false);
883 break;
885 case PE_DockWindowSeparator: {
886 widget = dynamic_cast<QWidget*>(painter->device());
887 bool flat = true;
889 if (widget && widget->parent() &&
890 widget->parent()->inherits("QToolBar")) {
891 Q3ToolBar *toolbar = dynamic_cast<Q3ToolBar*>(widget->parent());
892 if (toolbar) {
893 // toolbar not floating or in a QMainWindow
894 flat = flatToolbar(toolbar);
898 if (flat)
899 painter->fillRect(rect, group.background());
900 else
901 drawPhaseGradient(painter, rect, group.background(),
902 !(horiz), 0, 0, -1, -1, true);
904 if (horiz) {
905 int cx = w/2 - 1;
906 painter->setPen(group.mid());
907 painter->drawLine(cx, 0, cx, h-2);
908 if (!flat) painter->drawLine(0, h-1, w-1, h-1);
910 painter->setPen(group.midlight());
911 painter->drawLine(cx+1, 0, cx+1, h-2);
912 } else {
913 int cy = h/2 - 1;
914 painter->setPen(group.mid());
915 painter->drawLine(0, cy, w-2, cy);
916 if (!flat) painter->drawLine(w-1, 0, w-1, h-1);
918 painter->setPen(group.midlight());
919 painter->drawLine(0, cy+1, w-2, cy+1);
921 break;
924 case PE_SizeGrip: {
925 int sw = QMIN(h, w) - 1;
926 y = y2 - sw;
928 if (reverse_) {
929 x2 = x + sw;
930 for (int n = 0; n < 4; ++n) {
931 painter->setPen(group.dark());
932 painter->drawLine(x, y, x2, y2);
933 painter->setPen(group.midlight());
934 painter->drawLine(x, y+1, x2-1, y2);
935 y += 3;;
936 x2 -= 3;;
938 } else {
939 x = x2 - sw;
940 for (int n = 0; n < 4; ++n) {
941 painter->setPen(group.dark());
942 painter->drawLine(x, y2, x2, y);
943 painter->setPen(group.midlight());
944 painter->drawLine(x+1, y2, x2, y+1);
945 x += 3;
946 y += 3;
950 break;
953 case PE_CheckMark:
954 painter->setPen(group.text());
955 painter->drawPixmap(x+w/2-4, y+h/2-4, bcheck);
956 break;
958 case PE_SpinWidgetPlus:
959 case PE_SpinWidgetMinus:
960 if (enabled)
961 painter->setPen((flags & Style_Sunken)
962 ? group.midlight() : group.dark());
963 else
964 painter->setPen(group.mid());
965 painter->drawPixmap(x+w/2-3, y+h/2-3,
966 (element==PE_SpinWidgetPlus) ? bplus : bminus);
967 break;
969 case PE_SpinWidgetUp:
970 case PE_ArrowUp:
971 if (flags & Style_Enabled)
972 painter->setPen((flags & Style_Sunken)
973 ? group.midlight() : group.dark());
974 else
975 painter->setPen(group.mid());
976 painter->drawPixmap(x+w/2-3, y+h/2-3, uarrow);
977 break;
979 case PE_SpinWidgetDown:
980 case PE_ArrowDown:
981 if (enabled) painter->setPen((flags & Style_Sunken)
982 ? group.midlight() : group.dark());
983 else painter->setPen(group.mid());
984 painter->drawPixmap(x+w/2-3, y+h/2-3, darrow);
985 break;
987 case PE_ArrowLeft:
988 if (enabled) painter->setPen((flags & Style_Sunken)
989 ? group.midlight() : group.dark());
990 else painter->setPen(group.mid());
991 painter->drawPixmap(x+w/2-3, y+h/2-3, larrow);
992 break;
994 case PE_ArrowRight:
995 if (enabled) painter->setPen((flags & Style_Sunken)
996 ? group.midlight() : group.dark());
997 else painter->setPen(group.mid());
998 painter->drawPixmap(x+w/2-3, y+h/2-3, rarrow);
999 break;
1001 default:
1002 KStyle::drawPrimitive(element, painter, rect, group, flags, option);
1006 //////////////////////////////////////////////////////////////////////////////
1007 // drawKStylePrimitive()
1008 // ---------------------
1009 // Draw the element
1011 void PhaseStyle::drawKStylePrimitive(KStylePrimitive element,
1012 QPainter *painter,
1013 const QWidget *widget,
1014 const QRect &rect,
1015 const QColorGroup &group,
1016 SFlags flags,
1017 const QStyleOption &option) const
1019 bool horiz = flags & Style_Horizontal;
1020 int x, y, w, h, x2, y2, n, cx, cy;
1022 rect.rect(&x, &y, &w, &h);
1023 x2 = rect.right();
1024 y2 = rect.bottom();
1025 cx = x + w/2;
1026 cy = y + h/2;
1028 switch (element) {
1029 case KPE_ToolBarHandle:
1030 cx-=2; cy-=2;
1031 drawPhaseGradient(painter, rect, group.background(),
1032 !horiz, 0, 0, w-1, h-1, true);
1033 if (horiz) {
1034 for (n = -5; n <= 5; n += 5) {
1035 kColorBitmaps(painter, group, cx, cy+n,
1036 0, &doodad_mid, &doodad_light, 0, 0, 0);
1038 painter->setPen(group.mid());
1039 painter->drawLine(x, y2, x2, y2);
1040 } else {
1041 for (n = -5; n <= 5; n += 5) {
1042 kColorBitmaps(painter, group, cx+n, cy,
1043 0, &doodad_mid, &doodad_light, 0, 0, 0);
1045 painter->setPen(group.mid());
1046 painter->drawLine(x2, y, x2, y2);
1048 break;
1050 //case KPE_DockWindowHandle:
1051 case KPE_GeneralHandle:
1052 cx-=2; cy-=2;
1053 painter->fillRect(rect, group.brush(QColorGroup::Background));
1055 if (horiz) {
1056 for (n = -5; n <= 5; n += 5) {
1057 kColorBitmaps(painter, group, cx, cy+n,
1058 0, &doodad_mid, &doodad_light, 0, 0, 0);
1060 } else {
1061 for (n = -5; n <= 5; n += 5) {
1062 kColorBitmaps(painter, group, cx+n, cy,
1063 0, &doodad_mid, &doodad_light, 0, 0, 0);
1066 break;
1068 case KPE_ListViewExpander:
1069 painter->setPen(group.mid());
1070 if (flags & Style_On) {
1071 painter->drawPixmap(x+w/2-4, y+h/2-4, rexpand);
1072 } else {
1073 painter->drawPixmap(x+w/2-4, y+h/2-4, dexpand);
1075 break;
1077 case KPE_ListViewBranch:
1078 painter->setPen(group.mid());
1079 if (flags & Style_Horizontal) {
1080 painter->drawLine(x, cy, x2, cy);
1081 } else {
1082 painter->drawLine(cx, y, cx, y2);
1084 break;
1086 case KPE_SliderGroove: {
1087 const QSlider* slider = dynamic_cast<const QSlider*>(widget);
1088 if (slider) {
1089 if (slider->orientation() == Horizontal) {
1090 y = cy - 3;
1091 h = 7;
1092 } else {
1093 x = cx - 3;
1094 w = 7;
1097 drawPhasePanel(painter, x, y, w, h, group, true,
1098 &group.brush(QColorGroup::Mid));
1099 break;
1102 case KPE_SliderHandle: {
1103 const QSlider* slider = dynamic_cast<const QSlider*>(widget);
1104 if (slider) {
1105 QColor color = (widget==hover_)
1106 ? group.button().light(contrast)
1107 : group.button();
1108 if (slider->orientation() == Horizontal) {
1109 drawPhaseBevel(painter, cx-5, y, 6, h, group, color,
1110 false, false, false);
1111 drawPhaseBevel(painter, cx, y, 6, h, group, color,
1112 false, false, false);
1113 } else {
1114 drawPhaseBevel(painter, x, cy-5, w, 6, group, color,
1115 false, true, false);
1116 drawPhaseBevel(painter, x, cy, w, 6, group, color,
1117 false, true, false);
1120 break;
1123 default:
1124 KStyle::drawKStylePrimitive(element, painter, widget, rect,
1125 group, flags, option);
1129 //////////////////////////////////////////////////////////////////////////////
1130 // drawControl()
1131 // -------------
1132 // Draw the control
1134 void PhaseStyle::drawControl(ControlElement element,
1135 QPainter *painter,
1136 const QWidget *widget,
1137 const QRect &rect,
1138 const QColorGroup &group,
1139 SFlags flags,
1140 const QStyleOption &option) const
1142 bool active, enabled, depress;
1143 int x, y, w, h, x2, y2, dx;
1144 QMenuItem *mi;
1145 QIcon::Mode mode;
1146 QIcon::State state;
1147 QPixmap pixmap;
1149 rect.rect(&x, &y, &w, &h);
1150 x2 = rect.right();
1151 y2 = rect.bottom();
1153 switch (element) {
1154 case CE_PushButton: {
1155 depress = flags & (Style_Down | Style_On);
1156 int bd = pixelMetric(PM_ButtonDefaultIndicator, widget) + 1;
1158 if ((flags & Style_ButtonDefault) && !depress) {
1159 drawPhasePanel(painter, x, y, w, h, group, true,
1160 &group.brush(QColorGroup::Mid));
1161 drawPhaseBevel(painter, x+bd, y+bd, w-bd*2, h-bd*2, group,
1162 (widget==hover_)
1163 ? group.button().light(contrast)
1164 : group.button(),
1165 false, false, false);
1166 } else {
1167 drawPhaseButton(painter, x, y, w, h, group,
1168 (widget==hover_)
1169 ? group.button().light(contrast)
1170 : group.button(), depress);
1173 if (flags & Style_HasFocus) { // draw focus
1174 drawPrimitive(PE_FocusRect, painter,
1175 subRect(SR_PushButtonFocusRect, widget),
1176 group, flags);
1178 break;
1181 case CE_PushButtonLabel: {
1182 const QPushButton* button = dynamic_cast<const QPushButton*>(widget);
1183 if (!button) {
1184 KStyle::drawControl(element, painter, widget, rect, group,
1185 flags, option);
1186 return;
1188 active = button->isOn() || button->isDown();
1190 if (active) { // shift contents
1191 x++; y++;
1192 flags |= Style_Sunken;
1195 if (button->isMenuButton()) { // menu indicator
1196 int dx = pixelMetric(PM_MenuButtonIndicator, widget);
1197 drawPrimitive(PE_ArrowDown, painter,
1198 QRect(x+w-dx-2, y+2, dx, h-4),
1199 group, flags, option);
1200 w -= dx;
1203 if (button->iconSet() && !button->iconSet()->isNull()) { // draw icon
1204 if (button->isEnabled()) {
1205 if (button->hasFocus()) {
1206 mode = QIcon::Active;
1207 } else {
1208 mode = QIcon::Normal;
1210 } else {
1211 mode = QIcon::Disabled;
1214 if (button->isToggleButton() && button->isOn()) {
1215 state = QIcon::On;
1216 } else {
1217 state = QIcon::Off;
1220 pixmap = button->iconSet()->pixmap(QIcon::Small, mode, state);
1221 if (button->text().isEmpty() && !button->pixmap()) {
1222 painter->drawPixmap(x+w/2 - pixmap.width()/2,
1223 y+h/2 - pixmap.height()/2, pixmap);
1224 } else {
1225 painter->drawPixmap(x+4, y+h/2 - pixmap.height()/2, pixmap);
1227 x += pixmap.width() + 4;
1228 w -= pixmap.width() + 4;
1231 if (active || button->isDefault()) { // default button
1232 for(int n=0; n<2; n++) {
1233 drawItem(painter, QRect(x+n, y, w, h),
1234 AlignCenter | ShowPrefix,
1235 button->colorGroup(),
1236 button->isEnabled(),
1237 button->pixmap(),
1238 button->text(), -1,
1239 (button->isEnabled()) ?
1240 &button->colorGroup().buttonText() :
1241 &button->colorGroup().mid());
1243 } else { // normal button
1244 drawItem(painter, QRect(x, y, w, h),
1245 AlignCenter | ShowPrefix,
1246 button->colorGroup(),
1247 button->isEnabled(),
1248 button->pixmap(),
1249 button->text(), -1,
1250 (button->isEnabled()) ?
1251 &button->colorGroup().buttonText() :
1252 &button->colorGroup().mid());
1254 break;
1257 case CE_CheckBoxLabel:
1258 case CE_RadioButtonLabel: {
1259 const Q3Button *b = dynamic_cast<const Q3Button*>(widget);
1260 if (!b) return;
1262 int alignment = reverse_ ? AlignRight : AlignLeft;
1263 drawItem(painter, rect, alignment | AlignVCenter | ShowPrefix,
1264 group, flags & Style_Enabled, b->pixmap(), b->text());
1266 // only draw focus if content (forms on html won't)
1267 if ((flags & Style_HasFocus) && ((b->text()) || b->pixmap())) {
1268 drawPrimitive(PE_FocusRect, painter,
1269 visualRect(subRect(SR_RadioButtonFocusRect,
1270 widget), widget),
1271 group, flags);
1273 break;
1276 case CE_DockWindowEmptyArea: {
1277 const Q3ToolBar *tb = dynamic_cast<const Q3ToolBar*>(widget);
1278 if (tb) {
1279 // toolbar not floating or in a QMainWindow
1280 if (flatToolbar(tb)) {
1281 if (tb->backgroundMode() == PaletteButton)
1282 // force default button color to background color
1283 painter->fillRect(rect, group.background());
1284 else
1285 painter->fillRect(rect, tb->paletteBackgroundColor());
1288 break;
1291 case CE_MenuBarEmptyArea:
1292 drawPhaseGradient(painter, QRect(x, y, w, h), group.background(),
1293 (w<h), 0, 0, 0, 0, false);
1294 break;
1296 case CE_MenuBarItem: {
1297 const QMenuBar *mbar = dynamic_cast<const QMenuBar*>(widget);
1298 if (!mbar) {
1299 KStyle::drawControl(element, painter, widget, rect, group,
1300 flags, option);
1301 return;
1303 mi = option.menuItem();
1304 QRect prect = mbar->rect();
1306 if ((flags & Style_Active) && (flags & Style_HasFocus)) {
1307 if (flags & Style_Down) {
1308 drawPhasePanel(painter, x, y, w, h, group, true,
1309 &group.brush(QColorGroup::Background));
1310 } else {
1311 drawPhaseBevel(painter, x, y, w, h,
1312 group, group.background(),
1313 false, false, false);
1315 } else {
1316 drawPhaseGradient(painter, rect, group.background(), false, x, y,
1317 prect.width()-2, prect.height()-2, false);
1319 drawItem(painter, rect,
1320 AlignCenter | AlignVCenter |
1321 DontClip | ShowPrefix | SingleLine,
1322 group, flags & Style_Enabled,
1323 mi->pixmap(), mi->text());
1324 break;
1327 case CE_PopupMenuItem: {
1328 const Q3PopupMenu *popup = dynamic_cast<const Q3PopupMenu*>(widget);
1329 if (!popup) {
1330 KStyle::drawControl(element, painter, widget, rect, group,
1331 flags, option);
1332 return;
1335 mi = option.menuItem();
1336 if (!mi) {
1337 painter->fillRect(rect, group.button());
1338 break;
1341 int tabwidth = option.tabWidth();
1342 int checkwidth = option.maxIconWidth();
1343 bool checkable = popup->isCheckable();
1344 bool etchtext = styleHint(SH_EtchDisabledText);
1345 active = flags & Style_Active;
1346 enabled = mi->isEnabled();
1347 QRect vrect;
1349 if (checkable) checkwidth = QMAX(checkwidth, 20);
1351 // draw background
1352 if (active && enabled) {
1353 painter->fillRect(x, y, w, h, group.highlight());
1354 } else if (widget->erasePixmap() &&
1355 !widget->erasePixmap()->isNull()) {
1356 painter->drawPixmap(x, y, *widget->erasePixmap(), x, y, w, h);
1357 } else {
1358 painter->fillRect(x, y, w, h, group.background());
1361 // draw separator
1362 if (mi->isSeparator()) {
1363 painter->setPen(group.dark());
1364 painter->drawLine(x+checkwidth+1, y+1, x2-checkwidth-1, y+1);
1365 painter->setPen(group.mid());
1366 painter->drawLine(x+checkwidth, y, x2-checkwidth-1, y);
1367 painter->drawPoint(x+checkwidth, y+1);
1368 painter->setPen(group.midlight());
1369 painter->drawLine(x+checkwidth+1, y2, x2-checkwidth, y2);
1370 painter->drawPoint(x2-checkwidth, y2-1);
1371 break;
1374 // draw icon
1375 if (mi->iconSet() && !mi->isChecked()) {
1376 if (active)
1377 mode = enabled ? QIcon::Active : QIcon::Disabled;
1378 else
1379 mode = enabled ? QIcon::Normal : QIcon::Disabled;
1381 pixmap = mi->iconSet()->pixmap(QIcon::Small, mode);
1382 QRect pmrect(0, 0, pixmap.width(), pixmap.height());
1383 vrect = visualRect(QRect(x, y, checkwidth, h), rect);
1384 pmrect.moveCenter(vrect.center());
1385 painter->drawPixmap(pmrect.topLeft(), pixmap);
1388 // draw check
1389 if (mi->isChecked()) {
1390 int cx = reverse_ ? x+w - checkwidth : x;
1391 drawPrimitive(PE_CheckMark, painter,
1392 QRect(cx + ITEMFRAME, y + ITEMFRAME,
1393 checkwidth - ITEMFRAME*2, h - ITEMFRAME*2),
1394 group, Style_Default |
1395 (active ? Style_Enabled : Style_On));
1398 // draw text
1399 int xm = ITEMFRAME + checkwidth + ITEMHMARGIN;
1400 int xp = reverse_ ?
1401 x + tabwidth + RIGHTBORDER + ITEMHMARGIN + ITEMFRAME - 1 :
1402 x + xm;
1403 int offset = reverse_ ? -1 : 1;
1404 int tw = w - xm - tabwidth - ARROWMARGIN - ITEMHMARGIN * 3
1405 - ITEMFRAME + 1;
1407 painter->setPen(enabled ? (active ? group.highlightedText() :
1408 group.buttonText()) : group.mid());
1410 if (mi->custom()) { // draws own label
1411 painter->save();
1412 if (etchtext && !enabled && !active) {
1413 painter->setPen(group.light());
1414 mi->custom()->paint(painter, group, active, enabled,
1415 xp+offset, y+ITEMVMARGIN+1,
1416 tw, h-2*ITEMVMARGIN);
1417 painter->setPen(group.mid());
1419 mi->custom()->paint(painter, group, active, enabled,
1420 xp, y+ITEMVMARGIN, tw, h-2*ITEMVMARGIN);
1421 painter->restore();
1423 else { // draw label
1424 QString text = mi->text();
1426 if (!text.isNull()) {
1427 int t = text.find('\t');
1428 int tflags = AlignVCenter | DontClip |
1429 ShowPrefix | SingleLine |
1430 (reverse_ ? AlignRight : AlignLeft);
1432 if (t >= 0) {
1433 int tabx = reverse_ ?
1434 x + RIGHTBORDER + ITEMHMARGIN + ITEMFRAME :
1435 x + w - tabwidth - RIGHTBORDER - ITEMHMARGIN
1436 - ITEMFRAME;
1438 // draw right label (accerator)
1439 if (etchtext && !enabled) { // etched
1440 painter->setPen(group.light());
1441 painter->drawText(tabx+offset, y+ITEMVMARGIN+1,
1442 tabwidth, h-2*ITEMVMARGIN,
1443 tflags, text.mid(t+1));
1444 painter->setPen(group.mid());
1446 painter->drawText(tabx, y+ITEMVMARGIN,
1447 tabwidth, h-2*ITEMVMARGIN,
1448 tflags, text.mid(t+1));
1449 text = text.left(t);
1452 // draw left label
1453 if (etchtext && !enabled) { // etched
1454 painter->setPen(group.light());
1455 painter->drawText(xp+offset, y+ITEMVMARGIN+1,
1456 tw, h-2*ITEMVMARGIN,
1457 tflags, text, t);
1458 painter->setPen(group.mid());
1460 painter->drawText(xp, y+ITEMVMARGIN,
1461 tw, h-2*ITEMVMARGIN,
1462 tflags, text, t);
1464 else if (mi->pixmap()) { // pixmap as label
1465 pixmap = *mi->pixmap();
1466 if (pixmap.depth() == 1)
1467 painter->setBackgroundMode(OpaqueMode);
1469 dx = ((w - pixmap.width()) / 2) + ((w - pixmap.width()) % 2);
1470 painter->drawPixmap(x+dx, y+ITEMFRAME, pixmap);
1472 if (pixmap.depth() == 1)
1473 painter->setBackgroundMode(TransparentMode);
1477 if (mi->popup()) { // draw submenu arrow
1478 PrimitiveElement arrow = reverse_ ? PE_ArrowLeft : PE_ArrowRight;
1479 int dim = (h-2*ITEMFRAME) / 2;
1480 vrect = visualRect(QRect(x + w - ARROWMARGIN - ITEMFRAME - dim,
1481 y + h / 2 - dim / 2, dim, dim), rect);
1482 drawPrimitive(arrow, painter, vrect, group,
1483 enabled ? Style_Enabled : Style_Default);
1485 break;
1488 case CE_TabBarTab: {
1489 const QTabBar* tab = dynamic_cast<const QTabBar*>(widget);
1490 if (tab) {
1491 if ((widget == hover_) && (option.tab() == hovertab_)) {
1492 flags |= Style_MouseOver;
1494 // this guy can get complicated, we we do it elsewhere
1495 drawPhaseTab(painter, x, y, w, h, group, tab, option,
1496 flags);
1497 } else { // not a tabbar
1498 KStyle::drawControl(element, painter, widget, rect, group,
1499 flags, option);
1500 return;
1502 break;
1505 case CE_ProgressBarGroove: {
1506 drawPhasePanel(painter, x, y, w, h, group, true,
1507 &group.brush(QColorGroup::Base));
1508 break;
1511 case CE_ProgressBarContents: {
1512 const Q3ProgressBar* pbar = dynamic_cast<const Q3ProgressBar*>(widget);
1513 if (!pbar) {
1514 KStyle::drawControl(element, painter, widget, rect, group,
1515 flags, option);
1516 return;
1518 subRect(SR_ProgressBarContents, widget).rect(&x, &y, &w, &h);
1520 painter->setBrush(group.brush(QColorGroup::Highlight));
1521 painter->setPen(group.dark());
1523 if (!pbar->totalSteps()) {
1524 // busy indicator
1525 int bar = pixelMetric(PM_ProgressBarChunkWidth, widget) + 2;
1526 int progress = pbar->progress() % ((w-bar) * 2);
1527 if (progress > (w-bar)) progress = 2 * (w-bar) - progress;
1528 painter->drawRect(x+progress+1, y+1, bar-2, h-2);
1529 } else {
1530 double progress = static_cast<double>(pbar->progress()) /
1531 static_cast<double>(pbar->totalSteps());
1532 dx = static_cast<int>(w * progress);
1533 if (dx < 4) break;
1534 if (reverse_) x += w - dx;
1535 painter->drawRect(x+1, y+1, dx-2, h-2);
1537 break;
1540 #if (QT_VERSION >= 0x030200)
1541 case CE_ToolBoxTab: {
1542 const QToolBox *box = dynamic_cast<const QToolBox*>(widget);
1543 if (!box) {
1544 KStyle::drawControl(element, painter, widget, rect, group,
1545 flags, option);
1546 return;
1549 const int rx = x2 - 20;
1550 const int cx = rx - h + 1;
1552 Q3PointArray parray(6);
1553 parray.putPoints(0, 6,
1554 x-1,y, cx,y, rx-2,y2-2, x2+1,y2-2,
1555 x2+1,y2+2, x-1,y2+2);
1557 if (box->currentItem() && (flags & Style_Selected)) {
1558 painter->setPen(group.dark());
1559 painter->setBrush(box->currentItem()->paletteBackgroundColor());
1560 painter->drawConvexPolygon(parray, 0, 6);
1561 painter->setBrush(Qt::NoBrush);
1562 } else {
1563 painter->setClipRegion(parray, QPainter::CoordPainter);
1564 drawPhaseGradient(painter, rect,
1565 group.background(),
1566 false, 0, 0, 0, h*2, false);
1567 painter->setClipping(false);
1568 painter->drawPolyline(parray, 0, 4);
1571 parray.putPoints(0, 4, x,y+1, cx,y+1, rx-2,y2-1, x2,y2-1);
1572 painter->setPen(group.midlight());
1573 painter->drawPolyline(parray, 0, 4);
1575 break;
1577 #endif
1579 default:
1580 KStyle::drawControl(element, painter, widget, rect, group,
1581 flags, option);
1585 //////////////////////////////////////////////////////////////////////////////
1586 // drawControlMask()
1587 // -----------------
1588 // Draw a bitmask for the element
1590 void PhaseStyle::drawControlMask(ControlElement element,
1591 QPainter *painter,
1592 const QWidget *widget,
1593 const QRect &rect,
1594 const QStyleOption &option) const
1596 switch (element) {
1597 case CE_PushButton:
1598 painter->fillRect(rect, Qt::color1);
1599 painter->setPen(Qt::color0);
1600 break;
1602 default:
1603 KStyle::drawControlMask(element, painter, widget, rect, option);
1607 //////////////////////////////////////////////////////////////////////////////
1608 // drawComplexControl()
1609 // --------------------
1610 // Draw a complex control
1612 void PhaseStyle::drawComplexControl(ComplexControl control,
1613 QPainter *painter,
1614 const QWidget *widget,
1615 const QRect &rect,
1616 const QColorGroup &group,
1617 SFlags flags,
1618 SCFlags controls,
1619 SCFlags active,
1620 const QStyleOption &option) const
1622 bool down = flags & Style_Down;
1623 bool on = flags & Style_On;
1624 bool raised = flags & Style_Raised;
1625 bool sunken = flags & Style_Sunken;
1626 QRect subrect;
1627 int x, y, w, h, x2, y2;
1628 rect.rect(&x, &y, &w, &h);
1630 switch (control) {
1631 case CC_ComboBox: {
1632 const QComboBox * combo = dynamic_cast<const QComboBox*>(widget);
1633 if (!combo) {
1634 KStyle::drawComplexControl(control, painter, widget, rect, group,
1635 flags, controls, active, option);
1636 return;
1639 sunken = (active == SC_ComboBoxArrow);
1640 drawPhaseButton(painter, x, y, w, h, group,
1641 (widget==hover_)
1642 ? group.button().light(contrast)
1643 : group.button(), sunken);
1645 if (controls & SC_ComboBoxArrow) { // draw arrow box
1646 subrect = visualRect(querySubControlMetrics(CC_ComboBox, widget,
1647 SC_ComboBoxArrow), widget);
1649 subrect.rect(&x, &y, &w, &h);
1650 int slot = QMAX(h/4, 6) + (h % 2);
1651 drawPhasePanel(painter, x+3, y+(h/2)-(slot/2), w-6,
1652 slot, group, true,
1653 sunken ? &group.brush(QColorGroup::Midlight)
1654 : &group.brush(QColorGroup::Mid));
1657 if (controls & SC_ComboBoxEditField) { // draw edit box
1658 if (combo->editable()) { // editable box
1659 subrect = visualRect(querySubControlMetrics(CC_ComboBox,
1660 widget, SC_ComboBoxEditField), widget);
1661 x2 = subrect.right(); y2 = subrect.bottom();
1662 painter->setPen(group.dark());
1663 painter->drawLine(x2+1, y, x2+1, y2);
1664 painter->setPen(group.midlight());
1665 painter->drawLine(x2+2, y, x2+2, y2-1);
1666 painter->setPen(group.button());
1667 painter->drawPoint(x2+2, y2);
1668 } else if (combo->hasFocus()) { // non editable box
1669 subrect = visualRect(subRect(SR_ComboBoxFocusRect,
1670 combo), widget);
1671 drawPrimitive(PE_FocusRect, painter, subrect, group,
1672 Style_FocusAtBorder,
1673 QStyleOption(group.highlight()));
1677 painter->setPen(group.buttonText()); // for subsequent text
1678 break;
1681 case CC_ScrollBar: {
1682 // always a three button scrollbar
1683 const QScrollBar *sb = dynamic_cast<const QScrollBar*>(widget);
1684 if (!sb) {
1685 KStyle::drawComplexControl(control, painter, widget, rect, group,
1686 flags, controls, active, option);
1687 return;
1690 QRect srect;
1691 bool horizontal = (sb->orientation() == Qt::Horizontal);
1692 SFlags scrollflags = (horizontal ? Style_Horizontal : Style_Default);
1694 if (sb->minValue() == sb->maxValue()) scrollflags |= Style_Default;
1695 else scrollflags |= Style_Enabled;
1697 // addline
1698 if (controls & SC_ScrollBarAddLine) {
1699 srect = querySubControlMetrics(control, widget,
1700 SC_ScrollBarAddLine, option);
1701 if (srect.isValid())
1702 drawPrimitive(PE_ScrollBarAddLine, painter, srect, group,
1703 scrollflags | ((active == SC_ScrollBarAddLine)
1704 ? Style_Down : Style_Default));
1707 // subline (two of them)
1708 if (controls & SC_ScrollBarSubLine) {
1709 // top/left subline
1710 srect = querySubControlMetrics(control, widget,
1711 SC_ScrollBarSubLine, option);
1712 if (srect.isValid())
1713 drawPrimitive(PE_ScrollBarSubLine, painter, srect, group,
1714 scrollflags | ((active == SC_ScrollBarSubLine)
1715 ? Style_Down : Style_Default));
1716 // bottom/right subline
1717 srect = querySubControlMetrics(control, widget,
1718 SC_ScrollBarAddLine, option);
1719 if (srect.isValid()) {
1720 if (horizontal) srect.moveBy(-srect.width()+1, 0);
1721 else srect.moveBy(0, -srect.height()+1);
1722 drawPrimitive(PE_ScrollBarSubLine, painter, srect, group,
1723 scrollflags | ((active == SC_ScrollBarSubLine)
1724 ? Style_Down : Style_Default));
1728 // addpage
1729 if (controls & SC_ScrollBarAddPage) {
1730 srect = querySubControlMetrics(control, widget,
1731 SC_ScrollBarAddPage, option);
1732 if (srect.isValid()) {
1733 if (horizontal) srect.addCoords(1, 0, 1, 0);
1734 else srect.addCoords(0, 1, 0, 1);
1735 drawPrimitive(PE_ScrollBarAddPage, painter, srect, group,
1736 scrollflags | ((active == SC_ScrollBarAddPage)
1737 ? Style_Down : Style_Default));
1741 // subpage
1742 if (controls & SC_ScrollBarSubPage) {
1743 srect = querySubControlMetrics(control, widget,
1744 SC_ScrollBarSubPage, option);
1745 if (srect.isValid()) {
1746 drawPrimitive(PE_ScrollBarSubPage, painter, srect, group,
1747 scrollflags | ((active == SC_ScrollBarSubPage)
1748 ? Style_Down : Style_Default));
1752 // slider
1753 if (controls & SC_ScrollBarSlider) {
1754 srect = querySubControlMetrics(control, widget,
1755 SC_ScrollBarSlider, option);
1756 if (srect.isValid()) {
1757 if (horizontal) srect.addCoords(0, 0, 1, 0);
1758 else srect.addCoords(0, 0, 0, 1);
1759 drawPrimitive(PE_ScrollBarSlider, painter, srect, group,
1760 scrollflags | ((active == SC_ScrollBarSlider)
1761 ? Style_Down : Style_Default));
1762 // focus
1763 if (sb->hasFocus()) {
1764 srect.addCoords(2, 2, -2, -2);
1765 drawPrimitive(PE_FocusRect, painter, srect, group,
1766 Style_Default);
1770 break;
1773 case CC_SpinWidget: {
1774 const Q3SpinWidget *spin = dynamic_cast<const Q3SpinWidget*>(widget);
1775 if (!spin) {
1776 KStyle::drawComplexControl(control, painter, widget, rect, group,
1777 flags, controls, active, option);
1778 return;
1781 PrimitiveElement element;
1783 // draw frame
1784 if (controls & SC_SpinWidgetFrame) {
1785 drawPhasePanel(painter, x, y, w, h, group, true, NULL);
1788 // draw button field
1789 if (controls & SC_SpinWidgetButtonField) {
1790 subrect = querySubControlMetrics(CC_SpinWidget, widget,
1791 SC_SpinWidgetButtonField,
1792 option);
1793 if (reverse_) subrect.moveLeft(spin->upRect().left());
1794 drawPhaseBevel(painter, subrect.x(), subrect.y(),
1795 subrect.width(), subrect.height(), group,
1796 (widget==hover_)
1797 ? group.button().light(contrast)
1798 : group.button(), false, false, false);
1801 // draw up arrow
1802 if (controls & SC_SpinWidgetUp) {
1803 subrect = spin->upRect();
1805 sunken = (active == SC_SpinWidgetUp);
1806 if (spin->buttonSymbols() == Q3SpinWidget::PlusMinus)
1807 element = PE_SpinWidgetPlus;
1808 else
1809 element = PE_SpinWidgetUp;
1811 drawPrimitive(element, painter, subrect, group, flags
1812 | ((active == SC_SpinWidgetUp)
1813 ? Style_On | Style_Sunken : Style_Raised));
1816 // draw down button
1817 if (controls & SC_SpinWidgetDown) {
1818 subrect = spin->downRect();
1820 sunken = (active == SC_SpinWidgetDown);
1821 if (spin->buttonSymbols() == Q3SpinWidget::PlusMinus)
1822 element = PE_SpinWidgetMinus;
1823 else
1824 element = PE_SpinWidgetDown;
1826 drawPrimitive(element, painter, subrect, group, flags
1827 | ((active == SC_SpinWidgetDown)
1828 ? Style_On | Style_Sunken : Style_Raised));
1830 break;
1833 case CC_ToolButton: {
1834 const QToolButton *btn = dynamic_cast<const QToolButton*>(widget);
1835 if (!btn) {
1836 KStyle::drawComplexControl(control, painter, widget, rect, group,
1837 flags, controls, active, option);
1838 return;
1841 Q3ToolBar *toolbar;
1842 bool horiz = true;
1843 bool normal = !(down || on || raised); // normal button state
1845 x2 = rect.right();
1846 y2 = rect.bottom();
1848 // check for QToolBar parent
1849 if (btn->parent() && btn->parent()->inherits("QToolBar")) {
1850 toolbar = dynamic_cast<Q3ToolBar*>(btn->parent());
1851 if (toolbar) {
1852 horiz = (toolbar->orientation() == Qt::Horizontal);
1853 if (normal) { // draw background
1854 if (flatToolbar(toolbar)) {
1855 // toolbar not floating or in a QMainWindow
1856 painter->fillRect(rect, group.background());
1857 } else {
1858 drawPhaseGradient(painter, rect, group.background(),
1859 !horiz, 0, 0,
1860 toolbar->width()-3,
1861 toolbar->height()-3, true);
1862 painter->setPen(group.mid());
1863 if (horiz) {
1864 painter->drawLine(x, y2, x2, y2);
1865 } else {
1866 painter->drawLine(x2, y, x2, y2);
1872 // check for QToolBarExtensionWidget parent
1873 else if (btn->parent() &&
1874 btn->parent()->inherits(QTOOLBAREXTENSION)) {
1875 QWidget *extension;
1876 if ((extension = dynamic_cast<QWidget*>(btn->parent()))) {
1877 toolbar = dynamic_cast<Q3ToolBar*>(extension->parent());
1878 if (toolbar) {
1879 horiz = (toolbar->orientation() == Qt::Horizontal);
1880 if (normal) { // draw background
1881 drawPhaseGradient(painter, rect, group.background(),
1882 !horiz, 0, 0, toolbar->width()-3,
1883 toolbar->height()-3, true);
1888 // check for background pixmap
1889 else if (normal && btn->parentWidget() &&
1890 btn->parentWidget()->backgroundPixmap() &&
1891 !btn->parentWidget()->backgroundPixmap()->isNull()) {
1892 QPixmap pixmap = *(btn->parentWidget()->backgroundPixmap());
1893 painter->drawTiledPixmap(rect, pixmap, btn->pos());
1895 // everything else
1896 else if (normal) {
1897 // toolbutton not on a toolbar
1898 painter->fillRect(rect, group.background());
1901 // now draw active buttons
1902 if (down || on) {
1903 drawPhasePanel(painter, x, y, w, h, group, true,
1904 &group.brush(QColorGroup::Button));
1905 } else if (raised) {
1906 drawPhaseBevel(painter, x, y, w, h, group, group.button(),
1907 false, !horiz, true);
1909 painter->setPen(group.text());
1910 break;
1913 default:
1914 KStyle::drawComplexControl(control, painter, widget, rect, group,
1915 flags, controls, active, option);
1916 break;
1920 //////////////////////////////////////////////////////////////////////////////
1921 // drawComplexControlMask()
1922 // ------------------------
1923 // Draw a bitmask for the control
1925 void PhaseStyle::drawComplexControlMask(ComplexControl control,
1926 QPainter *painter,
1927 const QWidget *widget,
1928 const QRect &rect,
1929 const QStyleOption &option) const
1931 switch (control) {
1932 case CC_ComboBox:
1933 case CC_ToolButton: {
1934 painter->fillRect(rect, Qt::color1);
1935 painter->setPen(Qt::color0);
1936 break;
1939 default:
1940 KStyle::drawComplexControlMask(control,painter,widget,rect,option);
1944 //////////////////////////////////////////////////////////////////////////////
1945 // pixelMetric()
1946 // -------------
1947 // Get the pixel metric for metric
1949 int PhaseStyle::pixelMetric(PixelMetric metric, const QWidget *widget) const
1951 // not using widget's font, so that all metrics are uniform
1952 int em = QMAX(QApplication::fontMetrics().strikeOutPos() * 3, 17);
1954 switch (metric) {
1955 case PM_DefaultFrameWidth:
1956 return 2;
1958 case PM_ButtonDefaultIndicator: // size of default indicator
1959 return 2;
1961 case PM_ButtonMargin: // Space betweeen frame and label
1962 return 3;
1964 case PM_TabBarTabOverlap: // Amount of tab overlap
1965 return 1;
1967 case PM_TabBarTabHSpace: // extra tab spacing
1968 return 24;
1970 case PM_TabBarTabVSpace:
1971 if (const QTabBar *tb = dynamic_cast<const QTabBar*>(widget)) {
1972 if (tb->shape() == QTabBar::RoundedAbove) {
1973 return 10;
1974 } else {
1975 return 6;
1978 return 0;
1980 case PM_ExclusiveIndicatorWidth: // radiobutton size
1981 case PM_ExclusiveIndicatorHeight:
1982 case PM_IndicatorWidth: // checkbox size
1983 case PM_IndicatorHeight:
1984 case PM_CheckListButtonSize: // checkbox size in qlistview items
1985 case PM_ScrollBarExtent: // base width of a vertical scrollbar
1986 return em & 0xfffe;
1988 case PM_SplitterWidth: // width of spitter
1989 return (em / 3) & 0xfffe;
1991 case PM_ScrollBarSliderMin: // minimum length of slider
1992 return em * 2;
1994 case PM_SliderThickness: // slider thickness
1995 case PM_SliderControlThickness:
1996 return em;
1998 default:
1999 return KStyle::pixelMetric(metric, widget);
2003 //////////////////////////////////////////////////////////////////////////////
2004 // querySubControlMetrics()
2005 // ------------------------
2006 // Get metrics for subcontrols of complex controls
2008 QRect PhaseStyle::querySubControlMetrics(ComplexControl control,
2009 const QWidget *widget,
2010 SubControl subcontrol,
2011 const QStyleOption &option) const
2013 QRect rect;
2015 const int fw = pixelMetric(PM_DefaultFrameWidth, widget);
2016 int w = widget->width(), h = widget->height();
2017 int xc;
2019 switch (control) {
2021 case CC_ComboBox: {
2022 xc = h; // position between edit and arrow
2024 switch (subcontrol) {
2025 case SC_ComboBoxFrame: // total combobox area
2026 rect = widget->rect();
2027 break;
2029 case SC_ComboBoxArrow: // the right side
2030 rect.setRect(w-xc, fw, xc-fw, h-(fw*2));
2031 break;
2033 case SC_ComboBoxEditField: // the left side
2034 rect.setRect(fw, fw, w-xc-fw-1, h-(fw*2));
2035 break;
2037 case SC_ComboBoxListBoxPopup: // the list popup box
2038 rect = option.rect();
2039 break;
2041 default:
2042 break;
2044 break;
2047 case CC_ScrollBar: {
2048 const QScrollBar *sb = dynamic_cast<const QScrollBar*>(widget);
2049 if (!sb) break;
2051 bool horizontal = (sb->orientation() == Qt::Horizontal);
2052 rect = KStyle::querySubControlMetrics(control, widget,
2053 subcontrol, option);
2055 // adjust the standard metrics so controls can "overlap"
2056 if (subcontrol == SC_ScrollBarGroove) {
2057 if (horizontal) rect.addCoords(-1, 0, 1, 0);
2058 else rect.addCoords(0, -1, 0, 1);
2060 break;
2063 case CC_SpinWidget: {
2064 bool odd = widget->height() % 2;
2065 xc = (h * 3 / 4) + odd; // position between edit and arrows
2067 switch (subcontrol) {
2068 case SC_SpinWidgetButtonField:
2069 rect.setRect(w-xc, 1, xc-1, h-2);
2070 break;
2072 case SC_SpinWidgetEditField:
2073 rect.setRect(fw, fw, w-xc-fw, h-(fw*2));
2074 break;
2076 case SC_SpinWidgetFrame:
2077 rect = widget->rect();
2078 break;
2080 case SC_SpinWidgetUp:
2081 rect.setRect(w-xc, (h/2)-(odd ? 6 : 7), xc-1, 6);
2082 break;
2084 case SC_SpinWidgetDown:
2085 rect.setRect(w-xc, (h/2)+1, xc-1, odd ? 7 : 6);
2086 break;
2088 default:
2089 break;
2091 break;
2094 default:
2095 rect = KStyle::querySubControlMetrics(control, widget, subcontrol,
2096 option);
2099 return rect;
2102 //////////////////////////////////////////////////////////////////////////////
2103 // sizeFromContents()
2104 // ------------------
2105 // Returns the size of widget based on the contentsize
2107 QSize PhaseStyle::sizeFromContents(ContentsType contents,
2108 const QWidget* widget,
2109 const QSize &contentsize,
2110 const QStyleOption &option ) const
2112 int w = contentsize.width();
2113 int h = contentsize.height();
2115 switch (contents) {
2116 case CT_PushButton: {
2117 const QPushButton* button = dynamic_cast<const QPushButton*>(widget);
2118 if (!button) {
2119 return KStyle::sizeFromContents(contents, widget, contentsize,
2120 option);
2122 int margin = pixelMetric(PM_ButtonMargin, widget)
2123 + pixelMetric(PM_DefaultFrameWidth, widget) + 4;
2125 w += margin + 6; // add room for bold font
2126 h += margin;
2128 // standard width and heights
2129 if (button->isDefault() || button->autoDefault()) {
2130 if (w < 80 && !button->pixmap()) w = 80;
2132 if (h < 22) h = 22;
2133 return QSize(w, h);
2136 case CT_PopupMenuItem: {
2137 if (!widget || option.isDefault()) return contentsize;
2138 const Q3PopupMenu *popup = dynamic_cast<const Q3PopupMenu*>(widget);
2139 if (!popup) {
2140 return KStyle::sizeFromContents(contents, widget, contentsize,
2141 option);
2143 QMenuItem *item = option.menuItem();
2145 if (item->custom()) {
2146 w = item->custom()->sizeHint().width();
2147 h = item->custom()->sizeHint().height();
2148 if (!item->custom()->fullSpan())
2149 h += ITEMVMARGIN*2 + ITEMFRAME*2;
2150 } else if (item->widget()) { // a menu item that is a widget
2151 w = contentsize.width();
2152 h = contentsize.height();
2153 } else if (item->isSeparator()) {
2154 w = h = 3;
2155 } else {
2156 if (item->pixmap()) {
2157 h = QMAX(h, item->pixmap()->height() + ITEMFRAME*2);
2158 } else {
2159 h = QMAX(h, MINICONSIZE + ITEMFRAME*2);
2160 h = QMAX(h, popup->fontMetrics().height()
2161 + ITEMVMARGIN*2 + ITEMFRAME*2);
2163 if (item->iconSet())
2164 h = QMAX(h, item->iconSet()->
2165 pixmap(QIcon::Small, QIcon::Normal).height()
2166 + ITEMFRAME*2);
2169 if (!item->text().isNull() && item->text().find('\t') >= 0)
2170 w += 12;
2171 else if (item->popup())
2172 w += 2 * ARROWMARGIN;
2174 if (option.maxIconWidth() || popup->isCheckable()) {
2175 w += QMAX(option.maxIconWidth(),
2176 QIcon::iconSize(QIcon::Small).width())
2177 + ITEMHMARGIN*2;
2179 w += RIGHTBORDER;
2180 return QSize(w, h);
2183 default:
2184 return KStyle::sizeFromContents(contents, widget, contentsize,
2185 option);
2189 //////////////////////////////////////////////////////////////////////////////
2190 // Miscellaneous //
2191 //////////////////////////////////////////////////////////////////////////////
2193 //////////////////////////////////////////////////////////////////////////////
2194 // flatToolbar()
2195 // -------------
2196 // Is the toolbar "flat"
2198 bool PhaseStyle::flatToolbar(const Q3ToolBar *toolbar) const
2200 if (!toolbar) return true; // not on a toolbar
2201 if (!toolbar->isMovingEnabled()) return true; // immobile toolbars are flat
2202 if (!toolbar->area()) return true; // not docked
2203 if (toolbar->place() == Q3DockWindow::OutsideDock) return true; // ditto
2204 if (!toolbar->mainWindow()) return true; // not in a main window
2205 return false;
2208 //////////////////////////////////////////////////////////////////////////////
2209 // eventFilter()
2210 // -------------
2211 // Grab events we are interested in. Most of this routine is to handle the
2212 // exceptions to the normal styling rules.
2214 bool PhaseStyle::eventFilter(QObject *object, QEvent *event)
2216 if (KStyle::eventFilter(object, event)) return true;
2217 if (!object->isWidgetType()) return false;
2219 bool horiz;
2220 int x, y, w, h;
2221 Q3Frame *frame;
2222 Q3ToolBar *toolbar;
2223 QWidget *widget;
2225 // painting events
2226 if (event->type() == QEvent::Paint) {
2227 // make sure we do the most specific stuff first
2229 // KDE Toolbar Widget
2230 // patch by Daniel Brownlees <dbrownlees@paradise.net.nz>
2231 if (object->parent() && !qstrcmp(object->name(), KTOOLBARWIDGET)) {
2232 if (0 == (widget = dynamic_cast<QWidget*>(object))) return false;
2233 QWidget *parent = dynamic_cast<QWidget*>(object->parent());
2234 int px = widget->x(), py = widget->y();
2235 // find the toolbar
2236 while (parent && parent->parent()
2237 && !dynamic_cast<Q3ToolBar*>(parent)) {
2238 px += parent->x();
2239 py += parent->y();
2240 parent = dynamic_cast<QWidget*>(parent->parent());
2242 if (!parent) return false;
2243 widget->rect().rect(&x, &y, &w, &h);
2244 QRect prect = parent->rect();
2246 toolbar = dynamic_cast<Q3ToolBar*>(parent);
2247 horiz = (toolbar) ? (toolbar->orientation() == Qt::Horizontal)
2248 : (prect.height() < prect.width());
2249 QPainter painter(widget);
2250 if (flatToolbar(toolbar)) {
2251 painter.fillRect(widget->rect(),
2252 parent->colorGroup().background());
2253 } else {
2254 drawPhaseGradient(&painter, widget->rect(),
2255 parent->colorGroup().background(),
2256 !horiz, px, py,
2257 prect.width(), prect.height(), true);
2258 if (horiz && (h==prect.height()-2)) {
2259 painter.setPen(parent->colorGroup().mid());
2260 painter.drawLine(x, h-1, w-1, h-1);
2261 } else if (!horiz && (w==prect.width()-2)) {
2262 painter.setPen(parent->colorGroup().mid());
2263 painter.drawLine(w-1, y, w-1, h-1);
2268 // QToolBarExtensionWidget
2269 else if ((object->parent()) &&
2270 (toolbar = dynamic_cast<Q3ToolBar*>(object->parent()))) {
2271 if (0 == (widget = dynamic_cast<QWidget*>(object))) return false;
2272 horiz = (toolbar->orientation() == Qt::Horizontal);
2273 QPainter painter(widget);
2274 widget->rect().rect(&x, &y, &w, &h);
2275 // draw the extension
2276 drawPhaseGradient(&painter, widget->rect(),
2277 toolbar->colorGroup().background(),
2278 !horiz, x, y, w-1, h-1, true);
2279 if (horiz) {
2280 painter.setPen(toolbar->colorGroup().dark());
2281 painter.drawLine(w-1, 0, w-1, h-1);
2282 painter.setPen(toolbar->colorGroup().mid());
2283 painter.drawLine(w-2, 0, w-2, h-2);
2284 painter.drawLine(x, h-1, w-2, h-1);
2285 painter.drawLine(x, y, x, h-2);
2286 painter.setPen(toolbar->colorGroup().midlight());
2287 painter.drawLine(x+1, y, x+1, h-2);
2288 } else {
2289 painter.setPen(toolbar->colorGroup().dark());
2290 painter.drawLine(0, h-1, w-1, h-1);
2291 painter.setPen(toolbar->colorGroup().mid());
2292 painter.drawLine(0, h-2, w-2, h-2);
2293 painter.drawLine(w-1, y, w-1, h-2);
2294 painter.drawLine(x, y, w-2, y);
2295 painter.setPen(toolbar->colorGroup().midlight());
2296 painter.drawLine(x, y+1, w-2, y+1);
2300 // QFrame lines (do this guy last)
2301 else if (0 != (frame = dynamic_cast<Q3Frame*>(object))) {
2302 Q3Frame::Shape shape = frame->frameShape();
2303 switch (shape) {
2304 case Q3Frame::HLine:
2305 case Q3Frame::VLine: {
2306 // NOTE: assuming lines have no content
2307 QPainter painter(frame);
2308 frame->rect().rect(&x, &y, &w, &h);
2309 painter.setPen(frame->colorGroup().dark());
2310 if (shape == Q3Frame::HLine) {
2311 painter.drawLine(0, h/2, w, h/2);
2312 } else if (shape == Q3Frame::VLine) {
2313 painter.drawLine(w/2, 0, w/2, h);
2315 return true;
2317 default:
2318 break;
2322 } else if (highlights_) { // "mouseover" events
2323 if (::qt_cast<QPushButton*>(object) ||
2324 ::qt_cast<QComboBox*>(object) ||
2325 ::qt_cast<Q3SpinWidget*>(object) ||
2326 ::qt_cast<QCheckBox*>(object) ||
2327 ::qt_cast<QRadioButton*>(object) ||
2328 ::qt_cast<QSlider*>(object) ||
2329 object->inherits(QSPLITTERHANDLE)) {
2330 if (event->type() == QEvent::Enter) {
2331 if (0 != (widget = dynamic_cast<QWidget*>(object)) &&
2332 widget->isEnabled()) {
2333 hover_ = widget;
2334 widget->repaint(false);
2336 } else if (event->type() == QEvent::Leave) {
2337 if (0 != (widget = dynamic_cast<QWidget*>(object))) {
2338 hover_ = 0;
2339 widget->repaint(false);
2342 } else if (::qt_cast<QTabBar*>(object)) { // special case for qtabbar
2343 if (event->type() == QEvent::Enter) {
2344 if (0 != (widget = dynamic_cast<QWidget*>(object)) &&
2345 widget->isEnabled()) {
2346 hover_ = widget;
2347 hovertab_ = 0;;
2348 widget->repaint(false);
2350 } else if (event->type() == QEvent::Leave) {
2351 if (0 != (widget = dynamic_cast<QWidget*>(object))) {
2352 hover_ = 0;
2353 hovertab_ = 0;;
2354 widget->repaint(false);
2356 } else if (event->type() == QEvent::MouseMove) {
2357 QTabBar *tabbar;
2358 if (0 != (tabbar = dynamic_cast<QTabBar*>(object))) {
2359 QMouseEvent *me;
2360 if (0 != (me = dynamic_cast<QMouseEvent*>(event))) {
2361 QTab *tab = tabbar->selectTab(me->pos());
2362 if (hovertab_ != tab) {
2363 hovertab_ = tab;
2364 tabbar->repaint(false);
2372 return false;
2375 //////////////////////////////////////////////////////////////////////////////
2376 // GradientSet //
2377 //////////////////////////////////////////////////////////////////////////////
2379 //////////////////////////////////////////////////////////////////////////////
2380 // GradientSet()
2381 // -------------
2382 // Constructor
2384 GradientSet::GradientSet(const QColor &color, int size)
2385 : color_(color), size_(size)
2387 for (int n=0; n<GradientTypeCount; ++n) set[n] = 0;
2390 //////////////////////////////////////////////////////////////////////////////
2391 // ~GradientSet()
2392 // --------------
2393 // Destructor
2395 GradientSet::~GradientSet()
2397 for (int n=0; n<GradientTypeCount; ++n) if (set[n]) delete set[n];
2400 //////////////////////////////////////////////////////////////////////////////
2401 // gradient()
2402 // ----------
2403 // Return the appropriate gradient pixmap
2405 KPixmap* GradientSet::gradient(bool horizontal, bool reverse)
2407 GradientType type;
2409 if (horizontal) {
2410 type = (reverse) ? HorizontalReverse : Horizontal;
2411 } else {
2412 type = (reverse) ? VerticalReverse : Vertical;
2415 // lazy allocate
2416 if (!set[type]) {
2417 set[type] = new KPixmap();
2418 switch (type) {
2419 case Horizontal:
2420 set[type]->resize(size_, 16);
2421 KPixmapEffect::gradient(*set[type],
2422 color_.light(contrast),
2423 color_.dark(contrast),
2424 KPixmapEffect::HorizontalGradient);
2425 break;
2427 case HorizontalReverse:
2428 set[type]->resize(size_, 16);
2429 KPixmapEffect::gradient(*set[type],
2430 color_.dark(contrast),
2431 color_.light(contrast),
2432 KPixmapEffect::HorizontalGradient);
2433 break;
2435 case Vertical:
2436 set[type]->resize(16, size_);
2437 KPixmapEffect::gradient(*set[type],
2438 color_.light(contrast),
2439 color_.dark(contrast),
2440 KPixmapEffect::VerticalGradient);
2441 break;
2443 case VerticalReverse:
2444 set[type]->resize(16, size_);
2445 KPixmapEffect::gradient(*set[type],
2446 color_.dark(contrast),
2447 color_.light(contrast),
2448 KPixmapEffect::VerticalGradient);
2449 break;
2451 default:
2452 break;
2455 return (set[type]);
2458 //////////////////////////////////////////////////////////////////////////////
2459 // Plugin Stuff //
2460 //////////////////////////////////////////////////////////////////////////////
2462 class PhaseStylePlugin : public QStylePlugin
2464 public:
2465 PhaseStylePlugin();
2466 QStringList keys() const;
2467 QStyle *create(const QString &key);
2470 PhaseStylePlugin::PhaseStylePlugin() : QStylePlugin() { ; }
2472 QStringList PhaseStylePlugin::keys() const
2474 return QStringList() << "Phase";
2477 QStyle* PhaseStylePlugin::create(const QString& key)
2479 if (key.lower() == "phase")
2480 return new PhaseStyle();
2481 return 0;
2484 KDE_Q_EXPORT_PLUGIN(PhaseStylePlugin)
2486 #include "phasestyle.moc"