Adapt to new KWarning/kFatal/kDebug api
[kdeartwork.git] / styles / phase / phasestyle.cpp
blob7294f2252fcc147c6982258aceedfa09737f19d0
1 //////////////////////////////////////////////////////////////////////////////
2 // phasestyle.cpp
3 // -------------------
4 // Qt widget style
5 // -------------------
6 // Copyright (c) 2004-2007 David Johnson
7 // Please see the header file for copyright and license information.
8 //////////////////////////////////////////////////////////////////////////////
9 //
10 // Some miscellaneous notes
12 // Menu and toolbars are painted with the background color by default. This
13 // differs from the Qt default of giving them PaletteButton backgrounds.
14 // Menubars have normal gradients, toolbars have reverse.
16 // Some toolbars are not part of a QMainWindows, such as in a KDE file dialog.
17 // In these cases we treat the toolbar as "floating" and paint it flat.
19 //////////////////////////////////////////////////////////////////////////////
21 #include <QApplication>
22 #include <QBitmap>
23 #include <QCheckBox>
24 #include <QComboBox>
25 #include <QDockWidget>
26 #include <QKeyEvent>
27 #include <QLinearGradient>
28 #include <QMenuBar>
29 #include <QPainter>
30 #include <QPixmapCache>
31 #include <QProgressBar>
32 #include <QStylePlugin>
33 #include <QPushButton>
34 #include <QRadioButton>
35 #include <QSettings>
36 #include <QSpinBox>
37 #include <QSplitterHandle>
38 #include <QToolBar>
40 #include <limits.h>
42 #include "phasestyle.h"
43 #include "bitmaps.h"
45 // some convenient constants
46 static const int ARROWMARGIN = 6;
47 static const int ITEMFRAME = 1;
48 static const int ITEMHMARGIN = 3;
49 static const int ITEMVMARGIN = 0;
50 static const int MAXGRADIENTSIZE = 64;
52 static const double PI = 3.14159265359;
54 //////////////////////////////////////////////////////////////////////////////
55 // Construction, Destruction, Initialization //
56 //////////////////////////////////////////////////////////////////////////////
58 //////////////////////////////////////////////////////////////////////////////
59 // PhaseStyle()
60 // -----------
61 // Constructor
63 PhaseStyle::PhaseStyle()
64 : QWindowsStyle(), gradients_(QPixmap::defaultDepth() > 8), timerid_(0)
66 // get config
67 QSettings settings;
68 if (gradients_) { // don't bother setting if already false
69 gradients_ =
70 settings.value("/phasestyle/Settings/gradients", true).toBool();
71 contrast_ = 100 + settings.value("/Qt/KDE/contrast", 5).toInt();
73 highlights_ =
74 settings.value("/phasestyle/Settings/highlights", true).toBool();
76 // create bitmaps
77 const QSize arrowsz(6, 6);
78 const QSize btnsz(10, 10);
79 bitmaps_.insert(UArrow, QBitmap::fromData(arrowsz, uarrow_bits));
80 bitmaps_.insert(DArrow, QBitmap::fromData(arrowsz, darrow_bits));
81 bitmaps_.insert(LArrow, QBitmap::fromData(arrowsz, larrow_bits));
82 bitmaps_.insert(RArrow, QBitmap::fromData(arrowsz, rarrow_bits));
83 bitmaps_.insert(PlusSign, QBitmap::fromData(arrowsz, plussign_bits));
84 bitmaps_.insert(MinusSign, QBitmap::fromData(arrowsz, minussign_bits));
85 bitmaps_.insert(CheckMark, QBitmap::fromData(btnsz, checkmark_bits));
86 bitmaps_.insert(TitleClose, QBitmap::fromData(btnsz, title_close_bits));
87 bitmaps_.insert(TitleMin, QBitmap::fromData(btnsz, title_min_bits));
88 bitmaps_.insert(TitleMax, QBitmap::fromData(btnsz, title_max_bits));
89 bitmaps_.insert(TitleNormal, QBitmap::fromData(btnsz, title_normal_bits));
90 bitmaps_.insert(TitleHelp, QBitmap::fromData(btnsz, title_help_bits));
93 PhaseStyle::~PhaseStyle() { ; }
95 //////////////////////////////////////////////////////////////////////////////
96 // Polishing //
97 //////////////////////////////////////////////////////////////////////////////
99 //////////////////////////////////////////////////////////////////////////////
100 // polish()
101 // --------
102 // Initialize application specific
104 void PhaseStyle::polish(QApplication* app)
106 QWindowsStyle::polish(app);
109 //////////////////////////////////////////////////////////////////////////////
110 // polish()
111 // --------
112 // Initialize the appearance of widget
114 void PhaseStyle::polish(QWidget *widget)
116 if (highlights_ &&
117 (qobject_cast<QPushButton*>(widget) ||
118 qobject_cast<QComboBox*>(widget) ||
119 qobject_cast<QAbstractSpinBox*>(widget) ||
120 qobject_cast<QCheckBox*>(widget) ||
121 qobject_cast<QRadioButton*>(widget) ||
122 qobject_cast<QSplitterHandle*>(widget) ||
123 qobject_cast<QSlider*>(widget) ||
124 qobject_cast<QTabBar*>(widget))) {
125 // mouseover highlighting
126 widget->setAttribute(Qt::WA_Hover);
128 if (widget->inherits("QDockSeparator")
129 || widget->inherits("QDockWidgetSeparator")
130 || widget->inherits("Q3DockWindowResizeHandle")) {
131 widget->setAttribute(Qt::WA_Hover);
133 if (qobject_cast<QProgressBar *>(widget)) {
134 // potentially animate progressbars
135 widget->installEventFilter(this);
139 //////////////////////////////////////////////////////////////////////////////
140 // polish()
141 // --------
142 // Initialize the palette
144 void PhaseStyle::polish(QPalette &pal)
146 // clear out gradients on a color change
147 QPixmapCache::clear();
149 // adjust bevel colors to have better contrast (KDE like)
150 QColor background;
152 int highlightval = 100 + (2*(contrast_-100)+4)*16/10;
153 int lowlightval = 100 + (2*(contrast_-100)+4)*10;
155 background = pal.color(QPalette::Active, QPalette::Window);
156 pal.setColor(QPalette::Active, QPalette::Light,
157 background.light(highlightval));
158 pal.setColor(QPalette::Active, QPalette::Dark,
159 background.dark(lowlightval));
160 pal.setColor(QPalette::Active, QPalette::Mid,
161 background.dark(120));
162 pal.setColor(QPalette::Active, QPalette::Midlight,
163 background.light(110));
165 background = pal.color(QPalette::Inactive, QPalette::Window);
166 pal.setColor(QPalette::Inactive, QPalette::Light,
167 background.light(highlightval));
168 pal.setColor(QPalette::Inactive, QPalette::Dark,
169 background.dark(lowlightval));
170 pal.setColor(QPalette::Inactive, QPalette::Mid,
171 background.dark(120));
172 pal.setColor(QPalette::Inactive, QPalette::Midlight,
173 background.light(110));
175 background = pal.color(QPalette::Disabled, QPalette::Window);
176 pal.setColor(QPalette::Disabled, QPalette::Light,
177 background.light(highlightval));
178 pal.setColor(QPalette::Disabled, QPalette::Dark,
179 background.dark(lowlightval));
180 pal.setColor(QPalette::Disabled, QPalette::Mid,
181 background.dark(120));
182 pal.setColor(QPalette::Disabled, QPalette::Midlight,
183 background.light(110));
185 // TODO: make sure indicator branches show up correctly in Solaris
186 // color scheme (mid is too close to base)
189 //////////////////////////////////////////////////////////////////////////////
190 // unPolish()
191 // ----------
192 // Undo the application polish
194 void PhaseStyle::unpolish(QApplication *app)
196 QWindowsStyle::unpolish(app);
199 //////////////////////////////////////////////////////////////////////////////
200 // unPolish()
201 // ----------
202 // Undo the initialization of a widget appearance
204 void PhaseStyle::unPolish(QWidget *widget)
206 if (highlights_ &&
207 (qobject_cast<QPushButton*>(widget) ||
208 qobject_cast<QComboBox*>(widget) ||
209 qobject_cast<QAbstractSpinBox*>(widget) ||
210 qobject_cast<QCheckBox*>(widget) ||
211 qobject_cast<QRadioButton*>(widget) ||
212 qobject_cast<QSplitterHandle*>(widget) ||
213 qobject_cast<QSlider*>(widget) ||
214 qobject_cast<QTabBar*>(widget))) {
215 // turn off mouseover highlighting
216 widget->setAttribute(Qt::WA_Hover, false);
218 if (widget->inherits("QDockSeparator")
219 || widget->inherits("QDockWidgetSeparator")
220 || widget->inherits("Q3DockWindowResizeHandle")) {
221 widget->setAttribute(Qt::WA_Hover, false);
223 if (qobject_cast<QProgressBar *>(widget)) {
224 widget->removeEventFilter(this);
228 //////////////////////////////////////////////////////////////////////////////
229 // standardPalette()
230 // -----------------
231 // Return a standard palette
233 QPalette PhaseStyle::standardPalette() const
235 QColor window(0xee, 0xee, 0xee);
236 QColor button(0xdd, 0xdd, 0xe3);
237 QColor highlight(0x60, 0x90, 0xc0);
238 QPalette pal(window, window);
240 pal.setBrush(QPalette::Button, button);
241 pal.setBrush(QPalette::Highlight, highlight);
243 pal.setBrush(QPalette::Disabled, QPalette::Button, window);
244 pal.setBrush(QPalette::Disabled, QPalette::Foreground, window.dark());
245 pal.setBrush(QPalette::Disabled, QPalette::Text, window.dark());
246 pal.setBrush(QPalette::Disabled, QPalette::ButtonText, window.dark());
248 // adjust bevel colors to have better contrast (KDE like)
249 QColor background;
251 int highlightval = 100 + (2*(contrast_-100)+4)*16/10;
252 int lowlightval = 100 + (2*(contrast_-100)+4)*10;
254 background = pal.color(QPalette::Active, QPalette::Window);
255 pal.setColor(QPalette::Active, QPalette::Light,
256 background.light(highlightval));
257 pal.setColor(QPalette::Active, QPalette::Dark,
258 background.dark(lowlightval));
259 pal.setColor(QPalette::Active, QPalette::Mid,
260 background.dark(120));
261 pal.setColor(QPalette::Active, QPalette::Midlight,
262 background.light(110));
264 background = pal.color(QPalette::Inactive, QPalette::Window);
265 pal.setColor(QPalette::Inactive, QPalette::Light,
266 background.light(highlightval));
267 pal.setColor(QPalette::Inactive, QPalette::Dark,
268 background.dark(lowlightval));
269 pal.setColor(QPalette::Inactive, QPalette::Mid,
270 background.dark(120));
271 pal.setColor(QPalette::Inactive, QPalette::Midlight,
272 background.light(110));
274 background = pal.color(QPalette::Disabled, QPalette::Window);
275 pal.setColor(QPalette::Disabled, QPalette::Light,
276 background.light(highlightval));
277 pal.setColor(QPalette::Disabled, QPalette::Dark,
278 background.dark(lowlightval));
279 pal.setColor(QPalette::Disabled, QPalette::Mid,
280 background.dark(120));
281 pal.setColor(QPalette::Disabled, QPalette::Midlight,
282 background.light(110));
284 return pal;
287 //////////////////////////////////////////////////////////////////////////////
288 // Drawing //
289 //////////////////////////////////////////////////////////////////////////////
291 //////////////////////////////////////////////////////////////////////////////
292 // drawPhaseGradient()
293 // ------------------
294 // Draw a gradient
296 void PhaseStyle::drawPhaseGradient(QPainter *painter,
297 const QRect &rect,
298 QColor color,
299 bool horizontal,
300 const QSize &gsize,
301 bool reverse) const
303 if (!gradients_) {
304 painter->fillRect(rect, color);
305 return;
308 int size = (horizontal) ? gsize.width() : gsize.height();
310 if (size > MAXGRADIENTSIZE) { // keep it sensible
311 painter->fillRect(rect, color);
312 return;
315 GradientType type;
316 QString name;
317 QPixmap pixmap;
319 if (horizontal) type = (reverse) ? HorizontalReverse : Horizontal;
320 else type = (reverse) ? VerticalReverse : Vertical;
322 name = QString("%1.%2.%3").arg(color.name()).arg(size).arg(type);
323 if (!QPixmapCache::find(name, pixmap)) {
324 QPainter cachepainter;
326 switch (type) {
327 case Horizontal: {
328 pixmap = QPixmap(size, 16);
329 QLinearGradient gradient(0, 0, size, 0);
330 gradient.setColorAt(0, color.light(contrast_));
331 gradient.setColorAt(1, color.dark(contrast_));
332 cachepainter.begin(&pixmap);
333 cachepainter.fillRect(pixmap.rect(), gradient);
334 cachepainter.end();
335 break;
337 case HorizontalReverse: {
338 pixmap = QPixmap(size, 16);
339 QLinearGradient gradient(0, 0, size, 0);
340 gradient.setColorAt(0, color.dark(contrast_));
341 gradient.setColorAt(1, color.light(contrast_));
342 cachepainter.begin(&pixmap);
343 cachepainter.fillRect(pixmap.rect(), gradient);
344 cachepainter.end();
345 break;
347 case Vertical: {
348 pixmap = QPixmap(16, size);
349 QLinearGradient gradient(0, 0, 0, size);
350 gradient.setColorAt(0, color.light(contrast_));
351 gradient.setColorAt(1, color.dark(contrast_));
352 cachepainter.begin(&pixmap);
353 cachepainter.fillRect(pixmap.rect(), gradient);
354 cachepainter.end();
355 break;
357 case VerticalReverse: {
358 pixmap = QPixmap(16, size);
359 QLinearGradient gradient(0, 0, 0, size);
360 gradient.setColorAt(0, color.dark(contrast_));
361 gradient.setColorAt(1, color.light(contrast_));
362 cachepainter.begin(&pixmap);
363 cachepainter.fillRect(pixmap.rect(), gradient);
364 cachepainter.end();
365 break;
367 default:
368 break;
370 QPixmapCache::insert(name, pixmap);
373 painter->drawTiledPixmap(rect, pixmap);
376 //////////////////////////////////////////////////////////////////////////////
377 // drawPhaseBevel()
378 // ----------------
379 // Draw the basic Phase bevel
381 void PhaseStyle::drawPhaseBevel(QPainter *painter,
382 QRect rect,
383 const QPalette &pal,
384 const QBrush &fill,
385 bool sunken,
386 bool horizontal,
387 bool reverse) const
389 int x, y, w, h;
390 rect.getRect(&x, &y, &w, &h);
391 int x2 = rect.right();
392 int y2 = rect.bottom();
394 painter->save();
396 painter->setPen(pal.dark().color());
397 painter->drawRect(rect.adjusted(0, 0, -1, -1));
399 painter->setPen(sunken ? pal.mid().color() : pal.midlight().color());
400 painter->drawLine(x+1, y+1, x2-2, y+1);
401 painter->drawLine(x+1, y+2, x+1, y2-2);
403 painter->setPen(sunken ? pal.midlight().color() : pal.mid().color());
404 painter->drawLine(x+2, y2-1, x2-1, y2-1);
405 painter->drawLine(x2-1, y+2, x2-1, y2-2);
407 painter->setPen(pal.button().color());
408 painter->drawPoint(x+1, y2-1);
409 painter->drawPoint(x2-1, y+1);
411 if (sunken) {
412 // sunken bevels don't get gradients
413 painter->fillRect(rect.adjusted(2, 2, -2, -2), fill);
414 } else {
415 drawPhaseGradient(painter, rect.adjusted(2, 2, -2, -2), fill.color(),
416 horizontal, QSize(w-4, h-4), reverse);
418 painter->restore();
421 //////////////////////////////////////////////////////////////////////////////
422 // drawPhaseButton()
423 // ----------------
424 // Draw the basic Phase button
426 void PhaseStyle::drawPhaseButton(QPainter *painter,
427 QRect rect,
428 const QPalette &pal,
429 const QBrush &fill,
430 bool sunken) const
432 int x, y, w, h;
433 rect.getRect(&x, &y, &w, &h);
434 int x2 = rect.right();
435 int y2 = rect.bottom();
437 painter->save();
439 painter->setPen(pal.midlight().color());
440 painter->drawLine(x+1, y2, x2, y2);
441 painter->drawLine(x2, y+1, x2, y2-1);
443 painter->setPen(pal.mid().color());
444 painter->drawLine(x, y, x2-1, y);
445 painter->drawLine(x, y+1, x, y2-1);
447 painter->setPen(pal.window().color());
448 painter->drawPoint(x, y2);
449 painter->drawPoint(x2, y);
451 painter->restore();
452 drawPhaseBevel(painter, rect.adjusted(1, 1, -1, -1), pal, fill,
453 sunken, false, false);
456 //////////////////////////////////////////////////////////////////////////////
457 // drawPhasePanel()
458 // ----------------
459 // Draw the basic Phase panel
461 void PhaseStyle::drawPhasePanel(QPainter *painter,
462 const QRect &rect,
463 const QPalette &pal,
464 const QBrush &fill,
465 bool sunken) const
467 int x, y, w, h;
468 rect.getRect(&x, &y, &w, &h);
469 int x2 = rect.right();
470 int y2 = rect.bottom();
472 painter->save();
474 if (sunken) {
475 painter->setPen(pal.dark().color());
476 painter->drawRect(rect.adjusted(1, 1, -2, -2));
477 painter->setPen(pal.midlight().color());
478 painter->drawLine(x+1, y2, x2, y2);
479 painter->drawLine(x2, y+1, x2, y2-1);
480 painter->setPen(pal.mid().color());
481 painter->drawLine(x, y, x, y2-1);
482 painter->drawLine(x+1, y, x2-1, y);
483 painter->setPen(pal.window().color());
484 painter->drawPoint(x, y2);
485 painter->drawPoint(x2, y);
486 } else {
487 painter->setPen(pal.dark().color());
488 painter->drawRect(rect.adjusted(0, 0, -1, -1));
489 painter->setPen(pal.midlight().color());
490 painter->drawLine(x+1, y+1, x2-2, y+1);
491 painter->drawLine(x+1, y+2, x+1, y2-2);
492 painter->setPen(pal.mid().color());
493 painter->drawLine(x+2, y2-1, x2-1, y2-1);
494 painter->drawLine(x2-1, y+2, x2-1, y2-2);
495 painter->setPen(pal.window().color());
496 painter->drawPoint(x+1, y2-1);
497 painter->drawPoint(x2-1, y+1);
500 painter->fillRect(rect.adjusted(2, 2, -2, -2), fill);
501 painter->restore();
504 //////////////////////////////////////////////////////////////////////////////
505 // drawPhaseDoodads()
506 // ------------------
507 // Draw three doodads in rect
509 void PhaseStyle::drawPhaseDoodads(QPainter *painter,
510 const QRect& rect,
511 const QPalette &pal,
512 bool horizontal) const
514 int cx = rect.center().x();
515 int cy = rect.center().y();
517 QPen pen = painter->pen();
518 if (horizontal && (rect.width() >= 20)) {
519 for (int n = -5; n <= 5; n += 5) {
520 painter->setPen(pal.mid().color());
521 painter->drawLine(cx-1+n, cy+1, cx-1+n, cy-1);
522 painter->drawLine(cx+n, cy-1, cx+1+n, cy-1);
523 painter->setPen(pal.light().color());
524 painter->drawLine(cx+2+n, cy, cx+2+n, cy+2);
525 painter->drawLine(cx+1+n, cy+2, cx+n, cy+2);
527 } else if (!horizontal && (rect.height() >= 20)) {
528 for (int n = -5; n <= 5; n += 5) {
529 painter->setPen(pal.mid().color());
530 painter->drawLine(cx-1, cy+1+n, cx-1, cy-1+n);
531 painter->drawLine(cx, cy-1+n, cx+1, cy-1+n);
532 painter->setPen(pal.light().color());
533 painter->drawLine(cx+2, cy+n, cx+2, cy+2+n);
534 painter->drawLine(cx+1, cy+2+n, cx, cy+2+n);
537 painter->setPen(pen);
540 ///////////////////////////////////////////////////////////////////////////////
541 // drawPhaseTab()
542 // -------------
543 // Draw a Phase style tab
545 void PhaseStyle::drawPhaseTab(QPainter *painter,
546 const QPalette &pal,
547 const QStyleOptionTab *tab) const
549 const State &flags = tab->state;
550 const QStyleOptionTab::TabPosition &tabpos = tab->position;
551 const QStyleOptionTab::SelectedPosition &selpos = tab->selectedPosition;
553 bool selected = (flags & State_Selected);
554 bool mouseover = (flags & State_MouseOver) && !selected;
555 bool reverse = (tab->direction == Qt::RightToLeft);
556 bool corner = ((!reverse &&
557 (tab->cornerWidgets & QStyleOptionTab::LeftCornerWidget)) ||
558 (reverse &&
559 (tab->cornerWidgets & QStyleOptionTab::RightCornerWidget)));
560 bool first = ((!reverse && (tabpos == QStyleOptionTab::Beginning)) ||
561 (reverse && (tabpos == QStyleOptionTab::End)));
562 bool edge = (first && !corner);
563 bool prevselected = ((!reverse &&
564 (selpos == QStyleOptionTab::PreviousIsSelected)) ||
565 (reverse &&
566 (selpos == QStyleOptionTab::NextIsSelected)));
567 bool nextselected = ((!reverse &&
568 (selpos == QStyleOptionTab::NextIsSelected)) ||
569 (reverse &&
570 (selpos == QStyleOptionTab::PreviousIsSelected)));
572 // get rectangle
573 QRect rect = tab->rect;
574 if (!selected) {
575 switch (tab->shape) {
576 case QTabBar::RoundedNorth:
577 default:
578 rect.adjust(0, 2, 0, 0);
579 break;
581 case QTabBar::RoundedSouth:
582 rect.adjust(0, 0, 0, -2);
583 break;
585 case QTabBar::RoundedWest:
586 rect.adjust(2, 0, 0, 0);
587 break;
589 case QTabBar::RoundedEast:
590 rect.adjust(0, 0, -2, 0);
591 break;
595 int x, y, w, h;
596 rect.getRect(&x, &y, &w, &h);
597 const int x2 = rect.right();
598 const int y2 = rect.bottom();
600 painter->save();
602 // draw tab
603 switch (tab->shape) {
604 case QTabBar::RoundedNorth:
605 default:
606 // draw fill
607 if (selected) {
608 painter->fillRect(rect.adjusted(0, 1, 0, 0), pal.window());
609 } else {
610 drawPhaseGradient(painter, rect.adjusted(0, 1, 0, -2),
611 mouseover ?
612 pal.window().color() :
613 pal.window().color().dark(contrast_),
614 false, QSize(w, h), false);
617 // top frame
618 painter->setPen(pal.dark().color());
619 painter->drawLine(x, y, x2, y);
621 painter->setPen(pal.midlight().color());
622 if (nextselected) painter->drawLine(x+1, y+1, x2, y+1);
623 else if (prevselected) painter->drawLine(x, y+1, x2-2, y+1);
624 else painter->drawLine(x+1, y+1, x2-2, y+1);
626 // left frame
627 painter->setPen(pal.dark().color());
628 if (edge && selected) painter->drawLine(x, y, x, y2);
629 if (edge && !selected) painter->drawLine(x, y, x, y2-2);
630 if (!edge && selected) painter->drawLine(x, y, x, y2-1);
631 if (!edge && !selected && first) painter->drawLine(x, y, x, y2-2);
633 painter->setPen(pal.midlight().color());
634 if (selected) painter->drawLine(x+1, y+1, x+1, y2);
635 else if (first) painter->drawLine(x+1, y+1, x+1, y2-2);
636 else if (!prevselected) painter->drawLine(x, y+1, x, y2-2);
637 if (selected && !edge) painter->drawPoint(x, y2);
639 // right frame
640 if (!nextselected) {
641 painter->setPen(pal.dark().color());
642 painter->drawLine(x2, y+1, x2, y2-1);
644 painter->setPen(pal.mid().color());
645 if (selected) painter->drawLine(x2-1, y+2, x2-1, y2-1);
646 else painter->drawLine(x2-1, y+2, x2-1, y2-2);
648 if (selected) {
649 painter->setPen(pal.midlight().color());
650 painter->drawPoint(x2, y2);
653 break;
655 case QTabBar::RoundedSouth:
656 // draw fill
657 if (selected) {
658 painter->fillRect(rect.adjusted(0, 0, 0, -1), pal.window());
659 } else {
660 drawPhaseGradient(painter, rect.adjusted(0, 2, 0, -1),
661 mouseover ?
662 pal.window().color() :
663 pal.window().color().dark(contrast_),
664 false, QSize(w, h), false);
667 // bottom frame
668 painter->setPen(pal.dark().color());
669 painter->drawLine(x, y2, x2, y2);
671 painter->setPen(pal.mid().color());
672 if (nextselected) painter->drawLine(x, y2-1, x2, y2-1);
673 else painter->drawLine(x, y2-1, x2-1, y2-1);
675 painter->setPen(pal.window().color());
676 if (selected || first) painter->drawPoint(x+1, y2-1);
677 else if (!prevselected) painter->drawPoint(x, y2-1);
679 // left frame
680 painter->setPen(pal.dark().color());
681 if (selected && edge) painter->drawLine(x, y, x, y2);
682 else if (selected || first) painter->drawLine(x, y+1, x, y2);
684 painter->setPen(pal.midlight().color());
685 if (!prevselected) {
686 if (edge && selected) painter->drawLine(x+1, y, x+1, y2-2);
687 if (!edge && selected) painter->drawLine(x+1, y+1, x+1, y2-2);
688 if (first && !selected) painter->drawLine(x+1, y+2, x+1, y2-2);
689 if (!first && !selected) painter->drawLine(x, y+2, x, y2-2);
692 if (selected && !edge) {
693 painter->setPen(pal.mid().color());
694 painter->drawPoint(x, y);
697 // right frame
698 if (!nextselected) {
699 painter->setPen(pal.dark().color());
700 painter->drawLine(x2, y+1, x2, y2-1);
702 painter->setPen(pal.mid().color());
703 if (selected) {
704 painter->drawLine(x2-1, y, x2-1, y2-2);
705 painter->drawPoint(x2, y);
706 } else {
707 painter->drawLine(x2-1, y+2, x2-1, y2-2);
710 break;
712 case QTabBar::RoundedWest:
713 // draw fill
714 if (selected) {
715 painter->fillRect(rect.adjusted(1, 0, 0, 0), pal.window());
716 } else {
717 drawPhaseGradient(painter, rect.adjusted(1, 0, -2, 0),
718 mouseover ?
719 pal.window().color() :
720 pal.window().color().dark(contrast_),
721 true, QSize(w, h), false);
724 // left frame
725 painter->setPen(pal.dark().color());
726 painter->drawLine(x, y, x, y2);
728 painter->setPen(pal.midlight().color());
729 if (nextselected) painter->drawLine(x+1, y+1, x+1, y2);
730 else if (prevselected) painter->drawLine(x+1, y, x+1, y2-2);
731 else painter->drawLine(x+1, y+1, x+1, y2-2);
733 // top frame
734 painter->setPen(pal.dark().color());
735 if (edge || selected) painter->drawLine(x, y, x2-1, y);
736 if (edge && selected) painter->drawPoint(x2, y);
738 painter->setPen(pal.midlight().color());
739 if (edge && selected) painter->drawLine(x+1, y+1, x2, y+1);
740 else if (edge && !selected) painter->drawLine(x+1, y+1, x2-2, y+1);
741 else if (selected) painter->drawLine(x+1, y+1, x2, y+1);
742 else if (!prevselected) painter->drawLine(x+1, y, x2-2, y);
743 if (!edge && selected) painter->drawPoint(x2, y);
745 // bottom frame
746 if (!nextselected) {
747 painter->setPen(pal.dark().color());
748 if (selected) painter->drawLine(x, y2, x2-1, y2);
749 else painter->drawLine(x, y2, x2-2, y2);
751 painter->setPen(pal.mid().color());
752 if (selected) painter->drawLine(x+2, y2-1, x2-1, y2-1);
753 else painter->drawLine(x+2, y2-1, x2-2, y2-1);
755 if (selected) {
756 painter->setPen(pal.midlight().color());
757 painter->drawPoint(x2, y2);
760 break;
762 case QTabBar::RoundedEast:
763 // draw fill
764 if (selected) {
765 painter->fillRect(rect.adjusted(0, 0, -1, 0), pal.window());
766 } else {
767 drawPhaseGradient(painter, rect.adjusted(2, 0, -1, 0),
768 mouseover ?
769 pal.window().color() :
770 pal.window().color().dark(contrast_),
771 true, QSize(w, h), false);
774 // right frame
775 painter->setPen(pal.dark().color());
776 painter->drawLine(x2, y, x2, y2);
778 painter->setPen(pal.mid().color());
779 if (selected) painter->drawLine(x2-1, y+2, x2-1, y2-1);
780 else if (edge) painter->drawLine(x2-1, y+2, x2-1, y2);
781 else if (nextselected) painter->drawLine(x2-1, y+1, x2-1, y2);
782 else if (prevselected) painter->drawLine(x2-1, y, x2-1, y2-1);
783 else painter->drawLine(x2-1, y+1, x2-1, y2-1);
785 // top frame
786 painter->setPen(pal.dark().color());
787 if (edge || selected) painter->drawLine(x+1, y, x2, y);
788 if (edge && selected) painter->drawPoint(x, y);
790 painter->setPen(pal.midlight().color());
791 if (edge && selected) painter->drawLine(x, y+1, x2-2, y+1);
792 else if (edge && !selected) painter->drawLine(x+2, y+1, x2-2, y+1);
793 else if (selected) painter->drawLine(x+1, y+1, x2-2, y+1);
794 else if (!prevselected) painter->drawLine(x+2, y, x2-2, y);
795 if (!edge && selected) painter->drawPoint(x+1, y+1);
797 if (!edge && selected) {
798 painter->setPen(pal.mid().color());
799 painter->drawPoint(x, y);
802 // bottom frame
803 if (!nextselected) {
804 painter->setPen(pal.dark().color());
805 if (selected) painter->drawLine(x+1, y2, x2, y2);
806 else painter->drawLine(x+1, y2, x2, y2);
808 painter->setPen(pal.mid().color());
809 if (selected) {
810 painter->drawLine(x, y2-1, x2-2, y2-1);
811 painter->drawPoint(x, y2);
812 } else {
813 painter->drawLine(x+2, y2-1, x2-2, y2-1);
816 break;
819 painter->restore();
822 //////////////////////////////////////////////////////////////////////////////
823 // drawPrimitive()
824 // ---------------
825 // Draw a primitive element
827 void PhaseStyle::drawPrimitive(PrimitiveElement element,
828 const QStyleOption *option,
829 QPainter *painter,
830 const QWidget *widget) const
832 // shorthand
833 const State &flags = option->state;
834 const QPalette &pal = option->palette;
835 const QRect &rect = option->rect;
837 // common states
838 bool sunken = flags & State_Sunken;
839 bool on = flags & State_On;
840 bool depress = (sunken || on);
841 bool enabled = flags & State_Enabled;
842 bool horiz = flags & State_Horizontal;
843 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
845 int x, y, w, h;
846 rect.getRect(&x, &y, &w, &h);
847 int x2 = rect.right();
848 int y2 = rect.bottom();
849 int cx = rect.center().x();
850 int cy = rect.center().y();
852 QPolygon polygon;
854 painter->save();
856 switch (element) {
857 case PE_PanelButtonCommand: // command button (QPushbutton)
858 drawPhaseButton(painter, rect, pal, mouseover ?
859 pal.button().color().light(contrast_) :
860 pal.button(), depress);
861 break;
863 case PE_FrameButtonBevel: // panel frame for a button bevel
864 case PE_FrameButtonTool: // panel frame for a tool button
865 drawPhaseBevel(painter, rect, pal, Qt::NoBrush,
866 depress, false, false);
867 break;
869 case PE_PanelButtonBevel: // generic panel with a button bevel
870 case PE_IndicatorButtonDropDown: // indicator for a drop down button
871 drawPhaseBevel(painter, rect, pal, mouseover ?
872 pal.button().color().light(contrast_) :
873 pal.button(),
874 depress, false, false);
875 break;
877 case PE_PanelButtonTool: // panel for a tool button
878 drawPhaseBevel(painter, rect, pal, mouseover ?
879 pal.button().color().light(contrast_) :
880 pal.button(),
881 depress, false, true);
882 break;
884 case PE_FrameDefaultButton: // the frame around a default button
885 drawPhasePanel(painter, rect, pal, pal.mid(), true);
886 break;
888 case PE_Frame: // generic styled frame
889 case PE_FrameLineEdit: // frame around line edit
890 case PE_FrameMenu: // frame for popup windows/menus
891 case PE_FrameDockWidget: // frame for dock windows and toolbars
892 case PE_FrameTabWidget: // frame around tab widgets
893 case PE_FrameTabBarBase: // frame for base of a tab bar
894 drawPhasePanel(painter, rect, pal, Qt::NoBrush, sunken);
895 break;
897 case PE_FrameWindow: // frame for MDI or docking window
898 drawPhasePanel(painter, rect, pal, Qt::NoBrush, sunken);
899 // needs a black border
900 painter->setPen(pal.shadow().color());
901 painter->drawRect(rect.adjusted(0, 0, -1, -1));
902 break;
904 case PE_FrameGroupBox: // frame around a group box
905 painter->setPen(pal.dark().color());
906 painter->drawRect(rect.adjusted(0, 0, -1, -1));
907 break;
909 case PE_FrameFocusRect: { // generic focus indicator
910 painter->setPen(pal.highlight().color().dark(contrast_));
911 painter->drawRect(rect.adjusted(0, 0, -1, -1));
912 break;
915 case PE_IndicatorCheckBox: // on/off indicator for check box
916 drawPhasePanel(painter, rect.adjusted(1, 1, -1, -1),
917 pal, enabled ? pal.base() : pal.window(), true);
919 if (mouseover) {
920 painter->setPen(pal.highlight().color().dark(contrast_));
921 } else if (on || (flags & State_NoChange)) {
922 painter->setPen(pal.dark().color());
923 } else {
924 painter->setPen(Qt::NoPen);
926 if (on) {
927 painter->setBrush(pal.highlight());
928 } else if (flags & State_NoChange) {
929 painter->setBrush(pal.mid());
932 painter->drawRect(rect.adjusted(4, 4, -5, -5));
933 break;
935 case PE_IndicatorRadioButton: // on/off indicator for radio button
936 painter->setBrush(enabled ? pal.base() : pal.window());
938 painter->setPen(pal.dark().color());
939 polygon.setPoints(8, x+1,cy+1, x+1,cy, cx,y+1, cx+1,y+1,
940 x2-1,cy, x2-1,cy+1, cx+1,y2-1, cx,y2-1);
941 painter->drawConvexPolygon(polygon);
943 painter->setPen(pal.mid().color());
944 polygon.setPoints(4, x,cy, cx,y, cx+1,y, x2,cy);
945 painter->drawPolyline(polygon);
946 painter->setPen(pal.midlight().color());
947 polygon.setPoints(4, x2,cy+1, cx+1,y2, cx,y2, x,cy+1);
948 painter->drawPolyline(polygon);
950 if (on) {
951 painter->setBrush(pal.highlight());
952 painter->setPen(mouseover
953 ? pal.highlight().color().dark(contrast_)
954 : pal.dark().color());
955 polygon.setPoints(8, x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
956 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4);
957 painter->drawConvexPolygon(polygon);
958 } else if (mouseover) {
959 painter->setPen(pal.highlight().color().dark(contrast_));
960 polygon.setPoints(9, x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
961 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4,
962 x+4,cy+1);
963 painter->drawPolyline(polygon);
965 break;
967 case PE_IndicatorHeaderArrow: { // sort arrow on view header
968 const QStyleOptionHeader *header;
969 header = qstyleoption_cast<const QStyleOptionHeader *>(option);
970 if (header) {
971 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
972 drawPrimitive(PE_IndicatorArrowUp, option, painter, widget);
973 } else {
974 drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
977 break;
980 case PE_PanelMenuBar: // panel for menu bars
981 case PE_PanelToolBar: // panel for a toolbar
982 // adjust rect so we can use bevel
983 drawPhaseBevel(painter, rect.adjusted(-1, -1, 0, 0),
984 pal, pal.window(), false, (w < h),
985 (element==PE_PanelToolBar) ? true : false);
986 break;
988 case PE_FrameStatusBar: // frame for a section of a status bar
989 painter->setPen(pal.mid().color());
990 painter->drawLine(x, y, x2-1, y);
991 painter->drawLine(x, y+1, x, y2-1);
992 painter->setPen(pal.midlight().color());
993 painter->drawLine(x+1, y2, x2, y2);
994 painter->drawLine(x2, y+1, x2, y2-1);
995 break;
997 case PE_IndicatorDockWidgetResizeHandle: // resize handle for docks
998 painter->fillRect(rect,
999 (mouseover) ?
1000 pal.window().color().light(contrast_) :
1001 pal.window());
1002 drawPhaseDoodads(painter, rect, pal, horiz);
1003 break;
1006 case PE_IndicatorMenuCheckMark: // check mark used in a menu
1007 if (on) {
1008 painter->setBrush(pal.highlightedText());
1009 } else {
1010 painter->setBrush(sunken ? pal.dark() : pal.text());
1012 painter->setPen(painter->brush().color());
1013 painter->drawPixmap(cx-4, cy-4, bitmaps_[CheckMark]);
1014 break;
1016 case PE_IndicatorViewItemCheck: // on/off indicator for a view item
1017 case PE_Q3CheckListIndicator: { // Q3 checkbox of a list view item
1018 painter->setPen(pal.text().color());
1019 // draw box
1020 QRect box(0, 0, 13, 13);
1021 box.moveCenter(rect.center());
1022 painter->drawRect(box);
1023 painter->drawRect(box.adjusted(1,1,-1,-1));
1024 // draw check
1025 if (flags & State_On) {
1026 painter->setBrush(pal.text());
1027 painter->setPen(painter->brush().color());
1028 painter->drawPixmap(cx-4, cy-4, bitmaps_[CheckMark]);
1030 break;
1033 case PE_IndicatorBranch: { // branch lines of a tree view
1034 painter->setPen(pal.mid().color());
1035 painter->setBrush(pal.mid());
1037 int spacer = 0;
1038 // draw expander
1039 if (flags & State_Children) {
1040 QPolygon poly;
1041 if (flags & State_Open) {
1042 poly.setPoints(3, -4,-2, 4,-2, 0,2);
1043 } else {
1044 poly.setPoints(3, -2,-4, 2,0, -2,4);
1046 poly.translate(cx, cy);
1047 painter->drawPolygon(poly);
1049 spacer = 6;
1052 // draw lines
1053 if (flags & State_Item) {
1054 if (option->direction == Qt::RightToLeft)
1055 painter->drawLine(x, cy, cx-spacer, cy);
1056 else
1057 painter->drawLine(cx+spacer, cy, x2, cy);
1059 if (flags & State_Sibling) {
1060 painter->drawLine(cx, cy+spacer, cx, y2);
1062 if (flags & (State_Item|State_Sibling)) {
1063 painter->drawLine(cx, cy-spacer, cx, y);
1065 break;
1068 case PE_IndicatorToolBarHandle: // toolbar handle
1069 drawPhaseGradient(painter, rect, pal.window().color(),
1070 !horiz, rect.size(), true);
1071 drawPhaseDoodads(painter, rect, pal, !horiz);
1072 break;
1074 case PE_Q3DockWindowSeparator: // Q3 dock/toolbar separator
1075 case PE_IndicatorToolBarSeparator: // toolbar separator
1076 // TODO: lines don't go to edge of bar, need to fix
1077 if (horiz) {
1078 painter->setPen(pal.mid().color());
1079 painter->drawLine(cx, 0, cx, y2);
1080 painter->setPen(pal.midlight().color());
1081 painter->drawLine(cx+1, 0, cx+1, y2);
1082 } else {
1083 painter->setPen(pal.mid().color());
1084 painter->drawLine(0, cy, x2, cy);
1085 painter->setPen(pal.midlight().color());
1086 painter->drawLine(0, cy+1, x2, cy+1);
1088 break;
1090 case PE_IndicatorArrowUp: // generic up arrow
1091 case PE_IndicatorSpinUp: // spin up arrow
1092 painter->setBrush(enabled ? pal.dark() : pal.mid());
1093 painter->setPen(painter->brush().color());
1094 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1095 pixelMetric(PM_ButtonShiftVertical));
1096 painter->drawPixmap(cx-2, cy-2, bitmaps_[UArrow]);
1097 break;
1099 case PE_IndicatorArrowDown: // generic down arrow
1100 case PE_IndicatorSpinDown: // spin down arrow
1101 painter->setBrush(enabled ? pal.dark() : pal.mid());
1102 painter->setPen(painter->brush().color());
1103 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1104 pixelMetric(PM_ButtonShiftVertical));
1105 painter->drawPixmap(cx-2, cy-2, bitmaps_[DArrow]);
1106 break;
1108 case PE_IndicatorArrowLeft: // generic left arrow
1109 painter->setBrush(enabled ? pal.dark() : pal.mid());
1110 painter->setPen(painter->brush().color());
1111 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1112 pixelMetric(PM_ButtonShiftVertical));
1113 painter->drawPixmap(cx-2, cy-2, bitmaps_[LArrow]);
1114 break;
1116 case PE_IndicatorArrowRight: // generic right arrow
1117 painter->setBrush(enabled ? pal.dark() : pal.mid());
1118 painter->setPen(painter->brush().color());
1119 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1120 pixelMetric(PM_ButtonShiftVertical));
1121 painter->drawPixmap(cx-2, cy-2, bitmaps_[RArrow]);
1122 break;
1124 case PE_IndicatorSpinPlus: // spin plus sign
1125 painter->setBrush(enabled ? pal.dark() : pal.mid());
1126 painter->setPen(painter->brush().color());
1127 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1128 pixelMetric(PM_ButtonShiftVertical));
1129 painter->drawPixmap(cx-2, cy-2, bitmaps_[PlusSign]);
1130 break;
1132 case PE_IndicatorSpinMinus: // spin minus sign
1133 painter->setBrush(enabled ? pal.dark() : pal.mid());
1134 painter->setPen(painter->brush().color());
1135 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1136 pixelMetric(PM_ButtonShiftVertical));
1137 painter->drawPixmap(cx-2, cy-2, bitmaps_[MinusSign]);
1138 break;
1140 // not drawing these elements, as default is sufficient
1141 // case PE_PanelLineEdit: // panel for a line edit
1142 // case PE_Q3Separator: // Q3 generic separator
1143 // case PE_IndicatorTabTear: // jaggy torn tab indicator
1144 // case PE_IndicatorProgressChunk: // section of progress bar
1145 // case PE_Q3CheckListController: // Q3 controller of a list view item
1146 // case PE_Q3CheckListExclusiveIndicator: // Q3 radio of a list view item
1147 // case PE_PanelTipLabel: // panel for a tip
1149 default:
1150 QWindowsStyle::drawPrimitive(element, option, painter, widget);
1151 break;
1154 painter->restore();
1157 //////////////////////////////////////////////////////////////////////////////
1158 // drawControl()
1159 // -------------
1160 // Draw a control
1162 void PhaseStyle::drawControl(ControlElement element,
1163 const QStyleOption *option,
1164 QPainter *painter,
1165 const QWidget *widget) const
1167 const QRect &rect = option->rect;
1168 const State &flags = option->state;
1169 const QPalette &pal = option->palette;
1170 bool depress = flags & (State_Sunken | State_On);
1171 bool enabled = flags & State_Enabled;
1172 bool horizontal = flags & State_Horizontal;
1173 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
1175 int x, y, w, h;
1176 rect.getRect(&x, &y, &w, &h);
1177 int x2 = rect.right();
1178 int y2 = rect.bottom();
1179 //int cx = rect.center().x();
1180 int cy = rect.center().y();
1182 switch (element) {
1183 case CE_PushButtonBevel: { // QPushButton bevel and default indicator
1184 const QStyleOptionButton *button;
1185 button = qstyleoption_cast<const QStyleOptionButton *>(option);
1186 if (!button) break;
1188 if (!depress &&
1189 (button->features & QStyleOptionButton::DefaultButton)) {
1190 // draw default frame
1191 drawPrimitive(PE_FrameDefaultButton,
1192 option, painter, widget);
1193 // adjust size for bevel
1194 int dbi = pixelMetric(PM_ButtonDefaultIndicator,
1195 button, widget);
1196 QStyleOptionButton tempopt = *button;
1197 tempopt.rect.adjust(dbi, dbi, -dbi, -dbi);
1198 // draw bevel
1199 drawPrimitive(PE_PanelButtonBevel,
1200 &tempopt, painter, widget);
1201 } else if ((button->features & QStyleOptionButton::Flat)
1202 && !depress) {
1203 // flat button, don't draw anything
1204 } else {
1205 // draw normal button
1206 drawPrimitive(PE_PanelButtonCommand,
1207 button, painter, widget);
1210 if (button->features & QStyleOptionButton::HasMenu) {
1211 // get arrow rect
1212 int mbi = pixelMetric(PM_MenuButtonIndicator,
1213 button, widget);
1214 QStyleOptionButton tempopt = *button;
1215 tempopt.rect = QRect(rect.right()- mbi, rect.height() - 20,
1216 mbi, rect.height() - 4);
1217 // draw arrow
1218 drawPrimitive(PE_IndicatorArrowDown,
1219 &tempopt, painter, widget);
1221 break;
1224 case CE_DockWidgetTitle: { // dock window title
1225 const QStyleOptionDockWidget *doption;
1226 doption = qstyleoption_cast<const QStyleOptionDockWidget*>(option);
1227 if (!doption) break;
1229 if (doption->movable) {
1230 const QDockWidget *dwidget;
1231 dwidget = qobject_cast<const QDockWidget*>(widget);
1232 if (dwidget && dwidget->isFloating()) {
1233 drawPhaseGradient(painter, rect,
1234 pal.highlight().color(),
1235 false, rect.size(), false);
1236 } else {
1237 // TODO: Qt isn't drawing buttons centered
1238 drawPhaseBevel(painter, rect.adjusted(0, 0, 0, -1),
1239 pal, pal.window(), false, false, false);
1243 if (!doption->title.isEmpty()) {
1244 painter->setPen(pal.foreground().color());
1245 drawItemText(painter,
1246 rect.adjusted(4, 0, -4, -1), Qt::AlignCenter,
1247 pal, enabled, doption->title);
1249 break;
1252 case CE_Splitter: // splitter handle
1253 painter->fillRect(rect, mouseover ?
1254 pal.window().color().light(contrast_) :
1255 pal.window());
1256 drawPhaseDoodads(painter, rect, pal, !horizontal);
1257 break;
1259 case CE_TabBarTabShape: { // tab shape within a tabbar
1260 const QStyleOptionTab *tab;
1261 tab = qstyleoption_cast<const QStyleOptionTab*>(option);
1262 if (!tab) break;
1264 // use default for triangular tabs
1265 if (tab->shape != QTabBar::RoundedNorth &&
1266 tab->shape != QTabBar::RoundedWest &&
1267 tab->shape != QTabBar::RoundedSouth &&
1268 tab->shape != QTabBar::RoundedEast) {
1269 QWindowsStyle::drawControl(element, option, painter, widget);
1270 break;
1272 // this guy can get complicated, we we do it elsewhere
1273 drawPhaseTab(painter, pal, tab);
1274 break;
1277 case CE_ProgressBarGroove: // groove of progress bar
1278 drawPhasePanel(painter, rect, pal, pal.base(), true);
1279 break;
1281 case CE_ProgressBarContents: { // indicator of progress bar
1282 const QStyleOptionProgressBar *pbar;
1283 pbar = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
1284 if (!pbar) break;
1286 bool vertical = false;
1287 bool inverted = false;
1289 // Get v2 options
1290 const QStyleOptionProgressBarV2 *pb2;
1291 pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
1292 if (pb2) {
1293 vertical = (pb2->orientation == Qt::Vertical);
1294 inverted = pb2->invertedAppearance;
1297 if (vertical) {
1298 QMatrix matrix;
1299 qSwap(h, w); // flip width and height
1300 matrix.translate(h+5, 0.0);
1301 matrix.rotate(90.0);
1302 painter->setMatrix(matrix);
1305 bool reverse = (vertical ||
1306 (!vertical && (pbar->direction==Qt::RightToLeft)));
1307 if (inverted) reverse = !reverse;
1309 painter->save();
1311 painter->setBrush(pal.highlight());
1312 painter->setPen(pal.dark().color());
1314 if (pbar->minimum == 0 && pbar->maximum == 0) {
1315 // busy indicator
1316 int bar = pixelMetric(PM_ProgressBarChunkWidth, pbar, widget);
1317 int progress = pbar->progress % ((w-bar) * 2);
1318 if (progress > (w-bar)) progress = 2 * (w-bar) - progress;
1319 painter->drawRect(x+progress, y, bar-1, h-1);
1320 } else {
1321 double progress = (double)pbar->progress / (double)pbar->maximum;
1322 int dx = (int)(w * progress);
1323 if (dx > 2) {
1324 if (reverse) x += w - dx;
1325 painter->drawRect(x, y, dx-1, h-1);
1328 painter->restore();
1329 break;
1332 case CE_ProgressBarLabel: { // label of progress bar
1333 const QStyleOptionProgressBar *pbar;
1334 pbar = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
1335 if (!pbar) break;
1336 if (pbar->minimum == 0 && pbar->maximum == 0) break;
1338 painter->save();
1340 bool vert = false;
1341 bool invert = false;
1342 bool btt = false; // bottom to top text orientation
1343 const QStyleOptionProgressBarV2 *pbar2;
1344 pbar2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
1345 if (pbar2) {
1346 vert = (pbar2->orientation == Qt::Vertical);
1347 invert = pbar2->invertedAppearance;
1348 btt = pbar2->bottomToTop;
1351 if (vert) {
1352 QMatrix matrix;
1353 qSwap(w, h); // flip width and height
1354 if (btt) {
1355 matrix.translate(0.0, w);
1356 matrix.rotate(-90.0);
1357 } else {
1358 matrix.translate(h, 0.0);
1359 matrix.rotate(90.0);
1361 painter->setMatrix(matrix);
1364 QRect left;
1365 int ipos = int(((pbar->progress - pbar->minimum)
1366 / double(pbar->maximum - pbar->minimum)) * w);
1367 bool rtl = (pbar->direction == Qt::RightToLeft);
1368 bool flip = ((!vert && ((rtl && !invert) || (!rtl && invert)))
1369 || (vert && ((!invert && !btt) || (invert && btt))));
1370 if (flip) {
1371 ipos = w - ipos;
1372 if (ipos >= 0 && ipos <= w) {
1373 left = QRect(x, y, ipos, h);
1375 } else {
1376 if (ipos >= 0 && ipos <= w) {
1377 left = QRect(x, y, ipos, h);
1381 // QFont font = painter->font();
1382 // font.setBold(true);
1383 // painter->setFont(font);
1385 painter->setPen(flip
1386 ? pbar->palette.base().color()
1387 : pbar->palette.text().color());
1388 painter->drawText(x, y, w, h, Qt::AlignCenter, pbar->text);
1389 if (!left.isNull()) {
1390 painter->setPen(flip
1391 ? pbar->palette.text().color()
1392 : pbar->palette.base().color());
1393 painter->setClipRect(left, Qt::IntersectClip);
1394 painter->drawText(x, y, w, h, Qt::AlignCenter, pbar->text);
1396 painter->restore();
1397 break;
1400 case CE_MenuBarItem: { // menu item in a QMenuBar
1401 const QStyleOptionMenuItem *mbi;
1402 mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option);
1403 if (!mbi) break;
1405 if ((flags & State_Selected) && (flags & State_HasFocus)) {
1406 if (flags & State_Sunken) {
1407 drawPhasePanel(painter, rect, pal, pal.window(), true);
1408 } else {
1409 drawPhaseBevel(painter, rect, pal, pal.window(),
1410 false, false, false);
1412 } else {
1413 drawPhaseGradient(painter, rect, pal.window().color(), false,
1414 rect.size(), false);
1416 QCommonStyle::drawControl(element, mbi, painter, widget);
1417 break;
1420 case CE_MenuBarEmptyArea: // empty area of a QMenuBar
1421 drawPhaseGradient(painter, rect, pal.window().color(), false,
1422 rect.size(), false);
1423 break;
1425 case CE_MenuItem: { // menu item in a QMenu
1426 const QStyleOptionMenuItem *mi;
1427 mi = qstyleoption_cast<const QStyleOptionMenuItem *>(option);
1428 if (!mi) break;
1430 int checkwidth = qMax(mi->maxIconWidth, 20);
1431 bool active = (flags & State_Selected);
1432 int checked = (mi->checkType != QStyleOptionMenuItem::NotCheckable)
1433 ? mi->checked : false;
1434 QRect vrect;
1436 // draw background
1437 if (active && enabled) {
1438 painter->fillRect(rect, pal.highlight());
1439 } else {
1440 painter->fillRect(rect, pal.window());
1443 // draw separator
1444 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
1445 painter->setPen(pal.mid().color());
1446 painter->drawLine(x+checkwidth, cy-1, x2-checkwidth-1, cy-1);
1447 painter->setPen(pal.dark().color());
1448 painter->drawLine(x+checkwidth+1, cy, x2-checkwidth-1, cy);
1449 painter->drawPoint(x+checkwidth, cy);
1450 painter->setPen(pal.midlight().color());
1451 painter->drawLine(x+checkwidth+1, cy+1, x2-checkwidth, cy+1);
1452 painter->drawPoint(x2-checkwidth, cy+1);
1453 break;
1456 // draw icon
1457 if (!mi->icon.isNull() && !checked) {
1458 QIcon::Mode mode;
1459 if (active)
1460 mode = enabled ? QIcon::Active : QIcon::Disabled;
1461 else
1462 mode = enabled ? QIcon::Normal : QIcon::Disabled;
1464 QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize),
1465 mode);
1466 vrect = visualRect(mi->direction, rect,
1467 QRect(x, y, checkwidth, h));
1468 QRect pmrect(0, 0, pixmap.width(), pixmap.height());
1469 pmrect.moveCenter(vrect.center());
1470 painter->drawPixmap(pmrect.topLeft(), pixmap);
1473 // draw check
1474 if (checked) {
1475 QStyleOptionMenuItem newmi = *mi;
1476 newmi.state = State_None;
1477 if (enabled) newmi.state |= State_Enabled;
1478 if (active) newmi.state |= State_On;
1479 newmi.rect = visualRect(mi->direction, rect,
1480 QRect(x, y, checkwidth, h));
1481 drawPrimitive(PE_IndicatorMenuCheckMark, &newmi, painter, widget);
1484 // draw text
1485 int xm = ITEMFRAME + checkwidth + ITEMHMARGIN;
1486 int xp = x + xm;
1487 int tw = w - xm - mi->tabWidth - ARROWMARGIN - ITEMHMARGIN * 3
1488 - ITEMFRAME + 1;
1489 QString text = mi->text;
1490 QRect trect(xp, y+ITEMVMARGIN, tw, h - 2 * ITEMVMARGIN);
1491 vrect = visualRect(option->direction, rect, trect);
1493 if (enabled) {
1494 painter->setPen(active ? pal.highlightedText().color() :
1495 pal.windowText().color());
1496 } else {
1497 painter->setPen(pal.mid().color());
1500 if (!text.isEmpty()) { // draw label
1501 painter->save();
1503 if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
1504 QFont font = mi->font;
1505 font.setBold(true);
1506 painter->setFont(font);
1509 int t = text.indexOf('\t');
1510 int tflags = Qt::AlignVCenter | Qt::AlignLeft |
1511 Qt::TextDontClip | Qt::TextSingleLine;
1512 if (styleHint(SH_UnderlineShortcut, mi, widget))
1513 tflags |= Qt::TextShowMnemonic;
1514 else
1515 tflags |= Qt::TextHideMnemonic;
1517 if (t >= 0) { // draw right label (accelerator)
1518 QRect tabrect = visualRect(option->direction, rect,
1519 QRect(trect.topRight(),
1520 QPoint(rect.right(), trect.bottom())));
1521 painter->drawText(tabrect, tflags, text.mid(t+1));
1522 text = text.left(t);
1525 // draw left label
1526 painter->drawText(vrect, tflags, text.left(t));
1527 painter->restore();
1530 // draw submenu arrow
1531 if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) {
1532 PrimitiveElement arrow = (option->direction == Qt::RightToLeft)
1533 ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1534 int dim = (h-2*ITEMFRAME) / 2;
1535 vrect = visualRect(option->direction, rect,
1536 QRect(x + w - ARROWMARGIN - ITEMFRAME - dim,
1537 y + h / 2 - dim / 2, dim, dim));
1539 QStyleOptionMenuItem newmi = *mi;
1540 newmi.rect = vrect;
1541 newmi.state = enabled ? State_Enabled : State_None;
1542 if (active) {
1543 newmi.palette.setColor(QPalette::Dark,
1544 newmi.palette.highlightedText().color());
1546 drawPrimitive(arrow, &newmi, painter, widget);
1548 break;
1551 case CE_MenuTearoff: // tearoff area in menu
1552 if (flags & State_Selected)
1553 painter->fillRect(rect, pal.brush(QPalette::Highlight));
1554 else
1555 painter->fillRect(rect, pal.brush(QPalette::Window));
1556 painter->setPen(QPen(pal.mid().color(), 1, Qt::DotLine));
1557 painter->drawLine(x+6, cy-1, x2-6, cy-1);
1558 painter->setPen(QPen(pal.dark().color(), 1, Qt::DotLine));
1559 painter->drawLine(x+6, cy, x2-6, cy);
1560 painter->setPen(QPen(pal.midlight().color(), 1, Qt::DotLine));
1561 painter->drawLine(x+6, cy+1, x2-6, cy+1);
1562 break;
1564 case CE_ToolBoxTab: { // tab area of toolbox
1565 // TODO: account for reverse layout
1566 // TODO: Qt broken - palette isn't constant from tab to tab
1567 const QStyleOptionToolBox *box;
1568 box = qstyleoption_cast<const QStyleOptionToolBox*>(option);
1569 if (!box) break;
1571 const int rx = x2 - 20;
1572 const int cx = rx - h + 1;
1574 QPolygon polygon;
1575 polygon.setPoints(6,
1576 x-1,y, cx,y, rx-2,y2-2, x2+1,y2-2,
1577 x2+1,y2+1, x-1,y2+1);
1579 painter->save();
1581 if (flags & State_Selected) {
1582 painter->setPen(pal.dark().color());
1583 painter->setBrush(pal.window());
1584 painter->drawConvexPolygon(polygon);
1585 } else {
1586 painter->setClipRegion(polygon);
1587 drawPhaseGradient(painter, rect, pal.window().color(), false,
1588 QSize(w, h), false);
1589 painter->setClipping(false);
1590 painter->drawPolyline(polygon);
1593 polygon.setPoints(4, x,y+1, cx,y+1, rx-2,y2-1, x2,y2-1);
1594 painter->setPen(pal.midlight().color());
1595 painter->drawPolyline(polygon);
1597 painter->restore();
1598 break;
1601 case CE_SizeGrip: { // window resize handle
1602 int sw = qMin(h, w) - 1;
1603 y = y2 - sw;
1605 painter->save();
1606 if (option->direction == Qt::RightToLeft) {
1607 x2 = x + sw;
1608 for (int n = 0; n < 4; ++n) {
1609 painter->setPen(pal.mid().color());
1610 painter->drawLine(x, y, x2, y2);
1611 painter->setPen(pal.midlight().color());
1612 painter->drawLine(x, y+1, x2-1, y2);
1613 y += 3;
1614 x2 -= 3;
1616 } else {
1617 x = x2 - sw;
1618 for (int n = 0; n < 4; ++n) {
1619 painter->setPen(pal.mid().color());
1620 painter->drawLine(x, y2, x2, y);
1621 painter->setPen(pal.midlight().color());
1622 painter->drawLine(x+1, y2, x2, y+1);
1623 x += 3;
1624 y += 3;
1627 painter->restore();
1628 break;
1631 case CE_HeaderSection: { // header bevel
1632 const QStyleOptionHeader *header;
1633 header = qstyleoption_cast<const QStyleOptionHeader *>(option);
1634 if (!header) break;
1636 horizontal = (header->orientation == Qt::Horizontal);
1637 // adjust rect so headers overlap by one pixel
1638 QRect arect = rect.adjusted(-1, -1, 0, 0);
1639 if (depress) {
1640 painter->save();
1641 painter->setPen(pal.dark().color());
1642 painter->setBrush(pal.mid());
1643 painter->drawRect(arect.adjusted(0, 0, -1, -1));
1644 painter->restore();
1646 else {
1647 drawPhaseBevel(painter, arect, pal,
1648 pal.window(), false, !horizontal, true);
1650 break;
1653 case CE_ScrollBarAddLine: { // scrollbar scroll down
1654 PrimitiveElement arrow = (horizontal)
1655 ? PE_IndicatorArrowRight : PE_IndicatorArrowDown;
1657 drawPhaseBevel(painter, rect, pal, pal.button(),
1658 depress, !horizontal, true);
1659 drawPrimitive(arrow, option, painter, widget);
1660 break;
1662 case CE_ScrollBarSubLine: { // scrollbar scroll up
1663 const QStyleOptionSlider *sb;
1664 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
1665 if (!sb) break;
1667 int extent = pixelMetric(PM_ScrollBarExtent, sb, widget);
1669 QRect button1, button2;
1670 PrimitiveElement arrow;
1672 if (horizontal) {
1673 button1.setRect(x, y, extent, extent);
1674 button2.setRect(x2 - extent + 1, y, extent, extent);
1675 arrow = PE_IndicatorArrowLeft;
1676 } else {
1677 button1.setRect(x, y, extent, extent);
1678 button2.setRect(x, y2 - extent + 1, extent, extent);
1679 arrow = PE_IndicatorArrowUp;
1682 // draw buttons
1683 drawPhaseBevel(painter, button1, pal, pal.button(),
1684 depress, !horizontal, true);
1685 drawPhaseBevel(painter, button2, pal, pal.button(),
1686 depress, !horizontal, true);
1688 QStyleOptionSlider newoption = *sb;
1689 newoption.rect = button1;
1690 drawPrimitive(arrow, &newoption, painter, widget);
1691 newoption.rect = button2;
1692 drawPrimitive(arrow, &newoption, painter, widget);
1694 break;
1697 case CE_ScrollBarAddPage: // scrollbar page down
1698 case CE_ScrollBarSubPage: // scrollbar page up
1699 if (h) { // has a height, thus visible
1700 painter->fillRect(rect, pal.mid());
1701 painter->setPen(pal.dark().color());
1702 if (horizontal) { // vertical
1703 painter->drawLine(x, y, x2, y);
1704 painter->drawLine(x, y2, x2, y2);
1705 } else { // horizontal
1706 painter->drawLine(x, y, x, y2);
1707 painter->drawLine(x2, y, x2, y2);
1710 break;
1712 case CE_ScrollBarSlider: // scrollbar slider/thumb
1713 drawPhaseBevel(painter, rect, pal, mouseover ?
1714 pal.button().color().light(contrast_) : pal.button(),
1715 false, !horizontal, true);
1716 drawPhaseDoodads(painter, rect, pal, horizontal);
1717 break;
1719 case CE_RubberBand: { // rubberband (such as for iconview)
1720 const QStyleOptionRubberBand *rb;
1721 rb = qstyleoption_cast<const QStyleOptionRubberBand*>(option);
1722 if (rb) {
1723 painter->save();
1724 QColor color = pal.highlight().color();
1725 if (!rb->opaque) color.setAlpha(127);
1726 painter->setPen(color);
1727 if (!rb->opaque) color.setAlpha(31);
1728 painter->setBrush(color);
1729 QStyleHintReturnMask mask;
1730 painter->drawRect(rect.adjusted(0, 0, -1, -1));
1731 painter->restore();
1733 break;
1736 case CE_ToolBar: { // QToolBar
1737 drawPrimitive(PE_PanelToolBar, option, painter, widget);
1738 QRect grect = rect.adjusted(2, 2, -2, -2);
1739 drawPhaseGradient(painter, grect, pal.window().color(),
1740 !horizontal, grect.size(), true);
1741 break;
1744 // not drawing these controls, as default is sufficient
1745 // case CE_Q3DockWindowEmptyArea: // empty area of dock widget
1746 // case CE_PushButtonLabel:
1747 // case CE_FocusFrame:
1748 // case CE_CheckBox:
1749 // case CE_CheckBoxLabel:
1750 // case CE_ComboBoxLabel:
1751 // case CE_FocusFrame:
1752 // case CE_Header:
1753 // case CE_HeaderLabel:
1754 // case CE_MenuScroller:
1755 // case CE_RadioButton:
1756 // case CE_RadioButtonLabel:
1757 // case CE_ScrollBarFirst:
1758 // case CE_ScrollBarLast:
1759 // case CE_TabBarTab:
1760 // case CE_TabBarTabLabel:
1761 // case CE_ToolButtonLabel:
1763 default:
1764 QWindowsStyle::drawControl(element, option, painter, widget);
1765 break;
1769 //////////////////////////////////////////////////////////////////////////////
1770 // drawComplexControl()
1771 // --------------------
1772 // Draw complex control
1774 void PhaseStyle::drawComplexControl(ComplexControl control,
1775 const QStyleOptionComplex *option,
1776 QPainter *painter,
1777 const QWidget *widget) const
1779 const QRect &rect = option->rect;
1780 const State &flags = option->state;
1781 const QPalette &pal = option->palette;
1782 bool enabled = flags & State_Enabled;
1783 bool sunken = flags & State_Sunken;
1784 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
1785 int x, y, w, h;
1786 rect.getRect(&x, &y, &w, &h);
1787 QRect subrect;
1789 switch (control) {
1790 case CC_SpinBox: { // QSpinBox
1791 const QStyleOptionSpinBox *box;
1792 box = qstyleoption_cast<const QStyleOptionSpinBox*>(option);
1793 if (!box) break;
1795 QStyleOptionSpinBox copybox = *box;
1796 PrimitiveElement element;
1798 // draw frame
1799 if (box->frame && (box->subControls & SC_SpinBoxFrame)) {
1800 subrect = subControlRect(CC_SpinBox, box,
1801 SC_SpinBoxFrame, widget);
1802 drawPhasePanel(painter, subrect, pal, Qt::NoBrush, true);
1805 // draw button field
1806 subrect = subControlRect(CC_SpinBox, box,
1807 SC_SpinBoxFrame, widget);
1808 subrect.adjust(1, 1, -1, -1);
1809 int left = subControlRect(CC_SpinBox, box,
1810 SC_SpinBoxUp, widget).left();
1811 subrect.setLeft(left);
1812 drawPhaseBevel(painter, subrect, pal, mouseover ?
1813 pal.button().color().light(contrast_) :
1814 pal.button(),
1815 false, false, false);
1817 // draw up arrow
1818 if (box->subControls & SC_SpinBoxUp) {
1819 subrect = subControlRect(CC_SpinBox, box, SC_SpinBoxUp, widget);
1820 copybox.subControls = SC_SpinBoxUp;
1821 copybox.rect = subControlRect(CC_SpinBox, box,
1822 SC_SpinBoxUp, widget);
1824 if (box->buttonSymbols == QAbstractSpinBox::PlusMinus)
1825 element = PE_IndicatorSpinPlus;
1826 else
1827 element = PE_IndicatorSpinUp;
1829 if (box->activeSubControls == SC_SpinBoxUp && sunken) {
1830 copybox.state |= State_On;
1831 copybox.state |= State_Sunken;
1832 } else {
1833 copybox.state |= State_Raised;
1834 copybox.state &= ~State_Sunken;
1836 drawPrimitive(element, &copybox, painter, widget);
1839 // draw down arrow
1840 if (box->subControls & SC_SpinBoxDown) {
1841 subrect = subControlRect(CC_SpinBox, box, SC_SpinBoxDown, widget);
1842 copybox.subControls = SC_SpinBoxDown;
1843 copybox.rect = subControlRect(CC_SpinBox, box,
1844 SC_SpinBoxDown, widget);
1846 if (box->buttonSymbols == QAbstractSpinBox::PlusMinus)
1847 element = PE_IndicatorSpinMinus;
1848 else
1849 element = PE_IndicatorSpinDown;
1851 if (box->activeSubControls == SC_SpinBoxDown && sunken) {
1852 copybox.state |= State_On;
1853 copybox.state |= State_Sunken;
1854 } else {
1855 copybox.state |= State_Raised;
1856 copybox.state &= ~State_Sunken;
1858 drawPrimitive(element, &copybox, painter, widget);
1860 break;
1863 case CC_ComboBox: { // QComboBox
1864 const QStyleOptionComboBox *combo;
1865 combo = qstyleoption_cast<const QStyleOptionComboBox*>(option);
1866 if (!combo) break;
1868 subrect = subControlRect(CC_ComboBox, combo,
1869 SC_ComboBoxArrow, widget);
1870 if (combo->editable) {
1871 // draw frame
1872 drawPhasePanel(painter, rect, pal, Qt::NoBrush, true);
1873 // draw arrow box
1874 drawPhaseButton(painter, subrect, pal, mouseover
1875 ? pal.button().color().light(contrast_)
1876 : pal.button().color(), sunken);
1877 // finish off frame (because it overlaps)
1878 painter->setPen(pal.dark().color());
1879 painter->drawPoint(subrect.x(), subrect.top()+1);
1880 painter->drawPoint(subrect.x(), subrect.bottom()-1);
1881 painter->setPen(pal.light().color());
1882 painter->drawPoint(subrect.x(), subrect.bottom());
1883 } else {
1884 // draw bevel
1885 drawPhaseButton(painter, rect, pal, mouseover
1886 ? pal.button().color().light(contrast_)
1887 : pal.button().color(), sunken);
1890 if (combo->subControls & SC_ComboBoxArrow) { // draw slot
1891 int slot = qMax(h/4, 6) + (h%2);
1892 subrect.adjust(3, 0, -3, 0);
1893 subrect.setTop(subrect.top() + subrect.height()/2 - slot/2);
1894 subrect.setHeight(slot);
1895 drawPhasePanel(painter, subrect,
1896 pal, sunken ? pal.midlight() : pal.mid(),
1897 true);
1900 if ((flags & State_HasFocus) && !combo->editable) {
1901 QStyleOptionFocusRect focus;
1902 focus.QStyleOption::operator=(*combo);
1903 focus.rect = subElementRect(SE_ComboBoxFocusRect,
1904 combo, widget);
1905 drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
1907 break;
1910 case CC_Slider: { // QSlider
1911 const QStyleOptionSlider *slider;
1912 slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
1913 if (!slider) break;
1915 if (slider->subControls & SC_SliderGroove) {
1916 subrect = subControlRect(CC_Slider, slider,
1917 SC_SliderGroove, widget);
1918 if (subrect.isValid()) {
1919 if (slider->orientation == Qt::Horizontal) {
1920 subrect.setTop(subrect.top()+subrect.height()/2-3);
1921 subrect.setHeight(7);
1922 } else {
1923 subrect.setLeft(subrect.left()+subrect.width()/2-3);
1924 subrect.setWidth(7);
1926 drawPhasePanel(painter, subrect, pal, pal.mid(), true);
1930 if (slider->subControls & SC_SliderHandle) {
1931 subrect = subControlRect(CC_Slider, slider,
1932 SC_SliderHandle, widget);
1933 QColor color = mouseover
1934 ? pal.button().color().light(contrast_)
1935 : pal.button().color();
1937 if (slider->orientation == Qt::Horizontal) {
1938 subrect.setWidth(6);
1939 drawPhaseBevel(painter, subrect, pal, color,
1940 false, false, false);
1941 subrect.moveLeft(subrect.left()+5);
1942 drawPhaseBevel(painter, subrect, pal, color,
1943 false, false, false);
1944 } else {
1945 subrect.setHeight(6);
1946 drawPhaseBevel(painter, subrect, pal, color,
1947 false, true, false);
1948 subrect.moveTop(subrect.top()+5);
1949 drawPhaseBevel(painter, subrect, pal, color,
1950 false, true, false);
1954 if (slider->subControls & SC_SliderTickmarks) {
1955 bool ticksabove = slider->tickPosition & QSlider::TicksAbove;
1956 bool ticksbelow = slider->tickPosition & QSlider::TicksBelow;
1957 bool horizontal = (slider->orientation == Qt::Horizontal);
1959 int spaceavail = pixelMetric(PM_SliderSpaceAvailable,
1960 slider, widget);
1961 int interval = slider->tickInterval;
1962 if (interval==0) {
1963 interval = slider->singleStep;
1964 if (QStyle::sliderPositionFromValue(slider->minimum,
1965 slider->maximum,
1966 interval, spaceavail)
1967 - QStyle::sliderPositionFromValue(slider->minimum,
1968 slider->maximum,
1969 0, spaceavail) < 3)
1970 interval = slider->pageStep;
1972 if (interval < 2) interval = 2;
1974 QRect handle = subControlRect(CC_Slider, slider,
1975 SC_SliderHandle, widget);
1976 int pos, offset, span, ticksize;
1977 if (horizontal) {
1978 offset = handle.width() / 2;
1979 span = w - handle.width();
1980 ticksize = (h - handle.height()) / 2 - 1;
1981 } else {
1982 offset = handle.height() / 2;
1983 span = h - handle.height();
1984 ticksize = (w - handle.width()) / 2 - 1;
1987 QPen oldpen = painter->pen();
1988 painter->setPen(pal.dark().color());
1990 for (int n=slider->minimum; n<=slider->maximum; n+=interval) {
1991 pos = sliderPositionFromValue(slider->minimum,
1992 slider->maximum,
1993 n, span,
1994 slider->upsideDown);
1995 pos += offset;
1997 if (horizontal) {
1998 if (ticksabove) {
1999 painter->drawLine(pos, y, pos, y + ticksize);
2001 if (ticksbelow) {
2002 painter->drawLine(pos, rect.bottom(),
2003 pos, rect.bottom() - ticksize);
2005 } else {
2006 if (ticksabove) {
2007 painter->drawLine(x, pos, x + ticksize, pos);
2009 if (ticksbelow) {
2010 painter->drawLine(rect.right(), pos,
2011 rect.right() - ticksize, pos);
2015 painter->setPen(oldpen);
2018 break;
2021 case CC_Dial: { // QDial
2022 const QStyleOptionSlider *dial;
2023 dial = qstyleoption_cast<const QStyleOptionSlider*>(option);
2024 if (!dial) break;
2026 // avoid aliasing
2027 painter->setRenderHint(QPainter::Antialiasing, true);
2028 qreal cx = rect.center().x();
2029 qreal cy = rect.center().y();
2030 qreal radius = (qMin(w, h) / 2.0) - 2.0;
2031 qreal tick = qMax(radius / 6, 4.0);
2033 if (dial->subControls & SC_DialGroove) {
2034 QRectF groove = QRectF(cx-radius+tick, cy-radius+tick,
2035 radius*2-tick*2, radius*2-tick*2);
2037 // Note: State_MouseOver doesn't work well with QDial
2038 QLinearGradient gradient(0, groove.top(), 0, groove.bottom());
2039 gradient.setColorAt(0, pal.button().color().dark(contrast_));
2040 gradient.setColorAt(1, pal.button().color().light(contrast_));
2042 painter->setPen(pal.dark().color());
2043 painter->setBrush(gradient);
2044 painter->drawEllipse(groove);
2045 painter->setBrush(Qt::NoBrush);
2047 groove.adjust(1.0, 1.0, -1.0, -1.0);
2048 painter->setPen(pal.midlight().color());
2049 painter->drawArc(groove, 60*16, 150*16);
2050 painter->setPen(pal.button().color());
2051 painter->drawArc(groove, 30*16, 30*16);
2052 painter->drawArc(groove, 210*16, 30*16);
2053 painter->setPen(pal.mid().color());
2054 painter->drawArc(groove, 240*16, 150*16);
2057 if (dial->subControls & SC_DialHandle) {
2058 painter->save();
2059 qreal angle;
2060 qreal percent = (double)(dial->sliderValue - dial->minimum)
2061 / (double)(dial->maximum - dial->minimum);
2063 if (dial->maximum == dial->minimum) {
2064 angle = 0.0;
2065 } else if (dial->dialWrapping) {
2066 angle = percent * 360.0;
2067 } else {
2068 angle = percent * 315.0 + 22.5;
2071 painter->translate(cx, cy);
2072 painter->rotate(angle);
2074 bool ul = (angle > 135.0 && angle < 315.0);
2075 painter->setPen(ul ? pal.midlight().color() : pal.mid().color());
2076 painter->drawLine(QLineF(-1, radius-tick-1, -1, radius-tick*4));
2077 painter->setPen(pal.dark().color());
2078 painter->drawLine(QLineF(0, radius-tick, 0, radius-tick*4));
2079 painter->setPen(ul ? pal.mid().color() : pal.midlight().color());
2080 painter->drawLine(QLineF(1, radius-tick-1, 1, radius-tick*4));
2082 painter->restore();
2085 if (dial->subControls & QStyle::SC_DialTickmarks) {
2086 painter->save();
2087 painter->setPen(pal.dark().color());
2089 int ti = dial->tickInterval;
2090 int notches = (dial->maximum - dial->minimum + ti - 1) / ti;
2092 if (notches > 0) {
2093 qreal start, increment;
2094 if (dial->dialWrapping) {
2095 start = 0.0;
2096 increment = 360.0 / notches;
2097 } else {
2098 start = 22.5;
2099 increment = 315.0 / notches;
2102 painter->translate(cx, cy);
2103 painter->rotate(start);
2104 for (int n=0; n<=notches; ++n) {
2105 painter->drawLine(QLineF(0.0, radius,
2106 0.0, radius - tick / 2.0));
2107 painter->rotate(increment);
2110 painter->restore();
2113 painter->setRenderHint(QPainter::Antialiasing, false);
2114 break;
2117 case CC_TitleBar: { // QWorkspace titlebar
2118 // TODO: sync this look up with dock window titles ?
2119 const QStyleOptionTitleBar *title;
2120 title = qstyleoption_cast<const QStyleOptionTitleBar*>(option);
2121 if (!title) break;
2123 // draw titlebar frame
2124 drawPhaseGradient(painter, rect, pal.highlight().color(),
2125 false, rect.size(), false);
2127 int x2 = rect.right();
2128 int y2 = rect.bottom();
2130 painter->setPen(pal.shadow().color());
2131 painter->drawLine(x, y, x, y2);
2132 painter->drawLine(x, y, x2, y);
2133 painter->drawLine(x2, y, x2, y2);
2135 if (!(title->titleBarState & Qt::WindowMinimized))
2136 painter->setPen(pal.dark().color());
2137 painter->drawLine(x+1, y2, x2-1, y2);
2139 painter->setPen(pal.highlight().color().light(110));
2140 painter->drawLine(x+1, y+1, x2-2, y+1);
2141 painter->drawLine(x+1, y+2, x+1, y2-2);
2143 painter->setPen(pal.highlight().color().dark(120));
2144 painter->drawLine(x+2, y2-1, x2-1, y2-1);
2145 painter->drawLine(x2-1, y+2, x2-1, y2-2);
2147 painter->setPen(pal.highlight().color());
2148 painter->drawPoint(x+1, y2-1);
2149 painter->drawPoint(x2-1, y+1);
2151 // draw label
2152 if (title->subControls & SC_TitleBarLabel) {
2153 subrect = subControlRect(CC_TitleBar, title,
2154 SC_TitleBarLabel, widget);
2156 QFont font = painter->font();
2157 font.setBold(true);
2158 painter->setFont(font);
2159 painter->setPen(pal.text().color());
2160 painter->drawText(subrect.adjusted(1, 1, 1, 1),
2161 Qt::AlignCenter | Qt::TextSingleLine,
2162 title->text);
2163 painter->setPen(pal.highlightedText().color());
2164 painter->drawText(subrect, Qt::AlignCenter | Qt::TextSingleLine,
2165 title->text);
2168 // draw buttons
2169 QPixmap pix;
2170 bool down;
2171 QStyleOption tool(*title);
2173 painter->save();
2174 painter->setPen(pal.text().color());
2176 if ((title->subControls & SC_TitleBarSysMenu) &&
2177 (title->titleBarFlags & Qt::WindowSystemMenuHint)){
2178 subrect = subControlRect(CC_TitleBar, title,
2179 SC_TitleBarSysMenu, widget);
2180 if (!title->icon.isNull()) {
2181 title->icon.paint(painter, subrect);
2182 } else {
2183 down = ((title->activeSubControls & SC_TitleBarCloseButton)
2184 && (flags & State_Sunken));
2185 pix = standardPixmap(SP_TitleBarMenuButton, &tool, widget);
2186 tool.rect = subrect;
2187 tool.state = down ? State_Sunken : State_Raised;
2188 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2190 if (down) painter->translate(1, 1);
2191 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2195 if (title->subControls & SC_TitleBarCloseButton) {
2196 subrect = subControlRect(CC_TitleBar, title,
2197 SC_TitleBarCloseButton, widget);
2199 down = ((title->activeSubControls & SC_TitleBarCloseButton)
2200 && (flags & State_Sunken));
2201 if ((title->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool
2202 || qobject_cast<const QDockWidget *>(widget))
2203 pix = standardPixmap(SP_DockWidgetCloseButton, &tool, widget);
2204 else
2205 pix = standardPixmap(SP_TitleBarCloseButton, &tool, widget);
2206 tool.rect = subrect;
2207 tool.state = down ? State_Sunken : State_Raised;
2208 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2210 if (down) painter->translate(1, 1);
2211 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2214 if (title->subControls & SC_TitleBarMinButton) {
2215 subrect = subControlRect(CC_TitleBar, title,
2216 SC_TitleBarMinButton, widget);
2217 down = ((title->activeSubControls & SC_TitleBarMinButton)
2218 && (flags & State_Sunken));
2219 pix = standardPixmap(SP_TitleBarMinButton, &tool, widget);
2220 tool.rect = subrect;
2221 tool.state = down ? State_Sunken : State_Raised;
2222 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2224 if (down) painter->translate(1, 1);
2225 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2228 if ((title->subControls & SC_TitleBarMaxButton) &&
2229 (title->titleBarFlags & Qt::WindowMaximizeButtonHint)) {
2230 subrect = subControlRect(CC_TitleBar, title,
2231 SC_TitleBarMaxButton, widget);
2233 down = ((title->activeSubControls & SC_TitleBarMaxButton) &&
2234 (flags & State_Sunken));
2235 pix = standardPixmap(SP_TitleBarMaxButton, &tool, widget);
2236 tool.rect = subrect;
2237 tool.state = down ? State_Sunken : State_Raised;
2238 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2240 if (down) painter->translate(1, 1);
2241 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2244 if (title->subControls & SC_TitleBarNormalButton) {
2245 subrect = subControlRect(CC_TitleBar, title,
2246 SC_TitleBarNormalButton, widget);
2247 down = ((title->activeSubControls & SC_TitleBarNormalButton) &&
2248 (flags & State_Sunken));
2249 pix = standardPixmap(SP_TitleBarNormalButton, &tool, widget);
2250 tool.rect = subrect;
2251 tool.state = down ? State_Sunken : State_Raised;
2252 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2254 if (down) painter->translate(1, 1);
2255 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2258 if (title->subControls & SC_TitleBarContextHelpButton) {
2259 subrect = subControlRect(CC_TitleBar, title,
2260 SC_TitleBarContextHelpButton, widget);
2261 down = ((title->activeSubControls & SC_TitleBarContextHelpButton) &&
2262 (flags & State_Sunken));
2263 pix = standardPixmap(SP_TitleBarContextHelpButton, &tool, widget);
2264 tool.rect = subrect;
2265 tool.state = down ? State_Sunken : State_Raised;
2266 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2268 if (down) painter->translate(1, 1);
2269 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2271 painter->restore();
2273 break;
2276 // not drawing these controls, as default is sufficient
2277 // case CC_ScrollBar:
2278 // case CC_ToolButton:
2279 // case CC_GroupBox:
2281 default:
2282 QWindowsStyle::drawComplexControl(control, option, painter, widget);
2283 break;
2287 //////////////////////////////////////////////////////////////////////////////
2288 // standardPixmap()
2289 // ----------------
2290 // Get pixmap for style
2292 QPixmap PhaseStyle::standardPixmap(StandardPixmap pixmap,
2293 const QStyleOption *option,
2294 const QWidget *widget) const
2296 switch (pixmap) {
2297 case SP_TitleBarMenuButton:
2298 return QPixmap(title_menu_xpm);
2300 case SP_DockWidgetCloseButton:
2301 case SP_TitleBarCloseButton:
2302 return bitmaps_[TitleClose];
2304 case SP_TitleBarMinButton:
2305 return bitmaps_[TitleMin];
2307 case SP_TitleBarMaxButton:
2308 return bitmaps_[TitleMax];
2310 case SP_TitleBarNormalButton:
2311 return bitmaps_[TitleNormal];
2313 case SP_TitleBarContextHelpButton:
2314 return bitmaps_[TitleHelp];
2316 default:
2317 return QWindowsStyle::standardPixmap(pixmap, option, widget);
2322 //////////////////////////////////////////////////////////////////////////////
2323 // Metrics and Rects //
2324 //////////////////////////////////////////////////////////////////////////////
2326 //////////////////////////////////////////////////////////////////////////////
2327 // pixelMetric()
2328 // -------------
2329 // Get the pixel metric for metric
2331 int PhaseStyle::pixelMetric(PixelMetric metric,
2332 const QStyleOption *option,
2333 const QWidget *widget) const
2335 int ex = qMax(QApplication::fontMetrics().xHeight(), 17);
2337 switch (metric) {
2338 case PM_ButtonDefaultIndicator: // size of default button frame
2339 return 3;
2341 case PM_IndicatorWidth:
2342 case PM_IndicatorHeight:
2343 case PM_ExclusiveIndicatorWidth:
2344 case PM_ExclusiveIndicatorHeight:
2345 case PM_CheckListButtonSize:
2346 return ex & 0xfffe; // even size
2348 case PM_MenuBarPanelWidth:
2349 return 2;
2351 case PM_DockWidgetTitleMargin:
2352 return 2;
2354 case PM_DockWidgetFrameWidth:
2355 return 3;
2357 case PM_ScrollBarExtent: // base width of a vertical scrollbar
2358 return ex & 0xfffe;
2360 case PM_ScrollBarSliderMin: // minimum length of slider
2361 return ex * 2;
2363 case PM_TabBarTabHSpace: // extra tab spacing
2364 return 24;
2366 case PM_TabBarTabShiftVertical:
2367 return 2;
2369 case PM_TabBarTabVSpace: {
2370 const QStyleOptionTab *tab;
2371 tab = qstyleoption_cast<const QStyleOptionTab *>(option);
2372 if (tab) {
2373 if (tab->shape == QTabBar::RoundedNorth) {
2374 return 10;
2375 } else {
2376 return 6;
2379 return 0;
2382 case PM_ProgressBarChunkWidth: {
2383 int breadth = qMax(option->rect.width(), option->rect.height());
2384 return qMax(breadth / 10, 10);
2386 case PM_TitleBarHeight:
2387 return qMax(option ? option->fontMetrics.lineSpacing() : 0, 20);
2389 default:
2390 return QWindowsStyle::pixelMetric(metric, option, widget);
2394 //////////////////////////////////////////////////////////////////////////////
2395 // subElementRect()
2396 // ----------------
2397 // Return rect of subelement
2399 QRect PhaseStyle::subElementRect(SubElement element,
2400 const QStyleOption *option,
2401 const QWidget *widget) const
2403 QRect rect;
2404 int x, y, w, h;
2405 option->rect.getRect(&x, &y, &w, &h);
2407 switch (element) {
2408 case SE_PushButtonFocusRect:
2409 case SE_ComboBoxFocusRect:
2410 // adjust rect in one pixel
2411 rect = QWindowsStyle::subElementRect(element, option, widget);
2412 rect.adjust(1,1,-1,-1);
2413 break;
2415 case SE_ProgressBarContents:
2416 return option->rect.adjusted(3, 3, -3, -3);
2418 case SE_ProgressBarGroove:
2419 case SE_ProgressBarLabel:
2420 return option->rect;
2422 case SE_HeaderArrow: {
2423 int margin = pixelMetric(PM_HeaderMargin, option, widget);
2424 rect.setSize(QSize(h - margin*2, h - margin*2));
2425 if (option->state & State_Horizontal) {
2426 rect.moveTopLeft(QPoint(x + w - h, margin));
2427 } else {
2428 rect.moveTopLeft(QPoint(margin, margin));
2430 rect = visualRect(option->direction, option->rect, rect);
2431 break;
2434 case SE_ToolBoxTabContents:
2435 rect = visualRect(option->direction, option->rect, option->rect);
2436 break;
2438 default:
2439 rect = QWindowsStyle::subElementRect(element, option, widget);
2442 return rect;
2445 //////////////////////////////////////////////////////////////////////////////
2446 // subControlRect()
2447 // ----------------
2448 // Return rect of control
2450 QRect PhaseStyle::subControlRect(ComplexControl control,
2451 const QStyleOptionComplex *option,
2452 SubControl subcontrol,
2453 const QWidget *widget) const
2455 QRect rect;
2456 QRect ctlrect = option->rect;
2457 int x, y, w, h, x2, y2;
2458 const int fw = 2;
2459 ctlrect.getRect(&x, &y, &w, &h);
2460 x2 = ctlrect.right(); y2 = ctlrect.bottom();
2462 switch (control) {
2463 case CC_SpinBox: {
2464 const QStyleOptionSpinBox *box;
2465 box = qstyleoption_cast<const QStyleOptionSpinBox*>(option);
2466 if (!box) break;
2468 bool odd = widget->height() % 2;
2469 int bw = (h*3/4) - odd + 1; // width of button box
2470 switch (subcontrol) {
2471 case SC_SpinBoxUp:
2472 rect.setRect(w-bw, (h/2)-(odd ? 6 : 7), bw-1, 6);
2473 break;
2474 case SC_SpinBoxDown:
2475 rect.setRect(w-bw, (h/2)+1, bw-1, odd ? 7 : 6);
2476 break;
2477 case SC_SpinBoxEditField:
2478 rect.setRect(fw, fw, w-bw-fw, h-(fw*2));
2479 break;
2480 case SC_SpinBoxFrame:
2481 rect = ctlrect;
2482 break;
2483 default:
2484 break;
2486 rect = visualRect(box->direction, ctlrect, rect);
2487 break;
2490 case CC_ComboBox: {
2491 const QStyleOptionComboBox *combo;
2492 combo = qstyleoption_cast<const QStyleOptionComboBox*>(option);
2493 if (!combo) break;
2495 int bw = h; // position between edit and arrow
2496 switch (subcontrol) {
2497 case SC_ComboBoxFrame: // total combobox area
2498 rect = ctlrect;
2499 break;
2501 case SC_ComboBoxArrow: // the right side
2502 rect.setRect(w-bw, 0, bw, h);
2503 break;
2505 case SC_ComboBoxEditField: // the left side
2506 rect.setRect(fw, fw, w-bw-1, h-(fw*2));
2507 if (!combo->editable) {
2508 // give extra margin
2509 rect.adjust(pixelMetric(PM_ButtonMargin),
2510 0, 0, 0);
2512 break;
2514 case SC_ComboBoxListBoxPopup: // the list popup box
2515 rect = ctlrect;
2516 break;
2518 default:
2519 break;
2521 rect = visualRect(combo->direction, ctlrect, rect);
2522 break;
2525 case CC_ScrollBar: {
2526 // three button scrollbar
2527 const QStyleOptionSlider *sb;
2528 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
2529 if (!sb) break;
2531 bool horizontal = (sb->orientation == Qt::Horizontal);
2532 int extent = pixelMetric(PM_ScrollBarExtent, sb, widget);
2533 int slidermax = ((horizontal) ? ctlrect.width() : ctlrect.height())
2534 - (extent * 3);
2535 int slidermin = pixelMetric(PM_ScrollBarSliderMin, sb, widget);
2536 int sliderlen, sliderstart;
2538 // calculate slider length
2539 if (sb->maximum != sb->minimum) {
2540 int range = sb->maximum - sb->minimum;
2541 sliderlen = (sb->pageStep * slidermax) / (range + sb->pageStep);
2542 if ((sliderlen < slidermin) || (range > INT_MAX / 2))
2543 sliderlen = slidermin;
2544 if (sliderlen > slidermax)
2545 sliderlen = slidermax;
2546 } else {
2547 sliderlen = slidermax;
2550 sliderstart = extent + sliderPositionFromValue(sb->minimum,
2551 sb->maximum,
2552 sb->sliderPosition,
2553 slidermax - sliderlen,
2554 sb->upsideDown);
2556 switch (subcontrol) {
2557 case SC_ScrollBarAddLine:
2558 if (horizontal) {
2559 rect.setRect(x2 - extent + 1, y, extent, extent);
2560 } else {
2561 rect.setRect(x, y2 - extent + 1, extent, extent);
2563 break;
2565 case SC_ScrollBarSubLine:
2566 // rect that covers *both* subline buttons
2567 if (horizontal) {
2568 rect.setRect(x, y, w - extent + 1, extent);
2569 } else {
2570 rect.setRect(x, y, extent, h - extent + 1);
2572 break;
2574 case SC_ScrollBarAddPage:
2575 if (horizontal)
2576 rect.setRect(sliderstart + sliderlen, y,
2577 slidermax - sliderstart - sliderlen + extent + 1,
2578 extent);
2579 else
2580 rect.setRect(x, sliderstart + sliderlen, extent,
2581 slidermax - sliderstart - sliderlen + extent + 1);
2582 break;
2584 case SC_ScrollBarSubPage:
2585 if (horizontal) {
2586 rect.setRect(x + extent, y,
2587 sliderstart - (x + extent), extent);
2588 } else {
2589 rect.setRect(x, y + extent, extent,
2590 sliderstart - (x + extent));
2592 break;
2594 case SC_ScrollBarSlider:
2595 if (horizontal) {
2596 rect.setRect(sliderstart - 1, y, sliderlen + 2 + 1, extent);
2597 } else {
2598 rect.setRect(x, sliderstart - 1, extent, sliderlen + 2 + 1);
2600 break;
2602 case SC_ScrollBarGroove:
2603 if (horizontal) {
2604 rect = ctlrect.adjusted(extent, 0, -(extent*2), 0);
2605 } else {
2606 rect = ctlrect.adjusted(0, extent, 0, -(extent*2));
2608 break;
2610 default:
2611 break;
2613 rect = visualRect(sb->direction, ctlrect, rect);
2614 break;
2617 case CC_TitleBar: {
2618 const QStyleOptionTitleBar *title;
2619 title = qstyleoption_cast<const QStyleOptionTitleBar*>(option);
2620 if (!title) break;
2622 const int button = h - 2*fw;
2623 const int delta = button + fw;
2624 int offset = 0;
2626 bool minimized = title->titleBarState & Qt::WindowMinimized;
2627 bool maximized = title->titleBarState & Qt::WindowMaximized;
2629 switch (subcontrol) {
2630 case SC_TitleBarLabel:
2631 rect = ctlrect;
2632 if (title->titleBarFlags
2633 & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
2634 if (title->titleBarFlags & Qt::WindowSystemMenuHint)
2635 rect.adjust(delta, 0, -delta, 0);
2636 if (title->titleBarFlags & Qt::WindowMinimizeButtonHint)
2637 rect.adjust(0, 0, -delta, 0);
2638 if (title->titleBarFlags & Qt::WindowMaximizeButtonHint)
2639 rect.adjust(0, 0, -delta, 0);
2640 if (title->titleBarFlags & Qt::WindowContextHelpButtonHint)
2641 rect.adjust(0, 0, -delta, 0);
2642 rect.adjust(fw, fw, -fw, -fw);
2644 break;
2646 // right side buttons all fall through
2647 case SC_TitleBarContextHelpButton:
2648 if (title->titleBarFlags & Qt::WindowContextHelpButtonHint)
2649 offset += delta;
2651 case SC_TitleBarMinButton:
2652 if (!minimized &&
2653 (title->titleBarFlags & Qt::WindowMinimizeButtonHint))
2654 offset += delta;
2655 else if (subcontrol == SC_TitleBarMinButton)
2656 break;
2658 case SC_TitleBarNormalButton:
2659 if (minimized &&
2660 (title->titleBarFlags & Qt::WindowMinimizeButtonHint))
2661 offset += delta;
2662 else if (maximized &&
2663 (title->titleBarFlags & Qt::WindowMaximizeButtonHint))
2664 offset += delta;
2665 else if (subcontrol == SC_TitleBarNormalButton)
2666 break;
2668 case SC_TitleBarMaxButton:
2669 if (!maximized &&
2670 (title->titleBarFlags & Qt::WindowMaximizeButtonHint))
2671 offset += delta;
2672 else if (subcontrol == SC_TitleBarMaxButton)
2673 break;
2675 case SC_TitleBarCloseButton:
2676 if (title->titleBarFlags & Qt::WindowSystemMenuHint)
2677 offset += delta;
2678 else if (subcontrol == SC_TitleBarCloseButton)
2679 break;
2680 rect.setRect(x2 - offset + 1, y + fw, button, button);
2681 break;
2683 // left side buttons
2684 case SC_TitleBarSysMenu:
2685 if (title->titleBarFlags & Qt::WindowSystemMenuHint) {
2686 rect.setRect(x + fw, y + fw, button, button);
2688 break;
2690 default:
2691 break;
2694 rect = visualRect(title->direction, ctlrect, rect);
2695 break;
2698 default:
2699 rect = QWindowsStyle::subControlRect(control, option,
2700 subcontrol, widget);
2703 return rect;
2707 //////////////////////////////////////////////////////////////////////////////
2708 // hitTestComplexControl()
2709 // -----------------------
2710 // Return subcontrol of position
2712 QStyle::SubControl PhaseStyle::hitTestComplexControl(ComplexControl control,
2713 const QStyleOptionComplex *option,
2714 const QPoint &position,
2715 const QWidget *widget) const
2717 SubControl subcontrol = SC_None;
2718 QRect rect;
2720 switch (control) {
2721 case CC_ScrollBar: {
2722 const QStyleOptionSlider *sb;
2723 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
2724 if (!sb) break;
2726 // these cases are order dependent
2727 rect = subControlRect(control, sb, SC_ScrollBarSlider, widget);
2728 if (rect.contains(position)) {
2729 subcontrol = SC_ScrollBarSlider;
2730 break;
2733 rect = subControlRect(control, sb, SC_ScrollBarAddPage, widget);
2734 if (rect.contains(position)) {
2735 subcontrol = SC_ScrollBarAddPage;
2736 break;
2739 rect = subControlRect(control, sb, SC_ScrollBarSubPage, widget);
2740 if (rect.contains(position)) {
2741 subcontrol = SC_ScrollBarSubPage;
2742 break;
2745 rect = subControlRect(control, sb, SC_ScrollBarAddLine, widget);
2746 if (rect.contains(position)) {
2747 subcontrol = SC_ScrollBarAddLine;
2748 break;
2751 rect = subControlRect(control, sb, SC_ScrollBarSubLine, widget);
2752 if (rect.contains(position)) {
2753 subcontrol = SC_ScrollBarSubLine;
2754 break;
2757 break;
2760 default:
2761 subcontrol = QWindowsStyle::hitTestComplexControl(control, option,
2762 position, widget);
2763 break;
2766 return subcontrol;
2769 //////////////////////////////////////////////////////////////////////////////
2770 // Miscellaneous stuff //
2771 //////////////////////////////////////////////////////////////////////////////
2773 //////////////////////////////////////////////////////////////////////////////
2774 // styleHint()
2775 // -----------
2776 // "feel" hints for the GUI
2778 int PhaseStyle::styleHint(StyleHint hint,
2779 const QStyleOption *option,
2780 const QWidget *widget,
2781 QStyleHintReturn *data) const
2783 switch (hint) {
2784 case SH_Menu_SpaceActivatesItem:
2785 case SH_TitleBar_NoBorder:
2786 case SH_ToolTipLabel_Opacity:
2787 return 1;
2789 case SH_MainWindow_SpaceBelowMenuBar:
2790 return 0;
2792 case SH_UnderlineShortcut:
2793 if (QApplication::keyboardModifiers() & Qt::AltModifier) {
2794 return 1;
2796 return 0;
2798 // TODO: investigate other hints, including:
2799 // SH_ItemView_ShowDecorationSelected
2800 // SH_ScrollBar_MiddleClickAbsolutePosition
2801 // SH_ToolBox_SelectedPageTitleBold
2802 // SH_ScrollView_FrameOnlyAroundContents
2804 default:
2805 return QWindowsStyle::styleHint(hint, option, widget, data);
2809 //////////////////////////////////////////////////////////////////////////////
2810 // eventFilter()
2811 // -------------
2812 // Handle events for animating progress bars
2814 bool PhaseStyle::eventFilter(QObject *object, QEvent *event)
2816 if (!object->isWidgetType())
2817 return QObject::eventFilter(object, event);
2819 switch (event->type()) {
2820 case QEvent::KeyRelease:
2821 case QEvent::KeyPress:
2822 if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Alt) {
2823 // find top level window
2824 QWidget *widget = qobject_cast<QWidget*>(object);
2825 widget = widget->window();
2826 if (widget->parentWidget()) {
2827 widget = widget->parentWidget()->window();
2830 // update all visible enabled children widgets
2831 QList<QWidget*> wlist = qFindChildren<QWidget *>(widget);
2832 for (int n=0 ; n<wlist.size(); n++) {
2833 if (wlist[n]->isEnabled() && wlist[n]->isVisible()) {
2834 wlist[n]->update();
2838 break;
2840 case QEvent::StyleChange:
2841 case QEvent::Show:
2842 if (QProgressBar *bar = qobject_cast<QProgressBar*>(object)) {
2843 bars_ << bar;
2844 if (bars_.size() == 1) {
2845 timerid_ = startTimer(25);
2848 break;
2850 case QEvent::Destroy:
2851 bars_.removeAll(reinterpret_cast<QProgressBar*>(object));
2852 break;
2854 case QEvent::Hide:
2855 if (QProgressBar *bar = qobject_cast<QProgressBar*>(object)) {
2856 bars_.removeAll(bar);
2857 if (bars_.isEmpty() && timerid_) {
2858 killTimer(timerid_);
2859 timerid_ = 0;
2862 default:
2863 break;
2866 return QWindowsStyle::eventFilter(object, event);
2869 //////////////////////////////////////////////////////////////////////////////
2870 // timerEvent()
2871 // ------------
2872 // Internal timer fired
2874 void PhaseStyle::timerEvent(QTimerEvent *event)
2876 if (event->timerId() == timerid_) {
2877 foreach (QProgressBar *bar, bars_) {
2878 if ((bar->minimum() == 0 && bar->maximum() == 0)) {
2879 bar->setValue(bar->value()+1);
2880 bar->update();
2884 event->ignore();
2887 //////////////////////////////////////////////////////////////////////////////
2888 // Plugin stuff //
2889 //////////////////////////////////////////////////////////////////////////////
2891 class PhaseStylePlugin : public QStylePlugin
2893 public:
2894 PhaseStylePlugin() { ; }
2895 QStringList keys() const {
2896 return QStringList() << "Phase";
2898 QStyle *create(const QString &key) {
2899 if (key.toLower() == "phase") {
2900 return new PhaseStyle();
2902 return 0;
2906 Q_EXPORT_PLUGIN(PhaseStylePlugin)