SVN_SILENT made messages (.desktop file)
[kdeartwork.git] / styles / phase / phasestyle.cpp
blobe67550218c780aff3f1a9d05763be68d00f998e9
1 // -*- indent-tabs-mode: nil -*-
2 //////////////////////////////////////////////////////////////////////////////
3 // phasestyle.cpp
4 // -------------------
5 // Qt widget style
6 // -------------------
7 // Copyright (c) 2004-2008 David Johnson <david@usermode.org>
8 // Please see the header file for copyright and license information.
9 //////////////////////////////////////////////////////////////////////////////
11 // Some miscellaneous notes
13 // Menu and toolbars are painted with the background color by default. This
14 // differs from the Qt default of giving them PaletteButton backgrounds.
15 // Menubars have normal gradients, toolbars have reverse.
17 // Some toolbars are not part of a QMainWindows, such as in a KDE file dialog.
18 // In these cases we treat the toolbar as "floating" and paint it flat.
20 //////////////////////////////////////////////////////////////////////////////
22 #include "phasestyle.h"
24 #include <QApplication>
25 #include <QBitmap>
26 #include <QCheckBox>
27 #include <QComboBox>
28 #include <QDialogButtonBox>
29 #include <QDockWidget>
30 #include <QKeyEvent>
31 #include <QLinearGradient>
32 #include <QMenuBar>
33 #include <QPainter>
34 #include <QPixmapCache>
35 #include <QProgressBar>
36 #include <QStylePlugin>
37 #include <QPushButton>
38 #include <QRadioButton>
39 #include <QSettings>
40 #include <QSpinBox>
41 #include <QSplitterHandle>
42 #include <QToolBar>
44 #include <limits.h>
46 #include "bitmaps.h"
48 // some convenient constants
49 static const int ARROWMARGIN = 6;
50 static const int ITEMFRAME = 1;
51 static const int ITEMHMARGIN = 3;
52 static const int ITEMVMARGIN = 0;
53 static const int MAXGRADIENTSIZE = 128;
55 //////////////////////////////////////////////////////////////////////////////
56 // Construction, Destruction, Initialization //
57 //////////////////////////////////////////////////////////////////////////////
59 //////////////////////////////////////////////////////////////////////////////
60 // PhaseStyle()
61 // -----------
62 // Constructor
64 PhaseStyle::PhaseStyle()
65 : QWindowsStyle(), gradients_(QPixmap::defaultDepth() > 8), timerid_(0)
67 // get phasestyle config
68 QSettings settings("phasestyle");
69 if (gradients_) { // don't bother setting if already false
70 gradients_ = settings.value("/gradients", true).toBool();
72 highlights_ = settings.value("/highlights", true).toBool();
74 // get contrast from KDE configs
75 QSettings kdesettings("Trolltech");
76 contrast_ = 100 + kdesettings.value("/Qt/KDE/contrast", 5).toInt();
78 // create bitmaps
79 const QSize arrowsz(6, 6);
80 const QSize btnsz(10, 10);
81 bitmaps_.insert(UArrow, QBitmap::fromData(arrowsz, uarrow_bits));
82 bitmaps_.insert(DArrow, QBitmap::fromData(arrowsz, darrow_bits));
83 bitmaps_.insert(LArrow, QBitmap::fromData(arrowsz, larrow_bits));
84 bitmaps_.insert(RArrow, QBitmap::fromData(arrowsz, rarrow_bits));
85 bitmaps_.insert(PlusSign, QBitmap::fromData(arrowsz, plussign_bits));
86 bitmaps_.insert(MinusSign, QBitmap::fromData(arrowsz, minussign_bits));
87 bitmaps_.insert(CheckMark, QBitmap::fromData(btnsz, checkmark_bits));
88 bitmaps_.insert(TitleClose, QBitmap::fromData(btnsz, title_close_bits));
89 bitmaps_.insert(TitleMin, QBitmap::fromData(btnsz, title_min_bits));
90 bitmaps_.insert(TitleMax, QBitmap::fromData(btnsz, title_max_bits));
91 bitmaps_.insert(TitleNormal, QBitmap::fromData(btnsz, title_normal_bits));
92 bitmaps_.insert(TitleHelp, QBitmap::fromData(btnsz, title_help_bits));
95 PhaseStyle::~PhaseStyle() { ; }
97 //////////////////////////////////////////////////////////////////////////////
98 // Polishing //
99 //////////////////////////////////////////////////////////////////////////////
101 //////////////////////////////////////////////////////////////////////////////
102 // polish()
103 // --------
104 // Initialize application specific
106 void PhaseStyle::polish(QApplication* app)
108 QWindowsStyle::polish(app);
111 //////////////////////////////////////////////////////////////////////////////
112 // polish()
113 // --------
114 // Initialize the appearance of widget
116 void PhaseStyle::polish(QWidget *widget)
118 if (highlights_ &&
119 (qobject_cast<QPushButton*>(widget) ||
120 qobject_cast<QComboBox*>(widget) ||
121 qobject_cast<QAbstractSpinBox*>(widget) ||
122 qobject_cast<QCheckBox*>(widget) ||
123 qobject_cast<QRadioButton*>(widget) ||
124 qobject_cast<QSplitterHandle*>(widget) ||
125 qobject_cast<QSlider*>(widget) ||
126 qobject_cast<QTabBar*>(widget))) {
127 // mouseover highlighting
128 widget->setAttribute(Qt::WA_Hover);
130 if (widget->inherits("QDockSeparator")
131 || widget->inherits("QDockWidgetSeparator")) {
132 widget->setAttribute(Qt::WA_Hover);
134 if (qobject_cast<QProgressBar*>(widget)) {
135 // potentially animate progressbars
136 widget->installEventFilter(this);
140 //////////////////////////////////////////////////////////////////////////////
141 // polish()
142 // --------
143 // Initialize the palette
145 void PhaseStyle::polish(QPalette &pal)
147 // clear out gradients on a color change
148 QPixmapCache::clear();
150 // adjust bevel colors to have better contrast (KDE like)
151 QColor background;
153 int highlightval = 100 + (2*(contrast_-100)+4)*16/10;
154 int lowlightval = 100 + (2*(contrast_-100)+4)*10;
156 background = pal.color(QPalette::Active, QPalette::Window);
157 pal.setColor(QPalette::Active, QPalette::Light,
158 background.lighter(highlightval));
159 pal.setColor(QPalette::Active, QPalette::Dark,
160 background.darker(lowlightval));
161 pal.setColor(QPalette::Active, QPalette::Mid,
162 background.darker(120));
163 pal.setColor(QPalette::Active, QPalette::Midlight,
164 background.lighter(110));
166 background = pal.color(QPalette::Inactive, QPalette::Window);
167 pal.setColor(QPalette::Inactive, QPalette::Light,
168 background.lighter(highlightval));
169 pal.setColor(QPalette::Inactive, QPalette::Dark,
170 background.darker(lowlightval));
171 pal.setColor(QPalette::Inactive, QPalette::Mid,
172 background.darker(120));
173 pal.setColor(QPalette::Inactive, QPalette::Midlight,
174 background.lighter(110));
176 background = pal.color(QPalette::Disabled, QPalette::Window);
177 pal.setColor(QPalette::Disabled, QPalette::Light,
178 background.lighter(highlightval));
179 pal.setColor(QPalette::Disabled, QPalette::Dark,
180 background.darker(lowlightval));
181 pal.setColor(QPalette::Disabled, QPalette::Mid,
182 background.darker(120));
183 pal.setColor(QPalette::Disabled, QPalette::Midlight,
184 background.lighter(110));
187 //////////////////////////////////////////////////////////////////////////////
188 // unPolish()
189 // ----------
190 // Undo the application polish
192 void PhaseStyle::unpolish(QApplication *app)
194 QWindowsStyle::unpolish(app);
197 //////////////////////////////////////////////////////////////////////////////
198 // unPolish()
199 // ----------
200 // Undo the initialization of a widget appearance
202 void PhaseStyle::unpolish(QWidget *widget)
204 if (highlights_ &&
205 (qobject_cast<QPushButton*>(widget) ||
206 qobject_cast<QComboBox*>(widget) ||
207 qobject_cast<QAbstractSpinBox*>(widget) ||
208 qobject_cast<QCheckBox*>(widget) ||
209 qobject_cast<QRadioButton*>(widget) ||
210 qobject_cast<QSplitterHandle*>(widget) ||
211 qobject_cast<QSlider*>(widget) ||
212 qobject_cast<QTabBar*>(widget))) {
213 // turn off mouseover highlighting
214 widget->setAttribute(Qt::WA_Hover, false);
216 if (widget->inherits("QDockSeparator")
217 || widget->inherits("QDockWidgetSeparator")) {
218 widget->setAttribute(Qt::WA_Hover, false);
220 if (qobject_cast<QProgressBar*>(widget)) {
221 widget->removeEventFilter(this);
225 //////////////////////////////////////////////////////////////////////////////
226 // standardPalette()
227 // -----------------
228 // Return a standard palette
230 QPalette PhaseStyle::standardPalette() const
232 QColor window(0xee, 0xee, 0xee);
233 QColor button(0xdd, 0xdd, 0xe3);
234 QColor highlight(0x60, 0x90, 0xc0);
235 QPalette pal(window, window);
237 pal.setBrush(QPalette::Button, button);
238 pal.setBrush(QPalette::Highlight, highlight);
240 pal.setBrush(QPalette::Disabled, QPalette::Button, window);
241 pal.setBrush(QPalette::Disabled, QPalette::Foreground, window.darker());
242 pal.setBrush(QPalette::Disabled, QPalette::Text, window.darker());
243 pal.setBrush(QPalette::Disabled, QPalette::ButtonText, window.darker());
245 return pal;
248 //////////////////////////////////////////////////////////////////////////////
249 // Drawing //
250 //////////////////////////////////////////////////////////////////////////////
252 //////////////////////////////////////////////////////////////////////////////
253 // drawPhaseGradient()
254 // ------------------
255 // Draw a gradient
257 void PhaseStyle::drawPhaseGradient(QPainter *painter,
258 const QRect &rect,
259 QColor color,
260 bool horizontal,
261 const QSize &gsize,
262 bool reverse) const
264 if (!gradients_) {
265 painter->fillRect(rect, color);
266 return;
269 int size = (horizontal) ? gsize.width() : gsize.height();
271 if (size > MAXGRADIENTSIZE) { // keep it sensible
272 painter->fillRect(rect, color);
273 return;
276 GradientType type;
277 QString name;
278 QPixmap pixmap;
280 if (horizontal) type = (reverse) ? HorizontalReverse : Horizontal;
281 else type = (reverse) ? VerticalReverse : Vertical;
283 name = QString("%1.%2.%3").arg(color.name()).arg(size).arg(type);
284 if (!QPixmapCache::find(name, pixmap)) {
285 QPainter cachepainter;
287 switch (type) {
288 case Horizontal: {
289 pixmap = QPixmap(size, 16);
290 QLinearGradient gradient(0, 0, size, 0);
291 gradient.setColorAt(0, color.lighter(contrast_));
292 gradient.setColorAt(1, color.darker(contrast_));
293 cachepainter.begin(&pixmap);
294 cachepainter.fillRect(pixmap.rect(), gradient);
295 cachepainter.end();
296 break;
298 case HorizontalReverse: {
299 pixmap = QPixmap(size, 16);
300 QLinearGradient gradient(0, 0, size, 0);
301 gradient.setColorAt(0, color.darker(contrast_));
302 gradient.setColorAt(1, color.lighter(contrast_));
303 cachepainter.begin(&pixmap);
304 cachepainter.fillRect(pixmap.rect(), gradient);
305 cachepainter.end();
306 break;
308 case Vertical: {
309 pixmap = QPixmap(16, size);
310 QLinearGradient gradient(0, 0, 0, size);
311 gradient.setColorAt(0, color.lighter(contrast_));
312 gradient.setColorAt(1, color.darker(contrast_));
313 cachepainter.begin(&pixmap);
314 cachepainter.fillRect(pixmap.rect(), gradient);
315 cachepainter.end();
316 break;
318 case VerticalReverse: {
319 pixmap = QPixmap(16, size);
320 QLinearGradient gradient(0, 0, 0, size);
321 gradient.setColorAt(0, color.darker(contrast_));
322 gradient.setColorAt(1, color.lighter(contrast_));
323 cachepainter.begin(&pixmap);
324 cachepainter.fillRect(pixmap.rect(), gradient);
325 cachepainter.end();
326 break;
328 default:
329 break;
331 QPixmapCache::insert(name, pixmap);
334 painter->drawTiledPixmap(rect, pixmap);
337 //////////////////////////////////////////////////////////////////////////////
338 // drawPhaseBevel()
339 // ----------------
340 // Draw the basic Phase bevel
342 void PhaseStyle::drawPhaseBevel(QPainter *painter,
343 QRect rect,
344 const QPalette &pal,
345 const QBrush &fill,
346 bool sunken,
347 bool horizontal,
348 bool reverse) const
350 int x, y, w, h;
351 rect.getRect(&x, &y, &w, &h);
352 int x2 = rect.right();
353 int y2 = rect.bottom();
355 QPen pen = painter->pen();
357 painter->setPen(pal.dark().color());
358 painter->drawRect(rect.adjusted(0, 0, -1, -1));
360 painter->setPen(sunken ? pal.mid().color() : pal.midlight().color());
361 painter->drawLine(x+1, y+1, x2-2, y+1);
362 painter->drawLine(x+1, y+2, x+1, y2-2);
364 painter->setPen(sunken ? pal.midlight().color() : pal.mid().color());
365 painter->drawLine(x+2, y2-1, x2-1, y2-1);
366 painter->drawLine(x2-1, y+2, x2-1, y2-2);
368 painter->setPen(pal.button().color());
369 painter->drawPoint(x+1, y2-1);
370 painter->drawPoint(x2-1, y+1);
372 if (sunken) {
373 // sunken bevels don't get gradients
374 painter->fillRect(rect.adjusted(2, 2, -2, -2), fill);
375 } else {
376 drawPhaseGradient(painter, rect.adjusted(2, 2, -2, -2), fill.color(),
377 horizontal, QSize(w-4, h-4), reverse);
379 painter->setPen(pen);
382 //////////////////////////////////////////////////////////////////////////////
383 // drawPhaseButton()
384 // ----------------
385 // Draw the basic Phase button
387 void PhaseStyle::drawPhaseButton(QPainter *painter,
388 QRect rect,
389 const QPalette &pal,
390 const QBrush &fill,
391 bool sunken) const
393 int x, y, w, h;
394 rect.getRect(&x, &y, &w, &h);
395 int x2 = rect.right();
396 int y2 = rect.bottom();
398 QPen pen = painter->pen();
400 painter->setPen(pal.midlight().color());
401 painter->drawLine(x+1, y2, x2, y2);
402 painter->drawLine(x2, y+1, x2, y2-1);
404 painter->setPen(pal.mid().color());
405 painter->drawLine(x, y, x2-1, y);
406 painter->drawLine(x, y+1, x, y2-1);
408 painter->setPen(pal.window().color());
409 painter->drawPoint(x, y2);
410 painter->drawPoint(x2, y);
412 painter->setPen(pen);
413 drawPhaseBevel(painter, rect.adjusted(1, 1, -1, -1), pal, fill,
414 sunken, false, false);
417 //////////////////////////////////////////////////////////////////////////////
418 // drawPhasePanel()
419 // ----------------
420 // Draw the basic Phase panel
422 void PhaseStyle::drawPhasePanel(QPainter *painter,
423 const QRect &rect,
424 const QPalette &pal,
425 const QBrush &fill,
426 bool sunken) const
428 int x, y, w, h;
429 rect.getRect(&x, &y, &w, &h);
430 int x2 = rect.right();
431 int y2 = rect.bottom();
433 QPen pen = painter->pen();
435 if (sunken) {
436 painter->setPen(pal.dark().color());
437 painter->drawRect(rect.adjusted(1, 1, -2, -2));
438 painter->setPen(pal.midlight().color());
439 painter->drawLine(x+1, y2, x2, y2);
440 painter->drawLine(x2, y+1, x2, y2-1);
441 painter->setPen(pal.mid().color());
442 painter->drawLine(x, y, x, y2-1);
443 painter->drawLine(x+1, y, x2-1, y);
444 painter->setPen(pal.window().color());
445 painter->drawPoint(x, y2);
446 painter->drawPoint(x2, y);
447 } else {
448 painter->setPen(pal.dark().color());
449 painter->drawRect(rect.adjusted(0, 0, -1, -1));
450 painter->setPen(pal.midlight().color());
451 painter->drawLine(x+1, y+1, x2-2, y+1);
452 painter->drawLine(x+1, y+2, x+1, y2-2);
453 painter->setPen(pal.mid().color());
454 painter->drawLine(x+2, y2-1, x2-1, y2-1);
455 painter->drawLine(x2-1, y+2, x2-1, y2-2);
456 painter->setPen(pal.window().color());
457 painter->drawPoint(x+1, y2-1);
458 painter->drawPoint(x2-1, y+1);
461 painter->fillRect(rect.adjusted(2, 2, -2, -2), fill);
462 painter->setPen(pen);
465 //////////////////////////////////////////////////////////////////////////////
466 // drawPhaseDoodads()
467 // ------------------
468 // Draw three doodads in rect
470 void PhaseStyle::drawPhaseDoodads(QPainter *painter,
471 const QRect& rect,
472 const QPalette &pal,
473 bool horizontal) const
475 int cx = rect.center().x();
476 int cy = rect.center().y();
478 QPen pen = painter->pen();
479 if (horizontal && (rect.width() >= 20)) {
480 for (int n = -5; n <= 5; n += 5) {
481 painter->setPen(pal.mid().color());
482 painter->drawLine(cx-1+n, cy+1, cx-1+n, cy-1);
483 painter->drawLine(cx+n, cy-1, cx+1+n, cy-1);
484 painter->setPen(pal.light().color());
485 painter->drawLine(cx+2+n, cy, cx+2+n, cy+2);
486 painter->drawLine(cx+1+n, cy+2, cx+n, cy+2);
488 } else if (!horizontal && (rect.height() >= 20)) {
489 for (int n = -5; n <= 5; n += 5) {
490 painter->setPen(pal.mid().color());
491 painter->drawLine(cx-1, cy+1+n, cx-1, cy-1+n);
492 painter->drawLine(cx, cy-1+n, cx+1, cy-1+n);
493 painter->setPen(pal.light().color());
494 painter->drawLine(cx+2, cy+n, cx+2, cy+2+n);
495 painter->drawLine(cx+1, cy+2+n, cx, cy+2+n);
498 painter->setPen(pen);
501 ///////////////////////////////////////////////////////////////////////////////
502 // drawPhaseTab()
503 // -------------
504 // Draw a Phase style tab
506 void PhaseStyle::drawPhaseTab(QPainter *painter,
507 const QPalette &pal,
508 const QStyleOptionTab *tab) const
510 const State &flags = tab->state;
511 const QStyleOptionTab::TabPosition &tabpos = tab->position;
512 const QStyleOptionTab::SelectedPosition &selpos = tab->selectedPosition;
514 bool selected = (flags & State_Selected);
515 bool mouseover = (flags & State_MouseOver) && !selected;
516 bool vertical = (tab->shape == QTabBar::RoundedEast) ||
517 (tab->shape == QTabBar::RoundedWest);
518 bool reverse = (tab->direction == Qt::RightToLeft);
519 bool corner = (tab->cornerWidgets & QStyleOptionTab::LeftCornerWidget);
520 bool first = (tabpos == QStyleOptionTab::Beginning);
521 bool rlast = (tabpos == QStyleOptionTab::End) && reverse;
522 bool only = (tabpos == QStyleOptionTab::OnlyOneTab);
523 bool edge = (first && !corner) || only;
524 bool leftedge = vertical ? edge : (edge && !reverse);
525 bool rightedge = vertical ? edge : (edge && reverse);
526 bool prevselected = (selpos == QStyleOptionTab::PreviousIsSelected);
527 bool nextselected = (selpos == QStyleOptionTab::NextIsSelected);
528 if (reverse && !vertical) {
529 qSwap(prevselected, nextselected);
532 // get rectangle
533 QRect rect = tab->rect;
534 if (!selected) {
535 switch (tab->shape) {
536 case QTabBar::RoundedNorth:
537 default:
538 rect.adjust(0, 2, 0, 0);
539 break;
541 case QTabBar::RoundedSouth:
542 rect.adjust(0, 0, 0, -2);
543 break;
545 case QTabBar::RoundedWest:
546 rect.adjust(2, 0, 0, 0);
547 break;
549 case QTabBar::RoundedEast:
550 rect.adjust(0, 0, -2, 0);
551 break;
555 int x, y, w, h;
556 rect.getRect(&x, &y, &w, &h);
557 const int x2 = rect.right();
558 const int y2 = rect.bottom();
560 painter->save();
562 // draw tab
563 switch (tab->shape) {
564 case QTabBar::RoundedNorth:
565 default:
566 // draw fill
567 if (selected) {
568 painter->fillRect(rect.adjusted(0, 1, 0, 0), pal.window());
569 } else {
570 drawPhaseGradient(painter, rect.adjusted(0, 1, 0, -2),
571 mouseover ?
572 pal.window().color() :
573 pal.window().color().darker(contrast_),
574 false, QSize(w, h), false);
577 // top frame
578 painter->setPen(pal.dark().color());
579 painter->drawLine(x, y, x2, y);
581 painter->setPen(pal.midlight().color());
582 if (nextselected) painter->drawLine(x+1, y+1, x2, y+1);
583 else if (prevselected) painter->drawLine(x, y+1, x2-2, y+1);
584 else painter->drawLine(x+1, y+1, x2-2, y+1);
586 // left frame
587 painter->setPen(pal.dark().color());
588 if (leftedge && selected) painter->drawLine(x, y, x, y2);
589 if (leftedge && !selected) painter->drawLine(x, y, x, y2-2);
590 if (!leftedge && selected) painter->drawLine(x, y, x, y2-1);
591 if (!selected && rlast) painter->drawLine(x, y, x, y2-2);
592 painter->setPen(pal.midlight().color());
593 if (selected) painter->drawLine(x+1, y+1, x+1, y2);
594 else if (leftedge) painter->drawLine(x+1, y+1, x+1, y2-2);
595 else if (rlast) painter->drawLine(x+1, y+1, x+1, y2-2);
596 else if (!prevselected) painter->drawLine(x, y+1, x, y2-2);
597 if (selected && !leftedge) painter->drawPoint(x, y2);
599 // right frame
600 if (!nextselected) {
601 painter->setPen(pal.dark().color());
602 if (rightedge && selected) painter->drawLine(x2, y+1, x2, y2);
603 if (rightedge) painter->drawLine(x2, y+1, x2, y2+1);
604 else painter->drawLine(x2, y+1, x2, y2-1);
605 painter->setPen(pal.mid().color());
606 if (rightedge && selected) painter->drawLine(x2-1, y+2, x2-1, y2);
607 else if (selected) painter->drawLine(x2-1, y+2, x2-1, y2-1);
608 else painter->drawLine(x2-1, y+2, x2-1, y2-2);
610 if (selected && !rightedge) {
611 painter->setPen(pal.midlight().color());
612 painter->drawPoint(x2, y2);
616 break;
618 case QTabBar::RoundedSouth:
619 // draw fill
620 if (selected) {
621 painter->fillRect(rect.adjusted(0, 0, 0, -1), pal.window());
622 } else {
623 drawPhaseGradient(painter, rect.adjusted(0, 2, 0, -1),
624 mouseover ?
625 pal.window().color() :
626 pal.window().color().darker(contrast_),
627 false, QSize(w, h), false);
630 // bottom frame
631 painter->setPen(pal.dark().color());
632 painter->drawLine(x, y2, x2, y2);
634 painter->setPen(pal.mid().color());
635 if (nextselected) painter->drawLine(x, y2-1, x2, y2-1);
636 else painter->drawLine(x, y2-1, x2-1, y2-1);
638 painter->setPen(pal.window().color());
639 if (selected || first) painter->drawPoint(x+1, y2-1);
640 else if (!prevselected) painter->drawPoint(x, y2-1);
642 // left frame
643 painter->setPen(pal.dark().color());
644 if (selected && leftedge) painter->drawLine(x, y, x, y2);
645 else if (selected || leftedge || rlast) painter->drawLine(x, y+1, x, y2);
647 painter->setPen(pal.midlight().color());
648 if (!prevselected) {
649 if (leftedge && selected) painter->drawLine(x+1, y, x+1, y2-2);
650 else if (leftedge && !selected) painter->drawLine(x+1, y+2, x+1, y2-2);
651 else if (selected) painter->drawLine(x+1, y+1, x+1, y2-2);
652 else if (rlast) painter->drawLine(x+1, y+2, x+1, y2-2);
653 else painter->drawLine(x, y+2, x, y2-2);
656 if (selected && !leftedge) {
657 painter->setPen(pal.mid().color());
658 painter->drawPoint(x, y);
661 // right frame
662 if (!nextselected) {
663 painter->setPen(pal.dark().color());
664 if (rightedge && selected) painter->drawLine(x2, y, x2, y2-1);
665 else painter->drawLine(x2, y+1, x2, y2-1);
667 painter->setPen(pal.mid().color());
668 if (selected) {
669 painter->drawLine(x2-1, y, x2-1, y2-2);
670 if (!rightedge) painter->drawPoint(x2, y);
671 } else {
672 painter->drawLine(x2-1, y+2, x2-1, y2-2);
675 break;
677 case QTabBar::RoundedWest:
678 // draw fill
679 if (selected) {
680 painter->fillRect(rect.adjusted(1, 0, 0, 0), pal.window());
681 } else {
682 drawPhaseGradient(painter, rect.adjusted(1, 0, -2, 0),
683 mouseover ?
684 pal.window().color() :
685 pal.window().color().darker(contrast_),
686 true, QSize(w, h), false);
689 // left frame
690 painter->setPen(pal.dark().color());
691 painter->drawLine(x, y, x, y2);
693 painter->setPen(pal.midlight().color());
694 if (nextselected) painter->drawLine(x+1, y+1, x+1, y2);
695 else if (prevselected) painter->drawLine(x+1, y, x+1, y2-2);
696 else painter->drawLine(x+1, y+1, x+1, y2-2);
698 // top frame
699 painter->setPen(pal.dark().color());
700 if (leftedge || selected) painter->drawLine(x, y, x2-1, y);
701 if (leftedge && selected) painter->drawPoint(x2, y);
703 painter->setPen(pal.midlight().color());
704 if (leftedge && selected) painter->drawLine(x+1, y+1, x2, y+1);
705 else if (leftedge && !selected) painter->drawLine(x+1, y+1, x2-2, y+1);
706 else if (selected) painter->drawLine(x+1, y+1, x2, y+1);
707 else if (!prevselected) painter->drawLine(x+1, y, x2-2, y);
708 if (!leftedge && selected) painter->drawPoint(x2, y);
710 // bottom frame
711 if (!nextselected) {
712 painter->setPen(pal.dark().color());
713 if (rightedge && selected) painter->drawLine(x, y2, x2, y2);
714 else if (selected) painter->drawLine(x, y2, x2-1, y2);
715 else painter->drawLine(x, y2, x2-2, y2);
717 painter->setPen(pal.mid().color());
718 if (selected) painter->drawLine(x+2, y2-1, x2-1, y2-1);
719 else painter->drawLine(x+2, y2-1, x2-2, y2-1);
721 if (selected) {
722 painter->setPen(pal.midlight().color());
723 if (!rightedge) painter->drawPoint(x2, y2);
726 break;
728 case QTabBar::RoundedEast:
729 // draw fill
730 if (selected) {
731 painter->fillRect(rect.adjusted(0, 0, -1, 0), pal.window());
732 } else {
733 drawPhaseGradient(painter, rect.adjusted(2, 0, -1, 0),
734 mouseover ?
735 pal.window().color() :
736 pal.window().color().darker(contrast_),
737 true, QSize(w, h), false);
740 // right frame
741 painter->setPen(pal.dark().color());
742 painter->drawLine(x2, y, x2, y2);
744 painter->setPen(pal.mid().color());
745 if (selected) painter->drawLine(x2-1, y+2, x2-1, y2-1);
746 else if (leftedge) painter->drawLine(x2-1, y+2, x2-1, y2);
747 else if (nextselected) painter->drawLine(x2-1, y+1, x2-1, y2);
748 else if (prevselected) painter->drawLine(x2-1, y, x2-1, y2-1);
749 else painter->drawLine(x2-1, y+1, x2-1, y2-1);
751 // top frame
752 painter->setPen(pal.dark().color());
753 if (leftedge || selected) painter->drawLine(x+1, y, x2, y);
754 if (leftedge && selected) painter->drawPoint(x, y);
756 painter->setPen(pal.midlight().color());
757 if (leftedge && selected) painter->drawLine(x, y+1, x2-2, y+1);
758 else if (leftedge && !selected) painter->drawLine(x+2, y+1, x2-2, y+1);
759 else if (selected) painter->drawLine(x+1, y+1, x2-2, y+1);
760 else if (!prevselected) painter->drawLine(x+2, y, x2-2, y);
761 if (!leftedge && selected) painter->drawPoint(x+1, y+1);
763 if (!leftedge && selected) {
764 painter->setPen(pal.mid().color());
765 painter->drawPoint(x, y);
768 // bottom frame
769 if (!nextselected) {
770 painter->setPen(pal.dark().color());
771 if (rightedge && selected) painter->drawLine(x, y2, x2, y2);
772 else if (selected) painter->drawLine(x+1, y2, x2, y2);
773 else painter->drawLine(x+1, y2, x2, y2);
775 painter->setPen(pal.mid().color());
776 if (selected) {
777 painter->drawLine(x, y2-1, x2-2, y2-1);
778 if (!rightedge) painter->drawPoint(x, y2);
779 } else {
780 painter->drawLine(x+2, y2-1, x2-2, y2-1);
783 break;
786 painter->restore();
789 //////////////////////////////////////////////////////////////////////////////
790 // drawPrimitive()
791 // ---------------
792 // Draw a primitive element
794 void PhaseStyle::drawPrimitive(PrimitiveElement element,
795 const QStyleOption *option,
796 QPainter *painter,
797 const QWidget *widget) const
799 // shorthand
800 const State &flags = option->state;
801 const QPalette &pal = option->palette;
802 const QRect &rect = option->rect;
804 // common states
805 bool sunken = flags & State_Sunken;
806 bool on = flags & State_On;
807 bool depress = (sunken || on);
808 bool enabled = flags & State_Enabled;
809 bool horiz = flags & State_Horizontal;
810 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
812 int x, y, w, h;
813 rect.getRect(&x, &y, &w, &h);
814 int x2 = rect.right();
815 int y2 = rect.bottom();
816 int cx = rect.center().x();
817 int cy = rect.center().y();
819 QPolygon polygon;
821 painter->save();
823 switch (element) {
824 case PE_PanelButtonCommand: // command button (QPushbutton)
825 drawPhaseButton(painter, rect, pal, mouseover ?
826 pal.button().color().lighter(contrast_) :
827 pal.button(), depress);
828 break;
830 case PE_FrameButtonBevel: // panel frame for a button bevel
831 case PE_FrameButtonTool: // panel frame for a tool button
832 drawPhaseBevel(painter, rect, pal, Qt::NoBrush,
833 depress, false, false);
834 break;
836 case PE_PanelButtonBevel: // generic panel with a button bevel
837 case PE_IndicatorButtonDropDown: // indicator for a drop down button
838 drawPhaseBevel(painter, rect, pal, mouseover ?
839 pal.button().color().lighter(contrast_) :
840 pal.button(),
841 depress, false, false);
842 break;
844 case PE_PanelButtonTool: // panel for a tool button
845 if (widget && widget->inherits("QDockWidgetTitleButton")) {
846 bool floating = (widget->parentWidget() && widget->parentWidget()->isWindow());
848 if (mouseover || floating) {
849 drawPhasePanel(painter, rect, pal,
850 pal.window().color(), depress);
852 break;
855 drawPhaseBevel(painter, rect, pal, mouseover ?
856 pal.button().color().lighter(contrast_) :
857 pal.button(),
858 depress, false, true);
859 break;
861 case PE_FrameDefaultButton: // the frame around a default button
862 drawPhasePanel(painter, rect, pal, pal.mid(), true);
863 break;
865 case PE_Frame: // generic styled frame
866 case PE_FrameLineEdit: // frame around line edit
867 case PE_FrameMenu: // frame for popup windows/menus
868 case PE_FrameDockWidget: // frame for dock windows and toolbars
869 case PE_FrameTabWidget: // frame around tab widgets
870 drawPhasePanel(painter, rect, pal, Qt::NoBrush, sunken);
871 break;
873 case PE_FrameTabBarBase: // frame for base of a tab bar
874 // don't draw anything
875 break;
877 case PE_FrameWindow: // frame for MDI or docking window
878 drawPhasePanel(painter, rect, pal, Qt::NoBrush, sunken);
879 // needs a black border
880 painter->setPen(pal.shadow().color());
881 painter->drawRect(rect.adjusted(0, 0, -1, -1));
882 break;
884 case PE_FrameGroupBox: // frame around a group box
885 painter->setPen(pal.dark().color());
886 painter->drawRect(rect.adjusted(0, 0, -1, -1));
887 break;
889 case PE_FrameFocusRect: { // generic focus indicator
890 QColor focus(pal.highlight().color());
891 focus.setAlphaF(0.66);
892 painter->setPen(focus);
893 painter->drawRect(rect.adjusted(0, 0, -1, -1));
894 break;
897 case PE_IndicatorCheckBox: // on/off indicator for check box
898 drawPhasePanel(painter, rect.adjusted(1, 1, -1, -1),
899 pal, enabled ? pal.base() : pal.window(), true);
901 if (mouseover) {
902 painter->setPen(pal.highlight().color().darker(contrast_));
903 } else if (on || (flags & State_NoChange)) {
904 painter->setPen(pal.dark().color());
905 } else {
906 painter->setPen(Qt::NoPen);
908 if (on) {
909 painter->setBrush(pal.highlight());
910 } else if (flags & State_NoChange) {
911 painter->setBrush(pal.mid());
914 painter->drawRect(rect.adjusted(4, 4, -5, -5));
915 break;
917 case PE_IndicatorRadioButton: // on/off indicator for radio button
918 painter->setBrush(enabled ? pal.base() : pal.window());
920 painter->setPen(pal.dark().color());
921 polygon.setPoints(8, x+1,cy+1, x+1,cy, cx,y+1, cx+1,y+1,
922 x2-1,cy, x2-1,cy+1, cx+1,y2-1, cx,y2-1);
923 painter->drawConvexPolygon(polygon);
925 painter->setPen(pal.mid().color());
926 polygon.setPoints(4, x,cy, cx,y, cx+1,y, x2,cy);
927 painter->drawPolyline(polygon);
928 painter->setPen(pal.midlight().color());
929 polygon.setPoints(4, x2,cy+1, cx+1,y2, cx,y2, x,cy+1);
930 painter->drawPolyline(polygon);
932 if (on) {
933 painter->setBrush(pal.highlight());
934 painter->setPen(mouseover
935 ? pal.highlight().color().darker(contrast_)
936 : pal.dark().color());
937 polygon.setPoints(8, x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
938 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4);
939 painter->drawConvexPolygon(polygon);
940 } else if (mouseover) {
941 painter->setPen(pal.highlight().color().darker(contrast_));
942 polygon.setPoints(9, x+4,cy+1, x+4,cy, cx,y+4, cx+1,y+4,
943 x2-4,cy, x2-4,cy+1, cx+1,y2-4, cx,y2-4,
944 x+4,cy+1);
945 painter->drawPolyline(polygon);
947 break;
949 case PE_IndicatorHeaderArrow: { // sort arrow on view header
950 const QStyleOptionHeader *header;
951 header = qstyleoption_cast<const QStyleOptionHeader *>(option);
952 if (header) {
953 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
954 drawPrimitive(PE_IndicatorArrowUp, option, painter, widget);
955 } else {
956 drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
959 break;
962 case PE_PanelMenuBar: // panel for menu bars
963 case PE_PanelToolBar: // panel for a toolbar
964 // adjust rect so we can use bevel
965 drawPhaseBevel(painter, rect.adjusted(-1, -1, 0, 0),
966 pal, pal.window(), false, (w < h),
967 (element==PE_PanelToolBar) ? true : false);
968 break;
970 case PE_FrameStatusBar: // frame for a section of a status bar
971 painter->setPen(pal.mid().color());
972 painter->drawLine(x, y, x2-1, y);
973 painter->drawLine(x, y+1, x, y2-1);
974 painter->setPen(pal.midlight().color());
975 painter->drawLine(x+1, y2, x2, y2);
976 painter->drawLine(x2, y+1, x2, y2-1);
977 break;
979 case PE_IndicatorDockWidgetResizeHandle: // resize handle for docks
980 painter->fillRect(rect,
981 (mouseover) ?
982 pal.window().color().lighter(contrast_) :
983 pal.window());
984 drawPhaseDoodads(painter, rect, pal, horiz);
985 break;
988 case PE_IndicatorMenuCheckMark: // check mark used in a menu
989 if (on) {
990 painter->setBrush(pal.highlightedText());
991 } else {
992 painter->setBrush(sunken ? pal.dark() : pal.text());
994 painter->setPen(painter->brush().color());
995 painter->drawPixmap(cx-4, cy-4, bitmaps_[CheckMark]);
996 break;
998 case PE_IndicatorViewItemCheck: // on/off indicator for a view item
999 case PE_Q3CheckListIndicator: { // Q3 checkbox of a list view item
1000 painter->setPen(pal.text().color());
1001 // draw box
1002 QRect box(0, 0, 13, 13);
1003 box.moveCenter(rect.center());
1004 painter->drawRect(box);
1005 painter->drawRect(box.adjusted(1,1,-1,-1));
1006 // draw check
1007 if (flags & State_On) {
1008 painter->setBrush(pal.text());
1009 painter->setPen(painter->brush().color());
1010 painter->drawPixmap(cx-4, cy-4, bitmaps_[CheckMark]);
1012 break;
1015 case PE_IndicatorBranch: { // branch lines of a tree view
1016 if (pal.color(QPalette::Active, QPalette::Base).value() < 192) {
1017 painter->setPen(pal.text().color());
1018 painter->setBrush(pal.text());
1019 } else {
1020 painter->setPen(pal.mid().color());
1021 painter->setBrush(pal.mid());
1024 int spacer = 0;
1025 // draw expander
1026 if (flags & State_Children) {
1027 QPolygon poly;
1028 if (flags & State_Open) {
1029 poly.setPoints(3, -4,-2, 4,-2, 0,2);
1030 } else {
1031 poly.setPoints(3, -2,-4, 2,0, -2,4);
1033 poly.translate(cx, cy);
1034 painter->drawPolygon(poly);
1036 spacer = 6;
1039 // draw lines
1040 if (flags & State_Item) {
1041 if (option->direction == Qt::RightToLeft)
1042 painter->drawLine(x, cy, cx-spacer, cy);
1043 else
1044 painter->drawLine(cx+spacer, cy, x2, cy);
1046 if (flags & State_Sibling) {
1047 painter->drawLine(cx, cy+spacer, cx, y2);
1049 if (flags & (State_Item|State_Sibling)) {
1050 painter->drawLine(cx, cy-spacer, cx, y);
1052 break;
1055 case PE_IndicatorToolBarHandle: // toolbar handle
1056 drawPhaseGradient(painter, rect, pal.window().color(),
1057 !horiz, rect.size(), true);
1058 drawPhaseDoodads(painter, rect, pal, !horiz);
1059 break;
1061 case PE_Q3DockWindowSeparator: // Q3 dock/toolbar separator
1062 case PE_IndicatorToolBarSeparator: // toolbar separator
1063 // TODO: lines don't go to edge of bar, need to fix
1064 if (horiz) {
1065 painter->setPen(pal.mid().color());
1066 painter->drawLine(cx, 0, cx, y2);
1067 painter->setPen(pal.midlight().color());
1068 painter->drawLine(cx+1, 0, cx+1, y2);
1069 } else {
1070 painter->setPen(pal.mid().color());
1071 painter->drawLine(0, cy, x2, cy);
1072 painter->setPen(pal.midlight().color());
1073 painter->drawLine(0, cy+1, x2, cy+1);
1075 break;
1077 case PE_IndicatorArrowUp: // generic up arrow
1078 case PE_IndicatorSpinUp: // spin up arrow
1079 painter->setBrush(enabled ? pal.dark() : pal.mid());
1080 painter->setPen(painter->brush().color());
1081 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1082 pixelMetric(PM_ButtonShiftVertical));
1083 painter->drawPixmap(cx-2, cy-2, bitmaps_[UArrow]);
1084 break;
1086 case PE_IndicatorArrowDown: // generic down arrow
1087 case PE_IndicatorSpinDown: // spin down arrow
1088 painter->setBrush(enabled ? pal.dark() : pal.mid());
1089 painter->setPen(painter->brush().color());
1090 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1091 pixelMetric(PM_ButtonShiftVertical));
1092 painter->drawPixmap(cx-2, cy-2, bitmaps_[DArrow]);
1093 break;
1095 case PE_IndicatorArrowLeft: // generic left arrow
1096 painter->setBrush(enabled ? pal.dark() : pal.mid());
1097 painter->setPen(painter->brush().color());
1098 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1099 pixelMetric(PM_ButtonShiftVertical));
1100 painter->drawPixmap(cx-2, cy-2, bitmaps_[LArrow]);
1101 break;
1103 case PE_IndicatorArrowRight: // generic right arrow
1104 painter->setBrush(enabled ? pal.dark() : pal.mid());
1105 painter->setPen(painter->brush().color());
1106 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1107 pixelMetric(PM_ButtonShiftVertical));
1108 painter->drawPixmap(cx-2, cy-2, bitmaps_[RArrow]);
1109 break;
1111 case PE_IndicatorSpinPlus: // spin plus sign
1112 painter->setBrush(enabled ? pal.dark() : pal.mid());
1113 painter->setPen(painter->brush().color());
1114 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1115 pixelMetric(PM_ButtonShiftVertical));
1116 painter->drawPixmap(cx-2, cy-2, bitmaps_[PlusSign]);
1117 break;
1119 case PE_IndicatorSpinMinus: // spin minus sign
1120 painter->setBrush(enabled ? pal.dark() : pal.mid());
1121 painter->setPen(painter->brush().color());
1122 if (sunken) painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
1123 pixelMetric(PM_ButtonShiftVertical));
1124 painter->drawPixmap(cx-2, cy-2, bitmaps_[MinusSign]);
1125 break;
1127 // not drawing these elements, as default is sufficient
1128 // case PE_PanelLineEdit: // panel for a line edit
1129 // case PE_Q3Separator: // Q3 generic separator
1130 // case PE_IndicatorTabTear: // jaggy torn tab indicator
1131 // case PE_IndicatorProgressChunk: // section of progress bar
1132 // case PE_Q3CheckListController: // Q3 controller of a list view item
1133 // case PE_Q3CheckListExclusiveIndicator: // Q3 radio of a list view item
1134 // case PE_PanelTipLabel: // panel for a tip
1136 default:
1137 QWindowsStyle::drawPrimitive(element, option, painter, widget);
1138 break;
1141 painter->restore();
1144 //////////////////////////////////////////////////////////////////////////////
1145 // drawControl()
1146 // -------------
1147 // Draw a control
1149 void PhaseStyle::drawControl(ControlElement element,
1150 const QStyleOption *option,
1151 QPainter *painter,
1152 const QWidget *widget) const
1154 const QRect &rect = option->rect;
1155 const State &flags = option->state;
1156 const QPalette &pal = option->palette;
1157 bool depress = flags & (State_Sunken | State_On);
1158 bool enabled = flags & State_Enabled;
1159 bool horizontal = flags & State_Horizontal;
1160 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
1162 int x, y, w, h;
1163 rect.getRect(&x, &y, &w, &h);
1164 int x2 = rect.right();
1165 int y2 = rect.bottom();
1166 //int cx = rect.center().x();
1167 int cy = rect.center().y();
1169 switch (element) {
1170 case CE_PushButtonBevel: { // QPushButton bevel and default indicator
1171 const QStyleOptionButton *button;
1172 button = qstyleoption_cast<const QStyleOptionButton *>(option);
1173 if (!button) break;
1175 if (!depress &&
1176 (button->features & QStyleOptionButton::DefaultButton)) {
1177 // draw default frame
1178 drawPrimitive(PE_FrameDefaultButton,
1179 option, painter, widget);
1180 // adjust size for bevel
1181 int dbi = pixelMetric(PM_ButtonDefaultIndicator,
1182 button, widget);
1183 QStyleOptionButton tempopt = *button;
1184 tempopt.rect.adjust(dbi, dbi, -dbi, -dbi);
1185 // draw bevel
1186 drawPrimitive(PE_PanelButtonBevel,
1187 &tempopt, painter, widget);
1188 } else if ((button->features & QStyleOptionButton::Flat)
1189 && !depress) {
1190 // flat button, don't draw anything
1191 } else {
1192 // draw normal button
1193 drawPrimitive(PE_PanelButtonCommand,
1194 button, painter, widget);
1197 if (button->features & QStyleOptionButton::HasMenu) {
1198 // get arrow rect
1199 int mbi = pixelMetric(PM_MenuButtonIndicator,
1200 button, widget);
1201 QStyleOptionButton tempopt = *button;
1202 tempopt.rect = QRect(rect.right()- mbi, rect.height() - 20,
1203 mbi, rect.height() - 4);
1204 // draw arrow
1205 drawPrimitive(PE_IndicatorArrowDown,
1206 &tempopt, painter, widget);
1208 break;
1211 case CE_DockWidgetTitle: { // dock window title
1212 const QStyleOptionDockWidget *doption;
1213 doption = qstyleoption_cast<const QStyleOptionDockWidget*>(option);
1214 if (!doption) break;
1216 const QStyleOptionDockWidgetV2 *v2;
1217 v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(option);
1218 bool vertical = (v2 == 0) ? false : v2->verticalTitleBar;
1220 bool floating = false;
1222 if (doption->movable) {
1223 const QDockWidget *dwidget;
1224 dwidget = qobject_cast<const QDockWidget*>(widget);
1225 floating = (dwidget && dwidget->isFloating());
1226 if (floating) {
1227 drawPhaseGradient(painter, rect,
1228 pal.highlight().color(),
1229 vertical, rect.size(), false);
1230 } else {
1231 painter->setPen(pal.midlight().color());
1232 painter->drawLine(x, y, x2-1, y);
1233 painter->drawLine(x, y, x, y2-1);
1234 painter->setPen(pal.mid().color());
1235 painter->drawLine(x+1, y2, x2, y2);
1236 painter->drawLine(x2, y+1, x2, y2);
1237 drawPhaseGradient(painter, rect.adjusted(1, 1, -1, -1),
1238 pal.window().color(),
1239 vertical, QSize(w-2, h-2), false);
1243 if (!doption->title.isEmpty()) {
1244 painter->save();
1246 QRect trect = subElementRect(SE_DockWidgetTitleBarText,
1247 option, widget);
1249 if (vertical) {
1250 painter->translate(trect.center().x(), trect.center().y());
1251 painter->rotate(-90);
1252 painter->translate(-trect.center().x(), -trect.center().y());
1253 trect = painter->worldMatrix().inverted().mapRect(trect);
1256 if (floating) {
1257 QFont font = painter->font();
1258 font.setBold(true);
1259 painter->setFont(font);
1262 drawItemText(painter,
1263 trect.adjusted(4, 0, -4, -1),
1264 Qt::AlignCenter | Qt::TextShowMnemonic,
1265 pal, enabled, doption->title,
1266 floating ? QPalette::HighlightedText : QPalette::WindowText);
1268 painter->restore();
1270 break;
1273 case CE_Splitter: // splitter handle
1274 painter->fillRect(rect, mouseover ?
1275 pal.window().color().lighter(contrast_) :
1276 pal.window());
1277 drawPhaseDoodads(painter, rect, pal, !horizontal);
1278 break;
1280 case CE_TabBarTabShape: { // tab shape within a tabbar
1281 const QStyleOptionTab *tab;
1282 tab = qstyleoption_cast<const QStyleOptionTab*>(option);
1283 if (!tab) break;
1285 // use default for triangular tabs
1286 if (tab->shape != QTabBar::RoundedNorth &&
1287 tab->shape != QTabBar::RoundedWest &&
1288 tab->shape != QTabBar::RoundedSouth &&
1289 tab->shape != QTabBar::RoundedEast) {
1290 QWindowsStyle::drawControl(element, option, painter, widget);
1291 break;
1293 // this guy can get complicated, we we do it elsewhere
1294 drawPhaseTab(painter, pal, tab);
1295 break;
1298 case CE_ProgressBarGroove: // groove of progress bar
1299 drawPhasePanel(painter, rect, pal, pal.base(), true);
1300 break;
1302 case CE_ProgressBarContents: { // indicator of progress bar
1303 const QStyleOptionProgressBar *pbar;
1304 pbar = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
1305 if (!pbar) break;
1307 bool vertical = false;
1308 bool inverted = false;
1310 // Get v2 options
1311 const QStyleOptionProgressBarV2 *pb2;
1312 pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
1313 if (pb2) {
1314 vertical = (pb2->orientation == Qt::Vertical);
1315 inverted = pb2->invertedAppearance;
1318 if (vertical) {
1319 QMatrix matrix;
1320 qSwap(h, w); // flip width and height
1321 matrix.translate(h+5, 0.0);
1322 matrix.rotate(90.0);
1323 painter->setMatrix(matrix);
1326 bool reverse = (vertical ||
1327 (!vertical && (pbar->direction==Qt::RightToLeft)));
1328 if (inverted) reverse = !reverse;
1330 painter->save();
1332 painter->setBrush(pal.highlight());
1333 painter->setPen(pal.dark().color());
1335 if (pbar->minimum == 0 && pbar->maximum == 0) {
1336 // busy indicator
1337 int bar = pixelMetric(PM_ProgressBarChunkWidth, pbar, widget);
1338 int progress = pbar->progress % ((w-bar) * 2);
1339 if (progress > (w-bar)) progress = 2 * (w-bar) - progress;
1340 painter->drawRect(x+progress, y, bar-1, h-1);
1341 } else {
1342 double progress = (double)pbar->progress / (double)pbar->maximum;
1343 int dx = (int)(w * progress);
1344 if (dx > 2) {
1345 if (reverse) x += w - dx;
1346 painter->drawRect(x, y, dx-1, h-1);
1349 painter->restore();
1350 break;
1353 case CE_ProgressBarLabel: { // label of progress bar
1354 const QStyleOptionProgressBar *pbar;
1355 pbar = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
1356 if (!pbar) break;
1357 if (pbar->minimum == 0 && pbar->maximum == 0) break;
1359 painter->save();
1361 bool vert = false;
1362 bool invert = false;
1363 bool btt = false; // bottom to top text orientation
1364 const QStyleOptionProgressBarV2 *pbar2;
1365 pbar2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
1366 if (pbar2) {
1367 vert = (pbar2->orientation == Qt::Vertical);
1368 invert = pbar2->invertedAppearance;
1369 btt = pbar2->bottomToTop;
1372 if (vert) {
1373 QMatrix matrix;
1374 qSwap(w, h); // flip width and height
1375 if (btt) {
1376 matrix.translate(0.0, w);
1377 matrix.rotate(-90.0);
1378 } else {
1379 matrix.translate(h, 0.0);
1380 matrix.rotate(90.0);
1382 painter->setMatrix(matrix);
1385 QRect left;
1386 int ipos = int(((pbar->progress - pbar->minimum)
1387 / double(pbar->maximum - pbar->minimum)) * w);
1388 bool rtl = (pbar->direction == Qt::RightToLeft);
1389 bool flip = ((!vert && ((rtl && !invert) || (!rtl && invert)))
1390 || (vert && ((!invert && !btt) || (invert && btt))));
1391 if (flip) {
1392 ipos = w - ipos;
1393 if (ipos >= 0 && ipos <= w) {
1394 left = QRect(x, y, ipos, h);
1396 } else {
1397 if (ipos >= 0 && ipos <= w) {
1398 left = QRect(x, y, ipos, h);
1402 // QFont font = painter->font();
1403 // font.setBold(true);
1404 // painter->setFont(font);
1406 painter->setPen(flip
1407 ? pbar->palette.base().color()
1408 : pbar->palette.text().color());
1409 painter->drawText(x, y, w, h, Qt::AlignCenter, pbar->text);
1410 if (!left.isNull()) {
1411 painter->setPen(flip
1412 ? pbar->palette.text().color()
1413 : pbar->palette.base().color());
1414 painter->setClipRect(left, Qt::IntersectClip);
1415 painter->drawText(x, y, w, h, Qt::AlignCenter, pbar->text);
1417 painter->restore();
1418 break;
1421 case CE_MenuBarItem: { // menu item in a QMenuBar
1422 const QStyleOptionMenuItem *mbi;
1423 mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option);
1424 if (!mbi) break;
1426 if ((flags & State_Selected) && (flags & State_HasFocus)) {
1427 if (flags & State_Sunken) {
1428 drawPhasePanel(painter, rect, pal, pal.window(), true);
1429 } else {
1430 drawPhaseBevel(painter, rect, pal, pal.window(),
1431 false, false, false);
1433 } else {
1434 drawPhaseGradient(painter, rect, pal.window().color(), false,
1435 rect.size(), false);
1437 QCommonStyle::drawControl(element, mbi, painter, widget);
1438 break;
1441 case CE_MenuBarEmptyArea: // empty area of a QMenuBar
1442 drawPhaseGradient(painter, rect, pal.window().color(), false,
1443 rect.size(), false);
1444 break;
1446 case CE_MenuItem: { // menu item in a QMenu
1447 const QStyleOptionMenuItem *mi;
1448 mi = qstyleoption_cast<const QStyleOptionMenuItem *>(option);
1449 if (!mi) break;
1451 int checkwidth = qMax(mi->maxIconWidth, 20);
1452 bool active = (flags & State_Selected);
1453 int checked = (mi->checkType != QStyleOptionMenuItem::NotCheckable)
1454 ? mi->checked : false;
1455 QRect vrect;
1457 // draw background
1458 if (active && enabled) {
1459 painter->fillRect(rect, pal.highlight());
1460 } else {
1461 painter->fillRect(rect, pal.window());
1464 // draw separator
1465 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
1466 painter->setPen(pal.mid().color());
1467 painter->drawLine(x+checkwidth, cy-1, x2-checkwidth-1, cy-1);
1468 painter->setPen(pal.dark().color());
1469 painter->drawLine(x+checkwidth+1, cy, x2-checkwidth-1, cy);
1470 painter->drawPoint(x+checkwidth, cy);
1471 painter->setPen(pal.midlight().color());
1472 painter->drawLine(x+checkwidth+1, cy+1, x2-checkwidth, cy+1);
1473 painter->drawPoint(x2-checkwidth, cy+1);
1474 break;
1477 // set pen for text and icons
1478 if (enabled) {
1479 painter->setPen(active ? pal.highlightedText().color() :
1480 pal.windowText().color());
1481 } else {
1482 painter->setPen(pal.mid().color());
1485 // draw icon
1486 if (!mi->icon.isNull() && !checked) {
1487 QIcon::Mode mode;
1488 if (active)
1489 mode = enabled ? QIcon::Active : QIcon::Disabled;
1490 else
1491 mode = enabled ? QIcon::Normal : QIcon::Disabled;
1493 QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize),
1494 mode);
1495 vrect = visualRect(mi->direction, rect,
1496 QRect(x, y, checkwidth, h));
1497 QRect pmrect(0, 0, pixmap.width(), pixmap.height());
1498 pmrect.moveCenter(vrect.center());
1499 painter->drawPixmap(pmrect.topLeft(), pixmap);
1502 // draw check
1503 if (checked) {
1504 QStyleOptionMenuItem newmi = *mi;
1505 newmi.state = State_None;
1506 if (enabled) newmi.state |= State_Enabled;
1507 if (active) newmi.state |= State_On;
1508 newmi.rect = visualRect(mi->direction, rect,
1509 QRect(x, y, checkwidth, h));
1510 drawPrimitive(PE_IndicatorMenuCheckMark, &newmi, painter, widget);
1513 // draw text
1514 int xm = ITEMFRAME + checkwidth + ITEMHMARGIN;
1515 int xp = x + xm;
1516 int tw = w - xm - mi->tabWidth - ARROWMARGIN - ITEMHMARGIN * 3
1517 - ITEMFRAME + 1;
1518 QString text = mi->text;
1519 QRect trect(xp, y+ITEMVMARGIN, tw, h - 2 * ITEMVMARGIN);
1520 vrect = visualRect(option->direction, rect, trect);
1522 if (!text.isEmpty()) { // draw label
1523 painter->save();
1525 if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
1526 QFont font = mi->font;
1527 font.setBold(true);
1528 painter->setFont(font);
1531 int t = text.indexOf('\t');
1532 int tflags = Qt::AlignVCenter | Qt::AlignLeft |
1533 Qt::TextDontClip | Qt::TextSingleLine;
1534 if (styleHint(SH_UnderlineShortcut, mi, widget))
1535 tflags |= Qt::TextShowMnemonic;
1536 else
1537 tflags |= Qt::TextHideMnemonic;
1539 if (t >= 0) { // draw right label (accelerator)
1540 QRect tabrect = visualRect(option->direction, rect,
1541 QRect(trect.topRight(),
1542 QPoint(rect.right(), trect.bottom())));
1543 painter->drawText(tabrect, tflags, text.mid(t+1));
1544 text = text.left(t);
1547 // draw left label
1548 painter->drawText(vrect, tflags, text.left(t));
1549 painter->restore();
1552 // draw submenu arrow
1553 if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) {
1554 PrimitiveElement arrow = (option->direction == Qt::RightToLeft)
1555 ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1556 int dim = (h-2*ITEMFRAME) / 2;
1557 vrect = visualRect(option->direction, rect,
1558 QRect(x + w - ARROWMARGIN - ITEMFRAME - dim,
1559 y + h / 2 - dim / 2, dim, dim));
1561 QStyleOptionMenuItem newmi = *mi;
1562 newmi.rect = vrect;
1563 newmi.state = enabled ? State_Enabled : State_None;
1564 if (active) {
1565 newmi.palette.setColor(QPalette::Dark,
1566 newmi.palette.highlightedText().color());
1568 drawPrimitive(arrow, &newmi, painter, widget);
1570 break;
1573 case CE_MenuTearoff: // tearoff area in menu
1574 if (flags & State_Selected)
1575 painter->fillRect(rect, pal.brush(QPalette::Highlight));
1576 else
1577 painter->fillRect(rect, pal.brush(QPalette::Window));
1578 painter->setPen(QPen(pal.mid().color(), 1, Qt::DotLine));
1579 painter->drawLine(x+6, cy-1, x2-6, cy-1);
1580 painter->setPen(QPen(pal.dark().color(), 1, Qt::DotLine));
1581 painter->drawLine(x+6, cy, x2-6, cy);
1582 painter->setPen(QPen(pal.midlight().color(), 1, Qt::DotLine));
1583 painter->drawLine(x+6, cy+1, x2-6, cy+1);
1584 break;
1586 case CE_ToolBoxTab: { // tab area of toolbox
1587 // TODO: account for reverse layout
1588 // TODO: Qt broken - palette isn't constant from tab to tab
1589 const QStyleOptionToolBox *box;
1590 box = qstyleoption_cast<const QStyleOptionToolBox*>(option);
1591 if (!box) break;
1593 const int rx = x2 - 20;
1594 const int cx = rx - h + 1;
1596 QPolygon polygon;
1597 polygon.setPoints(6,
1598 x-1,y, cx,y, rx-2,y2-2, x2+1,y2-2,
1599 x2+1,y2+1, x-1,y2+1);
1601 painter->save();
1603 if (flags & State_Selected) {
1604 painter->setPen(pal.dark().color());
1605 painter->setBrush(pal.window());
1606 painter->drawConvexPolygon(polygon);
1607 } else {
1608 painter->setClipRegion(polygon);
1609 drawPhaseGradient(painter, rect, pal.window().color(), false,
1610 QSize(w, h), false);
1611 painter->setClipping(false);
1612 painter->drawPolyline(polygon);
1615 polygon.setPoints(4, x,y+1, cx,y+1, rx-2,y2-1, x2,y2-1);
1616 painter->setPen(pal.midlight().color());
1617 painter->drawPolyline(polygon);
1619 painter->restore();
1620 break;
1623 case CE_SizeGrip: { // window resize handle
1624 int sw = qMin(h, w) - 1;
1625 y = y2 - sw;
1627 QPen pen = painter->pen();
1628 if (option->direction == Qt::RightToLeft) {
1629 x2 = x + sw;
1630 for (int n = 0; n < 4; ++n) {
1631 painter->setPen(pal.mid().color());
1632 painter->drawLine(x, y, x2, y2);
1633 painter->setPen(pal.midlight().color());
1634 painter->drawLine(x, y+1, x2-1, y2);
1635 y += 3;
1636 x2 -= 3;
1638 } else {
1639 x = x2 - sw;
1640 for (int n = 0; n < 4; ++n) {
1641 painter->setPen(pal.mid().color());
1642 painter->drawLine(x, y2, x2, y);
1643 painter->setPen(pal.midlight().color());
1644 painter->drawLine(x+1, y2, x2, y+1);
1645 x += 3;
1646 y += 3;
1649 painter->setPen(pen);
1650 break;
1653 case CE_HeaderSection: { // header bevel
1654 const QStyleOptionHeader *header;
1655 header = qstyleoption_cast<const QStyleOptionHeader *>(option);
1656 if (!header) break;
1658 horizontal = (header->orientation == Qt::Horizontal);
1659 // adjust rect so headers overlap by one pixel
1660 QRect arect = rect.adjusted(-1, -1, 0, 0);
1661 if (depress) {
1662 painter->save();
1663 painter->setPen(pal.dark().color());
1664 painter->setBrush(pal.mid());
1665 painter->drawRect(arect.adjusted(0, 0, -1, -1));
1666 painter->restore();
1668 else {
1669 drawPhaseBevel(painter, arect, pal,
1670 pal.window(), false, !horizontal, true);
1672 break;
1675 case CE_ScrollBarAddLine: { // scrollbar scroll down
1676 PrimitiveElement arrow = (horizontal)
1677 ? PE_IndicatorArrowRight : PE_IndicatorArrowDown;
1679 drawPhaseBevel(painter, rect, pal, pal.button(),
1680 depress, !horizontal, true);
1681 drawPrimitive(arrow, option, painter, widget);
1682 break;
1684 case CE_ScrollBarSubLine: { // scrollbar scroll up
1685 const QStyleOptionSlider *sb;
1686 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
1687 if (!sb) break;
1689 int extent = pixelMetric(PM_ScrollBarExtent, sb, widget);
1691 QRect button1, button2;
1692 PrimitiveElement arrow;
1694 if (horizontal) {
1695 button1.setRect(x, y, extent, extent);
1696 button2.setRect(x2 - extent + 1, y, extent, extent);
1697 arrow = PE_IndicatorArrowLeft;
1698 } else {
1699 button1.setRect(x, y, extent, extent);
1700 button2.setRect(x, y2 - extent + 1, extent, extent);
1701 arrow = PE_IndicatorArrowUp;
1704 // draw buttons
1705 drawPhaseBevel(painter, button1, pal, pal.button(),
1706 depress, !horizontal, true);
1707 drawPhaseBevel(painter, button2, pal, pal.button(),
1708 depress, !horizontal, true);
1710 QStyleOptionSlider newoption = *sb;
1711 newoption.rect = button1;
1712 drawPrimitive(arrow, &newoption, painter, widget);
1713 newoption.rect = button2;
1714 drawPrimitive(arrow, &newoption, painter, widget);
1716 break;
1719 case CE_ScrollBarAddPage: // scrollbar page down
1720 case CE_ScrollBarSubPage: // scrollbar page up
1721 if (h) { // has a height, thus visible
1722 QPen pen = painter->pen();
1723 painter->fillRect(rect, pal.mid());
1724 painter->setPen(pal.dark().color());
1725 if (horizontal) { // vertical
1726 painter->drawLine(x, y, x2, y);
1727 painter->drawLine(x, y2, x2, y2);
1728 } else { // horizontal
1729 painter->drawLine(x, y, x, y2);
1730 painter->drawLine(x2, y, x2, y2);
1732 painter->setPen(pen);
1734 break;
1736 case CE_ScrollBarSlider: // scrollbar slider/thumb
1737 drawPhaseBevel(painter, rect, pal, mouseover ?
1738 pal.button().color().lighter(contrast_) : pal.button(),
1739 false, !horizontal, true);
1740 drawPhaseDoodads(painter, rect, pal, horizontal);
1741 break;
1743 case CE_RubberBand: { // rubberband (such as for iconview)
1744 const QStyleOptionRubberBand *rb;
1745 rb = qstyleoption_cast<const QStyleOptionRubberBand*>(option);
1746 if (rb) {
1747 painter->save();
1748 QColor color = pal.highlight().color();
1749 if (!rb->opaque) color.setAlpha(127);
1750 painter->setPen(color);
1751 if (!rb->opaque) color.setAlpha(31);
1752 painter->setBrush(color);
1753 QStyleHintReturnMask mask;
1754 painter->drawRect(rect.adjusted(0, 0, -1, -1));
1755 painter->restore();
1757 break;
1760 case CE_ToolBar: { // QToolBar
1761 drawPrimitive(PE_PanelToolBar, option, painter, widget);
1762 QRect grect = rect.adjusted(2, 2, -2, -2);
1763 drawPhaseGradient(painter, grect, pal.window().color(),
1764 !horizontal, grect.size(), true);
1765 break;
1768 // not drawing these controls, as default is sufficient
1769 // case CE_Q3DockWindowEmptyArea: // empty area of dock widget
1770 // case CE_PushButtonLabel:
1771 // case CE_FocusFrame:
1772 // case CE_CheckBox:
1773 // case CE_CheckBoxLabel:
1774 // case CE_ComboBoxLabel:
1775 // case CE_Header:
1776 // case CE_HeaderLabel:
1777 // case CE_MenuScroller:
1778 // case CE_RadioButton:
1779 // case CE_RadioButtonLabel:
1780 // case CE_ScrollBarFirst:
1781 // case CE_ScrollBarLast:
1782 // case CE_TabBarTab:
1783 // case CE_TabBarTabLabel:
1784 // case CE_ToolButtonLabel:
1786 default:
1787 QWindowsStyle::drawControl(element, option, painter, widget);
1788 break;
1792 //////////////////////////////////////////////////////////////////////////////
1793 // drawComplexControl()
1794 // --------------------
1795 // Draw complex control
1797 void PhaseStyle::drawComplexControl(ComplexControl control,
1798 const QStyleOptionComplex *option,
1799 QPainter *painter,
1800 const QWidget *widget) const
1802 const QRect &rect = option->rect;
1803 const State &flags = option->state;
1804 const QPalette &pal = option->palette;
1805 bool enabled = flags & State_Enabled;
1806 bool sunken = flags & State_Sunken;
1807 bool mouseover = highlights_ && (flags & State_MouseOver) && enabled;
1808 int x, y, w, h;
1809 rect.getRect(&x, &y, &w, &h);
1810 QRect subrect;
1812 switch (control) {
1813 case CC_SpinBox: { // QSpinBox
1814 const QStyleOptionSpinBox *box;
1815 box = qstyleoption_cast<const QStyleOptionSpinBox*>(option);
1816 if (!box) break;
1818 QStyleOptionSpinBox copybox = *box;
1819 PrimitiveElement element;
1821 // draw frame
1822 if (box->frame && (box->subControls & SC_SpinBoxFrame)) {
1823 subrect = subControlRect(CC_SpinBox, box,
1824 SC_SpinBoxFrame, widget);
1825 drawPhasePanel(painter, subrect, pal, Qt::NoBrush, true);
1828 // draw button field
1829 subrect = subControlRect(CC_SpinBox, box,
1830 SC_SpinBoxFrame, widget);
1831 subrect.adjust(1, 1, -1, -1);
1832 int left = subControlRect(CC_SpinBox, box,
1833 SC_SpinBoxUp, widget).left();
1834 subrect.setLeft(left);
1835 drawPhaseBevel(painter, subrect, pal, mouseover ?
1836 pal.button().color().lighter(contrast_) :
1837 pal.button(),
1838 false, false, false);
1840 // draw up arrow
1841 if (box->subControls & SC_SpinBoxUp) {
1842 subrect = subControlRect(CC_SpinBox, box, SC_SpinBoxUp, widget);
1843 copybox.subControls = SC_SpinBoxUp;
1844 copybox.rect = subControlRect(CC_SpinBox, box,
1845 SC_SpinBoxUp, widget);
1847 if (box->buttonSymbols == QAbstractSpinBox::PlusMinus)
1848 element = PE_IndicatorSpinPlus;
1849 else
1850 element = PE_IndicatorSpinUp;
1852 if (box->activeSubControls == SC_SpinBoxUp && sunken) {
1853 copybox.state |= State_On;
1854 copybox.state |= State_Sunken;
1855 } else {
1856 copybox.state |= State_Raised;
1857 copybox.state &= ~State_Sunken;
1859 drawPrimitive(element, &copybox, painter, widget);
1862 // draw down arrow
1863 if (box->subControls & SC_SpinBoxDown) {
1864 subrect = subControlRect(CC_SpinBox, box, SC_SpinBoxDown, widget);
1865 copybox.subControls = SC_SpinBoxDown;
1866 copybox.rect = subControlRect(CC_SpinBox, box,
1867 SC_SpinBoxDown, widget);
1869 if (box->buttonSymbols == QAbstractSpinBox::PlusMinus)
1870 element = PE_IndicatorSpinMinus;
1871 else
1872 element = PE_IndicatorSpinDown;
1874 if (box->activeSubControls == SC_SpinBoxDown && sunken) {
1875 copybox.state |= State_On;
1876 copybox.state |= State_Sunken;
1877 } else {
1878 copybox.state |= State_Raised;
1879 copybox.state &= ~State_Sunken;
1881 drawPrimitive(element, &copybox, painter, widget);
1883 break;
1886 case CC_ComboBox: { // QComboBox
1887 const QStyleOptionComboBox *combo;
1888 combo = qstyleoption_cast<const QStyleOptionComboBox*>(option);
1889 if (!combo) break;
1891 subrect = subControlRect(CC_ComboBox, combo,
1892 SC_ComboBoxArrow, widget);
1894 if (combo->editable) {
1895 // draw frame
1896 drawPhasePanel(painter, rect, pal, Qt::NoBrush, true);
1897 // draw arrow box
1898 drawPhaseBevel(painter, subrect.adjusted(-1, -1, 1, 1),
1899 pal, mouseover
1900 ? pal.button().color().lighter(contrast_)
1901 : pal.button().color(), sunken, false);
1902 } else {
1903 // draw bevel
1904 drawPhaseButton(painter, rect, pal, mouseover
1905 ? pal.button().color().lighter(contrast_)
1906 : pal.button().color(), sunken);
1909 if (combo->subControls & SC_ComboBoxArrow) {
1910 // draw slot
1911 int slot = qMax(h/4, 6);
1912 slot = qMin(slot, 12) + (h%2);
1913 subrect.adjust(3, 0, -3, 0);
1914 subrect.setTop(subrect.top() + subrect.height()/2 - slot/2);
1915 subrect.setHeight(slot);
1916 drawPhasePanel(painter, subrect,
1917 pal, sunken ? pal.midlight() : pal.mid(),
1918 true);
1921 if ((flags & State_HasFocus) && !combo->editable) {
1922 QStyleOptionFocusRect focus;
1923 focus.QStyleOption::operator=(*combo);
1924 subrect = subElementRect(SE_ComboBoxFocusRect,
1925 combo, widget);
1926 focus.rect = visualRect(combo->direction, rect, subrect);
1927 drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
1929 break;
1932 case CC_Slider: { // QSlider
1933 const QStyleOptionSlider *slider;
1934 slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
1935 if (!slider) break;
1937 if (slider->subControls & SC_SliderGroove) {
1938 subrect = subControlRect(CC_Slider, slider,
1939 SC_SliderGroove, widget);
1940 if (subrect.isValid()) {
1941 if (slider->orientation == Qt::Horizontal) {
1942 subrect.setTop(subrect.top()+subrect.height()/2-3);
1943 subrect.setHeight(7);
1944 } else {
1945 subrect.setLeft(subrect.left()+subrect.width()/2-3);
1946 subrect.setWidth(7);
1948 drawPhasePanel(painter, subrect, pal, pal.mid(), true);
1952 if (slider->subControls & SC_SliderHandle) {
1953 subrect = subControlRect(CC_Slider, slider,
1954 SC_SliderHandle, widget);
1955 QColor color = mouseover
1956 ? pal.button().color().lighter(contrast_)
1957 : pal.button().color();
1959 if (slider->orientation == Qt::Horizontal) {
1960 subrect.setWidth(6);
1961 drawPhaseBevel(painter, subrect, pal, color,
1962 false, false, false);
1963 subrect.moveLeft(subrect.left()+5);
1964 drawPhaseBevel(painter, subrect, pal, color,
1965 false, false, false);
1966 } else {
1967 subrect.setHeight(6);
1968 drawPhaseBevel(painter, subrect, pal, color,
1969 false, true, false);
1970 subrect.moveTop(subrect.top()+5);
1971 drawPhaseBevel(painter, subrect, pal, color,
1972 false, true, false);
1976 if (slider->subControls & SC_SliderTickmarks) {
1977 bool ticksabove = slider->tickPosition & QSlider::TicksAbove;
1978 bool ticksbelow = slider->tickPosition & QSlider::TicksBelow;
1979 bool horizontal = (slider->orientation == Qt::Horizontal);
1981 int spaceavail = pixelMetric(PM_SliderSpaceAvailable,
1982 slider, widget);
1983 int interval = slider->tickInterval;
1984 if (interval==0) {
1985 interval = slider->singleStep;
1986 if (QStyle::sliderPositionFromValue(slider->minimum,
1987 slider->maximum,
1988 interval, spaceavail)
1989 - QStyle::sliderPositionFromValue(slider->minimum,
1990 slider->maximum,
1991 0, spaceavail) < 3)
1992 interval = slider->pageStep;
1994 if (interval < 2) interval = 2;
1996 QRect handle = subControlRect(CC_Slider, slider,
1997 SC_SliderHandle, widget);
1998 int pos, offset, span, ticksize;
1999 if (horizontal) {
2000 offset = handle.width() / 2;
2001 span = w - handle.width();
2002 ticksize = (h - handle.height()) / 2 - 1;
2003 } else {
2004 offset = handle.height() / 2;
2005 span = h - handle.height();
2006 ticksize = (w - handle.width()) / 2 - 1;
2009 QPen oldpen = painter->pen();
2010 painter->setPen(pal.dark().color());
2012 for (int n=slider->minimum; n<=slider->maximum; n+=interval) {
2013 pos = sliderPositionFromValue(slider->minimum,
2014 slider->maximum,
2015 n, span,
2016 slider->upsideDown);
2017 pos += offset;
2019 if (horizontal) {
2020 if (ticksabove) {
2021 painter->drawLine(pos, y, pos, y + ticksize);
2023 if (ticksbelow) {
2024 painter->drawLine(pos, rect.bottom(),
2025 pos, rect.bottom() - ticksize);
2027 } else {
2028 if (ticksabove) {
2029 painter->drawLine(x, pos, x + ticksize, pos);
2031 if (ticksbelow) {
2032 painter->drawLine(rect.right(), pos,
2033 rect.right() - ticksize, pos);
2037 painter->setPen(oldpen);
2040 break;
2043 case CC_Dial: { // QDial
2044 const QStyleOptionSlider *dial;
2045 dial = qstyleoption_cast<const QStyleOptionSlider*>(option);
2046 if (!dial) break;
2048 // avoid aliasing
2049 QPainter::RenderHints oldhints = painter->renderHints();
2050 painter->setRenderHint(QPainter::Antialiasing, true);
2052 qreal cx = rect.center().x();
2053 qreal cy = rect.center().y();
2054 qreal radius = (qMin(w, h) / 2.0) - 2.0;
2055 qreal tick = qMax(radius / 6, 4.0);
2057 if (dial->subControls & SC_DialGroove) {
2058 QRectF groove = QRectF(cx-radius+tick, cy-radius+tick,
2059 radius*2-tick*2, radius*2-tick*2);
2061 // Note: State_MouseOver doesn't work well with QDial
2062 QLinearGradient gradient(0, groove.top(), 0, groove.bottom());
2063 gradient.setColorAt(0, pal.button().color().darker(contrast_));
2064 gradient.setColorAt(1, pal.button().color().lighter(contrast_));
2066 painter->setPen(QPen(pal.dark().color(), 1.5));
2067 painter->setBrush(gradient);
2068 painter->drawEllipse(groove);
2069 painter->setBrush(Qt::NoBrush);
2071 groove.adjust(1.0, 1.0, -1.0, -1.0);
2072 painter->setPen(pal.midlight().color());
2073 painter->drawArc(groove, 60*16, 150*16);
2074 painter->setPen(pal.button().color());
2075 painter->drawArc(groove, 30*16, 30*16);
2076 painter->drawArc(groove, 210*16, 30*16);
2077 painter->setPen(pal.mid().color());
2078 painter->drawArc(groove, 240*16, 150*16);
2081 if (dial->subControls & SC_DialHandle) {
2082 painter->save();
2083 qreal angle;
2084 qreal percent = (double)(dial->sliderValue - dial->minimum)
2085 / (double)(dial->maximum - dial->minimum);
2087 if (dial->maximum == dial->minimum) {
2088 angle = 0.0;
2089 } else if (dial->dialWrapping) {
2090 angle = percent * 360.0;
2091 } else {
2092 angle = percent * 315.0 + 22.5;
2095 painter->translate(cx, cy);
2096 painter->rotate(angle);
2098 bool ul = (angle > 135.0 && angle < 315.0);
2099 painter->setPen(ul ? pal.midlight().color() : pal.mid().color());
2100 painter->drawLine(QLineF(-1, radius-tick-1, -1, radius-tick*4));
2101 painter->setPen(pal.dark().color());
2102 painter->drawLine(QLineF(0, radius-tick, 0, radius-tick*4));
2103 painter->setPen(ul ? pal.mid().color() : pal.midlight().color());
2104 painter->drawLine(QLineF(1, radius-tick-1, 1, radius-tick*4));
2106 painter->restore();
2109 if (dial->subControls & QStyle::SC_DialTickmarks) {
2110 painter->save();
2111 painter->setPen(pal.dark().color());
2113 int ti = dial->tickInterval;
2114 int notches = (dial->maximum - dial->minimum + ti - 1) / ti;
2116 if (notches > 0) {
2117 qreal start, increment;
2118 if (dial->dialWrapping) {
2119 start = 0.0;
2120 increment = 360.0 / notches;
2121 } else {
2122 start = 22.5;
2123 increment = 315.0 / notches;
2126 painter->translate(cx, cy);
2127 painter->rotate(start);
2128 for (int n=0; n<=notches; ++n) {
2129 painter->drawLine(QLineF(0.0, radius,
2130 0.0, radius - tick / 2.0));;
2131 painter->rotate(increment);
2134 painter->restore();
2137 painter->setRenderHints(oldhints);
2138 break;
2141 case CC_TitleBar: { // QWorkspace titlebar
2142 // TODO: sync this look up with dock window titles ?
2143 const QStyleOptionTitleBar *title;
2144 title = qstyleoption_cast<const QStyleOptionTitleBar*>(option);
2145 if (!title) break;
2147 bool shaded = (title->titleBarState & Qt::WindowMinimized);
2149 int x2 = rect.right();
2150 int y2 = rect.bottom();
2152 // draw titlebar frame
2153 drawPhaseGradient(painter, rect.adjusted(0,0,0,-3),
2154 pal.highlight().color(),
2155 false, rect.size(), false);
2157 painter->setPen(pal.shadow().color());
2158 painter->drawLine(x, y, x, y2);
2159 painter->drawLine(x, y, x2, y);
2160 painter->drawLine(x2, y, x2, y2);
2161 painter->setPen(pal.midlight().color());
2162 painter->drawLine(x+1, y+1, x2-2, y+1);
2163 painter->drawLine(x+1, y+2, x+1, y2);
2164 painter->setPen(pal.mid().color());
2165 painter->drawLine(x2-1, y+2, x2-1, y2);
2166 painter->setPen(pal.window().color());
2167 painter->drawLine(x+2, y+2, x2-2, y+2);
2168 painter->drawLine(x+2, y+2, x+2, y2);
2169 painter->drawLine(x2-2, y+2, x2-2, y2);
2170 painter->drawPoint(x2-1, y+1);
2171 if (shaded) {
2172 painter->setPen(pal.shadow().color());
2173 painter->drawLine(x, y2, x2, y2);
2174 painter->setPen(pal.mid().color());
2175 painter->drawLine(x+2, y2-1, x2-1, y2-1);
2176 painter->setPen(pal.window().color());
2177 painter->drawLine(x+2, y2-2, x2-2, y2-2);
2178 painter->drawPoint(x+1, y2-1);
2181 // draw label
2182 if (title->subControls & SC_TitleBarLabel) {
2183 subrect = subControlRect(CC_TitleBar, title,
2184 SC_TitleBarLabel, widget);
2186 QFont font = painter->font();
2187 font.setBold(true);
2188 painter->setFont(font);
2190 drawItemText(painter, subrect,
2191 Qt::AlignCenter |
2192 Qt::TextShowMnemonic |
2193 Qt::TextSingleLine,
2194 pal, enabled, title->text,
2195 QPalette::HighlightedText);
2198 // draw buttons
2199 QPixmap pix;
2200 bool down;
2201 QStyleOption tool(*title);
2203 painter->setPen(pal.windowText().color());
2205 // menu/icon button
2206 if ((title->subControls & SC_TitleBarSysMenu) &&
2207 (title->titleBarFlags & Qt::WindowSystemMenuHint)) {
2208 subrect = subControlRect(CC_TitleBar, title,
2209 SC_TitleBarSysMenu, widget);
2210 if (!title->icon.isNull()) {
2211 title->icon.paint(painter, subrect);
2212 } else {
2213 down = ((title->activeSubControls & SC_TitleBarCloseButton)
2214 && (flags & State_Sunken));
2215 pix = standardPixmap(SP_TitleBarMenuButton, &tool, widget);
2216 tool.rect = subrect;
2217 tool.state = down ? State_Sunken : State_Raised;
2218 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2220 if (down) painter->translate(1, 1);
2221 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2222 if (down) painter->translate(-1, -1);
2226 if (title->subControls & SC_TitleBarCloseButton) {
2227 subrect = subControlRect(CC_TitleBar, title,
2228 SC_TitleBarCloseButton, widget);
2229 if (!subrect.isNull()) {
2230 down = ((title->activeSubControls & SC_TitleBarCloseButton)
2231 && (flags & State_Sunken));
2232 pix = standardPixmap(SP_TitleBarCloseButton, &tool, widget);
2233 tool.rect = subrect;
2234 tool.state = down ? State_Sunken : State_Raised;
2235 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2237 if (down) painter->translate(1, 1);
2238 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2239 if (down) painter->translate(-1, -1);
2243 if (title->subControls & SC_TitleBarMinButton) {
2244 subrect = subControlRect(CC_TitleBar, title,
2245 SC_TitleBarMinButton, widget);
2246 if (!subrect.isNull()) {
2247 down = ((title->activeSubControls & SC_TitleBarMinButton)
2248 && (flags & State_Sunken));
2249 pix = standardPixmap(SP_TitleBarMinButton, &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);
2256 if (down) painter->translate(-1, -1);
2260 if ((title->subControls & SC_TitleBarMaxButton) &&
2261 (title->titleBarFlags & Qt::WindowMaximizeButtonHint)) {
2262 subrect = subControlRect(CC_TitleBar, title,
2263 SC_TitleBarMaxButton, widget);
2264 if (!subrect.isNull()) {
2265 down = ((title->activeSubControls & SC_TitleBarMaxButton) &&
2266 (flags & State_Sunken));
2267 pix = standardPixmap(SP_TitleBarMaxButton, &tool, widget);
2268 tool.rect = subrect;
2269 tool.state = down ? State_Sunken : State_Raised;
2270 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2272 if (down) painter->translate(1, 1);
2273 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2274 if (down) painter->translate(-1, -1);
2278 if ((title->subControls & SC_TitleBarNormalButton) &&
2279 (((title->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2280 (title->titleBarState & Qt::WindowMinimized)) ||
2281 ((title->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2282 (title->titleBarState & Qt::WindowMaximized)))) {
2283 subrect = subControlRect(CC_TitleBar, title,
2284 SC_TitleBarNormalButton, widget);
2285 if (!subrect.isNull()) {
2286 down = ((title->activeSubControls & SC_TitleBarNormalButton)
2287 && (flags & State_Sunken));
2288 pix = standardPixmap(SP_TitleBarNormalButton, &tool, widget);
2289 tool.rect = subrect;
2290 tool.state = down ? State_Sunken : State_Raised;
2291 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2293 if (down) painter->translate(1, 1);
2294 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2298 if ((title->subControls & SC_TitleBarContextHelpButton) &&
2299 (title->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
2300 subrect = subControlRect(CC_TitleBar, title,
2301 SC_TitleBarContextHelpButton, widget);
2302 if (!subrect.isNull()) {
2303 down = ((title->activeSubControls & SC_TitleBarContextHelpButton)
2304 && (flags & State_Sunken));
2305 pix = standardPixmap(SP_TitleBarContextHelpButton,
2306 &tool, widget);
2307 tool.rect = subrect;
2308 tool.state = down ? State_Sunken : State_Raised;
2309 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
2311 if (down) painter->translate(1, 1);
2312 drawItemPixmap(painter, subrect, Qt::AlignCenter, pix);
2313 if (down) painter->translate(-1, -1);
2317 break;
2320 // not drawing these controls, as default is sufficient
2321 // case CC_ScrollBar:
2322 // case CC_ToolButton:
2323 // case CC_GroupBox:
2325 default:
2326 QWindowsStyle::drawComplexControl(control, option, painter, widget);
2327 break;
2331 //////////////////////////////////////////////////////////////////////////////
2332 // standardPixmap()
2333 // ----------------
2334 // Get pixmap for style
2336 QPixmap PhaseStyle::standardPixmap(StandardPixmap pixmap,
2337 const QStyleOption *option,
2338 const QWidget *widget) const
2340 switch (pixmap) {
2341 case SP_TitleBarMenuButton:
2342 return QPixmap(title_menu_xpm);
2344 case SP_DockWidgetCloseButton:
2345 case SP_TitleBarCloseButton:
2346 return bitmaps_[TitleClose];
2348 case SP_TitleBarMinButton:
2349 return bitmaps_[TitleMin];
2351 case SP_TitleBarMaxButton:
2352 return bitmaps_[TitleMax];
2354 case SP_TitleBarNormalButton:
2355 return bitmaps_[TitleNormal];
2357 case SP_TitleBarContextHelpButton:
2358 return bitmaps_[TitleHelp];
2360 default:
2361 return QWindowsStyle::standardPixmap(pixmap, option, widget);
2366 //////////////////////////////////////////////////////////////////////////////
2367 // Metrics and Rects //
2368 //////////////////////////////////////////////////////////////////////////////
2370 //////////////////////////////////////////////////////////////////////////////
2371 // pixelMetric()
2372 // -------------
2373 // Get the pixel metric for metric
2375 int PhaseStyle::pixelMetric(PixelMetric metric,
2376 const QStyleOption *option,
2377 const QWidget *widget) const
2379 int ex = qMax(QApplication::fontMetrics().xHeight(), 17);
2381 switch (metric) {
2382 case PM_ButtonMargin:
2383 return 6;
2385 case PM_ButtonDefaultIndicator: // size of default button frame
2386 return 3; // half button margin
2388 case PM_IndicatorWidth:
2389 case PM_IndicatorHeight:
2390 case PM_ExclusiveIndicatorWidth:
2391 case PM_ExclusiveIndicatorHeight:
2392 case PM_CheckListButtonSize:
2393 return ex & 0xfffe; // even size
2395 case PM_MenuBarPanelWidth:
2396 return 2;
2398 case PM_DockWidgetTitleMargin:
2399 return 2;
2401 case PM_DockWidgetFrameWidth:
2402 return 3;
2404 case PM_ScrollBarExtent: // base width of a vertical scrollbar
2405 return ex & 0xfffe;
2407 case PM_ScrollBarSliderMin: // minimum length of slider
2408 return ex * 2;
2410 case PM_TabBarTabHSpace: // extra tab spacing
2411 return 24;
2413 case PM_TabBarTabShiftVertical:
2414 return 2;
2416 case PM_TabBarTabVSpace: {
2417 const QStyleOptionTab *tab;
2418 tab = qstyleoption_cast<const QStyleOptionTab *>(option);
2419 if (tab) {
2420 if (tab->shape == QTabBar::RoundedNorth) {
2421 return 10;
2422 } else {
2423 return 6;
2426 return 0;
2429 case PM_ProgressBarChunkWidth: {
2430 int breadth = qMax(option->rect.width(), option->rect.height());
2431 return qMax(breadth / 10, 10);
2434 case PM_TitleBarHeight:
2435 return qMax(widget ? widget->fontMetrics().lineSpacing() :
2436 (option ? option->fontMetrics.lineSpacing() : 0), 22);
2438 default:
2439 return QWindowsStyle::pixelMetric(metric, option, widget);
2443 //////////////////////////////////////////////////////////////////////////////
2444 // subElementRect()
2445 // ----------------
2446 // Return rect of subelement
2448 QRect PhaseStyle::subElementRect(SubElement element,
2449 const QStyleOption *option,
2450 const QWidget *widget) const
2452 QRect rect;
2453 const int fw = 2;
2454 int x, y, w, h;
2455 option->rect.getRect(&x, &y, &w, &h);
2457 switch (element) {
2458 case SE_ComboBoxFocusRect: {
2459 int bw = qMin(h, 32); // position between edit and arrow
2460 rect.setRect(fw*2, fw*2, w-bw-fw-1, h-(fw*4));
2461 break;
2464 case SE_ProgressBarContents:
2465 return option->rect.adjusted(3, 3, -3, -3);
2467 case SE_ProgressBarGroove:
2468 case SE_ProgressBarLabel:
2469 return option->rect;
2471 case SE_HeaderArrow: {
2472 int margin = pixelMetric(PM_HeaderMargin, option, widget);
2473 rect.setSize(QSize(h - margin*2, h - margin*2));
2474 if (option->state & State_Horizontal) {
2475 rect.moveTopLeft(QPoint(x + w - h, margin));
2476 } else {
2477 rect.moveTopLeft(QPoint(margin, margin));
2479 rect = visualRect(option->direction, option->rect, rect);
2480 break;
2483 case SE_ToolBoxTabContents:
2484 rect = visualRect(option->direction, option->rect, option->rect);
2485 break;
2487 case SE_DockWidgetTitleBarText: {
2488 rect = QWindowsStyle::subElementRect(element, option, widget);
2490 const QStyleOptionDockWidgetV2 *v2
2491 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(option);
2492 bool vertical = (v2 == 0) ? false : v2->verticalTitleBar;
2494 if (vertical) {
2495 rect.adjust(0, -3, 0, -3);
2496 } else {
2497 rect.adjust(-3, 0, 3, 0);
2499 break;
2502 case SE_DockWidgetFloatButton:
2503 case SE_DockWidgetCloseButton: {
2504 rect = QWindowsStyle::subElementRect(element, option, widget);
2506 const QStyleOptionDockWidgetV2 *v2
2507 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(option);
2508 bool vertical = (v2 == 0) ? false : v2->verticalTitleBar;
2510 if (vertical) {
2511 rect.moveTop(rect.top() + 3);
2512 } else {
2513 if (option->direction == Qt::LeftToRight) {
2514 rect.moveLeft(rect.left() - 3);
2515 } else {
2516 rect.moveLeft(rect.left() + 3);
2519 break;
2522 default:
2523 rect = QWindowsStyle::subElementRect(element, option, widget);
2526 return rect;
2529 //////////////////////////////////////////////////////////////////////////////
2530 // subControlRect()
2531 // ----------------
2532 // Return rect of control
2534 QRect PhaseStyle::subControlRect(ComplexControl control,
2535 const QStyleOptionComplex *option,
2536 SubControl subcontrol,
2537 const QWidget *widget) const
2539 QRect rect;
2540 QRect ctlrect = option->rect;
2541 int x, y, w, h, x2, y2;
2542 const int fw = 2;
2543 ctlrect.getRect(&x, &y, &w, &h);
2544 x2 = ctlrect.right(); y2 = ctlrect.bottom();
2546 switch (control) {
2547 case CC_SpinBox: {
2548 const QStyleOptionSpinBox *box;
2549 box = qstyleoption_cast<const QStyleOptionSpinBox*>(option);
2550 if (!box) break;
2552 bool odd = widget ? widget->height() % 2 : 0;
2553 int bw = (h*3/4) - odd + 1; // width of button box
2554 switch (subcontrol) {
2555 case SC_SpinBoxUp:
2556 rect.setRect(w-bw, (h/2)-(odd ? 6 : 7), bw-1, 6);
2557 break;
2558 case SC_SpinBoxDown:
2559 rect.setRect(w-bw, (h/2)+1, bw-1, odd ? 7 : 6);
2560 break;
2561 case SC_SpinBoxEditField:
2562 rect.setRect(fw, fw, w-bw-fw, h-(fw*2));
2563 break;
2564 case SC_SpinBoxFrame:
2565 rect = ctlrect;
2566 break;
2567 default:
2568 break;
2570 rect = visualRect(box->direction, ctlrect, rect);
2571 break;
2574 case CC_ComboBox: {
2575 const QStyleOptionComboBox *combo;
2576 combo = qstyleoption_cast<const QStyleOptionComboBox*>(option);
2577 if (!combo) break;
2579 int bw = qMin(h, 32); // position between edit and arrow
2580 switch (subcontrol) {
2581 case SC_ComboBoxFrame: // total combobox area
2582 rect = ctlrect;
2583 break;
2585 case SC_ComboBoxArrow: // the right side
2586 rect.setRect(w-bw, fw, bw-fw, h-(fw*2));
2587 break;
2589 case SC_ComboBoxEditField: // the left side
2590 rect.setRect(fw, fw, w-bw-fw-1, h-(fw*2));
2591 if (!combo->editable) {
2592 // give extra margin
2593 rect.adjust(pixelMetric(PM_ButtonMargin),
2594 0, 0, 0);
2596 break;
2598 case SC_ComboBoxListBoxPopup: // the list popup box
2599 rect = ctlrect;
2600 break;
2602 default:
2603 break;
2605 rect = visualRect(combo->direction, ctlrect, rect);
2606 break;
2609 case CC_ScrollBar: {
2610 // three button scrollbar
2611 const QStyleOptionSlider *sb;
2612 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
2613 if (!sb) break;
2615 bool horizontal = (sb->orientation == Qt::Horizontal);
2616 int extent = pixelMetric(PM_ScrollBarExtent, sb, widget);
2617 int slidermax = ((horizontal) ? ctlrect.width() : ctlrect.height())
2618 - (extent * 3);
2619 int slidermin = pixelMetric(PM_ScrollBarSliderMin, sb, widget);
2620 int sliderlen, sliderstart;
2622 // calculate slider length
2623 if (sb->maximum != sb->minimum) {
2624 int range = sb->maximum - sb->minimum;
2625 sliderlen = (sb->pageStep * slidermax) / (range + sb->pageStep);
2626 if ((sliderlen < slidermin) || (range > INT_MAX / 2))
2627 sliderlen = slidermin;
2628 if (sliderlen > slidermax)
2629 sliderlen = slidermax;
2630 } else {
2631 sliderlen = slidermax;
2634 sliderstart = extent + sliderPositionFromValue(sb->minimum,
2635 sb->maximum,
2636 sb->sliderPosition,
2637 slidermax - sliderlen,
2638 sb->upsideDown);
2640 switch (subcontrol) {
2641 case SC_ScrollBarAddLine:
2642 if (horizontal) {
2643 rect.setRect(x2 - extent + 1, y, extent, extent);
2644 } else {
2645 rect.setRect(x, y2 - extent + 1, extent, extent);
2647 break;
2649 case SC_ScrollBarSubLine:
2650 // rect that covers *both* subline buttons
2651 if (horizontal) {
2652 rect.setRect(x, y, w - extent + 1, extent);
2653 } else {
2654 rect.setRect(x, y, extent, h - extent + 1);
2656 break;
2658 case SC_ScrollBarAddPage:
2659 if (horizontal)
2660 rect.setRect(sliderstart + sliderlen, y,
2661 slidermax - sliderstart - sliderlen + extent + 1,
2662 extent);
2663 else
2664 rect.setRect(x, sliderstart + sliderlen, extent,
2665 slidermax - sliderstart - sliderlen + extent + 1);
2666 break;
2668 case SC_ScrollBarSubPage:
2669 if (horizontal) {
2670 rect.setRect(x + extent, y,
2671 sliderstart - (x + extent), extent);
2672 } else {
2673 rect.setRect(x, y + extent, extent,
2674 sliderstart - (x + extent));
2676 break;
2678 case SC_ScrollBarSlider:
2679 if (horizontal) {
2680 rect.setRect(sliderstart - 1, y, sliderlen + 2 + 1, extent);
2681 } else {
2682 rect.setRect(x, sliderstart - 1, extent, sliderlen + 2 + 1);
2684 break;
2686 case SC_ScrollBarGroove:
2687 if (horizontal) {
2688 rect = ctlrect.adjusted(extent, 0, -(extent*2), 0);
2689 } else {
2690 rect = ctlrect.adjusted(0, extent, 0, -(extent*2));
2692 break;
2694 default:
2695 break;
2697 rect = visualRect(sb->direction, ctlrect, rect);
2698 break;
2701 case CC_TitleBar: {
2702 const QStyleOptionTitleBar *title;
2703 title = qstyleoption_cast<const QStyleOptionTitleBar*>(option);
2704 if (!title) break;
2706 const int wfw = 3; // window frame width
2707 const int button = h - 2*wfw;
2708 const int delta = button + fw;
2709 int offset = 0;
2711 bool minimized = title->titleBarState & Qt::WindowMinimized;
2712 bool maximized = title->titleBarState & Qt::WindowMaximized;
2714 switch (subcontrol) {
2715 case SC_TitleBarLabel:
2716 rect = ctlrect;
2717 if (title->titleBarFlags
2718 & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
2719 if (title->titleBarFlags & Qt::WindowSystemMenuHint)
2720 rect.adjust(delta, 0, 0, 0);
2721 if (title->titleBarFlags & Qt::WindowMinimizeButtonHint)
2722 rect.adjust(0, 0, -delta, 0);
2723 if (title->titleBarFlags & Qt::WindowMaximizeButtonHint)
2724 rect.adjust(0, 0, -delta, 0);
2725 if (title->titleBarFlags & Qt::WindowContextHelpButtonHint)
2726 rect.adjust(0, 0, -delta, 0);
2727 rect.adjust(wfw, wfw, -wfw, -wfw);
2729 break;
2731 // right side buttons all fall through
2732 case SC_TitleBarContextHelpButton:
2733 if (title->titleBarFlags & Qt::WindowContextHelpButtonHint)
2734 offset += delta;
2736 case SC_TitleBarMinButton:
2737 if (!minimized &&
2738 (title->titleBarFlags & Qt::WindowMinimizeButtonHint))
2739 offset += delta;
2740 else if (subcontrol == SC_TitleBarMinButton)
2741 break;
2743 case SC_TitleBarNormalButton:
2744 if (minimized &&
2745 (title->titleBarFlags & Qt::WindowMinimizeButtonHint))
2746 offset += delta;
2747 else if (maximized &&
2748 (title->titleBarFlags & Qt::WindowMaximizeButtonHint))
2749 offset += delta;
2750 else if (subcontrol == SC_TitleBarNormalButton)
2751 break;
2753 case SC_TitleBarMaxButton:
2754 if (!maximized &&
2755 (title->titleBarFlags & Qt::WindowMaximizeButtonHint))
2756 offset += delta;
2757 else if (subcontrol == SC_TitleBarMaxButton)
2758 break;
2760 case SC_TitleBarCloseButton:
2761 if (title->titleBarFlags & Qt::WindowSystemMenuHint)
2762 offset += delta;
2763 else if (subcontrol == SC_TitleBarCloseButton)
2764 break;
2765 rect.setRect(x2 - offset, y + wfw, button, button);
2766 break;
2768 // left side buttons
2769 case SC_TitleBarSysMenu:
2770 if (title->titleBarFlags & Qt::WindowSystemMenuHint) {
2771 rect.setRect(x + wfw, y + wfw, button, button);
2773 break;
2775 default:
2776 break;
2779 rect = visualRect(title->direction, ctlrect, rect);
2780 break;
2783 default:
2784 rect = QWindowsStyle::subControlRect(control, option,
2785 subcontrol, widget);
2788 return rect;
2792 //////////////////////////////////////////////////////////////////////////////
2793 // hitTestComplexControl()
2794 // -----------------------
2795 // Return subcontrol of position
2797 QStyle::SubControl PhaseStyle::hitTestComplexControl(ComplexControl control,
2798 const QStyleOptionComplex *option,
2799 const QPoint &position,
2800 const QWidget *widget) const
2802 SubControl subcontrol = SC_None;
2803 QRect rect;
2805 switch (control) {
2806 case CC_ScrollBar: {
2807 const QStyleOptionSlider *sb;
2808 sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
2809 if (!sb) break;
2811 // these cases are order dependent
2812 rect = subControlRect(control, sb, SC_ScrollBarSlider, widget);
2813 if (rect.contains(position)) {
2814 subcontrol = SC_ScrollBarSlider;
2815 break;
2818 rect = subControlRect(control, sb, SC_ScrollBarAddPage, widget);
2819 if (rect.contains(position)) {
2820 subcontrol = SC_ScrollBarAddPage;
2821 break;
2824 rect = subControlRect(control, sb, SC_ScrollBarSubPage, widget);
2825 if (rect.contains(position)) {
2826 subcontrol = SC_ScrollBarSubPage;
2827 break;
2830 rect = subControlRect(control, sb, SC_ScrollBarAddLine, widget);
2831 if (rect.contains(position)) {
2832 subcontrol = SC_ScrollBarAddLine;
2833 break;
2836 rect = subControlRect(control, sb, SC_ScrollBarSubLine, widget);
2837 if (rect.contains(position)) {
2838 subcontrol = SC_ScrollBarSubLine;
2839 break;
2842 break;
2845 default:
2846 subcontrol = QWindowsStyle::hitTestComplexControl(control, option,
2847 position, widget);
2848 break;
2851 return subcontrol;
2854 //////////////////////////////////////////////////////////////////////////////
2855 // sizeFromContents()
2856 // ------------------
2857 // Return size of the element based on content
2859 QSize PhaseStyle::sizeFromContents(ContentsType contentstype,
2860 const QStyleOption *option,
2861 const QSize &contentssize,
2862 const QWidget *widget) const
2864 switch (contentstype) {
2865 case CT_PushButton: {
2866 const QStyleOptionButton *button;
2867 button = qstyleoption_cast<const QStyleOptionButton *>(option);
2868 QSize size = contentssize;
2869 if (button) {
2870 int bm = pixelMetric(PM_ButtonMargin, button, widget);
2871 int fw = pixelMetric(PM_DefaultFrameWidth, button, widget) * 2;
2872 size.rwidth() += bm + fw;
2873 size.rheight() += bm + fw;
2875 if (button->text.isEmpty()) {
2876 size = size.expandedTo(QSize(23, 23));
2877 } else {
2878 size = size.expandedTo(QSize(75, 23));
2881 if (button->features & QStyleOptionButton::AutoDefaultButton) {
2882 int dbi = pixelMetric(PM_ButtonDefaultIndicator,
2883 button,
2884 widget);
2885 size.rwidth() += dbi*2;
2886 // Note: don't expand height
2890 return size;
2893 default:
2894 return QWindowsStyle::sizeFromContents(contentstype,
2895 option,
2896 contentssize,
2897 widget);
2900 return QSize();
2903 //////////////////////////////////////////////////////////////////////////////
2904 // Miscellaneous stuff //
2905 //////////////////////////////////////////////////////////////////////////////
2907 //////////////////////////////////////////////////////////////////////////////
2908 // styleHint()
2909 // -----------
2910 // "feel" hints for the GUI
2912 int PhaseStyle::styleHint(StyleHint hint,
2913 const QStyleOption *option,
2914 const QWidget *widget,
2915 QStyleHintReturn *data) const
2917 switch (hint) {
2918 case SH_Menu_SpaceActivatesItem:
2919 case SH_TitleBar_NoBorder:
2920 case SH_ToolTipLabel_Opacity:
2921 return 1;
2923 case SH_MainWindow_SpaceBelowMenuBar:
2924 return 0;
2926 case SH_UnderlineShortcut:
2927 if (QApplication::keyboardModifiers() & Qt::AltModifier) {
2928 return 1;
2930 return 0;
2932 case SH_DialogButtonLayout:
2933 return QDialogButtonBox::KdeLayout;
2935 // TODO: investigate other hints, including:
2936 // SH_ItemView_ShowDecorationSelected
2937 // SH_ScrollBar_MiddleClickAbsolutePosition
2938 // SH_ToolBox_SelectedPageTitleBold
2939 // SH_ScrollView_FrameOnlyAroundContents
2941 default:
2942 return QWindowsStyle::styleHint(hint, option, widget, data);
2946 //////////////////////////////////////////////////////////////////////////////
2947 // eventFilter()
2948 // -------------
2949 // Handle events for animating progress bars
2951 bool PhaseStyle::eventFilter(QObject *object, QEvent *event)
2953 if (!object->isWidgetType())
2954 return QObject::eventFilter(object, event);
2956 switch (event->type()) {
2957 case QEvent::KeyRelease:
2958 case QEvent::KeyPress:
2959 if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Alt) {
2960 // find top level window
2961 QWidget *widget = qobject_cast<QWidget*>(object);
2962 widget = widget->window();
2963 if (widget->parentWidget()) {
2964 widget = widget->parentWidget()->window();
2967 // update all visible enabled children widgets
2968 QList<QWidget*> wlist = qFindChildren<QWidget *>(widget);
2969 for (int n=0 ; n<wlist.size(); n++) {
2970 if (wlist[n]->isEnabled() && wlist[n]->isVisible()) {
2971 wlist[n]->update();
2975 break;
2977 case QEvent::StyleChange:
2978 case QEvent::Show:
2979 if (QProgressBar *bar = qobject_cast<QProgressBar*>(object)) {
2980 bars_ << bar;
2981 if (bars_.size() == 1) {
2982 timerid_ = startTimer(25);
2985 break;
2987 case QEvent::Destroy:
2988 bars_.removeAll(reinterpret_cast<QProgressBar*>(object));
2989 break;
2991 case QEvent::Hide:
2992 if (QProgressBar *bar = qobject_cast<QProgressBar*>(object)) {
2993 bars_.removeAll(bar);
2994 if (bars_.isEmpty() && timerid_) {
2995 killTimer(timerid_);
2996 timerid_ = 0;
2999 default:
3000 break;
3003 return QWindowsStyle::eventFilter(object, event);
3006 //////////////////////////////////////////////////////////////////////////////
3007 // timerEvent()
3008 // ------------
3009 // Internal timer fired
3011 void PhaseStyle::timerEvent(QTimerEvent *event)
3013 if (event->timerId() == timerid_) {
3014 foreach (QProgressBar *bar, bars_) {
3015 if ((bar->minimum() == 0 && bar->maximum() == 0)) {
3016 bar->setValue(bar->value()+1);
3017 bar->update();
3021 event->ignore();
3024 //////////////////////////////////////////////////////////////////////////////
3025 // Plugin stuff //
3026 //////////////////////////////////////////////////////////////////////////////
3028 class PhaseStylePlugin : public QStylePlugin
3030 public:
3031 PhaseStylePlugin() { ; }
3032 QStringList keys() const {
3033 return QStringList() << "Phase";
3035 QStyle *create(const QString &key) {
3036 if (key.toLower() == "phase") {
3037 return new PhaseStyle();
3039 return 0;
3043 Q_EXPORT_PLUGIN(PhaseStylePlugin)