Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfusionstyle.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qfusionstyle_p.h"
5#include "qfusionstyle_p_p.h"
6
7#if QT_CONFIG(style_fusion) || defined(QT_PLUGIN)
8#include "qcommonstyle_p.h"
9#if QT_CONFIG(combobox)
10#include <qcombobox.h>
11#endif
12#if QT_CONFIG(pushbutton)
13#include <qpushbutton.h>
14#endif
15#if QT_CONFIG(abstractbutton)
16#include <qabstractbutton.h>
17#endif
18#include <qpainter.h>
19#include <qpainterpath.h>
20#include <qdir.h>
21#include <qstyleoption.h>
22#include <qapplication.h>
23#if QT_CONFIG(mainwindow)
24#include <qmainwindow.h>
25#endif
26#include <qfont.h>
27#if QT_CONFIG(groupbox)
28#include <qgroupbox.h>
29#endif
30#include <qpixmapcache.h>
31#if QT_CONFIG(scrollbar)
32#include <qscrollbar.h>
33#endif
34#if QT_CONFIG(spinbox)
35#include <qspinbox.h>
36#endif
37#if QT_CONFIG(abstractslider)
38#include <qabstractslider.h>
39#endif
40#if QT_CONFIG(slider)
41#include <qslider.h>
42#endif
43#if QT_CONFIG(splitter)
44#include <qsplitter.h>
45#endif
46#if QT_CONFIG(progressbar)
47#include <qprogressbar.h>
48#endif
49#if QT_CONFIG(wizard)
50#include <qwizard.h>
51#endif
52#include <qdrawutil.h>
53#include <private/qstylehelper_p.h>
54#include <private/qdrawhelper_p.h>
55#include <private/qapplication_p.h>
56#include <private/qwidget_p.h>
57
59
60using namespace Qt::StringLiterals;
61using namespace QStyleHelper;
62
63enum Direction {
64 TopDown,
65 FromLeft,
66 BottomUp,
67 FromRight
68};
69
70// from windows style
71static const int windowsItemFrame = 2; // menu item frame width
72static const int windowsItemVMargin = 8; // menu item ver text margin
73
74static const int groupBoxBottomMargin = 0; // space below the groupbox
75static const int groupBoxTopMargin = 3;
76
77#if QT_CONFIG(imageformat_xpm)
78static const char * const qt_titlebar_context_help[] = {
79 "10 10 3 1",
80 " c None",
81 "# c #000000",
82 "+ c #444444",
83 " +####+ ",
84 " ### ### ",
85 " ## ## ",
86 " +##+ ",
87 " +## ",
88 " ## ",
89 " ## ",
90 " ",
91 " ## ",
92 " ## "};
93#endif // QT_CONFIG(imageformat_xpm)
94
95static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
96{
97 const int maxFactor = 100;
98 QColor tmp = colorA;
99 tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
100 tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
101 tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
102 return tmp;
103}
104
105// The default button and handle gradient
106static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown)
107{
108 int x = rect.center().x();
109 int y = rect.center().y();
110 QLinearGradient gradient;
111 switch (direction) {
112 case FromLeft:
113 gradient = QLinearGradient(rect.left(), y, rect.right(), y);
114 break;
115 case FromRight:
116 gradient = QLinearGradient(rect.right(), y, rect.left(), y);
117 break;
118 case BottomUp:
119 gradient = QLinearGradient(x, rect.bottom(), x, rect.top());
120 break;
121 case TopDown:
122 default:
123 gradient = QLinearGradient(x, rect.top(), x, rect.bottom());
124 break;
125 }
126 if (baseColor.gradient())
127 gradient.setStops(baseColor.gradient()->stops());
128 else {
129 QColor gradientStartColor = baseColor.color().lighter(124);
130 QColor gradientStopColor = baseColor.color().lighter(102);
131 gradient.setColorAt(0, gradientStartColor);
132 gradient.setColorAt(1, gradientStopColor);
133 // Uncomment for adding shiny shading
134 // QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55);
135 // QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45);
136 // gradient.setColorAt(0.5, midColor1);
137 // gradient.setColorAt(0.501, midColor2);
138 }
139 return gradient;
140}
141
142static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QStyleOption *option, const QRect &rect, const QColor &color)
143{
144 if (rect.isEmpty())
145 return;
146
149 const int arrowWidth = int(QStyleHelper::dpiScaled(14, dpi));
150 const int arrowHeight = int(QStyleHelper::dpiScaled(8, dpi));
151
152 const int arrowMax = qMin(arrowHeight, arrowWidth);
153 const int rectMax = qMin(rect.height(), rect.width());
154 const int size = qMin(arrowMax, rectMax);
155
156 QPixmap cachePixmap;
157 const QString cacheKey = QStyleHelper::uniqueName("fusion-arrow"_L1
158 % HexString<uint>(type)
159 % HexString<uint>(color.rgba()),
160 option, rect.size(), dpr);
161 if (!QPixmapCache::find(cacheKey, &cachePixmap)) {
162 cachePixmap = styleCachePixmap(rect.size(), dpr);
163 QPainter cachePainter(&cachePixmap);
164
165 QRectF arrowRect;
166 arrowRect.setWidth(size);
167 arrowRect.setHeight(arrowHeight * size / arrowWidth);
169 arrowRect = arrowRect.transposed();
170 arrowRect.moveTo((rect.width() - arrowRect.width()) / 2.0,
171 (rect.height() - arrowRect.height()) / 2.0);
172
173 std::array<QPointF, 3> triangle;
174 switch (type) {
175 case Qt::DownArrow:
176 triangle = {arrowRect.topLeft(), arrowRect.topRight(), QPointF(arrowRect.center().x(), arrowRect.bottom())};
177 break;
178 case Qt::RightArrow:
179 triangle = {arrowRect.topLeft(), arrowRect.bottomLeft(), QPointF(arrowRect.right(), arrowRect.center().y())};
180 break;
181 case Qt::LeftArrow:
182 triangle = {arrowRect.topRight(), arrowRect.bottomRight(), QPointF(arrowRect.left(), arrowRect.center().y())};
183 break;
184 default:
185 triangle = {arrowRect.bottomLeft(), arrowRect.bottomRight(), QPointF(arrowRect.center().x(), arrowRect.top())};
186 break;
187 }
188
189 cachePainter.setPen(Qt::NoPen);
190 cachePainter.setBrush(color);
191 cachePainter.setRenderHint(QPainter::Antialiasing);
192 cachePainter.drawPolygon(triangle.data(), int(triangle.size()));
193
194 QPixmapCache::insert(cacheKey, cachePixmap);
195 }
196
197 painter->drawPixmap(rect, cachePixmap);
198}
199
200static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
201{
202 QColor dark;
203 dark.setHsv(option->palette.button().color().hue(),
204 qMin(255, (int)(option->palette.button().color().saturation())),
205 qMin(255, (int)(option->palette.button().color().value()*0.7)));
206
207 QColor highlight = option->palette.highlight().color();
208
209 bool active = (option->titleBarState & QStyle::State_Active);
210 QColor titleBarHighlight(255, 255, 255, 60);
211
212 if (sunken)
213 painter->fillRect(tmp.adjusted(1, 1, -1, -1), option->palette.highlight().color().darker(120));
214 else if (hover)
215 painter->fillRect(tmp.adjusted(1, 1, -1, -1), QColor(255, 255, 255, 20));
216
217 QColor mdiButtonGradientStartColor;
218 QColor mdiButtonGradientStopColor;
219
220 mdiButtonGradientStartColor = QColor(0, 0, 0, 40);
221 mdiButtonGradientStopColor = QColor(255, 255, 255, 60);
222
223 if (sunken)
224 titleBarHighlight = highlight.darker(130);
225
226 QLinearGradient gradient(tmp.center().x(), tmp.top(), tmp.center().x(), tmp.bottom());
227 gradient.setColorAt(0, mdiButtonGradientStartColor);
228 gradient.setColorAt(1, mdiButtonGradientStopColor);
229 QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110));
230
231 painter->setPen(QPen(mdiButtonBorderColor));
232 const QLine lines[4] = {
233 QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
234 QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
235 QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
236 QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2)
237 };
238 painter->drawLines(lines, 4);
239 const QPoint points[4] = {
240 QPoint(tmp.left() + 1, tmp.top() + 1),
241 QPoint(tmp.right() - 1, tmp.top() + 1),
242 QPoint(tmp.left() + 1, tmp.bottom() - 1),
243 QPoint(tmp.right() - 1, tmp.bottom() - 1)
244 };
246
247 painter->setPen(titleBarHighlight);
248 painter->drawLine(tmp.left() + 2, tmp.top() + 1, tmp.right() - 2, tmp.top() + 1);
249 painter->drawLine(tmp.left() + 1, tmp.top() + 2, tmp.left() + 1, tmp.bottom() - 2);
250
251 painter->setPen(QPen(gradient, 1));
252 painter->drawLine(tmp.right() + 1, tmp.top() + 2, tmp.right() + 1, tmp.bottom() - 2);
253 painter->drawPoint(tmp.right() , tmp.top() + 1);
254
255 painter->drawLine(tmp.left() + 2, tmp.bottom() + 1, tmp.right() - 2, tmp.bottom() + 1);
256 painter->drawPoint(tmp.left() + 1, tmp.bottom());
257 painter->drawPoint(tmp.right() - 1, tmp.bottom());
258 painter->drawPoint(tmp.right() , tmp.bottom() - 1);
259}
260
261/*
262 \internal
263*/
264QFusionStylePrivate::QFusionStylePrivate()
265{
266 animationFps = 60;
267}
268
285QFusionStyle::QFusionStyle() : QCommonStyle(*new QFusionStylePrivate)
286{
287 setObjectName("Fusion"_L1);
288}
289
295QFusionStyle::QFusionStyle(QFusionStylePrivate &dd) : QCommonStyle(dd)
296{
297}
298
302QFusionStyle::~QFusionStyle()
303{
304}
305
309void QFusionStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
310 bool enabled, const QString& text, QPalette::ColorRole textRole) const
311{
313 if (text.isEmpty())
314 return;
315
316 QPen savedPen = painter->pen();
317 if (textRole != QPalette::NoRole)
318 painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
320 painter->setPen(savedPen);
321}
322
323
327void QFusionStyle::drawPrimitive(PrimitiveElement elem,
328 const QStyleOption *option,
329 QPainter *painter, const QWidget *widget) const
330{
332 Q_D (const QFusionStyle);
333
334 QRect rect = option->rect;
335 int state = option->state;
336
337 const QColor outline = d->outline(option->palette);
338 const QColor highlightedOutline = d->highlightedOutline(option->palette);
339
340 const QColor tabFrameColor = d->tabFrameColor(option->palette);
341
342 switch (elem) {
343
344#if QT_CONFIG(groupbox)
345 // No frame drawn
346 case PE_FrameGroupBox:
347 {
348 QPixmap pixmap(":/qt-project.org/styles/commonstyle/images/fusion_groupbox.png"_L1);
349 qDrawBorderPixmap(painter, option->rect, QMargins(6, 6, 6, 6), pixmap);
350 break;
351 }
352#endif // QT_CONFIG(groupbox)
353 case PE_IndicatorBranch: {
354 if (!(option->state & State_Children))
355 break;
356 if (option->state & State_Open)
357 drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
358 else {
359 const bool reverse = (option->direction == Qt::RightToLeft);
360 drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget);
361 }
362 break;
363 }
364#if QT_CONFIG(tabbar)
365 case PE_FrameTabBarBase:
366 if (const QStyleOptionTabBarBase *tbb
367 = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
368 painter->save();
369 painter->setPen(QPen(outline.lighter(110)));
370 switch (tbb->shape) {
372 QRegion region(tbb->rect);
373 region -= tbb->selectedTabRect;
374 painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
375 painter->setClipRegion(region);
376 painter->setPen(option->palette.light().color());
377 painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1), tbb->rect.topRight() + QPoint(0, 1));
378 }
379 break;
381 painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
382 break;
384 painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
385 tbb->rect.right(), tbb->rect.bottom());
386 break;
388 painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
389 break;
394 painter->restore();
396 return;
397 }
398 painter->restore();
399 }
400 return;
401#endif // QT_CONFIG(tabbar)
402 case PE_PanelScrollAreaCorner: {
403 painter->save();
404 QColor alphaOutline = outline;
405 alphaOutline.setAlpha(180);
406 painter->setPen(alphaOutline);
407 painter->setBrush(option->palette.brush(QPalette::Window));
408 painter->drawRect(option->rect);
409 painter->restore();
410 } break;
411 case PE_IndicatorArrowUp:
412 case PE_IndicatorArrowDown:
413 case PE_IndicatorArrowRight:
414 case PE_IndicatorArrowLeft:
415 {
416 if (option->rect.width() <= 1 || option->rect.height() <= 1)
417 break;
418 QColor arrowColor = option->palette.windowText().color();
419 arrowColor.setAlpha(160);
421 switch (elem) {
422 case PE_IndicatorArrowDown:
423 arrow = Qt::DownArrow;
424 break;
425 case PE_IndicatorArrowRight:
426 arrow = Qt::RightArrow;
427 break;
428 case PE_IndicatorArrowLeft:
429 arrow = Qt::LeftArrow;
430 break;
431 default:
432 break;
433 }
434 qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor);
435 }
436 break;
437 case PE_IndicatorItemViewItemCheck:
438 {
440 button.QStyleOption::operator=(*option);
441 button.state &= ~State_MouseOver;
442 proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
443 }
444 return;
445 case PE_IndicatorHeaderArrow:
446 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
447 QRect r = header->rect;
448 QColor arrowColor = header->palette.windowText().color();
449 arrowColor.setAlpha(180);
450 QPoint offset = QPoint(0, -2);
451
452#if defined(Q_OS_LINUX)
453 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
454 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
455 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
456 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
457 }
458#else
459 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
460 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
461 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
462 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
463 }
464#endif
465 }
466 break;
467 case PE_IndicatorButtonDropDown:
468 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
469 break;
470
471 case PE_IndicatorToolBarSeparator:
472 {
473 QRect rect = option->rect;
474 const int margin = 6;
475 if (option->state & State_Horizontal) {
476 const int offset = rect.width()/2;
477 painter->setPen(QPen(option->palette.window().color().darker(110)));
478 painter->drawLine(rect.bottomLeft().x() + offset,
479 rect.bottomLeft().y() - margin,
480 rect.topLeft().x() + offset,
481 rect.topLeft().y() + margin);
482 painter->setPen(QPen(option->palette.window().color().lighter(110)));
483 painter->drawLine(rect.bottomLeft().x() + offset + 1,
484 rect.bottomLeft().y() - margin,
485 rect.topLeft().x() + offset + 1,
486 rect.topLeft().y() + margin);
487 } else { //Draw vertical separator
488 const int offset = rect.height()/2;
489 painter->setPen(QPen(option->palette.window().color().darker(110)));
490 painter->drawLine(rect.topLeft().x() + margin ,
491 rect.topLeft().y() + offset,
492 rect.topRight().x() - margin,
493 rect.topRight().y() + offset);
494 painter->setPen(QPen(option->palette.window().color().lighter(110)));
495 painter->drawLine(rect.topLeft().x() + margin ,
496 rect.topLeft().y() + offset + 1,
497 rect.topRight().x() - margin,
498 rect.topRight().y() + offset + 1);
499 }
500 }
501 break;
502 case PE_Frame: {
503 if (widget && widget->inherits("QComboBoxPrivateContainer")){
505 copy.state |= State_Raised;
506 proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
507 break;
508 }
509 painter->save();
510 QPen thePen(outline.lighter(108));
511 thePen.setCosmetic(false);
512 painter->setPen(thePen);
513 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
514 painter->restore(); }
515 break;
516 case PE_FrameMenu:
517 painter->save();
518 {
519 painter->setPen(QPen(outline));
520 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
521 QColor frameLight = option->palette.window().color().lighter(160);
522 QColor frameShadow = option->palette.window().color().darker(110);
523
524 //paint beveleffect
525 QRect frame = option->rect.adjusted(1, 1, -1, -1);
526 painter->setPen(frameLight);
527 painter->drawLine(frame.topLeft(), frame.bottomLeft());
528 painter->drawLine(frame.topLeft(), frame.topRight());
529
530 painter->setPen(frameShadow);
531 painter->drawLine(frame.topRight(), frame.bottomRight());
532 painter->drawLine(frame.bottomLeft(), frame.bottomRight());
533 }
534 painter->restore();
535 break;
536 case PE_FrameDockWidget:
537
538 painter->save();
539 {
540 QColor softshadow = option->palette.window().color().darker(120);
541
542 QRect rect= option->rect;
543 painter->setPen(softshadow);
544 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
545 painter->setPen(QPen(option->palette.light(), 1));
546 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
547 painter->setPen(QPen(option->palette.window().color().darker(120)));
548 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
549 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
550
551 }
552 painter->restore();
553 break;
554 case PE_PanelButtonTool:
555 painter->save();
556 if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) {
557 if (widget && widget->inherits("QDockWidgetTitleButton")) {
558 if (option->state & State_MouseOver)
559 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
560 } else {
561 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
562 }
563 }
564 painter->restore();
565 break;
566 case PE_IndicatorDockWidgetResizeHandle:
567 {
568 QStyleOption dockWidgetHandle = *option;
569 bool horizontal = option->state & State_Horizontal;
570 dockWidgetHandle.state.setFlag(State_Horizontal, !horizontal);
571 proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
572 }
573 break;
574 case PE_FrameWindow:
575 painter->save();
576 {
577 QRect rect= option->rect;
578 painter->setPen(QPen(outline.darker(150)));
579 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
580 painter->setPen(QPen(option->palette.light(), 1));
581 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
582 QPoint(rect.left() + 1, rect.bottom() - 1));
583 painter->setPen(QPen(option->palette.window().color().darker(120)));
584 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
585 QPoint(rect.right() - 2, rect.bottom() - 1));
586 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
587 QPoint(rect.right() - 1, rect.bottom() - 1));
588 }
589 painter->restore();
590 break;
591 case PE_FrameLineEdit:
592 {
593 QRect r = rect;
594 bool hasFocus = option->state & State_HasFocus;
595
596 painter->save();
597
599 // ### highdpi painter bug.
600 painter->translate(0.5, 0.5);
601
602 // Draw Outline
603 painter->setPen( QPen(hasFocus ? highlightedOutline : outline));
604 painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
605
606 if (hasFocus) {
607 QColor softHighlight = highlightedOutline;
608 softHighlight.setAlpha(40);
609 painter->setPen(softHighlight);
610 painter->drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
611 }
612 // Draw inner shadow
613 painter->setPen(d->topShadow());
614 painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
615
616 painter->restore();
617
618 }
619 break;
620 case PE_IndicatorCheckBox:
621 painter->save();
622 if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) {
624 painter->translate(0.5, 0.5);
625 rect = rect.adjusted(0, 0, -1, -1);
626
627 QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
629
630 // Gradient fill
631 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
632 gradient.setColorAt(0, (state & State_Sunken) ? pressedColor : option->palette.base().color().darker(115));
633 gradient.setColorAt(0.15, (state & State_Sunken) ? pressedColor : option->palette.base().color());
634 gradient.setColorAt(1, (state & State_Sunken) ? pressedColor : option->palette.base().color());
635
636 painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient);
637 painter->setPen(QPen(outline.lighter(110)));
638
639 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
640 painter->setPen(QPen(highlightedOutline));
642
643 QColor checkMarkColor = option->palette.text().color().darker(120);
644 const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding
645
646 if (checkbox->state & State_NoChange) {
647 gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
648 checkMarkColor.setAlpha(80);
649 gradient.setColorAt(0, checkMarkColor);
650 checkMarkColor.setAlpha(140);
651 gradient.setColorAt(1, checkMarkColor);
652 checkMarkColor.setAlpha(180);
653 painter->setPen(QPen(checkMarkColor, 1));
654 painter->setBrush(gradient);
655 painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
656
657 } else if (checkbox->state & State_On) {
659 qreal penWidth = QStyleHelper::dpiScaled(1.5, dpi);
660 penWidth = qMax<qreal>(penWidth, 0.13 * rect.height());
661 penWidth = qMin<qreal>(penWidth, 0.20 * rect.height());
662 QPen checkPen = QPen(checkMarkColor, penWidth);
663 checkMarkColor.setAlpha(210);
664 painter->translate(dpiScaled(-0.8, dpi), dpiScaled(0.5, dpi));
665 painter->setPen(checkPen);
667
668 // Draw checkmark
670 const qreal rectHeight = rect.height(); // assuming height equals width
671 path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47);
672 path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding);
673 path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding);
674 painter->drawPath(path.translated(rect.topLeft()));
675 }
676 }
677 painter->restore();
678 break;
679 case PE_IndicatorRadioButton:
680 painter->save();
681 {
682 QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
683 painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color());
685 QPainterPath circle;
686 const QPointF circleCenter = rect.center() + QPoint(1, 1);
687 const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1;
688 circle.addEllipse(circleCenter, outlineRadius, outlineRadius);
689 painter->setPen(QPen(option->palette.window().color().darker(150)));
690 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
691 painter->setPen(QPen(highlightedOutline));
692 painter->drawPath(circle);
693
694 if (state & (State_On )) {
695 circle = QPainterPath();
696 const qreal checkmarkRadius = outlineRadius / 2.32;
697 circle.addEllipse(circleCenter, checkmarkRadius, checkmarkRadius);
698 QColor checkMarkColor = option->palette.text().color().darker(120);
699 checkMarkColor.setAlpha(200);
700 painter->setPen(checkMarkColor);
701 checkMarkColor.setAlpha(180);
702 painter->setBrush(checkMarkColor);
703 painter->drawPath(circle);
704 }
705 }
706 painter->restore();
707 break;
708 case PE_IndicatorToolBarHandle:
709 {
710 //draw grips
711 if (option->state & State_Horizontal) {
712 for (int i = -3 ; i < 2 ; i += 3) {
713 for (int j = -8 ; j < 10 ; j += 3) {
714 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
715 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
716 }
717 }
718 } else { //vertical toolbar
719 for (int i = -6 ; i < 12 ; i += 3) {
720 for (int j = -3 ; j < 2 ; j += 3) {
721 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
722 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
723 }
724 }
725 }
726 break;
727 }
728 case PE_FrameDefaultButton:
729 break;
730 case PE_FrameFocusRect:
731 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
732 //### check for d->alt_down
733 if (!(fropt->state & State_KeyboardFocusChange))
734 return;
735 QRect rect = option->rect;
736
737 painter->save();
739 painter->translate(0.5, 0.5);
740 QColor fillcolor = highlightedOutline;
741 fillcolor.setAlpha(80);
742 painter->setPen(fillcolor.darker(120));
743 fillcolor.setAlpha(30);
744 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
745 gradient.setColorAt(0, fillcolor.lighter(160));
746 gradient.setColorAt(1, fillcolor);
747 painter->setBrush(gradient);
748 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
749 painter->restore();
750 }
751 break;
752 case PE_PanelButtonCommand:
753 {
754 bool isDefault = false;
755 bool isFlat = false;
756 bool isDown = (option->state & State_Sunken) || (option->state & State_On);
757 QRect r;
758
759 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) {
760 isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled);
761 isFlat = (button->features & QStyleOptionButton::Flat);
762 }
763
764 if (isFlat && !isDown) {
765 if (isDefault) {
766 r = option->rect.adjusted(0, 1, 0, -1);
768 const QLine lines[4] = {
769 QLine(QPoint(r.left() + 2, r.top()),
770 QPoint(r.right() - 2, r.top())),
771 QLine(QPoint(r.left(), r.top() + 2),
772 QPoint(r.left(), r.bottom() - 2)),
773 QLine(QPoint(r.right(), r.top() + 2),
774 QPoint(r.right(), r.bottom() - 2)),
775 QLine(QPoint(r.left() + 2, r.bottom()),
776 QPoint(r.right() - 2, r.bottom()))
777 };
778 painter->drawLines(lines, 4);
779 const QPoint points[4] = {
780 QPoint(r.right() - 1, r.bottom() - 1),
781 QPoint(r.right() - 1, r.top() + 1),
782 QPoint(r.left() + 1, r.bottom() - 1),
783 QPoint(r.left() + 1, r.top() + 1)
784 };
786 }
787 return;
788 }
789
790
791 bool isEnabled = option->state & State_Enabled;
792 bool hasFocus = (option->state & State_HasFocus && option->state & State_KeyboardFocusChange);
793 QColor buttonColor = d->buttonColor(option->palette);
794
795 QColor darkOutline = outline;
796 if (hasFocus | isDefault) {
797 darkOutline = highlightedOutline;
798 }
799
800 if (isDefault)
801 buttonColor = mergedColors(buttonColor, highlightedOutline.lighter(130), 90);
802
803 BEGIN_STYLE_PIXMAPCACHE(u"pushbutton-" + buttonColor.name(QColor::HexArgb))
804 r = rect.adjusted(0, 1, -1, 0);
805
806 p->setRenderHint(QPainter::Antialiasing, true);
807 p->translate(0.5, -0.5);
808
809 QLinearGradient gradient = qt_fusion_gradient(rect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
810 p->setPen(Qt::transparent);
811 p->setBrush(isDown ? QBrush(buttonColor.darker(110)) : gradient);
812 p->drawRoundedRect(r, 2.0, 2.0);
813 p->setBrush(Qt::NoBrush);
814
815 // Outline
816 p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline));
817 p->drawRoundedRect(r, 2.0, 2.0);
818
819 p->setPen(d->innerContrastLine());
820 p->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2.0, 2.0);
821
823 }
824 break;
825 case PE_FrameTabWidget:
826 painter->save();
827 painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
828#if QT_CONFIG(tabwidget)
829 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
830 QColor borderColor = outline.lighter(110);
831 QRect rect = option->rect.adjusted(0, 0, -1, -1);
832
833 // Shadow outline
834 if (twf->shape != QTabBar::RoundedSouth) {
835 rect.adjust(0, 0, 0, -1);
836 QColor alphaShadow(Qt::black);
837 alphaShadow.setAlpha(15);
838 painter->setPen(alphaShadow);
839 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->setPen(borderColor);
840 }
841
842 // outline
843 painter->setPen(outline);
845
846 // Inner frame highlight
847 painter->setPen(d->innerContrastLine());
848 painter->drawRect(rect.adjusted(1, 1, -1, -1));
849
850 }
851#endif // QT_CONFIG(tabwidget)
852 painter->restore();
853 break ;
854
855 case PE_FrameStatusBarItem:
856 break;
857 case PE_PanelMenu: {
858 painter->save();
859 const QBrush menuBackground = option->palette.base().color().lighter(108);
860 QColor borderColor = option->palette.window().color().darker(160);
861 qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground);
862 painter->restore();
863 }
864 break;
865
866 default:
868 break;
869 }
870}
871
875void QFusionStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
876 const QWidget *widget) const
877{
878 Q_D (const QFusionStyle);
879 QRect rect = option->rect;
880 QColor outline = d->outline(option->palette);
881 QColor highlightedOutline = d->highlightedOutline(option->palette);
882 QColor shadow = d->darkShade();
883
884 switch (element) {
885 case CE_ComboBoxLabel:
886 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
887 QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
888 painter->save();
889 painter->setClipRect(editRect);
890 if (!cb->currentIcon.isNull()) {
891 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
893 QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, painter->device()->devicePixelRatio(), mode);
894 QRect iconRect(editRect);
895 iconRect.setWidth(cb->iconSize.width() + 4);
896 iconRect = alignedRect(cb->direction,
898 iconRect.size(), editRect);
899 if (cb->editable)
900 painter->fillRect(iconRect, cb->palette.brush(QPalette::Base));
901 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
902
903 if (cb->direction == Qt::RightToLeft)
904 editRect.translate(-4 - cb->iconSize.width(), 0);
905 else
906 editRect.translate(cb->iconSize.width() + 4, 0);
907 }
908 if (!cb->currentText.isEmpty() && !cb->editable) {
909 proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
910 visualAlignment(cb->direction, cb->textAlignment),
911 cb->palette, cb->state & State_Enabled, cb->currentText,
912 cb->editable ? QPalette::Text : QPalette::ButtonText);
913 }
914 painter->restore();
915 }
916 break;
917 case CE_Splitter:
918 {
919 // Don't draw handle for single pixel splitters
920 if (option->rect.width() > 1 && option->rect.height() > 1) {
921 //draw grips
922 if (option->state & State_Horizontal) {
923 for (int j = -6 ; j< 12 ; j += 3) {
924 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 2, 2, d->lightShade());
925 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 1, 1, d->darkShade());
926 }
927 } else {
928 for (int i = -6; i< 12 ; i += 3) {
929 painter->fillRect(rect.center().x() + i, rect.center().y(), 2, 2, d->lightShade());
930 painter->fillRect(rect.center().x() + i, rect.center().y(), 1, 1, d->darkShade());
931 }
932 }
933 }
934 break;
935 }
936#if QT_CONFIG(rubberband)
937 case CE_RubberBand:
938 if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
939 QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
940 painter->save();
941 QColor penColor = highlight.darker(120);
942 penColor.setAlpha(180);
943 painter->setPen(penColor);
944 QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
945 qMin(highlight.green()/2 + 110, 255),
946 qMin(highlight.blue()/2 + 110, 255));
947 dimHighlight.setAlpha(widget && widget->isWindow() ? 255 : 80);
948 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
949 gradient.setColorAt(0, dimHighlight.lighter(120));
950 gradient.setColorAt(1, dimHighlight);
952 painter->translate(0.5, 0.5);
953 painter->setBrush(dimHighlight);
954 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
955 //when the rectangle we get is large enough, draw the inner rectangle.
956 if (option->rect.width() > 2 && option->rect.height() > 2) {
957 QColor innerLine = Qt::white;
958 innerLine.setAlpha(40);
959 painter->setPen(innerLine);
960 painter->drawRoundedRect(option->rect.adjusted(1, 1, -2, -2), 1, 1);
961 }
962 painter->restore();
963 }
964 break;
965#endif //QT_CONFIG(rubberband)
966 case CE_SizeGrip:
967 painter->save();
968 {
969 //draw grips
970 for (int i = -6; i< 12 ; i += 3) {
971 for (int j = -6 ; j< 12 ; j += 3) {
972 if ((option->direction == Qt::LeftToRight && i > -j) || (option->direction == Qt::RightToLeft && j > i) ) {
973 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
974 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
975 }
976 }
977 }
978 }
979 painter->restore();
980 break;
981#if QT_CONFIG(toolbar)
982 case CE_ToolBar:
983 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
984 // Reserve the beveled appearance only for mainwindow toolbars
985 if (widget && !(qobject_cast<const QMainWindow*> (widget->parentWidget())))
986 break;
987
988 // Draws the light line above and the dark line below menu bars and
989 // tool bars.
990 QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft());
991 if (!(option->state & State_Horizontal))
992 gradient = QLinearGradient(rect.left(), rect.center().y(),
993 rect.right(), rect.center().y());
994 gradient.setColorAt(0, option->palette.window().color().lighter(104));
995 gradient.setColorAt(1, option->palette.window().color());
996 painter->fillRect(option->rect, gradient);
997
998 QColor light = d->lightShade();
999 QColor shadow = d->darkShade();
1000
1001 QPen oldPen = painter->pen();
1002 if (toolBar->toolBarArea == Qt::TopToolBarArea) {
1003 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1004 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1005 // The end and onlyone top toolbar lines draw a double
1006 // line at the bottom to blend with the central
1007 // widget.
1008 painter->setPen(light);
1009 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1010 painter->setPen(shadow);
1011 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1012 option->rect.right(), option->rect.bottom() - 1);
1013 } else {
1014 // All others draw a single dark line at the bottom.
1015 painter->setPen(shadow);
1016 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1017 }
1018 // All top toolbar lines draw a light line at the top.
1019 painter->setPen(light);
1020 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1021 } else if (toolBar->toolBarArea == Qt::BottomToolBarArea) {
1022 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1023 || toolBar->positionOfLine == QStyleOptionToolBar::Middle) {
1024 // The end and middle bottom tool bar lines draw a dark
1025 // line at the bottom.
1026 painter->setPen(shadow);
1027 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1028 }
1029 if (toolBar->positionOfLine == QStyleOptionToolBar::Beginning
1030 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1031 // The beginning and only one tool bar lines draw a
1032 // double line at the bottom to blend with the
1033 // status bar.
1034 // ### The styleoption could contain whether the
1035 // main window has a menu bar and a status bar, and
1036 // possibly dock widgets.
1037 painter->setPen(shadow);
1038 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1039 option->rect.right(), option->rect.bottom() - 1);
1040 painter->setPen(light);
1041 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1042 }
1043 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1044 painter->setPen(shadow);
1045 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1046 painter->setPen(light);
1047 painter->drawLine(option->rect.left(), option->rect.top() + 1,
1048 option->rect.right(), option->rect.top() + 1);
1049
1050 } else {
1051 // All other bottom toolbars draw a light line at the top.
1052 painter->setPen(light);
1053 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1054 }
1055 }
1056 if (toolBar->toolBarArea == Qt::LeftToolBarArea) {
1057 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1058 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1059 // The middle and left end toolbar lines draw a light
1060 // line to the left.
1061 painter->setPen(light);
1062 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1063 }
1064 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1065 // All other left toolbar lines draw a dark line to the right
1066 painter->setPen(shadow);
1067 painter->drawLine(option->rect.right() - 1, option->rect.top(),
1068 option->rect.right() - 1, option->rect.bottom());
1069 painter->setPen(light);
1070 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1071 } else {
1072 // All other left toolbar lines draw a dark line to the right
1073 painter->setPen(shadow);
1074 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1075 }
1076 } else if (toolBar->toolBarArea == Qt::RightToolBarArea) {
1077 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1078 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1079 // Right middle and end toolbar lines draw the dark right line
1080 painter->setPen(shadow);
1081 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1082 }
1083 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1084 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1085 // The right end and single toolbar draws the dark
1086 // line on its left edge
1087 painter->setPen(shadow);
1088 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1089 // And a light line next to it
1090 painter->setPen(light);
1091 painter->drawLine(option->rect.left() + 1, option->rect.top(),
1092 option->rect.left() + 1, option->rect.bottom());
1093 } else {
1094 // Other right toolbars draw a light line on its left edge
1095 painter->setPen(light);
1096 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1097 }
1098 }
1099 painter->setPen(oldPen);
1100 }
1101 break;
1102#endif // QT_CONFIG(toolbar)
1103 case CE_DockWidgetTitle:
1104 painter->save();
1105 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
1106 bool verticalTitleBar = dwOpt->verticalTitleBar;
1107
1108 QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget);
1109 if (verticalTitleBar) {
1110 QRect rect = dwOpt->rect;
1111 QRect r = rect.transposed();
1112 titleRect = QRect(r.left() + rect.bottom()
1113 - titleRect.bottom(),
1114 r.top() + titleRect.left() - rect.left(),
1115 titleRect.height(), titleRect.width());
1116
1117 painter->translate(r.left(), r.top() + r.width());
1118 painter->rotate(-90);
1119 painter->translate(-r.left(), -r.top());
1120 }
1121
1122 if (!dwOpt->title.isEmpty()) {
1123 QString titleText
1124 = painter->fontMetrics().elidedText(dwOpt->title,
1125 Qt::ElideRight, titleRect.width());
1126 proxy()->drawItemText(painter,
1127 titleRect,
1129 dwOpt->state & State_Enabled, titleText,
1131 }
1132 }
1133 painter->restore();
1134 break;
1135 case CE_HeaderSection:
1136 painter->save();
1137 // Draws the header in tables.
1138 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1139 const QStyleOptionHeaderV2 *headerV2 = qstyleoption_cast<const QStyleOptionHeaderV2 *>(option);
1140 const bool isSectionDragTarget = headerV2 ? headerV2->isSectionDragTarget : false;
1141 const qreal dpr = painter->device()->devicePixelRatio();
1142 const QString pixmapName = QStyleHelper::uniqueName("headersection-"_L1
1143 % HexString(header->position)
1144 % HexString(header->orientation)
1145 % QLatin1Char(isSectionDragTarget ? '1' : '0'),
1146 option, option->rect.size(), dpr);
1147 QPixmap cache;
1148 if (!QPixmapCache::find(pixmapName, &cache)) {
1149 cache = styleCachePixmap(rect.size(), dpr);
1150 QRect pixmapRect(0, 0, rect.width(), rect.height());
1151 QPainter cachePainter(&cache);
1152 QColor buttonColor = d->buttonColor(option->palette);
1153 QColor gradientStartColor = buttonColor.lighter(104);
1154 QColor gradientStopColor = buttonColor.darker(102);
1155 if (isSectionDragTarget) {
1156 gradientStopColor = gradientStartColor.darker(130);
1157 gradientStartColor = gradientStartColor.darker(130);
1158 }
1159 QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft());
1160
1161 if (option->palette.window().gradient()) {
1162 gradient.setStops(option->palette.window().gradient()->stops());
1163 } else {
1164 QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 60);
1165 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
1166 gradient.setColorAt(0, gradientStartColor);
1167 gradient.setColorAt(0.5, midColor1);
1168 gradient.setColorAt(0.501, midColor2);
1169 gradient.setColorAt(0.92, gradientStopColor);
1170 gradient.setColorAt(1, gradientStopColor.darker(104));
1171 }
1172 cachePainter.fillRect(pixmapRect, gradient);
1173 cachePainter.setPen(d->innerContrastLine());
1174 cachePainter.setBrush(Qt::NoBrush);
1175 cachePainter.drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
1176 cachePainter.setPen(d->outline(option->palette));
1177 cachePainter.drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
1178
1179 if (header->orientation == Qt::Horizontal &&
1180 header->position != QStyleOptionHeader::End &&
1182 cachePainter.setPen(QColor(0, 0, 0, 40));
1183 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight() + QPoint(0, -1));
1184 cachePainter.setPen(d->innerContrastLine());
1185 cachePainter.drawLine(pixmapRect.topRight() + QPoint(-1, 0), pixmapRect.bottomRight() + QPoint(-1, -1));
1186 } else if (header->orientation == Qt::Vertical) {
1187 cachePainter.setPen(d->outline(option->palette));
1188 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
1189 }
1190 cachePainter.end();
1191 QPixmapCache::insert(pixmapName, cache);
1192 }
1193 painter->drawPixmap(rect.topLeft(), cache);
1194 }
1195 painter->restore();
1196 break;
1197 case CE_ProgressBarGroove:
1198 painter->save();
1199 {
1201 painter->translate(0.5, 0.5);
1202
1203 QColor shadowAlpha = Qt::black;
1204 shadowAlpha.setAlpha(16);
1205 painter->setPen(shadowAlpha);
1206 painter->drawLine(rect.topLeft() - QPoint(0, 1), rect.topRight() - QPoint(0, 1));
1207
1208 painter->setBrush(option->palette.base());
1209 painter->setPen(QPen(outline));
1210 painter->drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2);
1211
1212 // Inner shadow
1213 painter->setPen(d->topShadow());
1214 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
1215 QPoint(rect.right() - 1, rect.top() + 1));
1216 }
1217 painter->restore();
1218 break;
1219 case CE_ProgressBarContents:
1220 painter->save();
1222 if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1223 const auto indeterminate = (bar->minimum == 0 && bar->maximum == 0);
1224 const auto complete = bar->progress == bar->maximum;
1225 const auto vertical = !(bar->state & QStyle::State_Horizontal);
1226 const auto inverted = bar->invertedAppearance;
1227 const auto reverse = (bar->direction == Qt::RightToLeft) ^ inverted;
1228
1229 // If the orientation is vertical, we use a transform to rotate
1230 // the progress bar 90 degrees (counter)clockwise. This way we can use the
1231 // same rendering code for both orientations.
1232 if (vertical) {
1233 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1234 QTransform m;
1235 if (inverted) {
1236 m.rotate(90);
1237 m.translate(0, -rect.height());
1238 } else {
1239 m.rotate(-90);
1240 m.translate(-rect.width(), 0);
1241 }
1242 painter->setTransform(m, true);
1243 } else if (reverse) {
1245 m.translate(-rect.width(), 0);
1246 painter->setTransform(m, true);
1247 }
1248 painter->translate(0.5, 0.5);
1249
1250 const auto progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar
1251 const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum);
1252 const auto progressSteps = qint64(progress) - bar->minimum;
1253 const auto progressBarWidth = progressSteps * rect.width() / totalSteps;
1254 int width = indeterminate ? rect.width() : progressBarWidth;
1255
1256 int step = 0;
1258 QColor highlight = d->highlight(option->palette);
1259 QColor highlightedoutline = highlight.darker(140);
1260 if (qGray(outline.rgb()) > qGray(highlightedoutline.rgb()))
1261 outline = highlightedoutline;
1262
1263 if (!indeterminate)
1264 progressBar.setRect(rect.left(), rect.top(), width - 1, rect.height() - 1);
1265 else
1266 progressBar.setRect(rect.left(), rect.top(), rect.width() - 1, rect.height() - 1);
1267
1268 if (indeterminate || bar->progress > bar->minimum) {
1269
1270 painter->setPen(QPen(outline));
1271
1272 QColor highlightedGradientStartColor = highlight.lighter(120);
1273 QColor highlightedGradientStopColor = highlight;
1274 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
1275 gradient.setColorAt(0, highlightedGradientStartColor);
1276 gradient.setColorAt(1, highlightedGradientStopColor);
1277
1278 painter->setBrush(gradient);
1279
1280 painter->save();
1281 // 0.5 - half the width of a cosmetic pen (for vertical line below)
1282 if (!complete && !indeterminate)
1283 painter->setClipRect(QRectF(progressBar).adjusted(-1, -1, 0.5, 1));
1284
1286 if (!indeterminate && !complete)
1287 fillRect.setWidth(std::min(fillRect.width() + 2, rect.width() - 1)); // avoid round borders at the right end
1288 painter->drawRoundedRect(fillRect, 2, 2);
1289 painter->restore();
1290
1292 painter->setPen(QColor(255, 255, 255, 50));
1293 painter->drawRoundedRect(progressBar.adjusted(1, 1, -1, -1), 1, 1);
1294
1295 if (!indeterminate) {
1296#if QT_CONFIG(animation)
1297 (const_cast<QFusionStylePrivate*>(d))->stopAnimation(option->styleObject);
1298#endif
1299 } else {
1300 highlightedGradientStartColor.setAlpha(120);
1301 painter->setPen(QPen(highlightedGradientStartColor, 9.0));
1302 painter->setClipRect(progressBar.adjusted(1, 1, -1, -1));
1303#if QT_CONFIG(animation)
1304 if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(option->styleObject)))
1305 step = animation->animationStep() % 22;
1306 else
1307 (const_cast<QFusionStylePrivate*>(d))->startAnimation(new QProgressStyleAnimation(d->animationFps, option->styleObject));
1308#endif
1309 for (int x = progressBar.left() - rect.height(); x < rect.right() ; x += 22)
1310 painter->drawLine(x + step, progressBar.bottom() + 1,
1311 x + rect.height() + step, progressBar.top() - 2);
1312 }
1313 }
1314 if (!indeterminate && !complete) {
1315 QColor innerShadow(Qt::black);
1316 innerShadow.setAlpha(35);
1317 painter->setPen(innerShadow);
1318 painter->drawLine(progressBar.topRight() + QPoint(2, 1), progressBar.bottomRight() + QPoint(2, 0));
1319 painter->setPen(QPen(highlight.darker(140)));
1320 painter->drawLine(progressBar.topRight() + QPoint(1, 1), progressBar.bottomRight() + QPoint(1, 0));
1321 }
1322 }
1323 painter->restore();
1324 break;
1325 case CE_ProgressBarLabel:
1326 if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1327 QRect rect = bar->rect;
1328 QRect leftRect = rect;
1329 QRect rightRect = rect;
1330 QColor textColor = option->palette.text().color();
1331 QColor alternateTextColor = d->highlightedText(option->palette);
1332
1333 painter->save();
1334 const auto vertical = !(bar->state & QStyle::State_Horizontal);
1335 const auto inverted = bar->invertedAppearance;
1336 const auto reverse = (bar->direction == Qt::RightToLeft) ^ inverted;
1337 const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum);
1338 const auto progressSteps = qint64(bar->progress) - bar->minimum;
1339 const auto progressIndicatorPos = progressSteps * (vertical ? rect.height() : rect.width()) / totalSteps;
1340
1341 if (vertical) {
1342 if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.height()) {
1343 if (inverted) {
1344 leftRect.setHeight(progressIndicatorPos);
1345 rightRect.setY(progressIndicatorPos);
1346 } else {
1347 leftRect.setHeight(rect.height() - progressIndicatorPos);
1348 rightRect.setY(rect.height() - progressIndicatorPos);
1349 }
1350 }
1351 } else {
1352 if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) {
1353 if (reverse) {
1354 leftRect.setWidth(rect.width() - progressIndicatorPos);
1355 rightRect.setX(rect.width() - progressIndicatorPos);
1356 } else {
1357 leftRect.setWidth(progressIndicatorPos);
1358 rightRect.setX(progressIndicatorPos);
1359 }
1360 }
1361 }
1362
1363 const auto firstIsAlternateColor = (vertical && !inverted) || (!vertical && reverse);
1364 painter->setClipRect(rightRect);
1365 painter->setPen(firstIsAlternateColor ? alternateTextColor : textColor);
1367 painter->setPen(firstIsAlternateColor ? textColor : alternateTextColor);
1368 painter->setClipRect(leftRect);
1370
1371 painter->restore();
1372 }
1373 break;
1374 case CE_MenuBarItem:
1375 painter->save();
1376 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
1377 {
1379 item.rect = mbi->rect.adjusted(0, 1, 0, -3);
1380 QColor highlightOutline = option->palette.highlight().color().darker(125);
1381 painter->fillRect(rect, option->palette.window());
1382
1384
1385 bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
1386 bool dis = !(mbi->state & State_Enabled);
1387
1388 QRect r = option->rect;
1389 if (act) {
1390 painter->setBrush(option->palette.highlight().color());
1391 painter->setPen(QPen(highlightOutline));
1392 painter->drawRect(r.adjusted(0, 0, -1, -1));
1393
1394 // painter->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2);
1395
1396 //draw text
1399 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1401 proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
1402 } else {
1403
1404 QColor shadow = mergedColors(option->palette.window().color().darker(120),
1405 outline.lighter(140), 60);
1406 painter->setPen(QPen(shadow));
1407 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1408 }
1409 }
1410 painter->restore();
1411 break;
1412 case CE_MenuItem:
1413 painter->save();
1414 // Draws one item in a popup menu.
1415 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1416 QColor highlightOutline = highlightedOutline;
1417 QColor highlight = option->palette.highlight().color();
1418 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
1419 int w = 0;
1420 const int margin = int(QStyleHelper::dpiScaled(5, option));
1421 if (!menuItem->text.isEmpty()) {
1422 painter->setFont(menuItem->font);
1423 proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0),
1425 menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
1427 w = menuItem->fontMetrics.horizontalAdvance(menuItem->text) + margin;
1428 }
1429 painter->setPen(shadow.lighter(106));
1430 const bool reverse = menuItem->direction == Qt::RightToLeft;
1431 qreal y = menuItem->rect.center().y() + 0.5f;
1432 painter->drawLine(QPointF(menuItem->rect.left() + margin + (reverse ? 0 : w), y),
1433 QPointF(menuItem->rect.right() - margin - (reverse ? w : 0), y));
1434 painter->restore();
1435 break;
1436 }
1437 const bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
1438 if (selected) {
1439 QRect r = option->rect;
1440 painter->fillRect(r, highlight);
1441 painter->setPen(QPen(highlightOutline));
1442 painter->drawRect(QRectF(r).adjusted(0.5, 0.5, -0.5, -0.5));
1443 }
1444 const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
1445 const bool checked = menuItem->checked;
1446 const bool sunken = menuItem->state & State_Sunken;
1447 const bool enabled = menuItem->state & State_Enabled;
1448
1449 const int checkColHOffset = QFusionStylePrivate::menuItemHMargin + windowsItemFrame - 1;
1450 // icon checkbox's highlight column width
1451 int checkcol = qMax<int>(menuItem->rect.height() * 0.79,
1452 qMax<int>(menuItem->maxIconWidth, dpiScaled(21, option)));
1453 bool ignoreCheckMark = false;
1454 if (
1455#if QT_CONFIG(combobox)
1456 qobject_cast<const QComboBox*>(widget) ||
1457#endif
1458 (option->styleObject && option->styleObject->property("_q_isComboBoxPopupItem").toBool()))
1459 ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
1460
1461 if (!ignoreCheckMark || menuItem->state & (State_On | State_Off)) {
1462 // Check, using qreal and QRectF to avoid error accumulation
1463 const qreal boxMargin = dpiScaled(3.5, option);
1464 const qreal boxWidth = checkcol - 2 * boxMargin;
1465 QRect checkRect = QRectF(option->rect.left() + boxMargin + checkColHOffset,
1466 option->rect.center().y() - boxWidth/2 + 1, boxWidth,
1467 boxWidth).toRect();
1468 checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
1469 checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
1470 if (checkable) {
1471 if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
1472 // Radio button
1473 if (menuItem->state & State_On || checked || sunken) {
1476
1477 QPalette::ColorRole textRole = !enabled
1478 ? QPalette::Text :
1479 selected ? QPalette::HighlightedText
1481 painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
1482 const int adjustment = checkRect.height() * 0.3;
1483 painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment));
1484 }
1485 } else {
1486 // Check box
1487 if (menuItem->icon.isNull()) {
1489 box.QStyleOption::operator=(*option);
1490 box.rect = checkRect;
1491 if (checked || menuItem->state & State_On)
1492 box.state |= State_On;
1493 else
1494 box.state |= State_Off;
1495 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
1496 }
1497 }
1498 }
1499 } else { //ignore checkmark
1500 if (menuItem->icon.isNull())
1501 checkcol = 0;
1502 else
1503 checkcol = menuItem->maxIconWidth;
1504 }
1505
1506 // Text and icon, ripped from windows style
1507 const bool dis = !(menuItem->state & State_Enabled);
1508 const bool act = menuItem->state & State_Selected;
1509 const QStyleOption *opt = option;
1510 const QStyleOptionMenuItem *menuitem = menuItem;
1511
1512 QPainter *p = painter;
1513 QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
1514 QRect(menuitem->rect.x() + checkColHOffset, menuitem->rect.y(),
1515 checkcol, menuitem->rect.height()));
1516 if (!menuItem->icon.isNull()) {
1518 if (act && !dis)
1521
1522 int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
1523 QSize iconSize(smallIconSize, smallIconSize);
1524#if QT_CONFIG(combobox)
1525 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
1526 iconSize = combo->iconSize();
1527#endif
1528 if (checked)
1529 pixmap = menuItem->icon.pixmap(iconSize, painter->device()->devicePixelRatio(), mode, QIcon::On);
1530 else
1531 pixmap = menuItem->icon.pixmap(iconSize, painter->device()->devicePixelRatio(), mode);
1532
1533 QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize());
1534 pmr.moveCenter(vCheckRect.center());
1535 painter->setPen(menuItem->palette.text().color());
1536 if (!ignoreCheckMark && checkable && checked) {
1538 if (act) {
1539 QColor activeColor = mergedColors(option->palette.window().color(),
1540 option->palette.highlight().color());
1541 opt.palette.setBrush(QPalette::Button, activeColor);
1542 }
1543 opt.state |= State_Sunken;
1544 opt.rect = vCheckRect;
1545 proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
1546 }
1547 painter->drawPixmap(pmr.topLeft(), pixmap);
1548 }
1549 if (selected) {
1550 painter->setPen(menuItem->palette.highlightedText().color());
1551 } else {
1552 painter->setPen(menuItem->palette.text().color());
1553 }
1554 int x, y, w, h;
1555 menuitem->rect.getRect(&x, &y, &w, &h);
1556 QColor discol;
1557 if (dis) {
1558 discol = menuitem->palette.text().color();
1559 p->setPen(discol);
1560 }
1561 const int xm = checkColHOffset + checkcol + QFusionStylePrivate::menuItemHMargin;
1562 const int xpos = menuitem->rect.x() + xm;
1563
1564 const QRect textRect(xpos, y + windowsItemVMargin,
1565 w - xm - QFusionStylePrivate::menuRightBorder - menuitem->reservedShortcutWidth + 2,
1566 h - 2 * windowsItemVMargin);
1567 const QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
1568 QStringView s(menuitem->text);
1569 if (!s.isEmpty()) { // draw text
1570 p->save();
1571 const qsizetype tabIndex = s.indexOf(u'\t');
1573 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1574 text_flags |= Qt::TextHideMnemonic;
1575 text_flags |= Qt::AlignLeft;
1576 if (tabIndex >= 0) {
1577 QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
1579 QPoint(menuitem->rect.right(), textRect.bottom())));
1580 const QString textToDraw = s.mid(tabIndex + 1).toString();
1581 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
1582 p->setPen(menuitem->palette.light().color());
1583 p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1584 p->setPen(discol);
1585 }
1586 p->drawText(vShortcutRect, text_flags, textToDraw);
1587 s = s.left(tabIndex);
1588 }
1589 QFont font = menuitem->font;
1590 // font may not have any "hard" flags set. We override
1591 // the point size so that when it is resolved against the device, this font will win.
1592 // This is mainly to handle cases where someone sets the font on the window
1593 // and then the combo inherits it and passes it onward. At that point the resolve mask
1594 // is very, very weak. This makes it stonger.
1595 font.setPointSizeF(QFontInfo(menuItem->font).pointSizeF());
1596
1597 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1598 font.setBold(true);
1599
1600 p->setFont(font);
1602 const QString textToDraw = fontMetrics.elidedText(s.left(tabIndex).toString(),
1603 Qt::ElideMiddle, vTextRect.width(),
1604 text_flags);
1605 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
1606 p->setPen(menuitem->palette.light().color());
1607 p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1608 p->setPen(discol);
1609 }
1610 p->drawText(vTextRect, text_flags, textToDraw);
1611 p->restore();
1612 }
1613
1614 // Arrow
1615 if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1616 const int dim = (menuItem->rect.height() - 4) / 2;
1617 PrimitiveElement arrow;
1618 arrow = option->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1619 const int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
1620 QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
1621 QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
1622 QStyleOptionMenuItem newMI = *menuItem;
1623 newMI.rect = vSubMenuRect;
1624 newMI.state = !enabled ? State_None : State_Enabled;
1625 if (selected)
1626 newMI.palette.setColor(QPalette::WindowText,
1627 newMI.palette.highlightedText().color());
1628 proxy()->drawPrimitive(arrow, &newMI, painter, widget);
1629 }
1630 }
1631 painter->restore();
1632 break;
1633 case CE_MenuHMargin:
1634 case CE_MenuVMargin:
1635 break;
1636 case CE_MenuEmptyArea:
1637 break;
1638 case CE_PushButton:
1639 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1640 proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
1642 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
1643 proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
1644 }
1645 break;
1646 case CE_MenuBarEmptyArea:
1647 painter->save();
1648 {
1649 painter->fillRect(rect, option->palette.window());
1650 QColor shadow = mergedColors(option->palette.window().color().darker(120),
1651 outline.lighter(140), 60);
1652 painter->setPen(QPen(shadow));
1653 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1654 }
1655 painter->restore();
1656 break;
1657#if QT_CONFIG(tabbar)
1658 case CE_TabBarTabShape:
1659 painter->save();
1660 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
1661
1662 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1663 && (tab->shape == QTabBar::RoundedNorth
1664 || tab->shape == QTabBar::RoundedSouth));
1665 bool selected = tab->state & State_Selected;
1666 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1667 || (rtlHorTabs
1668 && tab->position == QStyleOptionTab::Beginning));
1669 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1670 int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
1671 rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0);
1672
1673 QRect r2(rect);
1674 int x1 = r2.left();
1675 int x2 = r2.right();
1676 int y1 = r2.top();
1677 int y2 = r2.bottom();
1678
1679 painter->setPen(d->innerContrastLine());
1680
1681 QTransform rotMatrix;
1682 bool flip = false;
1683 painter->setPen(shadow);
1684
1685 switch (tab->shape) {
1687 break;
1689 rotMatrix.rotate(180);
1690 rotMatrix.translate(0, -rect.height() + 1);
1691 rotMatrix.scale(-1, 1);
1692 painter->setTransform(rotMatrix, true);
1693 break;
1695 rotMatrix.rotate(180 + 90);
1696 rotMatrix.scale(-1, 1);
1697 flip = true;
1698 painter->setTransform(rotMatrix, true);
1699 break;
1701 rotMatrix.rotate(90);
1702 rotMatrix.translate(0, - rect.width() + 1);
1703 flip = true;
1704 painter->setTransform(rotMatrix, true);
1705 break;
1706 default:
1707 painter->restore();
1709 return;
1710 }
1711
1712 if (flip) {
1713 QRect tmp = rect;
1714 rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
1715 int temp = x1;
1716 x1 = y1;
1717 y1 = temp;
1718 temp = x2;
1719 x2 = y2;
1720 y2 = temp;
1721 }
1722
1724 painter->translate(0.5, 0.5);
1725
1726 QColor tabFrameColor = tab->features & QStyleOptionTab::HasFrame ?
1727 d->tabFrameColor(option->palette) :
1728 option->palette.window().color();
1729
1730 QLinearGradient fillGradient(rect.topLeft(), rect.bottomLeft());
1731 QLinearGradient outlineGradient(rect.topLeft(), rect.bottomLeft());
1732 QPen outlinePen = outline.lighter(110);
1733 if (selected) {
1734 fillGradient.setColorAt(0, tabFrameColor.lighter(104));
1735 // QColor highlight = option->palette.highlight().color();
1736 // if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) {
1737 // fillGradient.setColorAt(0, highlight.lighter(130));
1738 // outlineGradient.setColorAt(0, highlight.darker(130));
1739 // fillGradient.setColorAt(0.14, highlight);
1740 // outlineGradient.setColorAt(0.14, highlight.darker(130));
1741 // fillGradient.setColorAt(0.1401, tabFrameColor);
1742 // outlineGradient.setColorAt(0.1401, highlight.darker(130));
1743 // }
1744 fillGradient.setColorAt(1, tabFrameColor);
1745 outlineGradient.setColorAt(1, outline);
1746 outlinePen = QPen(outlineGradient, 1);
1747 } else {
1748 fillGradient.setColorAt(0, tabFrameColor.darker(108));
1749 fillGradient.setColorAt(0.85, tabFrameColor.darker(108));
1750 fillGradient.setColorAt(1, tabFrameColor.darker(116));
1751 }
1752
1753 QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3);
1754 painter->setPen(outlinePen);
1755 painter->save();
1756 painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3));
1757 painter->setBrush(fillGradient);
1758 painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.0, 2.0);
1760 painter->setPen(d->innerContrastLine());
1761 painter->drawRoundedRect(drawRect.adjusted(1, 1, -2, -1), 2.0, 2.0);
1762 painter->restore();
1763
1764 if (selected) {
1765 painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor);
1766 painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), d->innerContrastLine());
1767 painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), d->innerContrastLine());
1768 painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), d->innerContrastLine());
1769 }
1770 }
1771 painter->restore();
1772 break;
1773#endif //QT_CONFIG(tabbar)
1774 default:
1776 break;
1777 }
1778}
1779
1780extern QPalette qt_fusionPalette();
1781
1785QPalette QFusionStyle::standardPalette () const
1786{
1787 return qt_fusionPalette();
1788}
1789
1793void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
1794 QPainter *painter, const QWidget *widget) const
1795{
1796
1797 Q_D (const QFusionStyle);
1798
1799#if QT_CONFIG(spinbox) || QT_CONFIG(slider)
1800 QColor buttonColor = d->buttonColor(option->palette);
1801 QColor gradientStopColor = buttonColor;
1802#endif
1803#if QT_CONFIG(slider)
1804 QColor gradientStartColor = buttonColor.lighter(118);
1805#endif
1806 QColor outline = d->outline(option->palette);
1807
1808 QColor alphaCornerColor;
1809 if (widget) {
1810 // ### backgroundrole/foregroundrole should be part of the style option
1811 alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), outline);
1812 } else {
1813 alphaCornerColor = mergedColors(option->palette.window().color(), outline);
1814 }
1815
1816 switch (control) {
1817 case CC_GroupBox:
1818 painter->save();
1819 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
1820 // Draw frame
1821 QRect textRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
1822 QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
1823
1824 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
1826 frame.QStyleOption::operator=(*groupBox);
1827 frame.features = groupBox->features;
1828 frame.lineWidth = groupBox->lineWidth;
1829 frame.midLineWidth = groupBox->midLineWidth;
1830 frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
1831 painter->save();
1832 QRegion region(groupBox->rect);
1833 if (!groupBox->text.isEmpty()) {
1834 bool ltr = groupBox->direction == Qt::LeftToRight;
1835 QRect finalRect;
1836 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
1837 finalRect = checkBoxRect.united(textRect);
1838 finalRect.adjust(ltr ? -4 : -2, 0, ltr ? 2 : 4, 0);
1839 } else {
1840 finalRect = textRect;
1841 finalRect.adjust(-2, 0, 2, 0);
1842 }
1843 region -= finalRect.adjusted(0, 0, 0, 3 - textRect.height() / 2);
1844 }
1845 painter->setClipRegion(region);
1846 proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
1847 painter->restore();
1848 }
1849
1850 // Draw title
1851 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
1852 // groupBox->textColor gets the incorrect palette here
1853 painter->setPen(QPen(option->palette.windowText(), 1));
1854 int alignment = int(groupBox->textAlignment);
1855 if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
1857
1859 groupBox->palette, groupBox->state & State_Enabled, groupBox->text, QPalette::NoRole);
1860
1861 if (groupBox->state & State_HasFocus) {
1863 fropt.QStyleOption::operator=(*groupBox);
1864 fropt.rect = textRect.adjusted(-2, -1, 2, 1);
1865 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
1866 }
1867 }
1868
1869 // Draw checkbox
1870 if (groupBox->subControls & SC_GroupBoxCheckBox) {
1872 box.QStyleOption::operator=(*groupBox);
1873 box.rect = checkBoxRect;
1874 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
1875 }
1876 }
1877 painter->restore();
1878 break;
1879#if QT_CONFIG(spinbox)
1880 case CC_SpinBox:
1881 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
1882 const qreal dpr = painter->device()->devicePixelRatio();
1883 QPixmap cache;
1884 QString pixmapName = QStyleHelper::uniqueName("spinbox"_L1, spinBox, spinBox->rect.size(), dpr);
1885 if (!QPixmapCache::find(pixmapName, &cache)) {
1886
1888
1889 QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height());
1890 QRect rect = pixmapRect;
1891 QRect r = rect.adjusted(0, 1, 0, -1);
1892 QPainter cachePainter(&cache);
1893 QColor arrowColor = spinBox->palette.windowText().color();
1894 arrowColor.setAlpha(160);
1895
1896 bool isEnabled = (spinBox->state & State_Enabled);
1897 bool hover = isEnabled && (spinBox->state & State_MouseOver);
1898 bool sunken = (spinBox->state & State_Sunken);
1899 bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
1900 bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
1901 bool hasFocus = (option->state & State_HasFocus);
1902
1903 QStyleOptionSpinBox spinBoxCopy = *spinBox;
1904 spinBoxCopy.rect = pixmapRect;
1905 QRect upRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxUp, widget);
1906 QRect downRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxDown, widget);
1907
1908 if (spinBox->frame) {
1909 cachePainter.save();
1910 cachePainter.setRenderHint(QPainter::Antialiasing, true);
1911 cachePainter.translate(0.5, 0.5);
1912
1913 // Fill background
1914 cachePainter.setPen(Qt::NoPen);
1915 cachePainter.setBrush(option->palette.base());
1916 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
1917
1918 // Draw inner shadow
1919 cachePainter.setPen(d->topShadow());
1920 cachePainter.drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
1921
1922 if (!upRect.isNull()) {
1923 // Draw button gradient
1924 const QColor buttonColor = d->buttonColor(option->palette);
1925 const QRect updownRect = upRect.adjusted(0, -2, 0, downRect.height() + 2);
1926 const QLinearGradient gradient = qt_fusion_gradient(updownRect, (isEnabled && option->state & State_MouseOver )
1927 ? buttonColor : buttonColor.darker(104));
1928
1929 cachePainter.setPen(Qt::NoPen);
1930 cachePainter.setBrush(gradient);
1931
1932 cachePainter.save();
1933 cachePainter.setClipRect(updownRect);
1934 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
1935 cachePainter.setPen(QPen(d->innerContrastLine()));
1936 cachePainter.setBrush(Qt::NoBrush);
1937 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 2, 2);
1938 cachePainter.restore();
1939 }
1940
1941 if ((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) && upIsActive) {
1942 if (sunken)
1943 cachePainter.fillRect(upRect.adjusted(0, -1, 0, 0), gradientStopColor.darker(110));
1944 else if (hover)
1945 cachePainter.fillRect(upRect.adjusted(0, -1, 0, 0), d->innerContrastLine());
1946 }
1947
1948 if ((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) && downIsActive) {
1949 if (sunken)
1950 cachePainter.fillRect(downRect.adjusted(0, 0, 0, 1), gradientStopColor.darker(110));
1951 else if (hover)
1952 cachePainter.fillRect(downRect.adjusted(0, 0, 0, 1), d->innerContrastLine());
1953 }
1954
1955 cachePainter.setPen(hasFocus ? d->highlightedOutline(option->palette) : outline);
1956 cachePainter.setBrush(Qt::NoBrush);
1957 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
1958 if (hasFocus) {
1959 QColor softHighlight = option->palette.highlight().color();
1960 softHighlight.setAlpha(40);
1961 cachePainter.setPen(softHighlight);
1962 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
1963 }
1964 cachePainter.restore();
1965 }
1966
1968 // buttonSymbols == NoButtons results in 'null' rects
1969 // and a tiny rect painted in the corner.
1970 cachePainter.setPen(outline);
1971 if (spinBox->direction == Qt::RightToLeft)
1972 cachePainter.drawLine(QLineF(upRect.right(), upRect.top() - 0.5, upRect.right(), downRect.bottom() + 1.5));
1973 else
1974 cachePainter.drawLine(QLineF(upRect.left(), upRect.top() - 0.5, upRect.left(), downRect.bottom() + 1.5));
1975 }
1976
1977 if (upIsActive && sunken) {
1978 cachePainter.setPen(gradientStopColor.darker(130));
1979 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.right(), downRect.top());
1980 cachePainter.drawLine(upRect.left() + 1, upRect.top(), upRect.left() + 1, upRect.bottom());
1981 cachePainter.drawLine(upRect.left() + 1, upRect.top() - 1, upRect.right(), upRect.top() - 1);
1982 }
1983
1984 if (downIsActive && sunken) {
1985 cachePainter.setPen(gradientStopColor.darker(130));
1986 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.left() + 1, downRect.bottom() + 1);
1987 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.right(), downRect.top());
1988 cachePainter.setPen(gradientStopColor.darker(110));
1989 cachePainter.drawLine(downRect.left() + 1, downRect.bottom() + 1, downRect.right(), downRect.bottom() + 1);
1990 }
1991
1992 QColor disabledColor = mergedColors(arrowColor, option->palette.button().color());
1994 int centerX = upRect.center().x();
1995 int centerY = upRect.center().y();
1996
1997 // plus/minus
1998 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
1999 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2000 cachePainter.drawLine(centerX + 1, centerY - 2, centerX + 1, centerY + 2);
2001
2002 centerX = downRect.center().x();
2003 centerY = downRect.center().y();
2004 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
2005 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2006
2008 // arrows
2009 qt_fusion_draw_arrow(Qt::UpArrow, &cachePainter, option, upRect.adjusted(0, 0, 0, 1),
2010 (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
2011 qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downRect,
2012 (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
2013 }
2014
2015 cachePainter.end();
2016 QPixmapCache::insert(pixmapName, cache);
2017 }
2019 }
2020 break;
2021#endif // QT_CONFIG(spinbox)
2022 case CC_TitleBar:
2023 painter->save();
2024 if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
2025 const int buttonMargin = 5;
2026 bool active = (titleBar->titleBarState & State_Active);
2027 QRect fullRect = titleBar->rect;
2028 QPalette palette = option->palette;
2029 QColor highlight = option->palette.highlight().color();
2030
2031 QColor titleBarFrameBorder(active ? highlight.darker(180): outline.darker(110));
2032 QColor titleBarHighlight(active ? highlight.lighter(120): palette.window().color().lighter(120));
2033 QColor textColor(active ? 0xffffff : 0xff000000);
2034 QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
2035
2036 {
2037 // Fill title bar gradient
2038 QColor titlebarColor = QColor(active ? highlight: palette.window().color());
2039 QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
2040 option->rect.center().x(), option->rect.bottom());
2041
2042 gradient.setColorAt(0, titlebarColor.lighter(114));
2043 gradient.setColorAt(0.5, titlebarColor.lighter(102));
2044 gradient.setColorAt(0.51, titlebarColor.darker(104));
2045 gradient.setColorAt(1, titlebarColor);
2046 painter->fillRect(option->rect.adjusted(1, 1, -1, 0), gradient);
2047
2048 // Frame and rounded corners
2049 painter->setPen(titleBarFrameBorder);
2050
2051 // top outline
2052 painter->drawLine(fullRect.left() + 5, fullRect.top(), fullRect.right() - 5, fullRect.top());
2053 painter->drawLine(fullRect.left(), fullRect.top() + 4, fullRect.left(), fullRect.bottom());
2054 const QPoint points[5] = {
2055 QPoint(fullRect.left() + 4, fullRect.top() + 1),
2056 QPoint(fullRect.left() + 3, fullRect.top() + 1),
2057 QPoint(fullRect.left() + 2, fullRect.top() + 2),
2058 QPoint(fullRect.left() + 1, fullRect.top() + 3),
2059 QPoint(fullRect.left() + 1, fullRect.top() + 4)
2060 };
2062
2063 painter->drawLine(fullRect.right(), fullRect.top() + 4, fullRect.right(), fullRect.bottom());
2064 const QPoint points2[5] = {
2065 QPoint(fullRect.right() - 3, fullRect.top() + 1),
2066 QPoint(fullRect.right() - 4, fullRect.top() + 1),
2067 QPoint(fullRect.right() - 2, fullRect.top() + 2),
2068 QPoint(fullRect.right() - 1, fullRect.top() + 3),
2069 QPoint(fullRect.right() - 1, fullRect.top() + 4)
2070 };
2071 painter->drawPoints(points2, 5);
2072
2073 // draw bottomline
2074 painter->drawLine(fullRect.right(), fullRect.bottom(), fullRect.left(), fullRect.bottom());
2075
2076 // top highlight
2077 painter->setPen(titleBarHighlight);
2078 painter->drawLine(fullRect.left() + 6, fullRect.top() + 1, fullRect.right() - 6, fullRect.top() + 1);
2079 }
2080 // draw title
2081 QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
2082 painter->setPen(active? (titleBar->palette.text().color().lighter(120)) :
2083 titleBar->palette.text().color() );
2084 // Note workspace also does elliding but it does not use the correct font
2088 if (active)
2090 // min button
2091 if ((titleBar->subControls & SC_TitleBarMinButton) && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2092 !(titleBar->titleBarState& Qt::WindowMinimized)) {
2093 QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
2094 if (minButtonRect.isValid()) {
2095 bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
2096 bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
2097 qt_fusion_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
2098 QRect minButtonIconRect = minButtonRect.adjusted(buttonMargin ,buttonMargin , -buttonMargin, -buttonMargin);
2099 painter->setPen(textColor);
2100 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 3,
2101 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 3);
2102 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 4,
2103 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 4);
2104 painter->setPen(textAlphaColor);
2105 painter->drawLine(minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 3,
2106 minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 4);
2107 painter->drawLine(minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 3,
2108 minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 4);
2109 }
2110 }
2111 // max button
2112 if ((titleBar->subControls & SC_TitleBarMaxButton) && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2113 !(titleBar->titleBarState & Qt::WindowMaximized)) {
2114 QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
2115 if (maxButtonRect.isValid()) {
2116 bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
2117 bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
2118 qt_fusion_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
2119
2120 QRect maxButtonIconRect = maxButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2121
2122 painter->setPen(textColor);
2123 painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
2124 painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
2125 maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
2126 painter->setPen(textAlphaColor);
2127 const QPoint points[4] = {
2128 maxButtonIconRect.topLeft(),
2129 maxButtonIconRect.topRight(),
2130 maxButtonIconRect.bottomLeft(),
2131 maxButtonIconRect.bottomRight()
2132 };
2134 }
2135 }
2136
2137 // close button
2138 if ((titleBar->subControls & SC_TitleBarCloseButton) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2139 QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
2140 if (closeButtonRect.isValid()) {
2141 bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
2142 bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
2143 qt_fusion_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
2144 QRect closeIconRect = closeButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2145 painter->setPen(textAlphaColor);
2146 const QLine lines[4] = {
2147 QLine(closeIconRect.left() + 1, closeIconRect.top(),
2148 closeIconRect.right(), closeIconRect.bottom() - 1),
2149 QLine(closeIconRect.left(), closeIconRect.top() + 1,
2150 closeIconRect.right() - 1, closeIconRect.bottom()),
2151 QLine(closeIconRect.right() - 1, closeIconRect.top(),
2152 closeIconRect.left(), closeIconRect.bottom() - 1),
2153 QLine(closeIconRect.right(), closeIconRect.top() + 1,
2154 closeIconRect.left() + 1, closeIconRect.bottom())
2155 };
2156 painter->drawLines(lines, 4);
2157 const QPoint points[4] = {
2158 closeIconRect.topLeft(),
2159 closeIconRect.topRight(),
2160 closeIconRect.bottomLeft(),
2161 closeIconRect.bottomRight()
2162 };
2164
2165 painter->setPen(textColor);
2166 painter->drawLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
2167 closeIconRect.right() - 1, closeIconRect.bottom() - 1);
2168 painter->drawLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
2169 closeIconRect.right() - 1, closeIconRect.top() + 1);
2170 }
2171 }
2172
2173 // normalize button
2174 if ((titleBar->subControls & SC_TitleBarNormalButton) &&
2175 (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2176 (titleBar->titleBarState & Qt::WindowMinimized)) ||
2177 ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2178 (titleBar->titleBarState & Qt::WindowMaximized)))) {
2179 QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
2180 if (normalButtonRect.isValid()) {
2181
2182 bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
2183 bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
2184 QRect normalButtonIconRect = normalButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2185 qt_fusion_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
2186
2187 QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
2188 painter->setPen(textColor);
2189 painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
2190 painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
2191 frontWindowRect.right() - 1, frontWindowRect.top() + 1);
2192 painter->setPen(textAlphaColor);
2193 const QPoint points[4] = {
2194 frontWindowRect.topLeft(),
2195 frontWindowRect.topRight(),
2196 frontWindowRect.bottomLeft(),
2197 frontWindowRect.bottomRight()
2198 };
2200
2201 QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
2202 QRegion clipRegion = backWindowRect;
2203 clipRegion -= frontWindowRect;
2204 painter->save();
2205 painter->setClipRegion(clipRegion);
2206 painter->setPen(textColor);
2207 painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
2208 painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
2209 backWindowRect.right() - 1, backWindowRect.top() + 1);
2210 painter->setPen(textAlphaColor);
2211 const QPoint points2[4] = {
2212 backWindowRect.topLeft(),
2213 backWindowRect.topRight(),
2214 backWindowRect.bottomLeft(),
2215 backWindowRect.bottomRight()
2216 };
2217 painter->drawPoints(points2, 4);
2218 painter->restore();
2219 }
2220 }
2221
2222 // context help button
2223 if (titleBar->subControls & SC_TitleBarContextHelpButton
2224 && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
2225 QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
2226 if (contextHelpButtonRect.isValid()) {
2227 bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
2228 bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
2229 qt_fusion_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
2230#if QT_CONFIG(imageformat_xpm)
2231 QImage image(qt_titlebar_context_help);
2232 QColor alpha = textColor;
2233 alpha.setAlpha(128);
2234 image.setColor(1, textColor.rgba());
2235 image.setColor(2, alpha.rgba());
2237 painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image);
2238#endif
2239 }
2240 }
2241
2242 // shade button
2243 if (titleBar->subControls & SC_TitleBarShadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2244 QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
2245 if (shadeButtonRect.isValid()) {
2246 bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
2247 bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
2248 qt_fusion_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
2249 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, shadeButtonRect.adjusted(5, 7, -5, -7), textColor);
2250 }
2251 }
2252
2253 // unshade button
2254 if (titleBar->subControls & SC_TitleBarUnshadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2255 QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
2256 if (unshadeButtonRect.isValid()) {
2257 bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
2258 bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
2259 qt_fusion_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
2260 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, unshadeButtonRect.adjusted(5, 7, -5, -7), textColor);
2261 }
2262 }
2263
2264 if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2265 QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
2266 if (iconRect.isValid()) {
2267 if (!titleBar->icon.isNull()) {
2268 titleBar->icon.paint(painter, iconRect);
2269 } else {
2270 QStyleOption tool = *titleBar;
2271 QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
2272 tool.rect = iconRect;
2273 painter->save();
2274 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
2275 painter->restore();
2276 }
2277 }
2278 }
2279 }
2280 painter->restore();
2281 break;
2282#if QT_CONFIG(slider)
2283 case CC_ScrollBar:
2284 painter->save();
2285 if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
2286 bool wasActive = false;
2287 qreal expandScale = 1.0;
2288 qreal expandOffset = -1.0;
2289 QObject *styleObject = option->styleObject;
2290 if (styleObject && proxy()->styleHint(SH_ScrollBar_Transient, option, widget)) {
2291#if QT_CONFIG(animation)
2292 qreal opacity = 0.0;
2293 bool shouldExpand = false;
2294 const qreal maxExpandScale = 13.0 / 9.0;
2295#endif
2296
2297 int oldPos = styleObject->property("_q_stylepos").toInt();
2298 int oldMin = styleObject->property("_q_stylemin").toInt();
2299 int oldMax = styleObject->property("_q_stylemax").toInt();
2300 QRect oldRect = styleObject->property("_q_stylerect").toRect();
2301 QStyle::State oldState = static_cast<QStyle::State>(qvariant_cast<QStyle::State::Int>(styleObject->property("_q_stylestate")));
2302 uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt();
2303
2304 // a scrollbar is transient when the scrollbar itself and
2305 // its sibling are both inactive (ie. not pressed/hovered/moved)
2306 bool transient = !option->activeSubControls && !(option->state & State_On);
2307
2308 if (!transient ||
2309 oldPos != scrollBar->sliderPosition ||
2310 oldMin != scrollBar->minimum ||
2311 oldMax != scrollBar->maximum ||
2312 oldRect != scrollBar->rect ||
2313 oldState != scrollBar->state ||
2314 oldActiveControls != scrollBar->activeSubControls) {
2315
2317 styleObject->setProperty("_q_stylemin", scrollBar->minimum);
2318 styleObject->setProperty("_q_stylemax", scrollBar->maximum);
2319 styleObject->setProperty("_q_stylerect", scrollBar->rect);
2320 styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(scrollBar->state));
2321 styleObject->setProperty("_q_stylecontrols", static_cast<uint>(scrollBar->activeSubControls));
2322
2323#if QT_CONFIG(animation)
2324 // if the scrollbar is transient or its attributes, geometry or
2325 // state has changed, the opacity is reset back to 100% opaque
2326 opacity = 1.0;
2327
2328 QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
2329 if (transient) {
2330 if (!anim) {
2332 d->startAnimation(anim);
2333 } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2334 // the scrollbar was already fading out while the
2335 // state changed -> restart the fade out animation
2336 anim->setCurrentTime(0);
2337 }
2338 } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2339 d->stopAnimation(styleObject);
2340 }
2341#endif // animation
2342 }
2343
2344#if QT_CONFIG(animation)
2345 QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
2346 if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2347 // once a scrollbar was active (hovered/pressed), it retains
2348 // the active look even if it's no longer active while fading out
2349 if (oldActiveControls)
2350 anim->setActive(true);
2351
2352 wasActive = anim->wasActive();
2353 opacity = anim->currentValue();
2354 }
2355
2356 shouldExpand = (option->activeSubControls || wasActive);
2357 if (shouldExpand) {
2358 if (!anim && !oldActiveControls) {
2359 // Start expand animation only once and when entering
2361 d->startAnimation(anim);
2362 }
2363 if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) {
2364 expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue();
2365 expandOffset = 5.5 * anim->currentValue() - 1;
2366 } else {
2367 // Keep expanded state after the animation ends, and when fading out
2368 expandScale = maxExpandScale;
2369 expandOffset = 4.5;
2370 }
2371 }
2372 painter->setOpacity(opacity);
2373#endif // animation
2374 }
2375
2376 bool transient = proxy()->styleHint(SH_ScrollBar_Transient, option, widget);
2377 bool horizontal = scrollBar->orientation == Qt::Horizontal;
2378 bool sunken = scrollBar->state & State_Sunken;
2379
2380 QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
2381 QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
2382 QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
2383 QRect scrollBarGroove = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
2384
2385 QRect rect = option->rect;
2386 QColor alphaOutline = outline;
2387 alphaOutline.setAlpha(180);
2388
2389 QColor arrowColor = option->palette.windowText().color();
2390 arrowColor.setAlpha(160);
2391
2392 const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget);
2393 const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
2394
2395 if (transient) {
2396 if (horizontal) {
2397 rect.setY(rect.y() + 4.5 - expandOffset);
2398 scrollBarSlider.setY(scrollBarSlider.y() + 4.5 - expandOffset);
2399 scrollBarGroove.setY(scrollBarGroove.y() + 4.5 - expandOffset);
2400
2401 rect.setHeight(rect.height() * expandScale);
2402 scrollBarGroove.setHeight(scrollBarGroove.height() * expandScale);
2403 } else {
2404 rect.setX(rect.x() + 4.5 - expandOffset);
2405 scrollBarSlider.setX(scrollBarSlider.x() + 4.5 - expandOffset);
2406 scrollBarGroove.setX(scrollBarGroove.x() + 4.5 - expandOffset);
2407
2408 rect.setWidth(rect.width() * expandScale);
2409 scrollBarGroove.setWidth(scrollBarGroove.width() * expandScale);
2410 }
2411 }
2412
2413 // Paint groove
2414 if ((!transient || scrollBar->activeSubControls || wasActive) && scrollBar->subControls & SC_ScrollBarGroove) {
2415 QLinearGradient gradient(rect.center().x(), rect.top(),
2416 rect.center().x(), rect.bottom());
2417 if (!horizontal)
2418 gradient = QLinearGradient(rect.left(), rect.center().y(),
2419 rect.right(), rect.center().y());
2420 if (!transient || !isDarkBg) {
2421 gradient.setColorAt(0, buttonColor.darker(107));
2422 gradient.setColorAt(0.1, buttonColor.darker(105));
2423 gradient.setColorAt(0.9, buttonColor.darker(105));
2424 gradient.setColorAt(1, buttonColor.darker(107));
2425 } else {
2426 gradient.setColorAt(0, bgColor.lighter(157));
2427 gradient.setColorAt(0.1, bgColor.lighter(155));
2428 gradient.setColorAt(0.9, bgColor.lighter(155));
2429 gradient.setColorAt(1, bgColor.lighter(157));
2430 }
2431
2432 painter->save();
2433 if (transient)
2434 painter->setOpacity(0.8);
2435 painter->fillRect(rect, gradient);
2437 if (transient)
2438 painter->setOpacity(0.4);
2439 painter->setPen(alphaOutline);
2440 if (horizontal)
2441 painter->drawLine(rect.topLeft(), rect.topRight());
2442 else
2443 painter->drawLine(rect.topLeft(), rect.bottomLeft());
2444
2445 QColor subtleEdge = alphaOutline;
2446 subtleEdge.setAlpha(40);
2447 painter->setPen(subtleEdge);
2449 painter->drawRect(scrollBarGroove.adjusted(1, 0, -1, -1));
2450 painter->restore();
2451 }
2452
2453 QRect pixmapRect = scrollBarSlider;
2454 QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
2455 pixmapRect.center().x(), pixmapRect.bottom());
2456 if (!horizontal)
2457 gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
2458 pixmapRect.right(), pixmapRect.center().y());
2459
2460 QLinearGradient highlightedGradient = gradient;
2461
2462 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
2463 gradient.setColorAt(0, d->buttonColor(option->palette).lighter(108));
2464 gradient.setColorAt(1, d->buttonColor(option->palette));
2465
2466 highlightedGradient.setColorAt(0, gradientStartColor.darker(102));
2467 highlightedGradient.setColorAt(1, gradientStopColor.lighter(102));
2468
2469 // Paint slider
2470 if (scrollBar->subControls & SC_ScrollBarSlider) {
2471 if (transient) {
2472 QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1);
2474 painter->setBrush(isDarkBg ? d->lightShade() : d->darkShade());
2475 int r = qMin(rect.width(), rect.height()) / 2;
2476
2477 painter->save();
2480 painter->restore();
2481 } else {
2482 QRect pixmapRect = scrollBarSlider;
2483 painter->setPen(QPen(alphaOutline));
2484 if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider)
2485 painter->setBrush(midColor2);
2486 else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider)
2487 painter->setBrush(highlightedGradient);
2488 else if (!isDarkBg)
2489 painter->setBrush(gradient);
2490 else
2491 painter->setBrush(midColor2);
2492
2493 painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : -1, horizontal ? -1 : 0));
2494
2495 painter->setPen(d->innerContrastLine());
2496 painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
2497
2498 // Outer shadow
2499 // painter->setPen(subtleEdge);
2500 // if (horizontal) {
2503 // } else {
2506 // }
2507 }
2508 }
2509
2510 // The SubLine (up/left) buttons
2511 if (!transient && scrollBar->subControls & SC_ScrollBarSubLine) {
2512 if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
2513 painter->setBrush(gradientStopColor);
2514 else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
2515 painter->setBrush(highlightedGradient);
2516 else
2517 painter->setBrush(gradient);
2518
2520 painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
2521 painter->setPen(QPen(alphaOutline));
2522 if (option->state & State_Horizontal) {
2523 painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, 0, horizontal ? 1 : 0, horizontal ? -1 : 0));
2524 } else {
2525 painter->drawRect(scrollBarSubLine.adjusted(0, 0, horizontal ? 0 : -1, 0));
2526 }
2527
2528 QRect upRect = scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, horizontal ? -2 : -1, horizontal ? -1 : -2);
2530 painter->setPen(d->innerContrastLine());
2531 painter->drawRect(upRect);
2532
2533 // Arrows
2534 Qt::ArrowType arrowType = Qt::UpArrow;
2535 if (option->state & State_Horizontal)
2536 arrowType = option->direction == Qt::LeftToRight ? Qt::LeftArrow : Qt::RightArrow;
2537 qt_fusion_draw_arrow(arrowType, painter, option, upRect, arrowColor);
2538 }
2539
2540 // The AddLine (down/right) button
2541 if (!transient && scrollBar->subControls & SC_ScrollBarAddLine) {
2542 if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
2543 painter->setBrush(gradientStopColor);
2544 else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
2545 painter->setBrush(midColor2);
2546 else
2547 painter->setBrush(gradient);
2548
2550 painter->drawRect(scrollBarAddLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
2551 painter->setPen(QPen(alphaOutline, 1));
2552 if (option->state & State_Horizontal) {
2553 painter->drawRect(scrollBarAddLine.adjusted(horizontal ? -1 : 0, 0, horizontal ? -1 : 0, horizontal ? -1 : 0));
2554 } else {
2555 painter->drawRect(scrollBarAddLine.adjusted(0, horizontal ? 0 : -1, horizontal ? 0 : -1, horizontal ? 0 : -1));
2556 }
2557
2558 QRect downRect = scrollBarAddLine.adjusted(1, 1, -1, -1);
2559 painter->setPen(d->innerContrastLine());
2561 painter->drawRect(downRect);
2562
2563 Qt::ArrowType arrowType = Qt::DownArrow;
2564 if (option->state & State_Horizontal)
2565 arrowType = option->direction == Qt::LeftToRight ? Qt::RightArrow : Qt::LeftArrow;
2566 qt_fusion_draw_arrow(arrowType, painter, option, downRect, arrowColor);
2567 }
2568
2569 }
2570 painter->restore();
2571 break;
2572#endif // QT_CONFIG(slider)
2573 case CC_ComboBox:
2574 painter->save();
2575 if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
2576 bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange;
2577 bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
2578 bool isEnabled = (comboBox->state & State_Enabled);
2579 const qreal dpr = painter->device()->devicePixelRatio();
2580 QPixmap cache;
2581 const QString pixmapName = QStyleHelper::uniqueName("combobox"_L1
2582 % QLatin1StringView(sunken ? "-sunken" : "")
2583 % QLatin1StringView(comboBox->editable ? "-editable" : "")
2584 % QLatin1StringView(isEnabled ? "-enabled" : "")
2585 % QLatin1StringView(!comboBox->frame ? "-frameless" : ""),
2586 option, comboBox->rect.size(), dpr);
2587 if (!QPixmapCache::find(pixmapName, &cache)) {
2588 cache = styleCachePixmap(comboBox->rect.size(), dpr);
2589 QPainter cachePainter(&cache);
2590 QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
2591 QStyleOptionComboBox comboBoxCopy = *comboBox;
2592 comboBoxCopy.rect = pixmapRect;
2593
2594 QRect rect = pixmapRect;
2595 QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
2596 SC_ComboBoxArrow, widget);
2597 // Draw a line edit
2598 if (comboBox->editable) {
2599 QStyleOptionFrame buttonOption;
2600 buttonOption.QStyleOption::operator=(*comboBox);
2601 buttonOption.rect = rect;
2602 buttonOption.state = (comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus))
2603 | State_KeyboardFocusChange; // Always show hig
2604
2605 if (sunken) {
2606 buttonOption.state |= State_Sunken;
2607 buttonOption.state &= ~State_MouseOver;
2608 }
2609
2610 if (comboBox->frame) {
2611 cachePainter.save();
2612 cachePainter.setRenderHint(QPainter::Antialiasing, true);
2613 cachePainter.translate(0.5, 0.5);
2614 cachePainter.setPen(Qt::NoPen);
2615 cachePainter.setBrush(buttonOption.palette.base());
2616 cachePainter.drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2);
2617 cachePainter.restore();
2618 proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget);
2619 }
2620
2621 // Draw button clipped
2622 cachePainter.save();
2623 cachePainter.setClipRect(downArrowRect.adjusted(0, 0, 1, 0));
2624 buttonOption.rect.setLeft(comboBox->direction == Qt::LeftToRight ?
2625 downArrowRect.left() - 6: downArrowRect.right() + 6);
2626 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
2627 cachePainter.restore();
2628 cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 1));
2629
2630 if (!sunken) {
2631 int borderSize = 1;
2632 if (comboBox->direction == Qt::RightToLeft) {
2633 cachePainter.drawLine(QPoint(downArrowRect.right() - 1, downArrowRect.top() + borderSize ),
2634 QPoint(downArrowRect.right() - 1, downArrowRect.bottom() - borderSize));
2635 } else {
2636 cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
2637 QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
2638 }
2639 } else {
2640 if (comboBox->direction == Qt::RightToLeft) {
2641 cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + 2),
2642 QPoint(downArrowRect.right(), downArrowRect.bottom() - 2));
2643
2644 } else {
2645 cachePainter.drawLine(QPoint(downArrowRect.left(), downArrowRect.top() + 2),
2646 QPoint(downArrowRect.left(), downArrowRect.bottom() - 2));
2647 }
2648 }
2649 } else {
2650 QStyleOptionButton buttonOption;
2651 buttonOption.QStyleOption::operator=(*comboBox);
2652 buttonOption.rect = rect;
2653 buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus | State_KeyboardFocusChange);
2654 if (sunken) {
2655 buttonOption.state |= State_Sunken;
2656 buttonOption.state &= ~State_MouseOver;
2657 }
2658 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
2659 }
2660 if (comboBox->subControls & SC_ComboBoxArrow) {
2661 // Draw the up/down arrow
2662 QColor arrowColor = option->palette.buttonText().color();
2663 arrowColor.setAlpha(160);
2664 qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downArrowRect, arrowColor);
2665 }
2666 cachePainter.end();
2667 QPixmapCache::insert(pixmapName, cache);
2668 }
2669 painter->drawPixmap(comboBox->rect.topLeft(), cache);
2670 }
2671 painter->restore();
2672 break;
2673#if QT_CONFIG(slider)
2674 case CC_Slider:
2675 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
2676 const qreal dpr = painter->device()->devicePixelRatio();
2677 QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
2678 QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
2679
2680 bool horizontal = slider->orientation == Qt::Horizontal;
2681 bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
2682 bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
2683 QColor activeHighlight = d->highlight(option->palette);
2684 QPixmap cache;
2685 QBrush oldBrush = painter->brush();
2686 QPen oldPen = painter->pen();
2687 QColor shadowAlpha(Qt::black);
2688 shadowAlpha.setAlpha(10);
2689 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
2690 outline = d->highlightedOutline(option->palette);
2691
2692
2693 if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
2694 QColor grooveColor;
2695 grooveColor.setHsv(buttonColor.hue(),
2696 qMin(255, (int)(buttonColor.saturation())),
2697 qMin(255, (int)(buttonColor.value()*0.9)));
2698 QString groovePixmapName = QStyleHelper::uniqueName("slider_groove"_L1, option,
2699 groove.size(), dpr);
2700 QRect pixmapRect(0, 0, groove.width(), groove.height());
2701
2702 // draw background groove
2703 if (!QPixmapCache::find(groovePixmapName, &cache)) {
2704 cache = styleCachePixmap(pixmapRect.size(), dpr);
2705 QPainter groovePainter(&cache);
2706 groovePainter.setRenderHint(QPainter::Antialiasing, true);
2707 groovePainter.translate(0.5, 0.5);
2708 QLinearGradient gradient;
2709 if (horizontal) {
2710 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
2711 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
2712 }
2713 else {
2714 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
2715 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
2716 }
2717 groovePainter.setPen(QPen(outline));
2718 gradient.setColorAt(0, grooveColor.darker(110));
2719 gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115));
2720 groovePainter.setBrush(gradient);
2721 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
2722 groovePainter.end();
2723 QPixmapCache::insert(groovePixmapName, cache);
2724 }
2725 painter->drawPixmap(groove.topLeft(), cache);
2726
2727 // draw blue groove highlight
2728 QRect clipRect;
2729 if (!groovePixmapName.isEmpty())
2730 groovePixmapName += "_blue"_L1;
2731 if (!QPixmapCache::find(groovePixmapName, &cache)) {
2732 cache = styleCachePixmap(pixmapRect.size(), dpr);
2733 QPainter groovePainter(&cache);
2734 QLinearGradient gradient;
2735 if (horizontal) {
2736 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
2737 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
2738 }
2739 else {
2740 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
2741 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
2742 }
2743 QColor highlight = d->highlight(option->palette);
2744 QColor highlightedoutline = highlight.darker(140);
2745 QColor grooveOutline = outline;
2746 if (qGray(grooveOutline.rgb()) > qGray(highlightedoutline.rgb()))
2747 grooveOutline = highlightedoutline;
2748
2749 groovePainter.setRenderHint(QPainter::Antialiasing, true);
2750 groovePainter.translate(0.5, 0.5);
2751 groovePainter.setPen(QPen(grooveOutline));
2752 gradient.setColorAt(0, activeHighlight);
2753 gradient.setColorAt(1, activeHighlight.lighter(130));
2754 groovePainter.setBrush(gradient);
2755 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
2756 groovePainter.setPen(d->innerContrastLine());
2757 groovePainter.setBrush(Qt::NoBrush);
2758 groovePainter.drawRoundedRect(pixmapRect.adjusted(2, 2, -3, -3), 1, 1);
2759 groovePainter.end();
2760 QPixmapCache::insert(groovePixmapName, cache);
2761 }
2762 if (horizontal) {
2763 if (slider->upsideDown)
2764 clipRect = QRect(handle.right(), groove.top(), groove.right() - handle.right(), groove.height());
2765 else
2766 clipRect = QRect(groove.left(), groove.top(),
2767 handle.left() - slider->rect.left(), groove.height());
2768 } else {
2769 if (slider->upsideDown)
2770 clipRect = QRect(groove.left(), handle.bottom(), groove.width(), groove.height() - (handle.bottom() - slider->rect.top()));
2771 else
2772 clipRect = QRect(groove.left(), groove.top(), groove.width(), handle.top() - groove.top());
2773 }
2774 painter->save();
2775 painter->setClipRect(clipRect.adjusted(0, 0, 1, 1), Qt::IntersectClip);
2776 painter->drawPixmap(groove.topLeft(), cache);
2777 painter->restore();
2778 }
2779
2780 if (option->subControls & SC_SliderTickmarks) {
2781 painter->save();
2782 painter->translate(slider->rect.x(), slider->rect.y());
2783 painter->setPen(outline);
2784 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
2785 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
2786 int interval = slider->tickInterval;
2787 if (interval <= 0) {
2788 interval = slider->singleStep;
2789 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
2790 available)
2791 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2792 0, available) < 3)
2793 interval = slider->pageStep;
2794 }
2795 if (interval <= 0)
2796 interval = 1;
2797
2798 int v = slider->minimum;
2799 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
2800 QVector<QLine> lines;
2801 while (v <= slider->maximum + 1) {
2802 if (v == slider->maximum + 1 && interval == 1)
2803 break;
2804 const int v_ = qMin(v, slider->maximum);
2805 int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
2806 v_, (horizontal
2807 ? slider->rect.width()
2808 : slider->rect.height()) - len,
2809 slider->upsideDown) + len / 2;
2810 int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
2811
2812 if (horizontal) {
2813 if (ticksAbove) {
2814 lines += QLine(pos, slider->rect.top() + extra,
2815 pos, slider->rect.top() + tickSize);
2816 }
2817 if (ticksBelow) {
2818 lines += QLine(pos, slider->rect.bottom() - extra,
2819 pos, slider->rect.bottom() - tickSize);
2820 }
2821 } else {
2822 if (ticksAbove) {
2823 lines += QLine(slider->rect.left() + extra, pos,
2824 slider->rect.left() + tickSize, pos);
2825 }
2826 if (ticksBelow) {
2827 lines += QLine(slider->rect.right() - extra, pos,
2828 slider->rect.right() - tickSize, pos);
2829 }
2830 }
2831 // in the case where maximum is max int
2832 int nextInterval = v + interval;
2833 if (nextInterval < v)
2834 break;
2835 v = nextInterval;
2836 }
2837 painter->drawLines(lines);
2838 painter->restore();
2839 }
2840 // draw handle
2841 if ((option->subControls & SC_SliderHandle) ) {
2842 QString handlePixmapName = QStyleHelper::uniqueName("slider_handle"_L1, option,
2843 handle.size(), dpr);
2844 if (!QPixmapCache::find(handlePixmapName, &cache)) {
2845 cache = styleCachePixmap(handle.size(), dpr);
2846 QRect pixmapRect(0, 0, handle.width(), handle.height());
2847 QPainter handlePainter(&cache);
2848 QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2);
2849
2850 // gradient fill
2851 QRect r = pixmapRect.adjusted(1, 1, -2, -2);
2852 QLinearGradient gradient = qt_fusion_gradient(gradRect, d->buttonColor(option->palette),horizontal ? TopDown : FromLeft);
2853
2854 handlePainter.setRenderHint(QPainter::Antialiasing, true);
2855 handlePainter.translate(0.5, 0.5);
2856
2857 handlePainter.setPen(Qt::NoPen);
2858 handlePainter.setBrush(QColor(0, 0, 0, 40));
2859 handlePainter.drawRect(horizontal ? r.adjusted(-1, 2, 1, -2) : r.adjusted(2, -1, -2, 1));
2860
2861 handlePainter.setPen(QPen(d->outline(option->palette)));
2862 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
2863 handlePainter.setPen(QPen(d->highlightedOutline(option->palette)));
2864
2865 handlePainter.setBrush(gradient);
2866 handlePainter.drawRoundedRect(r, 2, 2);
2867 handlePainter.setBrush(Qt::NoBrush);
2868 handlePainter.setPen(d->innerContrastLine());
2869 handlePainter.drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2);
2870
2871 QColor cornerAlpha = outline.darker(120);
2872 cornerAlpha.setAlpha(80);
2873
2874 //handle shadow
2875 handlePainter.setPen(shadowAlpha);
2876 handlePainter.drawLine(QPoint(r.left() + 2, r.bottom() + 1), QPoint(r.right() - 2, r.bottom() + 1));
2877 handlePainter.drawLine(QPoint(r.right() + 1, r.bottom() - 3), QPoint(r.right() + 1, r.top() + 4));
2878 handlePainter.drawLine(QPoint(r.right() - 1, r.bottom()), QPoint(r.right() + 1, r.bottom() - 2));
2879
2880 handlePainter.end();
2881 QPixmapCache::insert(handlePixmapName, cache);
2882 }
2883
2884 painter->drawPixmap(handle.topLeft(), cache);
2885
2886 }
2887 painter->setBrush(oldBrush);
2888 painter->setPen(oldPen);
2889 }
2890 break;
2891#endif // QT_CONFIG(slider)
2892#if QT_CONFIG(dial)
2893 case CC_Dial:
2894 if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
2895 QStyleHelper::drawDial(dial, painter);
2896 break;
2897#endif
2898 default:
2900 break;
2901 }
2902}
2903
2907int QFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
2908{
2909 int val = -1;
2910 switch (metric) {
2911 case PM_SliderTickmarkOffset:
2912 val = 4;
2913 break;
2914 case PM_HeaderMargin:
2915 case PM_ToolTipLabelFrameWidth:
2916 val = 2;
2917 break;
2918 case PM_ButtonDefaultIndicator:
2919 case PM_ButtonShiftHorizontal:
2920 case PM_ButtonShiftVertical:
2921 val = 0;
2922 break;
2923 case PM_MessageBoxIconSize:
2924 val = 48;
2925 break;
2926 case PM_ListViewIconSize:
2927 val = 24;
2928 break;
2929 case PM_ScrollBarSliderMin:
2930 val = 26;
2931 break;
2932 case PM_TitleBarHeight:
2933 val = 24;
2934 break;
2935 case PM_ScrollBarExtent:
2936 val = 14;
2937 break;
2938 case PM_SliderThickness:
2939 case PM_SliderLength:
2940 val = 15;
2941 break;
2942 case PM_DockWidgetTitleMargin:
2943 val = 1;
2944 break;
2945 case PM_SpinBoxFrameWidth:
2946 val = 3;
2947 break;
2948 case PM_MenuVMargin:
2949 case PM_MenuHMargin:
2950 case PM_MenuPanelWidth:
2951 val = 0;
2952 break;
2953 case PM_MenuBarItemSpacing:
2954 val = 6;
2955 break;
2956 case PM_MenuBarVMargin:
2957 case PM_MenuBarHMargin:
2958 case PM_MenuBarPanelWidth:
2959 val = 0;
2960 break;
2961 case PM_ToolBarHandleExtent:
2962 val = 9;
2963 break;
2964 case PM_ToolBarItemSpacing:
2965 val = 1;
2966 break;
2967 case PM_ToolBarFrameWidth:
2968 case PM_ToolBarItemMargin:
2969 val = 2;
2970 break;
2971 case PM_SmallIconSize:
2972 case PM_ButtonIconSize:
2973 val = 16;
2974 break;
2975 case PM_DockWidgetTitleBarButtonMargin:
2976 val = 2;
2977 break;
2978 case PM_TitleBarButtonSize:
2979 val = 19;
2980 break;
2981 case PM_MaximumDragDistance:
2982 return -1; // Do not dpi-scale because the value is magic
2983 case PM_TabCloseIndicatorWidth:
2984 case PM_TabCloseIndicatorHeight:
2985 val = 20;
2986 break;
2987 case PM_TabBarTabVSpace:
2988 val = 12;
2989 break;
2990 case PM_TabBarTabOverlap:
2991 val = 1;
2992 break;
2993 case PM_TabBarBaseOverlap:
2994 val = 2;
2995 break;
2996 case PM_SubMenuOverlap:
2997 val = -1;
2998 break;
2999 case PM_DockWidgetHandleExtent:
3000 case PM_SplitterWidth:
3001 val = 4;
3002 break;
3003 case PM_IndicatorHeight:
3004 case PM_IndicatorWidth:
3005 case PM_ExclusiveIndicatorHeight:
3006 case PM_ExclusiveIndicatorWidth:
3007 val = 14;
3008 break;
3009 case PM_ScrollView_ScrollBarSpacing:
3010 val = 0;
3011 break;
3012 case PM_ScrollView_ScrollBarOverlap:
3013 if (proxy()->styleHint(SH_ScrollBar_Transient, option, widget))
3014 return proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
3015 val = 0;
3016 break;
3017 case PM_DefaultFrameWidth:
3018 return 1; // Do not dpi-scale because the drawn frame is always exactly 1 pixel thick
3019 default:
3020 return QCommonStyle::pixelMetric(metric, option, widget);
3021 }
3023}
3024
3028QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
3029 const QSize &size, const QWidget *widget) const
3030{
3032 switch (type) {
3033 case CT_PushButton:
3034 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
3035 if (!btn->text.isEmpty() && newSize.width() < 80)
3036 newSize.setWidth(80);
3037 if (!btn->icon.isNull() && btn->iconSize.height() > 16)
3038 newSize -= QSize(0, 2);
3039 }
3040 break;
3041 case CT_GroupBox:
3042 if (option) {
3043 int topMargin = qMax(pixelMetric(PM_IndicatorHeight, option, widget), option->fontMetrics.height()) + groupBoxTopMargin;
3044 newSize += QSize(10, topMargin); // Add some space below the groupbox
3045 }
3046 break;
3047 case CT_RadioButton:
3048 case CT_CheckBox:
3049 newSize += QSize(0, 1);
3050 break;
3051 case CT_ToolButton:
3052 newSize += QSize(2, 2);
3053 break;
3054 case CT_SpinBox:
3055 newSize += QSize(0, -3);
3056 break;
3057 case CT_ComboBox:
3058 newSize += QSize(2, 4);
3059 break;
3060 case CT_LineEdit:
3061 newSize += QSize(0, 4);
3062 break;
3063 case CT_MenuBarItem:
3064 newSize += QSize(8, 5);
3065 break;
3066 case CT_MenuItem:
3067 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
3068 int w = size.width(); // Don't rely of QCommonStyle's width calculation here
3069 if (menuItem->text.contains(u'\t'))
3070 w += menuItem->reservedShortcutWidth;
3071 else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
3072 w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin, option);
3073 else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
3074 const QFontMetrics fm(menuItem->font);
3075 QFont fontBold = menuItem->font;
3076 fontBold.setBold(true);
3077 const QFontMetrics fmBold(fontBold);
3078 w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text);
3079 }
3081 // Windows always shows a check column
3082 const int checkcol = qMax<int>(menuItem->maxIconWidth,
3083 QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth, dpi));
3084 w += checkcol + windowsItemFrame;
3085 w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10, dpi);
3086 newSize.setWidth(w);
3087 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
3088 if (!menuItem->text.isEmpty()) {
3089 newSize.setHeight(menuItem->fontMetrics.height());
3090 }
3091 }
3092 else if (!menuItem->icon.isNull()) {
3093#if QT_CONFIG(combobox)
3094 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget)) {
3095 newSize.setHeight(qMax(combo->iconSize().height() + 2, newSize.height()));
3096 }
3097#endif
3098 }
3099 newSize.setWidth(newSize.width() + int(QStyleHelper::dpiScaled(12, dpi)));
3100 newSize.setWidth(qMax<int>(newSize.width(), int(QStyleHelper::dpiScaled(120, dpi))));
3101 }
3102 break;
3103 case CT_SizeGrip:
3104 newSize += QSize(4, 4);
3105 break;
3106 case CT_MdiControls:
3107 newSize -= QSize(1, 0);
3108 break;
3109 default:
3110 break;
3111 }
3112 return newSize;
3113}
3114
3118void QFusionStyle::polish(QApplication *app)
3119{
3121}
3122
3126void QFusionStyle::polish(QWidget *widget)
3127{
3129 if (false
3130#if QT_CONFIG(abstractbutton)
3131 || qobject_cast<QAbstractButton*>(widget)
3132#endif
3133#if QT_CONFIG(combobox)
3134 || qobject_cast<QComboBox *>(widget)
3135#endif
3136#if QT_CONFIG(progressbar)
3137 || qobject_cast<QProgressBar *>(widget)
3138#endif
3139#if QT_CONFIG(scrollbar)
3140 || qobject_cast<QScrollBar *>(widget)
3141#endif
3142#if QT_CONFIG(splitter)
3143 || qobject_cast<QSplitterHandle *>(widget)
3144#endif
3145#if QT_CONFIG(abstractslider)
3146 || qobject_cast<QAbstractSlider *>(widget)
3147#endif
3148#if QT_CONFIG(spinbox)
3149 || qobject_cast<QAbstractSpinBox *>(widget)
3150#endif
3151 || (widget->inherits("QDockSeparator"))
3152 || (widget->inherits("QDockWidgetSeparator"))
3153 ) {
3156 }
3157}
3158
3162void QFusionStyle::polish(QPalette &pal)
3163{
3165}
3166
3170void QFusionStyle::unpolish(QWidget *widget)
3171{
3173 if (false
3174#if QT_CONFIG(abstractbutton)
3175 || qobject_cast<QAbstractButton*>(widget)
3176#endif
3177#if QT_CONFIG(combobox)
3178 || qobject_cast<QComboBox *>(widget)
3179#endif
3180#if QT_CONFIG(progressbar)
3181 || qobject_cast<QProgressBar *>(widget)
3182#endif
3183#if QT_CONFIG(scrollbar)
3184 || qobject_cast<QScrollBar *>(widget)
3185#endif
3186#if QT_CONFIG(splitter)
3187 || qobject_cast<QSplitterHandle *>(widget)
3188#endif
3189#if QT_CONFIG(abstractslider)
3190 || qobject_cast<QAbstractSlider *>(widget)
3191#endif
3192#if QT_CONFIG(spinbox)
3193 || qobject_cast<QAbstractSpinBox *>(widget)
3194#endif
3195 || (widget->inherits("QDockSeparator"))
3196 || (widget->inherits("QDockWidgetSeparator"))
3197 ) {
3199 }
3200}
3201
3205void QFusionStyle::unpolish(QApplication *app)
3206{
3208}
3209
3213QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
3214 SubControl subControl, const QWidget *widget) const
3215{
3216 QRect rect = QCommonStyle::subControlRect(control, option, subControl, widget);
3217
3218 switch (control) {
3219#if QT_CONFIG(slider)
3220 case CC_Slider:
3221 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
3222 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
3223 switch (subControl) {
3224 case SC_SliderHandle: {
3225 const bool bothTicks = (slider->tickPosition & QSlider::TicksBothSides) == QSlider::TicksBothSides;
3226 if (slider->orientation == Qt::Horizontal) {
3227 rect.setHeight(proxy()->pixelMetric(PM_SliderThickness, option, widget));
3228 rect.setWidth(proxy()->pixelMetric(PM_SliderLength, option, widget));
3229 int centerY = slider->rect.center().y() - rect.height() / 2;
3230 if (!bothTicks) {
3231 if (slider->tickPosition & QSlider::TicksAbove)
3232 centerY += tickSize;
3233 if (slider->tickPosition & QSlider::TicksBelow)
3234 centerY -= tickSize - 1;
3235 }
3236 rect.moveTop(centerY);
3237 } else {
3238 rect.setWidth(proxy()->pixelMetric(PM_SliderThickness, option, widget));
3239 rect.setHeight(proxy()->pixelMetric(PM_SliderLength, option, widget));
3240 int centerX = slider->rect.center().x() - rect.width() / 2;
3241 if (!bothTicks) {
3242 if (slider->tickPosition & QSlider::TicksAbove)
3243 centerX += tickSize;
3244 if (slider->tickPosition & QSlider::TicksBelow)
3245 centerX -= tickSize - 1;
3246 }
3247 rect.moveLeft(centerX);
3248 }
3249 }
3250 break;
3251 case SC_SliderGroove: {
3252 QPoint grooveCenter = slider->rect.center();
3253 const int grooveThickness = QStyleHelper::dpiScaled(7, option);
3254 const bool bothTicks = (slider->tickPosition & QSlider::TicksBothSides) == QSlider::TicksBothSides;
3255 if (slider->orientation == Qt::Horizontal) {
3256 rect.setHeight(grooveThickness);
3257 if (!bothTicks) {
3258 if (slider->tickPosition & QSlider::TicksAbove)
3259 grooveCenter.ry() += tickSize;
3260 if (slider->tickPosition & QSlider::TicksBelow)
3261 grooveCenter.ry() -= tickSize - 1;
3262 }
3263 } else {
3264 rect.setWidth(grooveThickness);
3265 if (!bothTicks) {
3266 if (slider->tickPosition & QSlider::TicksAbove)
3267 grooveCenter.rx() += tickSize;
3268 if (slider->tickPosition & QSlider::TicksBelow)
3269 grooveCenter.rx() -= tickSize - 1;
3270 }
3271 }
3272 rect.moveCenter(grooveCenter);
3273 break;
3274 }
3275 default:
3276 break;
3277 }
3278 }
3279 break;
3280#endif // QT_CONFIG(slider)
3281#if QT_CONFIG(spinbox)
3282 case CC_SpinBox:
3283 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
3284 int center = spinbox->rect.height() / 2;
3285 int fw = spinbox->frame ? 3 : 0; // Is drawn with 3 pixels width in drawComplexControl, independently from PM_SpinBoxFrameWidth
3286 int y = fw;
3287 const int buttonWidth = QStyleHelper::dpiScaled(14, option);
3288 int x, lx, rx;
3289 x = spinbox->rect.width() - y - buttonWidth + 2;
3290 lx = fw;
3291 rx = x - fw;
3292 switch (subControl) {
3293 case SC_SpinBoxUp:
3294 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3295 return QRect();
3296 rect = QRect(x, fw, buttonWidth, center - fw);
3297 break;
3298 case SC_SpinBoxDown:
3299 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3300 return QRect();
3301
3302 rect = QRect(x, center, buttonWidth, spinbox->rect.bottom() - center - fw + 1);
3303 break;
3304 case SC_SpinBoxEditField:
3305 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
3306 rect = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
3307 } else {
3308 rect = QRect(lx, fw, rx - qMax(fw - 1, 0), spinbox->rect.height() - 2*fw);
3309 }
3310 break;
3311 case SC_SpinBoxFrame:
3312 rect = spinbox->rect;
3313 break;
3314 default:
3315 break;
3316 }
3317 rect = visualRect(spinbox->direction, spinbox->rect, rect);
3318 }
3319 break;
3320#endif // QT_CONFIG(spinbox)
3321 case CC_GroupBox:
3322 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
3323 const int groupBoxTextAlignment = groupBox->textAlignment;
3324 const bool hasVerticalAlignment = (groupBoxTextAlignment & Qt::AlignVertical_Mask) == Qt::AlignVCenter;
3325 const int fontMetricsHeight = groupBox->text.isEmpty() ? 0 : groupBox->fontMetrics.height();
3326
3327 if (subControl == SC_GroupBoxFrame)
3328 return rect;
3329 else if (subControl == SC_GroupBoxContents) {
3330 QRect frameRect = option->rect.adjusted(0, 0, 0, -groupBoxBottomMargin);
3331 int margin = 3;
3332 int leftMarginExtension = 0;
3333 const int indicatorHeight = option->subControls.testFlag(SC_GroupBoxCheckBox) ?
3334 pixelMetric(PM_IndicatorHeight, option, widget) : 0;
3335 const int topMargin = qMax(indicatorHeight, fontMetricsHeight) +
3336 groupBoxTopMargin;
3337 return frameRect.adjusted(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBoxBottomMargin);
3338 }
3339
3340 QSize textSize = option->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
3341 int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
3342 int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
3343
3344 const int width = textSize.width()
3345 + (option->subControls & QStyle::SC_GroupBoxCheckBox ? indicatorWidth + 5 : 0);
3346
3347 rect = QRect();
3348
3349 if (option->rect.width() > width) {
3350 switch (groupBoxTextAlignment & Qt::AlignHorizontal_Mask) {
3351 case Qt::AlignHCenter:
3352 rect.moveLeft((option->rect.width() - width) / 2);
3353 break;
3354 case Qt::AlignRight:
3355 rect.moveLeft(option->rect.width() - width
3356 - (hasVerticalAlignment ? proxy()->pixelMetric(PM_LayoutRightMargin, groupBox, widget) : 0));
3357 break;
3358 case Qt::AlignLeft:
3359 if (hasVerticalAlignment)
3360 rect.moveLeft(proxy()->pixelMetric(PM_LayoutLeftMargin, option, widget));
3361 break;
3362 }
3363 }
3364
3365 if (subControl == SC_GroupBoxCheckBox) {
3366 rect.setWidth(indicatorWidth);
3367 rect.setHeight(indicatorHeight);
3368 rect.moveTop(textSize.height() > indicatorHeight ? (textSize.height() - indicatorHeight) / 2 : 0);
3369 rect.translate(1, 0);
3370 } else if (subControl == SC_GroupBoxLabel) {
3371 rect.setSize(textSize);
3372 rect.moveTop(1);
3373 if (option->subControls & QStyle::SC_GroupBoxCheckBox)
3374 rect.translate(indicatorWidth + 5, 0);
3375 }
3376 return visualRect(option->direction, option->rect, rect);
3377 }
3378
3379 return rect;
3380
3381 case CC_ComboBox:
3382 switch (subControl) {
3383 case SC_ComboBoxArrow: {
3385 rect = visualRect(option->direction, option->rect, rect);
3386 rect.setRect(rect.right() - int(QStyleHelper::dpiScaled(18, dpi)), rect.top() - 2,
3387 int(QStyleHelper::dpiScaled(19, dpi)), rect.height() + 4);
3388 rect = visualRect(option->direction, option->rect, rect);
3389 }
3390 break;
3391 case SC_ComboBoxEditField: {
3392 int frameWidth = 2;
3393 rect = visualRect(option->direction, option->rect, rect);
3394 rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
3395 option->rect.width() - int(QStyleHelper::dpiScaled(19, option)) - 2 * frameWidth,
3396 option->rect.height() - 2 * frameWidth);
3397 if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
3398 if (!box->editable) {
3399 rect.adjust(2, 0, 0, 0);
3400 if (box->state & (State_Sunken | State_On))
3401 rect.translate(1, 1);
3402 }
3403 }
3404 rect = visualRect(option->direction, option->rect, rect);
3405 break;
3406 }
3407 default:
3408 break;
3409 }
3410 break;
3411 case CC_TitleBar:
3412 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
3413 SubControl sc = subControl;
3414 QRect &ret = rect;
3415 const int indent = 3;
3416 const int controlTopMargin = 3;
3417 const int controlBottomMargin = 3;
3418 const int controlWidthMargin = 2;
3419 const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin ;
3420 const int delta = controlHeight + controlWidthMargin;
3421 int offset = 0;
3422
3423 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3424 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3425
3426 switch (sc) {
3427 case SC_TitleBarLabel:
3428 if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
3429 ret = tb->rect;
3430 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3431 ret.adjust(delta, 0, -delta, 0);
3432 if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3433 ret.adjust(0, 0, -delta, 0);
3434 if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3435 ret.adjust(0, 0, -delta, 0);
3436 if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
3437 ret.adjust(0, 0, -delta, 0);
3438 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3439 ret.adjust(0, 0, -delta, 0);
3440 }
3441 break;
3442 case SC_TitleBarContextHelpButton:
3443 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3444 offset += delta;
3445 Q_FALLTHROUGH();
3446 case SC_TitleBarMinButton:
3447 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3448 offset += delta;
3449 else if (sc == SC_TitleBarMinButton)
3450 break;
3451 Q_FALLTHROUGH();
3452 case SC_TitleBarNormalButton:
3453 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3454 offset += delta;
3455 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3456 offset += delta;
3457 else if (sc == SC_TitleBarNormalButton)
3458 break;
3459 Q_FALLTHROUGH();
3460 case SC_TitleBarMaxButton:
3461 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3462 offset += delta;
3463 else if (sc == SC_TitleBarMaxButton)
3464 break;
3465 Q_FALLTHROUGH();
3466 case SC_TitleBarShadeButton:
3467 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3468 offset += delta;
3469 else if (sc == SC_TitleBarShadeButton)
3470 break;
3471 Q_FALLTHROUGH();
3472 case SC_TitleBarUnshadeButton:
3473 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3474 offset += delta;
3475 else if (sc == SC_TitleBarUnshadeButton)
3476 break;
3477 Q_FALLTHROUGH();
3478 case SC_TitleBarCloseButton:
3479 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3480 offset += delta;
3481 else if (sc == SC_TitleBarCloseButton)
3482 break;
3483 ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
3484 controlHeight, controlHeight);
3485 break;
3486 case SC_TitleBarSysMenu:
3487 if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3488 ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
3489 controlHeight, controlHeight);
3490 }
3491 break;
3492 default:
3493 break;
3494 }
3495 ret = visualRect(tb->direction, tb->rect, ret);
3496 }
3497 break;
3498 default:
3499 break;
3500 }
3501
3502 return rect;
3503}
3504
3505
3509QRect QFusionStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
3510{
3512}
3513
3517void QFusionStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
3518 int alignment, const QPixmap &pixmap) const
3519{
3521}
3522
3526QStyle::SubControl QFusionStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
3527 const QPoint &pt, const QWidget *w) const
3528{
3529 return QCommonStyle::hitTestComplexControl(cc, opt, pt, w);
3530}
3531
3535QPixmap QFusionStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
3536 const QStyleOption *opt) const
3537{
3538 return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt);
3539}
3540
3544int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
3545 QStyleHintReturn *returnData) const
3546{
3547 switch (hint) {
3548 case SH_Slider_SnapToValue:
3549 case SH_PrintDialog_RightAlignButtons:
3550 case SH_FontDialog_SelectAssociatedText:
3551 case SH_MenuBar_AltKeyNavigation:
3552 case SH_ComboBox_ListMouseTracking:
3553 case SH_Slider_StopMouseOverSlider:
3554 case SH_ScrollBar_MiddleClickAbsolutePosition:
3555 case SH_EtchDisabledText:
3556 case SH_TitleBar_AutoRaise:
3557 case SH_TitleBar_NoBorder:
3558 case SH_ItemView_ShowDecorationSelected:
3559 case SH_ItemView_ArrowKeysNavigateIntoChildren:
3560 case SH_ItemView_ChangeHighlightOnFocus:
3561 case SH_MenuBar_MouseTracking:
3562 case SH_Menu_MouseTracking:
3563 case SH_Menu_SupportsSections:
3564 return 1;
3565
3566#if defined(QT_PLATFORM_UIKIT)
3567 case SH_ComboBox_UseNativePopup:
3568 return 1;
3569#endif
3570
3571 case SH_ToolBox_SelectedPageTitleBold:
3572 case SH_ScrollView_FrameOnlyAroundContents:
3573 case SH_Menu_AllowActiveAndDisabled:
3574 case SH_MainWindow_SpaceBelowMenuBar:
3575 case SH_MessageBox_CenterButtons:
3576 case SH_RubberBand_Mask:
3577 return 0;
3578
3579 case SH_ComboBox_Popup:
3580 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
3581 return !cmb->editable;
3582 return 0;
3583
3584 case SH_Table_GridLineColor:
3585 return option ? option->palette.window().color().darker(120).rgba() : 0;
3586
3587 case SH_MessageBox_TextInteractionFlags:
3589#if QT_CONFIG(wizard)
3590 case SH_WizardStyle:
3591 return QWizard::ClassicStyle;
3592#endif
3593 case SH_Menu_SubMenuPopupDelay:
3594 return 225; // default from GtkMenu
3595
3596 case SH_WindowFrame_Mask:
3597 if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData)) {
3598 //left rounded corner
3599 mask->region = option->rect;
3600 mask->region -= QRect(option->rect.left(), option->rect.top(), 5, 1);
3601 mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 3, 1);
3602 mask->region -= QRect(option->rect.left(), option->rect.top() + 2, 2, 1);
3603 mask->region -= QRect(option->rect.left(), option->rect.top() + 3, 1, 2);
3604
3605 //right rounded corner
3606 mask->region -= QRect(option->rect.right() - 4, option->rect.top(), 5, 1);
3607 mask->region -= QRect(option->rect.right() - 2, option->rect.top() + 1, 3, 1);
3608 mask->region -= QRect(option->rect.right() - 1, option->rect.top() + 2, 2, 1);
3609 mask->region -= QRect(option->rect.right() , option->rect.top() + 3, 1, 2);
3610 return 1;
3611 }
3612 break;
3613 case SH_GroupBox_TextLabelVerticalAlignment: {
3614 if (const auto *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
3615 if (groupBox) {
3616 const auto vAlign = groupBox->textAlignment & Qt::AlignVertical_Mask;
3617 // default fusion style is AlignTop
3618 return vAlign == 0 ? Qt::AlignTop : vAlign;
3619 }
3620 }
3621 break;
3622 }
3623 default:
3624 break;
3625 }
3626 return QCommonStyle::styleHint(hint, option, widget, returnData);
3627}
3628
3630QRect QFusionStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
3631{
3633 switch (sr) {
3634 case SE_ProgressBarLabel:
3635 case SE_ProgressBarContents:
3636 case SE_ProgressBarGroove:
3637 return opt->rect;
3638 case SE_PushButtonFocusRect:
3639 r.adjust(0, 1, 0, -1);
3640 break;
3641 case SE_DockWidgetTitleBarText: {
3642 if (const QStyleOptionDockWidget *titlebar = qstyleoption_cast<const QStyleOptionDockWidget*>(opt)) {
3643 bool verticalTitleBar = titlebar->verticalTitleBar;
3644 if (verticalTitleBar) {
3645 r.adjust(0, 0, 0, -4);
3646 } else {
3648 r.adjust(4, 0, 0, 0);
3649 else
3650 r.adjust(0, 0, -4, 0);
3651 }
3652 }
3653
3654 break;
3655 }
3656 default:
3657 break;
3658 }
3659 return r;
3660}
3661
3665QIcon QFusionStyle::iconFromTheme(StandardPixmap standardIcon) const
3666{
3667 QIcon icon;
3668#if QT_CONFIG(imageformat_png)
3669 auto addIconFiles = [](QStringView prefix, QIcon &icon)
3670 {
3671 const auto fullPrefix = QStringLiteral(":/qt-project.org/styles/fusionstyle/images/") + prefix;
3672 static constexpr auto dockTitleIconSizes = {10, 16, 20, 32, 48, 64};
3673 for (int size : dockTitleIconSizes)
3674 icon.addFile(fullPrefix + QString::number(size) + QStringLiteral(".png"),
3675 QSize(size, size));
3676 };
3677 switch (standardIcon) {
3678 case SP_TitleBarNormalButton:
3679 addIconFiles(u"fusion_normalizedockup-", icon);
3680 break;
3681 case SP_TitleBarMinButton:
3682 addIconFiles(u"fusion_titlebar-min-", icon);
3683 break;
3684 case SP_TitleBarCloseButton:
3685 case SP_DockWidgetCloseButton:
3686 addIconFiles(u"fusion_closedock-", icon);
3687 break;
3688 default:
3689 break;
3690 }
3691#else // imageformat_png
3692 Q_UNUSED(standardIcon);
3693#endif // imageformat_png
3694 return icon;
3695}
3696
3700QIcon QFusionStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
3701 const QWidget *widget) const
3702{
3703 const auto icon = iconFromTheme(standardIcon);
3704 if (!icon.availableSizes().isEmpty())
3705 return icon;
3706 return QCommonStyle::standardIcon(standardIcon, option, widget);
3707}
3708
3712QPixmap QFusionStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
3713 const QWidget *widget) const
3714{
3715 auto getDevicePixelRatio = [](const QWidget *widget)
3716 {
3717 return widget ? widget->devicePixelRatio() : qApp->devicePixelRatio();
3718 };
3719 const auto icon = iconFromTheme(standardPixmap);
3720 if (!icon.availableSizes().isEmpty())
3721 return icon.pixmap(QSize(16, 16), getDevicePixelRatio(widget));
3722 return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
3723}
3724
3726
3727#include "moc_qfusionstyle_p.cpp"
3728
3729#endif // style_fusion|| QT_PLUGIN
void setCurrentTime(int msecs)
Qt::Orientation orientation
the orientation of the slider
int sliderPosition
the current slider position
int minimum
the sliders's minimum value
int maximum
the slider's maximum value
bool frame
whether the spin box draws itself with a frame
ButtonSymbols buttonSymbols
the current button symbol mode
virtual StepEnabled stepEnabled() const
Virtual function that determines whether stepping up and down is legal at any given time.
The QApplication class manages the GUI application's control flow and main settings.
\inmodule QtGui
Definition qbrush.h:30
const QGradient * gradient() const
Returns the gradient describing this brush.
Definition qbrush.cpp:791
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
int saturation() const noexcept
Returns the HSV saturation color component of this color.
Definition qcolor.cpp:1734
QColor darker(int f=200) const noexcept
Definition qcolor.cpp:2857
QRgb rgb() const noexcept
Returns the RGB value of the color.
Definition qcolor.cpp:1439
void setGreen(int green)
Sets the green color component of this color to green.
Definition qcolor.cpp:1568
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
Definition qcolor.cpp:1376
void setBlue(int blue)
Sets the blue color component of this color to blue.
Definition qcolor.cpp:1597
int red() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1528
int hue() const noexcept
Returns the HSV hue color component of this color.
Definition qcolor.cpp:1708
int blue() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1583
int green() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1555
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1481
void setHsv(int h, int s, int v, int a=255)
Sets a HSV color value; h is the hue, s is the saturation, v is the value and a is the alpha componen...
Definition qcolor.cpp:1099
int value() const noexcept
Returns the value color component of this color.
Definition qcolor.cpp:1756
QColor lighter(int f=150) const noexcept
Definition qcolor.cpp:2812
QString name(NameFormat format=HexRgb) const
Definition qcolor.cpp:834
@ HexArgb
Definition qcolor.h:36
void setRed(int red)
Sets the red color component of this color to red.
Definition qcolor.cpp:1541
The QComboBox widget combines a button with a dropdown list.
Definition qcombobox.h:24
The QCommonStyle class encapsulates the common Look and Feel of a GUI.
int pixelMetric(PixelMetric m, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr) const override
\reimp
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget=nullptr) const override
\reimp
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=nullptr) const override
\reimp
void unpolish(QWidget *widget) override
\reimp
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr) const override
QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr) const override
\reimp
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const override
\reimp
SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *w=nullptr) const override
\reimp
int styleHint(StyleHint sh, const QStyleOption *opt=nullptr, const QWidget *w=nullptr, QStyleHintReturn *shret=nullptr) const override
\reimp
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override
\reimp
void polish(QPalette &) override
\reimp
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w=nullptr) const override
\reimp
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w=nullptr) const override
\reimp
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const override
\reimp
\reentrant
Definition qfontinfo.h:16
qreal pointSizeF() const
Returns the point size of the matched window system font.
Definition qfont.cpp:3131
\reentrant \inmodule QtGui
int height() const
Returns the height of the font.
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags=0) const
\reentrant
Definition qfont.h:22
void setBold(bool)
If enable is true sets the font's weight to \l{Weight}{QFont::Bold}; otherwise sets the weight to \l{...
Definition qfont.h:373
void setPointSizeF(qreal)
Sets the point size to pointSize.
Definition qfont.cpp:1010
int midLineWidth
the width of the mid-line
Definition qframe.h:23
int lineWidth
the line width
Definition qframe.h:22
void setStops(const QGradientStops &stops)
Replaces the current set of stop points with the given stopPoints.
Definition qbrush.cpp:1608
void setColorAt(qreal pos, const QColor &color)
Creates a stop point at the given position with the given color.
Definition qbrush.cpp:1563
QGradientStops stops() const
Returns the stop points for this gradient.
Definition qbrush.cpp:1631
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition qicon.cpp:1019
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Disabled
Definition qicon.h:22
@ Normal
Definition qicon.h:22
@ Active
Definition qicon.h:22
QList< QSize > availableSizes(Mode mode=Normal, State state=Off) const
Definition qicon.cpp:1144
@ On
Definition qicon.h:23
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition qicon.cpp:834
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
\inmodule QtCore\compares equality \compareswith equality QLineF \endcompareswith
Definition qline.h:18
\inmodule QtGui
Definition qbrush.h:394
void setFinalStop(const QPointF &stop)
Definition qbrush.cpp:1943
void setStart(const QPointF &start)
Definition qbrush.cpp:1902
bool isEmpty() const noexcept
Definition qlist.h:401
\inmodule QtCore
Definition qmargins.h:24
\inmodule QtCore
Definition qobject.h:103
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4323
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:348
qreal devicePixelRatio() const
\inmodule QtGui
void addEllipse(const QRectF &rect)
Creates an ellipse within the specified boundingRectangle and adds it to the painter path as a closed...
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawPoint(const QPointF &pt)
Draws a single point at the given position using the current pen's color.
Definition qpainter.h:545
const QPen & pen() const
Returns the painter's current pen.
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition qpainter.h:519
void drawPath(const QPainterPath &path)
Draws the given painter path using the current pen for outline and the current brush for filling.
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or \nullptr if the painter is n...
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation.
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void drawLine(const QLineF &line)
Draws a line defined by line.
Definition qpainter.h:442
void restore()
Restores the current painter state (pops a saved state off the stack).
void rotate(qreal a)
Rotates the coordinate system clockwise.
const QBrush & brush() const
Returns the painter's current brush.
void setOpacity(qreal opacity)
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
void drawLines(const QLineF *lines, int lineCount)
Draws the first lineCount lines in the array lines using the current pen.
void save()
Saves the current painter state (pushes the state onto a stack).
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
Draws the rectangular portion source of the given image into the target rectangle in the paint device...
void setFont(const QFont &f)
Sets the painter's font to the given font.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
void drawEllipse(const QRectF &r)
Draws the ellipse defined by the given rectangle.
void setBrush(const QBrush &brush)
Sets the painter's brush to the given brush.
@ SmoothPixmapTransform
Definition qpainter.h:54
@ Antialiasing
Definition qpainter.h:52
void drawPoints(const QPointF *points, int pointCount)
Draws the first pointCount points in the array points using the current pen's color.
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint.
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode=Qt::AbsoluteSize)
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
void setTransform(const QTransform &transform, bool combine=false)
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & windowText() const
Returns the window text (general foreground) brush of the current color group.
Definition qpalette.h:83
const QBrush & brush(ColorGroup cg, ColorRole cr) const
Returns the brush in the specified color group, used for the given color role.
Definition qpalette.cpp:748
void setBrush(ColorRole cr, const QBrush &brush)
Sets the brush for the given color role to the specified brush for all groups in the palette.
Definition qpalette.h:151
@ HighlightedText
Definition qpalette.h:53
@ ButtonText
Definition qpalette.h:52
@ WindowText
Definition qpalette.h:51
@ Highlight
Definition qpalette.h:53
\inmodule QtGui
Definition qpen.h:28
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:818
constexpr QRect toRect() const noexcept
Returns a QRect based on the values of this rectangle.
Definition qrect.h:859
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:373
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:170
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:221
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr QPoint topRight() const noexcept
Returns the position of the rectangle's top-right corner.
Definition qrect.h:227
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr QRect transposed() const noexcept
Definition qrect.h:267
constexpr void translate(int dx, int dy) noexcept
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position.
Definition qrect.h:245
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
QRect united(const QRect &other) const noexcept
Definition qrect.h:420
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
constexpr QPoint center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:233
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
@ TicksAbove
Definition qslider.h:27
@ TicksBelow
Definition qslider.h:29
@ TicksBothSides
Definition qslider.h:31
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
The QStyleHintReturnMask class provides style hints that return a QRegion.
\variable QStyleOptionGraphicsItem::exposedRect
\variable QStyleOptionHeaderV2::textElideMode
\variable QStyleOptionToolButton::features
\variable QStyleOptionMenuItem::menuItemType
\variable QStyleOptionComplex::subControls
\variable QStyleOption::palette
\variable QStyleOptionFocusRect::backgroundColor
\variable QStyleOptionFrame::features
The QStyleOptionHeaderV2 class is used to describe the parameters for drawing a header.
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
\variable QStyleOptionProgressBar::minimum
\variable QStyleOptionButton::features
\variable QStyleOptionToolBox::selectedPosition
The QStyleOption class stores the parameters used by QStyle functions.
QStyle::State state
QPalette palette
Qt::LayoutDirection direction
@ State_Active
Definition qstyle.h:83
@ State_Horizontal
Definition qstyle.h:74
virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
Returns the area within the given rectangle in which to draw the specified pixmap according to the de...
Definition qstyle.cpp:534
@ SH_UnderlineShortcut
Definition qstyle.h:626
virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
Draws the given pixmap in the specified rectangle, according to the specified alignment,...
Definition qstyle.cpp:612
static int sliderPositionFromValue(int min, int max, int val, int space, bool upsideDown=false)
Converts the given logicalValue to a pixel position.
Definition qstyle.cpp:2222
SubControl
This enum describes the available sub controls.
Definition qstyle.h:347
@ SC_GroupBoxCheckBox
Definition qstyle.h:390
@ SC_GroupBoxLabel
Definition qstyle.h:391
@ SC_GroupBoxFrame
Definition qstyle.h:393
@ RoundedSouth
Definition qtabbar.h:42
@ RoundedNorth
Definition qtabbar.h:42
@ TriangularEast
Definition qtabbar.h:43
@ RoundedWest
Definition qtabbar.h:42
@ TriangularSouth
Definition qtabbar.h:43
@ RoundedEast
Definition qtabbar.h:42
@ TriangularWest
Definition qtabbar.h:43
@ TriangularNorth
Definition qtabbar.h:43
\reentrant
Definition qtextoption.h:18
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & rotate(qreal a, Qt::Axis axis=Qt::ZAxis, qreal distanceToPlane=1024.0f)
static QTransform fromScale(qreal dx, qreal dy)
Creates a matrix which corresponds to a scaling of sx horizontally and sy vertically.
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
uint toUInt(bool *ok=nullptr) const
Returns the variant as an unsigned int if the variant has userType() \l QMetaType::UInt,...
QRect toRect() const
Returns the variant as a QRect if the variant has userType() \l QMetaType::QRect; otherwise returns a...
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
QPalette palette
the widget's palette
Definition qwidget.h:132
QFontMetrics fontMetrics() const
Returns the font metrics for the widget's current font.
Definition qwidget.h:847
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
QPalette::ColorRole backgroundRole() const
Returns the background role of the widget.
Definition qwidget.cpp:4360
@ ClassicStyle
Definition qwizard.h:55
QOpenGLWidget * widget
[1]
QString text
QPushButton * button
[2]
QCache< int, Employee > cache
[0]
object setObjectName("A new object name")
opt iconSize
drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget)
rect
[4]
QStyleOptionButton subopt
[2]
uint alignment
direction
QStyleOptionButton opt
fontMetrics
else opt state
[0]
QRect textRect
const QStyleOptionButton * btn
[3]
void flip(QMatrix4x4 &matrix)
Definition qssgutils_p.h:78
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option)
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size, qreal dpr)
QColor backgroundColor(const QPalette &pal, const QWidget *widget)
Combined button and popup list for selecting options.
bool isEnabled()
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
@ AlignRight
Definition qnamespace.h:146
@ AlignVCenter
Definition qnamespace.h:155
@ AlignTop
Definition qnamespace.h:153
@ AlignHCenter
Definition qnamespace.h:148
@ AlignHorizontal_Mask
Definition qnamespace.h:151
@ AlignVertical_Mask
Definition qnamespace.h:161
@ AlignCenter
Definition qnamespace.h:163
@ AlignAbsolute
Definition qnamespace.h:150
@ AlignLeft
Definition qnamespace.h:144
@ TextSelectableByMouse
@ LinksAccessibleByMouse
@ WA_Hover
Definition qnamespace.h:340
@ WA_OpaquePaintEvent
Definition qnamespace.h:287
@ IntersectClip
@ LeftToolBarArea
@ BottomToolBarArea
@ TopToolBarArea
@ RightToolBarArea
@ LeftToRight
@ RightToLeft
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
ArrowType
@ UpArrow
@ RightArrow
@ LeftArrow
@ DownArrow
@ TextSingleLine
Definition qnamespace.h:170
@ TextDontClip
Definition qnamespace.h:171
@ TextHideMnemonic
Definition qnamespace.h:178
@ TextShowMnemonic
Definition qnamespace.h:173
@ white
Definition qnamespace.h:31
@ transparent
Definition qnamespace.h:47
@ black
Definition qnamespace.h:30
@ NoPen
@ NoBrush
QTextStream & center(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignCenter) on stream and returns stream.
@ WindowContextHelpButtonHint
Definition qnamespace.h:231
@ WindowMaximizeButtonHint
Definition qnamespace.h:229
@ WindowMinimizeButtonHint
Definition qnamespace.h:228
@ WindowShadeButtonHint
Definition qnamespace.h:232
@ WindowTitleHint
Definition qnamespace.h:226
@ WindowSystemMenuHint
Definition qnamespace.h:227
@ ElideMiddle
Definition qnamespace.h:191
@ ElideRight
Definition qnamespace.h:190
Definition image.cpp:4
QRectF fillRect(QRect rect, int background)
static jboolean copy(JNIEnv *, jobject)
#define Q_FALLTHROUGH()
#define qApp
static QString header(const QString &name)
void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, int lineWidth, const QBrush *fill)
Q_WIDGETS_EXPORT void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules=QTileRules(), QDrawBorderPixmap::DrawingHints hints=QDrawBorderPixmap::DrawingHints())
static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
static QByteArray cacheKey(Args &&...args)
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
GLenum mode
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLuint GLfloat GLfloat GLfloat x1
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei width
GLuint color
[2]
GLenum type
GLbitfield flags
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLsizei const GLint * box
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLfixed GLfixed GLint GLint GLfixed points
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLfloat * val
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLsizei len
GLfloat GLfloat GLfloat alpha
Definition qopenglext.h:418
Q_GUI_EXPORT QPalette qt_fusionPalette()
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
static QRectF alignedRect(bool mirrored, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
constexpr int qGray(int r, int g, int b)
Definition qrgb.h:36
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
QPixmap styleCachePixmap(const QSize &size, qreal pixelRatio)
Definition qstyle_p.h:38
#define BEGIN_STYLE_PIXMAPCACHE(a)
Definition qstyle_p.h:46
#define END_STYLE_PIXMAPCACHE
Definition qstyle_p.h:66
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define QT_CONFIG(feature)
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
#define Q_INT64_C(c)
Definition qtypes.h:57
static const uint base
Definition qurlidna.cpp:20
static const int windowsItemFrame
static const int windowsItemVMargin
QObject * styleObject(const QStyleOption *option)
QString title
[35]
QScrollBar * scrollBar
QPropertyAnimation animation
[0]
p rx()++
QRect r2(QPoint(100, 200), QSize(11, 16))
QGraphicsItem * item
QApplication app(argc, argv)
[0]
widget render & pixmap
QPainter painter(this)
[7]
aWidget window() -> setWindowTitle("New Window Title")
[2]
QFrame frame
[0]
QSpinBox * spinBox
[0]
QCheckBox * checkbox
[0]
QNetworkProxy proxy
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18