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 "qwindowsstyle_p.h"
5#include "qwindowsstyle_p_p.h"
6
7#if QT_CONFIG(style_windows) || defined(QT_PLUGIN)
8
9#include "qapplication.h"
10#include "qbitmap.h"
11#include "qdrawutil.h" // for now
12#include "qevent.h"
13#if QT_CONFIG(menu)
14#include "qmenu.h"
15#endif
16#if QT_CONFIG(menubar)
17#include "qmenubar.h"
18#include <private/qmenubar_p.h>
19#endif
20#include "qpaintengine.h"
21#include "qpainter.h"
22#if QT_CONFIG(rubberband)
23#include "qrubberband.h"
24#endif
25#include "qstyleoption.h"
26#if QT_CONFIG(tabbar)
27#include "qtabbar.h"
28#endif
29#include "qwidget.h"
30#include "qdebug.h"
31#if QT_CONFIG(mainwindow)
32#include "qmainwindow.h"
33#endif
34#include "qfile.h"
35#include "qtextstream.h"
36#include "qpixmapcache.h"
37#if QT_CONFIG(wizard)
38#include "qwizard.h"
39#endif
40#if QT_CONFIG(listview)
41#include "qlistview.h"
42#endif
43#include <private/qmath_p.h>
44#include <qmath.h>
45#include <QtGui/qpainterpath.h>
46#include <QtGui/qscreen.h>
47#include <QtGui/qwindow.h>
48#include <qpa/qplatformtheme.h>
49#include <qpa/qplatformscreen.h>
50#include <private/qguiapplication_p.h>
51#include <private/qhighdpiscaling_p.h>
52#include <qpa/qplatformintegration.h>
53#include <private/qwidget_p.h>
54
55#include <private/qstylehelper_p.h>
56#if QT_CONFIG(animation)
57#include <private/qstyleanimation_p.h>
58#endif
59
60#include <algorithm>
61
62QT_BEGIN_NAMESPACE
63
64#if defined(Q_OS_WIN)
65
66QT_BEGIN_INCLUDE_NAMESPACE
67#include "qt_windows.h"
68QT_END_INCLUDE_NAMESPACE
69# ifndef COLOR_GRADIENTACTIVECAPTION
70# define COLOR_GRADIENTACTIVECAPTION 27
71# endif
72# ifndef COLOR_GRADIENTINACTIVECAPTION
73# define COLOR_GRADIENTINACTIVECAPTION 28
74# endif
75
76Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &);
77#endif //Q_OS_WIN
78
79QT_BEGIN_INCLUDE_NAMESPACE
80#include <limits.h>
81QT_END_INCLUDE_NAMESPACE
82
83enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
84
85/*
86 \internal
87*/
88
89QWindowsStylePrivate::QWindowsStylePrivate() = default;
90
91// Returns \c true if the toplevel parent of \a widget has seen the Alt-key
92bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
93{
94 widget = widget->window();
95 return seenAlt.contains(t: widget);
96}
97
98/*!
99 \reimp
100*/
101bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
102{
103 // Records Alt- and Focus events
104 if (!o->isWidgetType())
105 return QObject::eventFilter(watched: o, event: e);
106
107 QWidget *widget = qobject_cast<QWidget*>(o);
108 Q_D(QWindowsStyle);
109 switch(e->type()) {
110 case QEvent::KeyPress:
111 if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
112 widget = widget->window();
113
114 // Alt has been pressed - find all widgets that care
115 const QList<QWidget *> children = widget->findChildren<QWidget *>();
116 auto ignorable = [](QWidget *w) {
117 return w->isWindow() || !w->isVisible()
118 || w->style()->styleHint(stylehint: SH_UnderlineShortcut, opt: nullptr, widget: w);
119 };
120 // Update states before repainting
121 d->seenAlt.append(t: widget);
122 d->alt_down = true;
123
124 // Repaint all relevant widgets
125 for (QWidget *w : children) {
126 if (!ignorable(w))
127 w->update();
128 }
129 }
130 break;
131 case QEvent::KeyRelease:
132 if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
133 widget = widget->window();
134
135 // Update state and repaint the menu bars.
136 d->alt_down = false;
137#if QT_CONFIG(menubar)
138 const QList<QMenuBar *> menuBars = widget->findChildren<QMenuBar *>();
139 for (QWidget *w : menuBars)
140 w->update();
141#endif
142 }
143 break;
144 case QEvent::Close:
145 // Reset widget when closing
146 d->seenAlt.removeAll(t: widget);
147 d->seenAlt.removeAll(t: widget->window());
148 break;
149 default:
150 break;
151 }
152 return QCommonStyle::eventFilter(watched: o, event: e);
153}
154
155/*!
156 \class QWindowsStyle
157 \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
158
159 \ingroup appearance
160 \inmodule QtWidgets
161 \internal
162
163 This style is Qt's default GUI style on Windows.
164
165 \image qwindowsstyle.png
166 \sa QWindowsVistaStyle, QMacStyle, QFusionStyle
167*/
168
169/*!
170 Constructs a QWindowsStyle object.
171*/
172QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
173{
174}
175
176/*!
177 \internal
178
179 Constructs a QWindowsStyle object.
180*/
181QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
182{
183}
184
185
186/*! Destroys the QWindowsStyle object. */
187QWindowsStyle::~QWindowsStyle()
188{
189}
190
191#ifdef Q_OS_WIN
192static inline QRgb colorref2qrgb(COLORREF col)
193{
194 return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
195}
196#endif
197
198/*! \reimp */
199void QWindowsStyle::polish(QApplication *app)
200{
201 QCommonStyle::polish(app);
202 QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
203 // We only need the overhead when shortcuts are sometimes hidden
204 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: nullptr) && app)
205 app->installEventFilter(filterObj: this);
206
207 const auto &palette = QGuiApplication::palette();
208 d->activeGradientCaptionColor = palette.highlight().color();
209 d->activeCaptionColor = d->activeGradientCaptionColor;
210 d->inactiveGradientCaptionColor = palette.dark().color();
211 d->inactiveCaptionColor = d->inactiveGradientCaptionColor;
212 d->inactiveCaptionText = palette.window().color();
213
214#if defined(Q_OS_WIN) //fetch native title bar colors
215 if (app->desktopSettingsAware()){
216 DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
217 DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
218 DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
219 DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
220 DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
221 d->activeCaptionColor = colorref2qrgb(activeCaption);
222 d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
223 d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
224 d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
225 d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
226 }
227#endif
228}
229
230/*! \reimp */
231void QWindowsStyle::unpolish(QApplication *app)
232{
233 QCommonStyle::unpolish(application: app);
234 app->removeEventFilter(obj: this);
235}
236
237/*! \reimp */
238void QWindowsStyle::polish(QWidget *widget)
239{
240 QCommonStyle::polish(widget);
241}
242
243/*! \reimp */
244void QWindowsStyle::unpolish(QWidget *widget)
245{
246 QCommonStyle::unpolish(widget);
247}
248
249/*!
250 \reimp
251*/
252void QWindowsStyle::polish(QPalette &pal)
253{
254 QCommonStyle::polish(pal);
255}
256
257int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget)
258{
259#if defined(Q_OS_WIN)
260 // The pixel metrics are in device indepentent pixels;
261 // hardcode DPI to 1x 96 DPI.
262 const int dpi = 96;
263
264 switch (pm) {
265 case QStyle::PM_DockWidgetFrameWidth:
266 return GetSystemMetricsForDpi(SM_CXFRAME, dpi);
267
268 case QStyle::PM_TitleBarHeight: {
269 const int resizeBorderThickness =
270 GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
271 if (widget && (widget->windowType() == Qt::Tool))
272 return GetSystemMetricsForDpi(SM_CYSMCAPTION, dpi) + resizeBorderThickness;
273 return GetSystemMetricsForDpi(SM_CYCAPTION, dpi) + resizeBorderThickness;
274 }
275
276 case QStyle::PM_ScrollBarExtent:
277 {
278 NONCLIENTMETRICS ncm;
279 ncm.cbSize = sizeof(NONCLIENTMETRICS);
280 if (SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpi))
281 return qMax(ncm.iScrollHeight, ncm.iScrollWidth);
282 }
283 break;
284
285 case QStyle::PM_MdiSubWindowFrameWidth:
286 return GetSystemMetricsForDpi(SM_CYFRAME, dpi);
287
288 default:
289 break;
290 }
291#else // Q_OS_WIN
292 Q_UNUSED(pm);
293 Q_UNUSED(widget);
294#endif
295 return QWindowsStylePrivate::InvalidMetric;
296}
297
298int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
299{
300 switch (pm) {
301 case QStyle::PM_ToolBarItemSpacing:
302 return 0;
303 case QStyle::PM_ButtonDefaultIndicator:
304 case QStyle::PM_ButtonShiftHorizontal:
305 case QStyle::PM_ButtonShiftVertical:
306 case QStyle::PM_MenuHMargin:
307 case QStyle::PM_MenuVMargin:
308 case QStyle::PM_ToolBarItemMargin:
309 return 1;
310 case QStyle::PM_DockWidgetSeparatorExtent:
311 return 4;
312#if QT_CONFIG(tabbar)
313 case QStyle::PM_TabBarTabShiftHorizontal:
314 return 0;
315 case QStyle::PM_TabBarTabShiftVertical:
316 return 2;
317#endif
318
319#if QT_CONFIG(slider)
320 case QStyle::PM_SliderLength:
321 return 11;
322#endif // QT_CONFIG(slider)
323
324#if QT_CONFIG(menu)
325 case QStyle::PM_MenuBarHMargin:
326 case QStyle::PM_MenuBarVMargin:
327 case QStyle::PM_MenuBarPanelWidth:
328 return 0;
329 case QStyle::PM_SmallIconSize:
330 return 16;
331 case QStyle::PM_LargeIconSize:
332 return 32;
333 case QStyle::PM_DockWidgetTitleMargin:
334 return 2;
335 case QStyle::PM_DockWidgetTitleBarButtonMargin:
336 case QStyle::PM_DockWidgetFrameWidth:
337 return 4;
338
339#endif // QT_CONFIG(menu)
340 case QStyle::PM_ToolBarHandleExtent:
341 return 10;
342 default:
343 break;
344 }
345 return QWindowsStylePrivate::InvalidMetric;
346}
347
348static QScreen *screenOf(const QWidget *w)
349{
350 if (w) {
351 if (auto screen = qt_widget_private(widget: const_cast<QWidget *>(w))->associatedScreen())
352 return screen;
353 }
354 return QGuiApplication::primaryScreen();
355}
356
357// Calculate the overall scale factor to obtain Qt Device Independent
358// Pixels from a native Windows size.
359qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
360{
361 return qreal(1) / QHighDpiScaling::factor(context: screenOf(w: widget));
362}
363
364/*!
365 \reimp
366*/
367int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
368{
369 int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget);
370 if (ret != QWindowsStylePrivate::InvalidMetric)
371 return ret;
372
373 ret = QWindowsStylePrivate::fixedPixelMetric(pm);
374 if (ret != QWindowsStylePrivate::InvalidMetric)
375 return int(QStyleHelper::dpiScaled(value: ret, option: opt));
376
377 ret = 0;
378
379 switch (pm) {
380 case PM_MaximumDragDistance:
381 ret = QCommonStyle::pixelMetric(m: PM_MaximumDragDistance, opt, widget);
382 if (ret == -1)
383 ret = 60;
384 break;
385
386#if QT_CONFIG(slider)
387 // Returns the number of pixels to use for the business part of the
388 // slider (i.e., the non-tickmark portion). The remaining space is shared
389 // equally between the tickmark regions.
390 case PM_SliderControlThickness:
391 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
392 int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
393 int ticks = sl->tickPosition;
394 int n = 0;
395 if (ticks & QSlider::TicksAbove)
396 ++n;
397 if (ticks & QSlider::TicksBelow)
398 ++n;
399 if (!n) {
400 ret = space;
401 break;
402 }
403
404 int thick = 6; // Magic constant to get 5 + 16 + 5
405 if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
406 thick += proxy()->pixelMetric(metric: PM_SliderLength, option: sl, widget) / 4;
407
408 space -= thick;
409 if (space > 0)
410 thick += (space * 2) / (n + 2);
411 ret = thick;
412 }
413 break;
414#endif // QT_CONFIG(slider)
415
416 case PM_IconViewIconSize:
417 ret = proxy()->pixelMetric(metric: PM_LargeIconSize, option: opt, widget);
418 break;
419
420 case PM_SplitterWidth:
421 ret = QStyleHelper::dpiScaled(value: 4, option: opt);
422 break;
423
424 default:
425 ret = QCommonStyle::pixelMetric(m: pm, opt, widget);
426 break;
427 }
428
429 return ret;
430}
431
432/*!
433 \reimp
434 */
435QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
436 const QWidget *widget) const
437{
438 return QCommonStyle::standardPixmap(sp: standardPixmap, opt, widget);
439}
440
441/*! \reimp */
442int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
443 QStyleHintReturn *returnData) const
444{
445 int ret = 0;
446
447 switch (hint) {
448 case SH_EtchDisabledText: {
449 const QPalette pal = opt ? opt->palette
450 : widget ? widget->palette()
451 : QPalette();
452 ret = pal.window().color().lightness() > pal.text().color().lightness()
453 ? 1 : 0;
454 break;
455 }
456 case SH_Slider_SnapToValue:
457 case SH_PrintDialog_RightAlignButtons:
458 case SH_FontDialog_SelectAssociatedText:
459 case SH_Menu_AllowActiveAndDisabled:
460 case SH_MenuBar_AltKeyNavigation:
461 case SH_MenuBar_MouseTracking:
462 case SH_Menu_MouseTracking:
463 case SH_ComboBox_ListMouseTracking:
464 case SH_Slider_StopMouseOverSlider:
465 case SH_MainWindow_SpaceBelowMenuBar:
466 ret = 1;
467
468 break;
469 case SH_ItemView_ShowDecorationSelected:
470#if QT_CONFIG(listview)
471 if (qobject_cast<const QListView*>(object: widget))
472 ret = 1;
473#endif
474 break;
475 case SH_ItemView_ChangeHighlightOnFocus:
476 ret = 1;
477 break;
478 case SH_ToolBox_SelectedPageTitleBold:
479 ret = 0;
480 break;
481
482#if defined(Q_OS_WIN)
483 case SH_UnderlineShortcut:
484 {
485 ret = 1;
486 BOOL cues = false;
487 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
488 ret = int(cues);
489 // Do nothing if we always paint underlines
490 Q_D(const QWindowsStyle);
491 if (!ret && widget && d) {
492#if QT_CONFIG(menubar)
493 const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
494 if (!menuBar && qobject_cast<const QMenu *>(widget)) {
495 QWidget *w = QApplication::activeWindow();
496 if (w && w != widget)
497 menuBar = w->findChild<QMenuBar *>();
498 }
499 // If we paint a menu bar draw underlines if is in the keyboardState
500 if (menuBar) {
501 if (menuBar->d_func()->keyboardState || d->altDown())
502 ret = 1;
503 // Otherwise draw underlines if the toplevel widget has seen an alt-press
504 } else
505#endif // QT_CONFIG(menubar)
506 if (d->hasSeenAlt(widget)) {
507 ret = 1;
508 }
509 }
510#if QT_CONFIG(accessibility)
511 if (!ret && opt && opt->type == QStyleOption::SO_MenuItem
512 && QStyleHelper::isInstanceOf(opt->styleObject, QAccessible::MenuItem)
513 && opt->styleObject->property("_q_showUnderlined").toBool())
514 ret = 1;
515#endif // QT_CONFIG(accessibility)
516 break;
517 }
518#endif // Q_OS_WIN
519 case SH_Menu_SubMenuSloppyCloseTimeout:
520 case SH_Menu_SubMenuPopupDelay: {
521#if defined(Q_OS_WIN)
522 DWORD delay;
523 if (SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0))
524 ret = delay;
525 else
526#endif // Q_OS_WIN
527 ret = 400;
528 break;
529 }
530#if QT_CONFIG(rubberband)
531 case SH_RubberBand_Mask:
532 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
533 ret = 0;
534 if (rbOpt->shape == QRubberBand::Rectangle) {
535 ret = true;
536 if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hint: returnData)) {
537 mask->region = opt->rect;
538 int size = 1;
539 if (widget && widget->isWindow())
540 size = 4;
541 mask->region -= opt->rect.adjusted(xp1: size, yp1: size, xp2: -size, yp2: -size);
542 }
543 }
544 }
545 break;
546#endif // QT_CONFIG(rubberband)
547#if QT_CONFIG(wizard)
548 case SH_WizardStyle:
549 ret = QWizard::ModernStyle;
550 break;
551#endif
552 case SH_ItemView_ArrowKeysNavigateIntoChildren:
553 ret = true;
554 break;
555 case SH_DialogButtonBox_ButtonsHaveIcons:
556 ret = 0;
557 break;
558 default:
559 ret = QCommonStyle::styleHint(sh: hint, opt, w: widget, shret: returnData);
560 break;
561 }
562 return ret;
563}
564
565/*! \reimp */
566void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
567 const QWidget *w) const
568{
569 // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
570 bool doRestore = false;
571
572 switch (pe) {
573#if QT_CONFIG(toolbar)
574 case PE_IndicatorToolBarSeparator:
575 {
576 QRect rect = opt->rect;
577 const int margin = 2;
578 QPen oldPen = p->pen();
579 if (opt->state & State_Horizontal){
580 const int offset = rect.width()/2;
581 p->setPen(opt->palette.dark().color());
582 p->drawLine(x1: rect.bottomLeft().x() + offset,
583 y1: rect.bottomLeft().y() - margin,
584 x2: rect.topLeft().x() + offset,
585 y2: rect.topLeft().y() + margin);
586 p->setPen(opt->palette.light().color());
587 p->drawLine(x1: rect.bottomLeft().x() + offset + 1,
588 y1: rect.bottomLeft().y() - margin,
589 x2: rect.topLeft().x() + offset + 1,
590 y2: rect.topLeft().y() + margin);
591 }
592 else{ //Draw vertical separator
593 const int offset = rect.height()/2;
594 p->setPen(opt->palette.dark().color());
595 p->drawLine(x1: rect.topLeft().x() + margin ,
596 y1: rect.topLeft().y() + offset,
597 x2: rect.topRight().x() - margin,
598 y2: rect.topRight().y() + offset);
599 p->setPen(opt->palette.light().color());
600 p->drawLine(x1: rect.topLeft().x() + margin ,
601 y1: rect.topLeft().y() + offset + 1,
602 x2: rect.topRight().x() - margin,
603 y2: rect.topRight().y() + offset + 1);
604 }
605 p->setPen(oldPen);
606 }
607 break;
608 case PE_IndicatorToolBarHandle:
609 p->save();
610 p->translate(dx: opt->rect.x(), dy: opt->rect.y());
611 if (opt->state & State_Horizontal) {
612 int x = opt->rect.width() / 2 - 4;
613 if (opt->direction == Qt::RightToLeft)
614 x -= 2;
615 if (opt->rect.height() > 4) {
616 qDrawShadePanel(p, x, y: 2, w: 3, h: opt->rect.height() - 4,
617 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
618 qDrawShadePanel(p, x: x + 3, y: 2, w: 3, h: opt->rect.height() - 4,
619 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
620 }
621 } else {
622 if (opt->rect.width() > 4) {
623 int y = opt->rect.height() / 2 - 4;
624 qDrawShadePanel(p, x: 2, y, w: opt->rect.width() - 4, h: 3,
625 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
626 qDrawShadePanel(p, x: 2, y: y + 3, w: opt->rect.width() - 4, h: 3,
627 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
628 }
629 }
630 p->restore();
631 break;
632
633#endif // QT_CONFIG(toolbar)
634 case PE_FrameButtonTool:
635 case PE_PanelButtonTool: {
636 QPen oldPen = p->pen();
637#if QT_CONFIG(dockwidget)
638 if (w && w->inherits(classname: "QDockWidgetTitleButton")) {
639 if (const QWidget *dw = w->parentWidget())
640 if (dw->isWindow()){
641 qDrawWinButton(p, r: opt->rect.adjusted(xp1: 1, yp1: 1, xp2: 0, yp2: 0), pal: opt->palette, sunken: opt->state & (State_Sunken | State_On),
642 fill: &opt->palette.button());
643
644 return;
645 }
646 }
647#endif // QT_CONFIG(dockwidget)
648 QBrush fill;
649 bool stippled;
650 bool panel = (pe == PE_PanelButtonTool);
651 if ((!(opt->state & State_Sunken ))
652 && (!(opt->state & State_Enabled)
653 || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
654 && (opt->state & State_On)) {
655 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
656 stippled = true;
657 } else {
658 fill = opt->palette.brush(cr: QPalette::Button);
659 stippled = false;
660 }
661
662 if (opt->state & (State_Raised | State_Sunken | State_On)) {
663 if (opt->state & State_AutoRaise) {
664 if (opt->state & (State_Enabled | State_Sunken | State_On)){
665 if (panel)
666 qDrawShadePanel(p, r: opt->rect, pal: opt->palette,
667 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1, fill: &fill);
668 else
669 qDrawShadeRect(p, r: opt->rect, pal: opt->palette,
670 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1);
671 }
672 if (stippled) {
673 p->setPen(opt->palette.button().color());
674 p->drawRect(r: opt->rect.adjusted(xp1: 1,yp1: 1,xp2: -2,yp2: -2));
675 }
676 } else {
677 qDrawWinButton(p, r: opt->rect, pal: opt->palette,
678 sunken: opt->state & (State_Sunken | State_On), fill: panel ? &fill : nullptr);
679 }
680 } else {
681 p->fillRect(opt->rect, fill);
682 }
683 p->setPen(oldPen);
684 break; }
685 case PE_PanelButtonCommand:
686 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
687 QBrush fill;
688 State flags = opt->state;
689 QPalette pal = opt->palette;
690 QRect r = opt->rect;
691 if (! (flags & State_Sunken) && (flags & State_On))
692 fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
693 else
694 fill = pal.brush(cr: QPalette::Button);
695
696 if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
697 p->setPen(pal.dark().color());
698 p->setBrush(fill);
699 p->drawRect(r: r.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1));
700 } else if (flags & (State_Raised | State_On | State_Sunken)) {
701 qDrawWinButton(p, r, pal, sunken: flags & (State_Sunken | State_On),
702 fill: &fill);
703 } else {
704 p->fillRect(r, fill);
705 }
706 }
707 break;
708 case PE_FrameDefaultButton: {
709 QPen oldPen = p->pen();
710 p->setPen(QPen(opt->palette.shadow().color(), 0));
711 QRectF rect = opt->rect;
712 const qreal dpi = QStyleHelper::dpi(option: opt);
713 const qreal topLevelAdjustment = QStyleHelper::dpiScaled(value: 0.5, dpi);
714 const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(value: -1.5, dpi);
715 rect.adjust(xp1: topLevelAdjustment, yp1: topLevelAdjustment,
716 xp2: bottomRightAdjustment, yp2: bottomRightAdjustment);
717 p->drawRect(rect);
718 p->setPen(oldPen);
719 break;
720 }
721 case PE_IndicatorCheckBox: {
722 QBrush fill;
723 if (opt->state & State_NoChange)
724 fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
725 else if (opt->state & State_Sunken)
726 fill = opt->palette.button();
727 else if (opt->state & State_Enabled)
728 fill = opt->palette.base();
729 else
730 fill = opt->palette.window();
731 p->save();
732 doRestore = true;
733 qDrawWinPanel(p, r: opt->rect, pal: opt->palette, sunken: true, fill: &fill);
734 if (opt->state & State_NoChange)
735 p->setPen(opt->palette.dark().color());
736 else
737 p->setPen(opt->palette.text().color());
738 }
739 Q_FALLTHROUGH();
740 case PE_IndicatorItemViewItemCheck:
741 if (!doRestore) {
742 p->save();
743 doRestore = true;
744 }
745#if QT_CONFIG(itemviews)
746 if (pe == PE_IndicatorItemViewItemCheck) {
747 const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
748 p->setPen(itemViewOpt
749 && itemViewOpt->showDecorationSelected
750 && opt->state & State_Selected
751 ? opt->palette.highlightedText().color()
752 : opt->palette.text().color());
753 if (opt->state & State_NoChange)
754 p->setBrush(opt->palette.brush(cr: QPalette::Button));
755 p->drawRect(x: opt->rect.x() + 1, y: opt->rect.y() + 1, w: opt->rect.width() - 2, h: opt->rect.height() - 2);
756 }
757#endif // QT_CONFIG(itemviews)
758 if (!(opt->state & State_Off)) {
759 std::array<QPointF, 6> points;
760 qreal scaleh = opt->rect.width() / 12.0;
761 qreal scalev = opt->rect.height() / 12.0;
762 points[0] = { opt->rect.x() + qreal(3.5) * scaleh, opt->rect.y() + qreal(5.5) * scalev };
763 points[1] = { points[0].x(), points[0].y() + 2 * scalev };
764 points[2] = { points[1].x() + 2 * scaleh, points[1].y() + 2 * scalev };
765 points[3] = { points[2].x() + 4 * scaleh, points[2].y() - 4 * scalev };
766 points[4] = { points[3].x(), points[3].y() - 2 * scalev };
767 points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev };
768 p->setPen(QPen(opt->palette.text().color(), 0));
769 p->setBrush(opt->palette.text());
770 p->drawPolygon(points: points.data(), pointCount: static_cast<int>(points.size()));
771 }
772 if (doRestore)
773 p->restore();
774 break;
775 case PE_FrameFocusRect:
776 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
777 //### check for d->alt_down
778 if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt, widget: w))
779 return;
780 QRect r = opt->rect;
781 p->save();
782 p->setBackgroundMode(Qt::TransparentMode);
783 QColor bg_col = fropt->backgroundColor;
784 if (!bg_col.isValid())
785 bg_col = p->background().color();
786 // Create an "XOR" color.
787 QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
788 (bg_col.green() ^ 0xff) & 0xff,
789 (bg_col.blue() ^ 0xff) & 0xff);
790 p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
791 p->setBrushOrigin(r.topLeft());
792 p->setPen(Qt::NoPen);
793 p->drawRect(x: r.left(), y: r.top(), w: r.width(), h: 1); // Top
794 p->drawRect(x: r.left(), y: r.bottom(), w: r.width(), h: 1); // Bottom
795 p->drawRect(x: r.left(), y: r.top(), w: 1, h: r.height()); // Left
796 p->drawRect(x: r.right(), y: r.top(), w: 1, h: r.height()); // Right
797 p->restore();
798 }
799 break;
800 case PE_IndicatorRadioButton:
801 {
802 QRect r = opt->rect;
803 p->save();
804 p->setRenderHint(hint: QPainter::Antialiasing, on: true);
805
806 QPointF circleCenter = r.center() + QPoint(1, 1);
807 qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1;
808
809 QPainterPath path1;
810 path1.addEllipse(center: circleCenter, rx: radius, ry: radius);
811 radius *= 0.85;
812 QPainterPath path2;
813 path2.addEllipse(center: circleCenter, rx: radius, ry: radius);
814 radius *= 0.85;
815 QPainterPath path3;
816 path3.addEllipse(center: circleCenter, rx: radius, ry: radius);
817 radius *= 0.5;
818 QPainterPath path4;
819 path4.addEllipse(center: circleCenter, rx: radius, ry: radius);
820
821 QPolygon topLeftPol, bottomRightPol;
822 topLeftPol.setPoints(nPoints: 3, firstx: r.x(), firsty: r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y());
823 bottomRightPol.setPoints(nPoints: 3, firstx: r.x(), firsty: r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y());
824
825 p->setClipRegion(QRegion(topLeftPol));
826 p->setPen(opt->palette.dark().color());
827 p->setBrush(opt->palette.dark());
828 p->drawPath(path: path1);
829 p->setPen(opt->palette.shadow().color());
830 p->setBrush(opt->palette.shadow());
831 p->drawPath(path: path2);
832
833 p->setClipRegion(QRegion(bottomRightPol));
834 p->setPen(opt->palette.light().color());
835 p->setBrush(opt->palette.light());
836 p->drawPath(path: path1);
837 p->setPen(opt->palette.midlight().color());
838 p->setBrush(opt->palette.midlight());
839 p->drawPath(path: path2);
840
841 QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ?
842 opt->palette.button().color() : opt->palette.base().color();
843
844 p->setClipping(false);
845 p->setPen(fillColor);
846 p->setBrush(fillColor);
847 p->drawPath(path: path3);
848
849 if (opt->state & State_On) {
850 p->setPen(opt->palette.text().color());
851 p->setBrush(opt->palette.text());
852 p->drawPath(path: path4);
853 }
854 p->restore();
855 break;
856 }
857#ifndef QT_NO_FRAME
858 case PE_Frame:
859 case PE_FrameMenu:
860 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
861 if (frame->lineWidth == 2 || pe == PE_Frame) {
862 QPalette popupPal = frame->palette;
863 if (pe == PE_FrameMenu) {
864 popupPal.setColor(acr: QPalette::Light, acolor: frame->palette.window().color());
865 popupPal.setColor(acr: QPalette::Midlight, acolor: frame->palette.light().color());
866 }
867 if (pe == PE_Frame && (frame->state & State_Raised))
868 qDrawWinButton(p, r: frame->rect, pal: popupPal, sunken: frame->state & State_Sunken);
869 else if (pe == PE_Frame && (frame->state & State_Sunken))
870 {
871 popupPal.setColor(acr: QPalette::Midlight, acolor: frame->palette.window().color());
872 qDrawWinPanel(p, r: frame->rect, pal: popupPal, sunken: frame->state & State_Sunken);
873 }
874 else
875 qDrawWinPanel(p, r: frame->rect, pal: popupPal, sunken: frame->state & State_Sunken);
876 } else {
877 QCommonStyle::drawPrimitive(pe, opt, p, w);
878 }
879 } else {
880 QPalette popupPal = opt->palette;
881 popupPal.setColor(acr: QPalette::Light, acolor: opt->palette.window().color());
882 popupPal.setColor(acr: QPalette::Midlight, acolor: opt->palette.light().color());
883 qDrawWinPanel(p, r: opt->rect, pal: popupPal, sunken: opt->state & State_Sunken);
884 }
885 break;
886#endif // QT_NO_FRAME
887 case PE_FrameButtonBevel:
888 case PE_PanelButtonBevel: {
889 QBrush fill;
890 bool panel = pe != PE_FrameButtonBevel;
891 p->setBrushOrigin(opt->rect.topLeft());
892 if (!(opt->state & State_Sunken) && (opt->state & State_On))
893 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
894 else
895 fill = opt->palette.brush(cr: QPalette::Button);
896
897 if (opt->state & (State_Raised | State_On | State_Sunken)) {
898 qDrawWinButton(p, r: opt->rect, pal: opt->palette, sunken: opt->state & (State_Sunken | State_On),
899 fill: panel ? &fill : nullptr);
900 } else {
901 if (panel)
902 p->fillRect(opt->rect, fill);
903 else
904 p->drawRect(r: opt->rect);
905 }
906 break; }
907 case PE_FrameWindow: {
908 QPalette popupPal = opt->palette;
909 popupPal.setColor(acr: QPalette::Light, acolor: opt->palette.window().color());
910 popupPal.setColor(acr: QPalette::Midlight, acolor: opt->palette.light().color());
911 qDrawWinPanel(p, r: opt->rect, pal: popupPal, sunken: opt->state & State_Sunken);
912 break; }
913#if QT_CONFIG(dockwidget)
914 case PE_IndicatorDockWidgetResizeHandle:
915 break;
916 case PE_FrameDockWidget:
917 if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
918 proxy()->drawPrimitive(pe: QStyle::PE_FrameWindow, opt, p, w);
919 }
920 break;
921#endif // QT_CONFIG(dockwidget)
922
923 case PE_FrameStatusBarItem:
924 qDrawShadePanel(p, r: opt->rect, pal: opt->palette, sunken: true, lineWidth: 1, fill: nullptr);
925 break;
926
927 case PE_IndicatorProgressChunk:
928 {
929 bool vertical = false, inverted = false;
930 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
931 vertical = !(pb->state & QStyle::State_Horizontal);
932 inverted = pb->invertedAppearance;
933 }
934
935 int space = 2;
936 int chunksize = proxy()->pixelMetric(metric: PM_ProgressBarChunkWidth, option: opt, widget: w) - space;
937 if (!vertical) {
938 if (opt->rect.width() <= chunksize)
939 space = 0;
940
941 if (inverted)
942 p->fillRect(x: opt->rect.x() + space, y: opt->rect.y(), w: opt->rect.width() - space, h: opt->rect.height(),
943 b: opt->palette.brush(cr: QPalette::Highlight));
944 else
945 p->fillRect(x: opt->rect.x(), y: opt->rect.y(), w: opt->rect.width() - space, h: opt->rect.height(),
946 b: opt->palette.brush(cr: QPalette::Highlight));
947 } else {
948 if (opt->rect.height() <= chunksize)
949 space = 0;
950
951 if (inverted)
952 p->fillRect(x: opt->rect.x(), y: opt->rect.y(), w: opt->rect.width(), h: opt->rect.height() - space,
953 b: opt->palette.brush(cr: QPalette::Highlight));
954 else
955 p->fillRect(x: opt->rect.x(), y: opt->rect.y() + space, w: opt->rect.width(), h: opt->rect.height() - space,
956 b: opt->palette.brush(cr: QPalette::Highlight));
957 }
958 }
959 break;
960
961 case PE_FrameTabWidget: {
962 qDrawWinButton(p, r: opt->rect, pal: opt->palette, sunken: false, fill: nullptr);
963 break;
964 }
965 default:
966 QCommonStyle::drawPrimitive(pe, opt, p, w);
967 }
968}
969
970/*! \reimp */
971void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
972 const QWidget *widget) const
973{
974 switch (ce) {
975#if QT_CONFIG(rubberband)
976 case CE_RubberBand:
977 if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
978 // ### workaround for slow general painter path
979 QPixmap tiledPixmap(16, 16);
980 QPainter pixmapPainter(&tiledPixmap);
981 pixmapPainter.setPen(Qt::NoPen);
982 pixmapPainter.setBrush(Qt::Dense4Pattern);
983 pixmapPainter.setBackground(Qt::white);
984 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
985 pixmapPainter.drawRect(x: 0, y: 0, w: tiledPixmap.width(), h: tiledPixmap.height());
986 pixmapPainter.end();
987 tiledPixmap = QPixmap::fromImage(image: tiledPixmap.toImage());
988 p->save();
989 QRect r = opt->rect;
990 QStyleHintReturnMask mask;
991 if (proxy()->styleHint(stylehint: QStyle::SH_RubberBand_Mask, opt, widget, returnData: &mask))
992 p->setClipRegion(mask.region);
993 p->drawTiledPixmap(x: r.x(), y: r.y(), w: r.width(), h: r.height(), pm: tiledPixmap);
994 p->restore();
995 return;
996 }
997 break;
998#endif // QT_CONFIG(rubberband)
999
1000#if QT_CONFIG(menu) && QT_CONFIG(mainwindow)
1001 case CE_MenuBarEmptyArea:
1002 if (widget && qobject_cast<const QMainWindow *>(object: widget->parentWidget())) {
1003 p->fillRect(opt->rect, opt->palette.button());
1004 QPen oldPen = p->pen();
1005 p->setPen(opt->palette.dark().color());
1006 p->drawLine(p1: opt->rect.bottomLeft(), p2: opt->rect.bottomRight());
1007 p->setPen(oldPen);
1008 }
1009 break;
1010#endif
1011#if QT_CONFIG(menu)
1012 case CE_MenuItem:
1013 if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1014 int x, y, w, h;
1015 menuitem->rect.getRect(ax: &x, ay: &y, aw: &w, ah: &h);
1016 int tab = menuitem->reservedShortcutWidth;
1017 bool dis = !(menuitem->state & State_Enabled);
1018 bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
1019 ? menuitem->checked : false;
1020 bool act = menuitem->state & State_Selected;
1021
1022 // windows always has a check column, regardless whether we have an icon or not
1023 int checkcol = qMax<int>(a: menuitem->maxIconWidth, b: QWindowsStylePrivate::windowsCheckMarkWidth);
1024
1025 QBrush fill = menuitem->palette.brush(cr: act ? QPalette::Highlight : QPalette::Button);
1026 p->fillRect(menuitem->rect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: 0), fill);
1027
1028 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
1029 int yoff = y-1 + h / 2;
1030 p->setPen(menuitem->palette.dark().color());
1031 p->drawLine(x1: x + 2, y1: yoff, x2: x + w - 4, y2: yoff);
1032 p->setPen(menuitem->palette.light().color());
1033 p->drawLine(x1: x + 2, y1: yoff + 1, x2: x + w - 4, y2: yoff + 1);
1034 return;
1035 }
1036
1037 QRect vCheckRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
1038 if (!menuitem->icon.isNull() && checked) {
1039 if (act) {
1040 qDrawShadePanel(p, r: vCheckRect,
1041 pal: menuitem->palette, sunken: true, lineWidth: 1,
1042 fill: &menuitem->palette.brush(cr: QPalette::Button));
1043 } else {
1044 QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
1045 qDrawShadePanel(p, r: vCheckRect, pal: menuitem->palette, sunken: true, lineWidth: 1, fill: &fill);
1046 }
1047 } else if (!act) {
1048 p->fillRect(vCheckRect, menuitem->palette.brush(cr: QPalette::Button));
1049 }
1050
1051 // On Windows Style, if we have a checkable item and an icon we
1052 // draw the icon recessed to indicate an item is checked. If we
1053 // have no icon, we draw a checkmark instead.
1054 if (!menuitem->icon.isNull()) {
1055 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1056 if (act && !dis)
1057 mode = QIcon::Active;
1058 const auto size = proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt, widget);
1059 const auto dpr = QStyleHelper::getDpr(painter: p);
1060 const auto state = checked ? QIcon::On : QIcon::Off;
1061 const auto pixmap = menuitem->icon.pixmap(size: QSize(size, size), devicePixelRatio: dpr, mode, state);
1062 QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize());
1063 pmr.moveCenter(p: vCheckRect.center());
1064 p->setPen(menuitem->palette.text().color());
1065 p->drawPixmap(p: pmr.topLeft(), pm: pixmap);
1066 } else if (checked) {
1067 QStyleOptionMenuItem newMi = *menuitem;
1068 newMi.state = State_None;
1069 if (!dis)
1070 newMi.state |= State_Enabled;
1071 if (act)
1072 newMi.state |= State_On | State_Selected;
1073 newMi.rect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
1074 menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
1075 checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
1076 menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
1077 proxy()->drawPrimitive(pe: PE_IndicatorMenuCheckMark, opt: &newMi, p, w: widget);
1078 }
1079 p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
1080
1081 QColor discol;
1082 if (dis) {
1083 discol = menuitem->palette.text().color();
1084 p->setPen(discol);
1085 }
1086
1087 int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
1088 int xpos = menuitem->rect.x() + xm;
1089 QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1090 w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1091 QRect vTextRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: textRect);
1092 QStringView s(menuitem->text);
1093 if (!s.isEmpty()) { // draw text
1094 p->save();
1095 qsizetype t = s.indexOf(c: u'\t');
1096 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1097 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: menuitem, widget))
1098 text_flags |= Qt::TextHideMnemonic;
1099 text_flags |= Qt::AlignLeft;
1100 if (t >= 0) {
1101 QRect vShortcutRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect,
1102 logicalRect: QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1103 const QString textToDraw = s.mid(pos: t + 1).toString();
1104 if (dis && !act && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget)) {
1105 p->setPen(menuitem->palette.light().color());
1106 p->drawText(r: vShortcutRect.adjusted(xp1: 1, yp1: 1, xp2: 1, yp2: 1), flags: text_flags, text: textToDraw);
1107 p->setPen(discol);
1108 }
1109 p->drawText(r: vShortcutRect, flags: text_flags, text: textToDraw);
1110 s = s.left(n: t);
1111 }
1112 QFont font = menuitem->font;
1113 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1114 font.setBold(true);
1115 p->setFont(font);
1116 const QString textToDraw = s.left(n: t).toString();
1117 if (dis && !act && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget)) {
1118 p->setPen(menuitem->palette.light().color());
1119 p->drawText(r: vTextRect.adjusted(xp1: 1, yp1: 1, xp2: 1, yp2: 1), flags: text_flags, text: textToDraw);
1120 p->setPen(discol);
1121 }
1122 p->drawText(r: vTextRect, flags: text_flags, text: textToDraw);
1123 p->restore();
1124 }
1125 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1126 int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
1127 PrimitiveElement arrow;
1128 arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1129 xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
1130 QRect vSubMenuRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1131 QStyleOptionMenuItem newMI = *menuitem;
1132 newMI.rect = vSubMenuRect;
1133 newMI.state = dis ? State_None : State_Enabled;
1134 if (act)
1135 newMI.palette.setColor(acr: QPalette::ButtonText,
1136 acolor: newMI.palette.highlightedText().color());
1137 proxy()->drawPrimitive(pe: arrow, opt: &newMI, p, w: widget);
1138 }
1139
1140 }
1141 break;
1142#endif // QT_CONFIG(menu)
1143#if QT_CONFIG(menubar)
1144 case CE_MenuBarItem:
1145 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1146 bool active = mbi->state & State_Selected;
1147 bool hasFocus = mbi->state & State_HasFocus;
1148 bool down = mbi->state & State_Sunken;
1149 QStyleOptionMenuItem newMbi = *mbi;
1150 p->fillRect(mbi->rect, mbi->palette.brush(cr: QPalette::Button));
1151 if (active || hasFocus) {
1152 QBrush b = mbi->palette.brush(cr: QPalette::Button);
1153 if (active && down)
1154 p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
1155 if (active && hasFocus)
1156 qDrawShadeRect(p, x: mbi->rect.x(), y: mbi->rect.y(), w: mbi->rect.width(),
1157 h: mbi->rect.height(), pal: mbi->palette, sunken: active && down, lineWidth: 1, midLineWidth: 0, fill: &b);
1158 if (active && down) {
1159 newMbi.rect.translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: mbi, widget),
1160 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: mbi, widget));
1161 p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
1162 }
1163 }
1164 QCommonStyle::drawControl(element: ce, opt: &newMbi, p, w: widget);
1165 }
1166 break;
1167#endif // QT_CONFIG(menubar)
1168#if QT_CONFIG(tabbar)
1169 case CE_TabBarTabShape:
1170 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1171 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1172 && (tab->shape == QTabBar::RoundedNorth
1173 || tab->shape == QTabBar::RoundedSouth));
1174 bool selected = tab->state & State_Selected;
1175 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1176 || (rtlHorTabs
1177 && tab->position == QStyleOptionTab::Beginning));
1178 bool firstTab = ((!rtlHorTabs
1179 && tab->position == QStyleOptionTab::Beginning)
1180 || (rtlHorTabs
1181 && tab->position == QStyleOptionTab::End));
1182 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1183 bool previousSelected =
1184 ((!rtlHorTabs
1185 && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
1186 || (rtlHorTabs
1187 && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
1188 bool nextSelected =
1189 ((!rtlHorTabs
1190 && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
1191 || (rtlHorTabs
1192 && tab->selectedPosition
1193 == QStyleOptionTab::PreviousIsSelected));
1194 int tabBarAlignment = proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: tab, widget);
1195 bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
1196 || (rtlHorTabs
1197 && tabBarAlignment == Qt::AlignRight);
1198
1199 bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
1200 || (rtlHorTabs
1201 && tabBarAlignment == Qt::AlignLeft);
1202
1203 QColor light = tab->palette.light().color();
1204 QColor dark = tab->palette.dark().color();
1205 QColor shadow = tab->palette.shadow().color();
1206 int borderThinkness = proxy()->pixelMetric(metric: PM_TabBarBaseOverlap, option: tab, widget);
1207 if (selected)
1208 borderThinkness /= 2;
1209 QRect r2(opt->rect);
1210 int x1 = r2.left();
1211 int x2 = r2.right();
1212 int y1 = r2.top();
1213 int y2 = r2.bottom();
1214 switch (tab->shape) {
1215 default:
1216 QCommonStyle::drawControl(element: ce, opt: tab, p, w: widget);
1217 break;
1218 case QTabBar::RoundedNorth: {
1219 if (!selected) {
1220 y1 += 2;
1221 x1 += onlyOne || firstTab ? borderThinkness : 0;
1222 x2 -= onlyOne || lastTab ? borderThinkness : 0;
1223 }
1224
1225 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window());
1226
1227 // Delete border
1228 if (selected) {
1229 p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window());
1230 p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window());
1231 }
1232 // Left
1233 if (firstTab || selected || onlyOne || !previousSelected) {
1234 p->setPen(light);
1235 p->drawLine(x1, y1: y1 + 2, x2: x1, y2: y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1236 p->drawPoint(x: x1 + 1, y: y1 + 1);
1237 }
1238 // Top
1239 {
1240 int beg = x1 + (previousSelected ? 0 : 2);
1241 int end = x2 - (nextSelected ? 0 : 2);
1242 p->setPen(light);
1243 p->drawLine(x1: beg, y1, x2: end, y2: y1);
1244 }
1245 // Right
1246 if (lastTab || selected || onlyOne || !nextSelected) {
1247 p->setPen(shadow);
1248 p->drawLine(x1: x2, y1: y1 + 2, x2, y2: y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1249 p->drawPoint(x: x2 - 1, y: y1 + 1);
1250 p->setPen(dark);
1251 p->drawLine(x1: x2 - 1, y1: y1 + 2, x2: x2 - 1, y2: y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1252 }
1253 break; }
1254 case QTabBar::RoundedSouth: {
1255 if (!selected) {
1256 y2 -= 2;
1257 x1 += firstTab ? borderThinkness : 0;
1258 x2 -= lastTab ? borderThinkness : 0;
1259 }
1260
1261 p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1262
1263 // Delete border
1264 if (selected) {
1265 p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window());
1266 p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window());
1267 }
1268 // Left
1269 if (firstTab || selected || onlyOne || !previousSelected) {
1270 p->setPen(light);
1271 p->drawLine(x1, y1: y2 - 2, x2: x1, y2: y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1272 p->drawPoint(x: x1 + 1, y: y2 - 1);
1273 }
1274 // Bottom
1275 {
1276 int beg = x1 + (previousSelected ? 0 : 2);
1277 int end = x2 - (nextSelected ? 0 : 2);
1278 p->setPen(shadow);
1279 p->drawLine(x1: beg, y1: y2, x2: end, y2);
1280 p->setPen(dark);
1281 p->drawLine(x1: beg, y1: y2 - 1, x2: end, y2: y2 - 1);
1282 }
1283 // Right
1284 if (lastTab || selected || onlyOne || !nextSelected) {
1285 p->setPen(shadow);
1286 p->drawLine(x1: x2, y1: y2 - 2, x2, y2: y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1287 p->drawPoint(x: x2 - 1, y: y2 - 1);
1288 p->setPen(dark);
1289 p->drawLine(x1: x2 - 1, y1: y2 - 2, x2: x2 - 1, y2: y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1290 }
1291 break; }
1292 case QTabBar::RoundedWest: {
1293 if (!selected) {
1294 x1 += 2;
1295 y1 += firstTab ? borderThinkness : 0;
1296 y2 -= lastTab ? borderThinkness : 0;
1297 }
1298
1299 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window());
1300
1301 // Delete border
1302 if (selected) {
1303 p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window());
1304 p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window());
1305 }
1306 // Top
1307 if (firstTab || selected || onlyOne || !previousSelected) {
1308 p->setPen(light);
1309 p->drawLine(x1: x1 + 2, y1, x2: x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y2: y1);
1310 p->drawPoint(x: x1 + 1, y: y1 + 1);
1311 }
1312 // Left
1313 {
1314 int beg = y1 + (previousSelected ? 0 : 2);
1315 int end = y2 - (nextSelected ? 0 : 2);
1316 p->setPen(light);
1317 p->drawLine(x1, y1: beg, x2: x1, y2: end);
1318 }
1319 // Bottom
1320 if (lastTab || selected || onlyOne || !nextSelected) {
1321 p->setPen(shadow);
1322 p->drawLine(x1: x1 + 3, y1: y2, x2: x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1323 p->drawPoint(x: x1 + 2, y: y2 - 1);
1324 p->setPen(dark);
1325 p->drawLine(x1: x1 + 3, y1: y2 - 1, x2: x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2: y2 - 1);
1326 p->drawPoint(x: x1 + 1, y: y2 - 1);
1327 p->drawPoint(x: x1 + 2, y: y2);
1328 }
1329 break; }
1330 case QTabBar::RoundedEast: {
1331 if (!selected) {
1332 x2 -= 2;
1333 y1 += firstTab ? borderThinkness : 0;
1334 y2 -= lastTab ? borderThinkness : 0;
1335 }
1336
1337 p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1338
1339 // Delete border
1340 if (selected) {
1341 p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window());
1342 p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window());
1343 }
1344 // Top
1345 if (firstTab || selected || onlyOne || !previousSelected) {
1346 p->setPen(light);
1347 p->drawLine(x1: x2 - 2, y1, x2: x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y2: y1);
1348 p->drawPoint(x: x2 - 1, y: y1 + 1);
1349 }
1350 // Right
1351 {
1352 int beg = y1 + (previousSelected ? 0 : 2);
1353 int end = y2 - (nextSelected ? 0 : 2);
1354 p->setPen(shadow);
1355 p->drawLine(x1: x2, y1: beg, x2, y2: end);
1356 p->setPen(dark);
1357 p->drawLine(x1: x2 - 1, y1: beg, x2: x2 - 1, y2: end);
1358 }
1359 // Bottom
1360 if (lastTab || selected || onlyOne || !nextSelected) {
1361 p->setPen(shadow);
1362 p->drawLine(x1: x2 - 2, y1: y2, x2: x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1363 p->drawPoint(x: x2 - 1, y: y2 - 1);
1364 p->setPen(dark);
1365 p->drawLine(x1: x2 - 2, y1: y2 - 1, x2: x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2: y2 - 1);
1366 }
1367 break; }
1368 }
1369 }
1370 break;
1371#endif // QT_CONFIG(tabbar)
1372 case CE_ToolBoxTabShape:
1373 qDrawShadePanel(p, r: opt->rect, pal: opt->palette,
1374 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1,
1375 fill: &opt->palette.brush(cr: QPalette::Button));
1376 break;
1377#if QT_CONFIG(splitter)
1378 case CE_Splitter:
1379 p->eraseRect(rect: opt->rect);
1380 break;
1381#endif // QT_CONFIG(splitter)
1382#if QT_CONFIG(scrollbar)
1383 case CE_ScrollBarSubLine:
1384 case CE_ScrollBarAddLine: {
1385 if ((opt->state & State_Sunken)) {
1386 p->setPen(opt->palette.dark().color());
1387 p->setBrush(opt->palette.brush(cr: QPalette::Button));
1388 p->drawRect(r: opt->rect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1));
1389 } else {
1390 QStyleOption buttonOpt = *opt;
1391 if (!(buttonOpt.state & State_Sunken))
1392 buttonOpt.state |= State_Raised;
1393 QPalette pal(opt->palette);
1394 pal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
1395 pal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
1396 qDrawWinButton(p, r: opt->rect, pal, sunken: opt->state & (State_Sunken | State_On),
1397 fill: &opt->palette.brush(cr: QPalette::Button));
1398 }
1399 PrimitiveElement arrow;
1400 if (opt->state & State_Horizontal) {
1401 if (ce == CE_ScrollBarAddLine)
1402 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
1403 else
1404 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1405 } else {
1406 if (ce == CE_ScrollBarAddLine)
1407 arrow = PE_IndicatorArrowDown;
1408 else
1409 arrow = PE_IndicatorArrowUp;
1410 }
1411 QStyleOption arrowOpt = *opt;
1412 arrowOpt.rect = opt->rect.adjusted(xp1: 4, yp1: 4, xp2: -4, yp2: -4);
1413 proxy()->drawPrimitive(pe: arrow, opt: &arrowOpt, p, w: widget);
1414 break; }
1415 case CE_ScrollBarAddPage:
1416 case CE_ScrollBarSubPage: {
1417 QBrush br;
1418 QBrush bg = p->background();
1419 Qt::BGMode bg_mode = p->backgroundMode();
1420 p->setPen(Qt::NoPen);
1421 p->setBackgroundMode(Qt::OpaqueMode);
1422
1423 if (opt->state & State_Sunken) {
1424 br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
1425 p->setBackground(opt->palette.dark().color());
1426 p->setBrush(br);
1427 } else {
1428 const QBrush paletteBrush = opt->palette.brush(cr: QPalette::Light);
1429 if (paletteBrush.style() == Qt::TexturePattern) {
1430 if (qHasPixmapTexture(brush: paletteBrush))
1431 br = QBrush(paletteBrush.texture());
1432 else
1433 br = QBrush(paletteBrush.textureImage());
1434 } else
1435 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1436 p->setBackground(opt->palette.window().color());
1437 p->setBrush(br);
1438 }
1439 p->drawRect(r: opt->rect);
1440 p->setBackground(bg);
1441 p->setBackgroundMode(bg_mode);
1442 break; }
1443 case CE_ScrollBarSlider:
1444 if (!(opt->state & State_Enabled)) {
1445 QBrush br;
1446 const QBrush paletteBrush = opt->palette.brush(cr: QPalette::Light);
1447 if (paletteBrush.style() == Qt::TexturePattern) {
1448 if (qHasPixmapTexture(brush: paletteBrush))
1449 br = QBrush(paletteBrush.texture());
1450 else
1451 br = QBrush(paletteBrush.textureImage());
1452 } else
1453 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1454 p->setPen(Qt::NoPen);
1455 p->setBrush(br);
1456 p->setBackgroundMode(Qt::OpaqueMode);
1457 p->drawRect(r: opt->rect);
1458 } else {
1459 QStyleOptionButton buttonOpt;
1460 buttonOpt.QStyleOption::operator=(other: *opt);
1461 buttonOpt.state = State_Enabled | State_Raised;
1462
1463 QPalette pal(opt->palette);
1464 pal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
1465 pal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
1466 qDrawWinButton(p, r: opt->rect, pal, sunken: false, fill: &opt->palette.brush(cr: QPalette::Button));
1467 }
1468 break;
1469#endif // QT_CONFIG(scrollbar)
1470 case CE_HeaderSection: {
1471 QBrush fill;
1472 if (opt->state & State_On)
1473 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1474 else
1475 fill = opt->palette.brush(cr: QPalette::Button);
1476
1477 if (opt->state & (State_Raised | State_Sunken)) {
1478 qDrawWinButton(p, r: opt->rect, pal: opt->palette, sunken: opt->state & State_Sunken, fill: &fill);
1479 } else {
1480 p->fillRect(opt->rect, fill);
1481 }
1482 break; }
1483#if QT_CONFIG(toolbar)
1484 case CE_ToolBar:
1485 if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
1486 // Reserve the beveled appearance only for mainwindow toolbars
1487 if (!(widget && qobject_cast<const QMainWindow*> (object: widget->parentWidget())))
1488 break;
1489
1490 QRect rect = opt->rect;
1491 bool paintLeftBorder = true;
1492 bool paintRightBorder = true;
1493 bool paintBottomBorder = true;
1494
1495 switch (toolbar->toolBarArea){
1496 case Qt::BottomToolBarArea :
1497 switch(toolbar->positionOfLine){
1498 case QStyleOptionToolBar::Beginning:
1499 case QStyleOptionToolBar::OnlyOne:
1500 paintBottomBorder = false;
1501 break;
1502 default:
1503 break;
1504 }
1505 Q_FALLTHROUGH(); // It continues in the end of the next case
1506 case Qt::TopToolBarArea :
1507 switch(toolbar->positionWithinLine){
1508 case QStyleOptionToolBar::Beginning:
1509 paintLeftBorder = false;
1510 break;
1511 case QStyleOptionToolBar::End:
1512 paintRightBorder = false;
1513 break;
1514 case QStyleOptionToolBar::OnlyOne:
1515 paintRightBorder = false;
1516 paintLeftBorder = false;
1517 break;
1518 default:
1519 break;
1520 }
1521 if (opt->direction == Qt::RightToLeft) //reverse layout changes the order of Beginning/end
1522 std::swap(a&: paintLeftBorder, b&: paintRightBorder);
1523 break;
1524 case Qt::RightToolBarArea :
1525 switch (toolbar->positionOfLine){
1526 case QStyleOptionToolBar::Beginning:
1527 case QStyleOptionToolBar::OnlyOne:
1528 paintRightBorder = false;
1529 break;
1530 default:
1531 break;
1532 }
1533 break;
1534 case Qt::LeftToolBarArea :
1535 switch (toolbar->positionOfLine){
1536 case QStyleOptionToolBar::Beginning:
1537 case QStyleOptionToolBar::OnlyOne:
1538 paintLeftBorder = false;
1539 break;
1540 default:
1541 break;
1542 }
1543 break;
1544 default:
1545 break;
1546 }
1547
1548
1549 //draw top border
1550 p->setPen(opt->palette.light().color());
1551 p->drawLine(p1: rect.topLeft(), p2: rect.topRight());
1552
1553 if (paintLeftBorder){
1554 p->setPen(opt->palette.light().color());
1555 p->drawLine(p1: rect.topLeft(), p2: rect.bottomLeft());
1556 }
1557
1558 if (paintRightBorder){
1559 p->setPen(opt->palette.dark().color());
1560 p->drawLine(p1: rect.topRight(), p2: rect.bottomRight());
1561 }
1562
1563 if (paintBottomBorder){
1564 p->setPen(opt->palette.dark().color());
1565 p->drawLine(p1: rect.bottomLeft(), p2: rect.bottomRight());
1566 }
1567 }
1568 break;
1569
1570
1571#endif // QT_CONFIG(toolbar)
1572
1573 case CE_ProgressBarContents:
1574 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1575 QRect rect = pb->rect;
1576 if (!rect.isValid())
1577 return;
1578
1579 const bool vertical = !(pb->state & QStyle::State_Horizontal);
1580 const bool inverted = pb->invertedAppearance;
1581
1582 QTransform m;
1583 if (vertical) {
1584 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1585 m.rotate(a: 90);
1586 m.translate(dx: 0, dy: -(rect.height() + rect.y()*2));
1587 }
1588 QPalette pal2 = pb->palette;
1589 // Correct the highlight color if it is the same as the background
1590 if (pal2.highlight() == pal2.window())
1591 pal2.setColor(acr: QPalette::Highlight, acolor: pb->palette.color(cg: QPalette::Active,
1592 cr: QPalette::Highlight));
1593 bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1594 if (inverted)
1595 reverse = !reverse;
1596 int w = rect.width();
1597 Q_D(const QWindowsStyle);
1598 if (pb->minimum == 0 && pb->maximum == 0) {
1599 const int unit_width = proxy()->pixelMetric(metric: PM_ProgressBarChunkWidth, option: pb, widget);
1600 QStyleOptionProgressBar pbBits = *pb;
1601 Q_ASSERT(unit_width >0);
1602
1603 pbBits.rect = rect;
1604 pbBits.palette = pal2;
1605
1606 int step = 0;
1607 int chunkCount = w / unit_width + 1;
1608#if QT_CONFIG(animation)
1609 if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(object: d->animation(target: opt->styleObject)))
1610 step = (animation->animationStep() / 3) % chunkCount;
1611 else
1612 d->startAnimation(animation: new QProgressStyleAnimation(d->animationFps, opt->styleObject));
1613#else
1614 Q_UNUSED(d);
1615#endif
1616 int chunksInRow = 5;
1617 int myY = pbBits.rect.y();
1618 int myHeight = pbBits.rect.height();
1619 int chunksToDraw = chunksInRow;
1620
1621 if (step > chunkCount - 5)chunksToDraw = (chunkCount - step);
1622 p->save();
1623 p->setClipRect(m.mapRect(QRectF(rect)).toRect());
1624
1625 int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step;
1626 int x = 0;
1627
1628 for (int i = 0; i < chunksToDraw ; ++i) {
1629 pbBits.rect.setRect(ax: x0 + x, ay: myY, aw: unit_width, ah: myHeight);
1630 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1631 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p, w: widget);
1632 x += reverse ? -unit_width : unit_width;
1633 }
1634 //Draw wrap-around chunks
1635 if ( step > chunkCount-5){
1636 x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
1637 x = 0;
1638 int chunksToDraw = step - (chunkCount - chunksInRow);
1639 for (int i = 0; i < chunksToDraw ; ++i) {
1640 pbBits.rect.setRect(ax: x0 + x, ay: myY, aw: unit_width, ah: myHeight);
1641 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1642 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p, w: widget);
1643 x += reverse ? -unit_width : unit_width;
1644 }
1645 }
1646 p->restore(); //restore state
1647 }
1648 else {
1649#if QT_CONFIG(animation)
1650 d->stopAnimation(target: opt->styleObject);
1651#endif
1652 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1653 }
1654 }
1655 break;
1656
1657#if QT_CONFIG(dockwidget)
1658 case CE_DockWidgetTitle:
1659
1660 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
1661 Q_D(const QWindowsStyle);
1662
1663 const bool verticalTitleBar = dwOpt->verticalTitleBar;
1664
1665 QRect rect = dwOpt->rect;
1666 QRect r = rect;
1667
1668 if (verticalTitleBar) {
1669 r = r.transposed();
1670
1671 p->save();
1672 p->translate(dx: r.left(), dy: r.top() + r.width());
1673 p->rotate(a: -90);
1674 p->translate(dx: -r.left(), dy: -r.top());
1675 }
1676
1677 bool floating = false;
1678 bool active = dwOpt->state & State_Active;
1679 QColor inactiveCaptionTextColor = d->inactiveCaptionText;
1680 if (dwOpt->movable) {
1681 QColor left, right;
1682
1683 //Titlebar gradient
1684 if (opt->state & QStyle::State_Window) {
1685 floating = true;
1686 if (active) {
1687 left = d->activeCaptionColor;
1688 right = d->activeGradientCaptionColor;
1689 } else {
1690 left = d->inactiveCaptionColor;
1691 right = d->inactiveGradientCaptionColor;
1692 }
1693 QBrush fillBrush(left);
1694 if (left != right) {
1695 QPoint p1(r.x(), r.top() + r.height()/2);
1696 QPoint p2(rect.right(), r.top() + r.height()/2);
1697 QLinearGradient lg(p1, p2);
1698 lg.setColorAt(pos: 0, color: left);
1699 lg.setColorAt(pos: 1, color: right);
1700 fillBrush = lg;
1701 }
1702 p->fillRect(r.adjusted(xp1: 0, yp1: 0, xp2: 0, yp2: -3), fillBrush);
1703 }
1704 }
1705 if (!dwOpt->title.isEmpty()) {
1706 QFont oldFont = p->font();
1707 if (floating) {
1708 QFont font = oldFont;
1709 font.setBold(true);
1710 p->setFont(font);
1711 }
1712 QPalette palette = dwOpt->palette;
1713 palette.setColor(acr: QPalette::Window, acolor: inactiveCaptionTextColor);
1714 QRect titleRect = subElementRect(r: SE_DockWidgetTitleBarText, opt, widget);
1715 if (verticalTitleBar) {
1716 titleRect = QRect(r.left() + rect.bottom()
1717 - titleRect.bottom(),
1718 r.top() + titleRect.left() - rect.left(),
1719 titleRect.height(), titleRect.width());
1720 }
1721 proxy()->drawItemText(painter: p, rect: titleRect,
1722 flags: Qt::AlignLeft | Qt::AlignVCenter | Qt::TextHideMnemonic, pal: palette,
1723 enabled: dwOpt->state & State_Enabled, text: dwOpt->title,
1724 textRole: floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
1725 p->setFont(oldFont);
1726 }
1727 if (verticalTitleBar)
1728 p->restore();
1729 }
1730 return;
1731#endif // QT_CONFIG(dockwidget)
1732#if QT_CONFIG(combobox)
1733 case CE_ComboBoxLabel:
1734 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1735 if (cb->state & State_HasFocus) {
1736 p->setPen(cb->palette.highlightedText().color());
1737 p->setBackground(cb->palette.highlight());
1738 } else {
1739 p->setPen(cb->palette.text().color());
1740 p->setBackground(cb->palette.window());
1741 }
1742 }
1743 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1744 break;
1745#endif // QT_CONFIG(combobox)
1746 default:
1747 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1748 }
1749}
1750
1751/*! \reimp */
1752QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
1753{
1754 QRect r;
1755 switch (sr) {
1756 case SE_SliderFocusRect:
1757 case SE_ToolBoxTabContents:
1758 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: opt->rect);
1759 break;
1760 case SE_DockWidgetTitleBarText: {
1761 r = QCommonStyle::subElementRect(r: sr, opt, widget: w);
1762 const QStyleOptionDockWidget *dwOpt
1763 = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
1764 const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
1765 int m = proxy()->pixelMetric(metric: PM_DockWidgetTitleMargin, option: opt, widget: w);
1766 if (verticalTitleBar) {
1767 r.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -m);
1768 } else {
1769 if (opt->direction == Qt::LeftToRight)
1770 r.adjust(dx1: m, dy1: 0, dx2: 0, dy2: 0);
1771 else
1772 r.adjust(dx1: 0, dy1: 0, dx2: -m, dy2: 0);
1773 }
1774 break;
1775 }
1776 case SE_ProgressBarContents:
1777 r = QCommonStyle::subElementRect(r: SE_ProgressBarGroove, opt, widget: w);
1778 r.adjust(dx1: 3, dy1: 3, dx2: -3, dy2: -3);
1779 break;
1780 default:
1781 r = QCommonStyle::subElementRect(r: sr, opt, widget: w);
1782 }
1783 return r;
1784}
1785
1786
1787/*! \reimp */
1788void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
1789 QPainter *p, const QWidget *widget) const
1790{
1791 switch (cc) {
1792#if QT_CONFIG(slider)
1793 case CC_Slider:
1794 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1795 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: slider, widget);
1796 int len = proxy()->pixelMetric(metric: PM_SliderLength, option: slider, widget);
1797 int ticks = slider->tickPosition;
1798 QRect groove = proxy()->subControlRect(cc: CC_Slider, opt: slider, sc: SC_SliderGroove, widget);
1799 QRect handle = proxy()->subControlRect(cc: CC_Slider, opt: slider, sc: SC_SliderHandle, widget);
1800
1801 if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
1802 int mid = thickness / 2;
1803
1804 if (ticks & QSlider::TicksAbove)
1805 mid += len / 8;
1806 if (ticks & QSlider::TicksBelow)
1807 mid -= len / 8;
1808
1809 p->setPen(slider->palette.shadow().color());
1810 if (slider->orientation == Qt::Horizontal) {
1811 qDrawWinPanel(p, x: groove.x(), y: groove.y() + mid - 2,
1812 w: groove.width(), h: 4, pal: slider->palette, sunken: true);
1813 p->drawLine(x1: groove.x() + 1, y1: groove.y() + mid - 1,
1814 x2: groove.x() + groove.width() - 3, y2: groove.y() + mid - 1);
1815 } else {
1816 qDrawWinPanel(p, x: groove.x() + mid - 2, y: groove.y(),
1817 w: 4, h: groove.height(), pal: slider->palette, sunken: true);
1818 p->drawLine(x1: groove.x() + mid - 1, y1: groove.y() + 1,
1819 x2: groove.x() + mid - 1, y2: groove.y() + groove.height() - 3);
1820 }
1821 }
1822
1823 if (slider->subControls & SC_SliderTickmarks) {
1824 QStyleOptionSlider tmpSlider = *slider;
1825 tmpSlider.subControls = SC_SliderTickmarks;
1826 QCommonStyle::drawComplexControl(cc, opt: &tmpSlider, p, w: widget);
1827 }
1828
1829 if (slider->subControls & SC_SliderHandle) {
1830 // 4444440
1831 // 4333310
1832 // 4322210
1833 // 4322210
1834 // 4322210
1835 // 4322210
1836 // *43210*
1837 // **410**
1838 // ***0***
1839 const QColor c0 = slider->palette.shadow().color();
1840 const QColor c1 = slider->palette.dark().color();
1841 // const QColor c2 = g.button();
1842 const QColor c3 = slider->palette.midlight().color();
1843 const QColor c4 = slider->palette.light().color();
1844 QBrush handleBrush;
1845
1846 if (slider->state & State_Enabled) {
1847 handleBrush = slider->palette.color(cr: QPalette::Button);
1848 } else {
1849 handleBrush = QBrush(slider->palette.color(cr: QPalette::Button),
1850 Qt::Dense4Pattern);
1851 }
1852
1853
1854 int x = handle.x(), y = handle.y(),
1855 wi = handle.width(), he = handle.height();
1856
1857 int x1 = x;
1858 int x2 = x+wi-1;
1859 int y1 = y;
1860 int y2 = y+he-1;
1861
1862 Qt::Orientation orient = slider->orientation;
1863 bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
1864 bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
1865
1866 if (slider->state & State_HasFocus) {
1867 QStyleOptionFocusRect fropt;
1868 fropt.QStyleOption::operator=(other: *slider);
1869 fropt.rect = subElementRect(sr: SE_SliderFocusRect, opt: slider, w: widget);
1870 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p, w: widget);
1871 }
1872
1873 if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
1874 Qt::BGMode oldMode = p->backgroundMode();
1875 p->setBackgroundMode(Qt::OpaqueMode);
1876 qDrawWinButton(p, r: QRect(x, y, wi, he), pal: slider->palette, sunken: false,
1877 fill: &handleBrush);
1878 p->setBackgroundMode(oldMode);
1879 return;
1880 }
1881
1882 QSliderDirection dir;
1883
1884 if (orient == Qt::Horizontal)
1885 dir = tickAbove ? SlUp : SlDown;
1886 else
1887 dir = tickAbove ? SlLeft : SlRight;
1888
1889 std::array<QPoint, 5> points;
1890 int d = 0;
1891 switch (dir) {
1892 case SlUp:
1893 y1 = y1 + wi / 2;
1894 d = (wi + 1) / 2 - 1;
1895 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2),
1896 QPoint(x2, y1), QPoint(x1 + d, y1 - d)};
1897 break;
1898 case SlDown:
1899 y2 = y2 - wi / 2;
1900 d = (wi + 1) / 2 - 1;
1901 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x1 + d, y2 + d),
1902 QPoint(x2, y2), QPoint(x2, y1)};
1903 break;
1904 case SlLeft:
1905 d = (he + 1) / 2 - 1;
1906 x1 = x1 + he / 2;
1907 points = {QPoint(x1, y1), QPoint(x1 - d, y1 + d), QPoint(x1,y2),
1908 QPoint(x2, y2), QPoint(x2, y1)};
1909 break;
1910 case SlRight:
1911 d = (he + 1) / 2 - 1;
1912 x2 = x2 - he / 2;
1913 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2),
1914 QPoint(x2 + d, y1 + d), QPoint(x2, y1)};
1915 break;
1916 }
1917
1918 QBrush oldBrush = p->brush();
1919 p->setPen(Qt::NoPen);
1920 p->setBrush(handleBrush);
1921 Qt::BGMode oldMode = p->backgroundMode();
1922 p->setBackgroundMode(Qt::OpaqueMode);
1923 p->drawRect(x: x1, y: y1, w: x2-x1+1, h: y2-y1+1);
1924 p->drawPolygon(points: points.data(), pointCount: static_cast<int>(points.size()));
1925 p->setBrush(oldBrush);
1926 p->setBackgroundMode(oldMode);
1927
1928 if (dir != SlUp) {
1929 p->setPen(c4);
1930 p->drawLine(x1, y1, x2, y2: y1);
1931 p->setPen(c3);
1932 p->drawLine(x1, y1: y1+1, x2, y2: y1+1);
1933 }
1934 if (dir != SlLeft) {
1935 p->setPen(c3);
1936 p->drawLine(x1: x1+1, y1: y1+1, x2: x1+1, y2);
1937 p->setPen(c4);
1938 p->drawLine(x1, y1, x2: x1, y2);
1939 }
1940 if (dir != SlRight) {
1941 p->setPen(c0);
1942 p->drawLine(x1: x2, y1, x2, y2);
1943 p->setPen(c1);
1944 p->drawLine(x1: x2-1, y1: y1+1, x2: x2-1, y2: y2-1);
1945 }
1946 if (dir != SlDown) {
1947 p->setPen(c0);
1948 p->drawLine(x1, y1: y2, x2, y2);
1949 p->setPen(c1);
1950 p->drawLine(x1: x1+1, y1: y2-1, x2: x2-1, y2: y2-1);
1951 }
1952
1953 switch (dir) {
1954 case SlUp:
1955 p->setPen(c4);
1956 p->drawLine(x1, y1, x2: x1+d, y2: y1-d);
1957 p->setPen(c0);
1958 d = wi - d - 1;
1959 p->drawLine(x1: x2, y1, x2: x2-d, y2: y1-d);
1960 d--;
1961 p->setPen(c3);
1962 p->drawLine(x1: x1+1, y1, x2: x1+1+d, y2: y1-d);
1963 p->setPen(c1);
1964 p->drawLine(x1: x2-1, y1, x2: x2-1-d, y2: y1-d);
1965 break;
1966 case SlDown:
1967 p->setPen(c4);
1968 p->drawLine(x1, y1: y2, x2: x1+d, y2: y2+d);
1969 p->setPen(c0);
1970 d = wi - d - 1;
1971 p->drawLine(x1: x2, y1: y2, x2: x2-d, y2: y2+d);
1972 d--;
1973 p->setPen(c3);
1974 p->drawLine(x1: x1+1, y1: y2, x2: x1+1+d, y2: y2+d);
1975 p->setPen(c1);
1976 p->drawLine(x1: x2-1, y1: y2, x2: x2-1-d, y2: y2+d);
1977 break;
1978 case SlLeft:
1979 p->setPen(c4);
1980 p->drawLine(x1, y1, x2: x1-d, y2: y1+d);
1981 p->setPen(c0);
1982 d = he - d - 1;
1983 p->drawLine(x1, y1: y2, x2: x1-d, y2: y2-d);
1984 d--;
1985 p->setPen(c3);
1986 p->drawLine(x1, y1: y1+1, x2: x1-d, y2: y1+1+d);
1987 p->setPen(c1);
1988 p->drawLine(x1, y1: y2-1, x2: x1-d, y2: y2-1-d);
1989 break;
1990 case SlRight:
1991 p->setPen(c4);
1992 p->drawLine(x1: x2, y1, x2: x2+d, y2: y1+d);
1993 p->setPen(c0);
1994 d = he - d - 1;
1995 p->drawLine(x1: x2, y1: y2, x2: x2+d, y2: y2-d);
1996 d--;
1997 p->setPen(c3);
1998 p->drawLine(x1: x2, y1: y1+1, x2: x2+d, y2: y1+1+d);
1999 p->setPen(c1);
2000 p->drawLine(x1: x2, y1: y2-1, x2: x2+d, y2: y2-1-d);
2001 break;
2002 }
2003 }
2004 }
2005 break;
2006#endif // QT_CONFIG(slider)
2007#if QT_CONFIG(scrollbar)
2008 case CC_ScrollBar:
2009 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2010 QStyleOptionSlider newScrollbar = *scrollbar;
2011 if (scrollbar->minimum == scrollbar->maximum)
2012 newScrollbar.state &= ~State_Enabled; //do not draw the slider.
2013 QCommonStyle::drawComplexControl(cc, opt: &newScrollbar, p, w: widget);
2014 }
2015 break;
2016#endif // QT_CONFIG(scrollbar)
2017#if QT_CONFIG(combobox)
2018 case CC_ComboBox:
2019 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2020 QBrush editBrush = cmb->palette.brush(cr: QPalette::Button);
2021 if ((cmb->subControls & SC_ComboBoxFrame)) {
2022 if (cmb->frame) {
2023 QPalette shadePal = opt->palette;
2024 shadePal.setColor(acr: QPalette::Midlight, acolor: shadePal.button().color());
2025 qDrawWinPanel(p, r: opt->rect, pal: shadePal, sunken: true, fill: &editBrush);
2026 }
2027 else {
2028 p->fillRect(opt->rect, editBrush);
2029 }
2030 }
2031 if (cmb->subControls & SC_ComboBoxArrow) {
2032 State flags = State_None;
2033
2034 QRect ar = proxy()->subControlRect(cc: CC_ComboBox, opt: cmb, sc: SC_ComboBoxArrow, widget);
2035 bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
2036 && cmb->state & State_Sunken;
2037 if (sunkenArrow) {
2038 p->setPen(cmb->palette.dark().color());
2039 p->setBrush(cmb->palette.brush(cr: QPalette::Button));
2040 p->drawRect(r: ar.adjusted(xp1: 0,yp1: 0,xp2: -1,yp2: -1));
2041 } else {
2042 // Make qDrawWinButton use the right colors for drawing the shade of the button
2043 QPalette pal(cmb->palette);
2044 pal.setColor(acr: QPalette::Button, acolor: cmb->palette.light().color());
2045 pal.setColor(acr: QPalette::Light, acolor: cmb->palette.button().color());
2046 qDrawWinButton(p, r: ar, pal, sunken: false,
2047 fill: &cmb->palette.brush(cr: QPalette::Button));
2048 }
2049
2050 ar.adjust(dx1: 2, dy1: 2, dx2: -2, dy2: -2);
2051 if (opt->state & State_Enabled)
2052 flags |= State_Enabled;
2053 if (opt->state & State_HasFocus)
2054 flags |= State_HasFocus;
2055
2056 if (sunkenArrow)
2057 flags |= State_Sunken;
2058 QStyleOption arrowOpt = *cmb;
2059 arrowOpt.rect = ar.adjusted(xp1: 1, yp1: 1, xp2: -1, yp2: -1);
2060 arrowOpt.state = flags;
2061 proxy()->drawPrimitive(pe: PE_IndicatorArrowDown, opt: &arrowOpt, p, w: widget);
2062 }
2063
2064 if (cmb->subControls & SC_ComboBoxEditField) {
2065 QRect re = proxy()->subControlRect(cc: CC_ComboBox, opt: cmb, sc: SC_ComboBoxEditField, widget);
2066 if (cmb->state & State_HasFocus && !cmb->editable)
2067 p->fillRect(x: re.x(), y: re.y(), w: re.width(), h: re.height(),
2068 b: cmb->palette.brush(cr: QPalette::Highlight));
2069
2070 if (cmb->state & State_HasFocus) {
2071 p->setPen(cmb->palette.highlightedText().color());
2072 p->setBackground(cmb->palette.highlight());
2073
2074 } else {
2075 p->setPen(cmb->palette.text().color());
2076 p->setBackground(cmb->palette.window());
2077 }
2078
2079 if (cmb->state & State_HasFocus && !cmb->editable) {
2080 QStyleOptionFocusRect focus;
2081 focus.QStyleOption::operator=(other: *cmb);
2082 focus.rect = subElementRect(sr: SE_ComboBoxFocusRect, opt: cmb, w: widget);
2083 focus.state |= State_FocusAtBorder;
2084 focus.backgroundColor = cmb->palette.highlight().color();
2085 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &focus, p, w: widget);
2086 }
2087 }
2088 }
2089 break;
2090#endif // QT_CONFIG(combobox)
2091#if QT_CONFIG(spinbox)
2092 case CC_SpinBox:
2093 if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
2094 QStyleOptionSpinBox copy = *sb;
2095 PrimitiveElement pe;
2096 bool enabled = opt->state & State_Enabled;
2097 if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
2098 QBrush editBrush = sb->palette.brush(cr: QPalette::Base);
2099 QRect r = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxFrame, widget);
2100 QPalette shadePal = sb->palette;
2101 shadePal.setColor(acr: QPalette::Midlight, acolor: shadePal.button().color());
2102 qDrawWinPanel(p, r, pal: shadePal, sunken: true, fill: &editBrush);
2103 }
2104
2105 QPalette shadePal(opt->palette);
2106 shadePal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
2107 shadePal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
2108
2109 if (sb->subControls & SC_SpinBoxUp) {
2110 copy.subControls = SC_SpinBoxUp;
2111 QPalette pal2 = sb->palette;
2112 if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
2113 pal2.setCurrentColorGroup(QPalette::Disabled);
2114 copy.state &= ~State_Enabled;
2115 }
2116
2117 copy.palette = pal2;
2118
2119 if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
2120 copy.state |= State_On;
2121 copy.state |= State_Sunken;
2122 } else {
2123 copy.state |= State_Raised;
2124 copy.state &= ~State_Sunken;
2125 }
2126 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
2127 : PE_IndicatorSpinUp);
2128
2129 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxUp, widget);
2130 qDrawWinButton(p, r: copy.rect, pal: shadePal, sunken: copy.state & (State_Sunken | State_On),
2131 fill: &copy.palette.brush(cr: QPalette::Button));
2132 copy.rect.adjust(dx1: 4, dy1: 1, dx2: -5, dy2: -1);
2133 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
2134 && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget) )
2135 {
2136 QStyleOptionSpinBox lightCopy = copy;
2137 lightCopy.rect.adjust(dx1: 1, dy1: 1, dx2: 1, dy2: 1);
2138 lightCopy.palette.setBrush(acr: QPalette::ButtonText, abrush: copy.palette.light());
2139 proxy()->drawPrimitive(pe, opt: &lightCopy, p, w: widget);
2140 }
2141 proxy()->drawPrimitive(pe, opt: &copy, p, w: widget);
2142 }
2143
2144 if (sb->subControls & SC_SpinBoxDown) {
2145 copy.subControls = SC_SpinBoxDown;
2146 copy.state = sb->state;
2147 QPalette pal2 = sb->palette;
2148 if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
2149 pal2.setCurrentColorGroup(QPalette::Disabled);
2150 copy.state &= ~State_Enabled;
2151 }
2152 copy.palette = pal2;
2153
2154 if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
2155 copy.state |= State_On;
2156 copy.state |= State_Sunken;
2157 } else {
2158 copy.state |= State_Raised;
2159 copy.state &= ~State_Sunken;
2160 }
2161 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
2162 : PE_IndicatorSpinDown);
2163
2164 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxDown, widget);
2165 qDrawWinButton(p, r: copy.rect, pal: shadePal, sunken: copy.state & (State_Sunken | State_On),
2166 fill: &copy.palette.brush(cr: QPalette::Button));
2167 copy.rect.adjust(dx1: 4, dy1: 0, dx2: -5, dy2: -1);
2168 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
2169 && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget) )
2170 {
2171 QStyleOptionSpinBox lightCopy = copy;
2172 lightCopy.rect.adjust(dx1: 1, dy1: 1, dx2: 1, dy2: 1);
2173 lightCopy.palette.setBrush(acr: QPalette::ButtonText, abrush: copy.palette.light());
2174 proxy()->drawPrimitive(pe, opt: &lightCopy, p, w: widget);
2175 }
2176 proxy()->drawPrimitive(pe, opt: &copy, p, w: widget);
2177 }
2178 }
2179 break;
2180#endif // QT_CONFIG(spinbox)
2181
2182 default:
2183 QCommonStyle::drawComplexControl(cc, opt, p, w: widget);
2184 }
2185}
2186
2187/*! \reimp */
2188QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
2189 const QSize &csz, const QWidget *widget) const
2190{
2191 QSize sz(csz);
2192 switch (ct) {
2193 case CT_PushButton:
2194 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2195 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2196 int w = sz.width(),
2197 h = sz.height();
2198 int defwidth = 0;
2199 if (btn->features & QStyleOptionButton::AutoDefaultButton)
2200 defwidth = 2 * proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn, widget);
2201 const qreal dpi = QStyleHelper::dpi(option: opt);
2202 int minwidth = int(QStyleHelper::dpiScaled(value: 75, dpi));
2203 int minheight = int(QStyleHelper::dpiScaled(value: 23, dpi));
2204
2205 if (w < minwidth + defwidth && !btn->text.isEmpty())
2206 w = minwidth + defwidth;
2207 if (h < minheight + defwidth)
2208 h = minheight + defwidth;
2209
2210 sz = QSize(w, h);
2211 }
2212 break;
2213#if QT_CONFIG(menu)
2214 case CT_MenuItem:
2215 if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
2216 int w = sz.width();
2217 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2218
2219 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
2220 sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
2221 }
2222 else if (mi->icon.isNull()) {
2223 sz.setHeight(sz.height() - 2);
2224 w -= 6;
2225 }
2226
2227 if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
2228 int iconExtent = proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt, widget);
2229 sz.setHeight(qMax(a: sz.height(),
2230 b: mi->icon.actualSize(size: QSize(iconExtent, iconExtent)).height()
2231 + 2 * QWindowsStylePrivate::windowsItemFrame));
2232 }
2233 int maxpmw = mi->maxIconWidth;
2234 int tabSpacing = 20;
2235 if (mi->text.contains(c: u'\t'))
2236 w += tabSpacing;
2237 else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
2238 w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
2239 else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
2240 // adjust the font and add the difference in size.
2241 // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
2242 QFontMetrics fm(mi->font);
2243 QFont fontBold = mi->font;
2244 fontBold.setBold(true);
2245 QFontMetrics fmBold(fontBold);
2246 w += fmBold.horizontalAdvance(mi->text) - fm.horizontalAdvance(mi->text);
2247 }
2248
2249 int checkcol = qMax<int>(a: maxpmw, b: QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
2250 w += checkcol;
2251 w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
2252 sz.setWidth(w);
2253 }
2254 break;
2255#endif // QT_CONFIG(menu)
2256#if QT_CONFIG(menubar)
2257 case CT_MenuBarItem:
2258 if (!sz.isEmpty())
2259 sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
2260 break;
2261#endif
2262 case CT_ToolButton:
2263#if QT_CONFIG(toolbutton)
2264 if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
2265 return sz += QSize(7, 6);
2266#endif // QT_CONFIG(toolbutton)
2267 Q_FALLTHROUGH();
2268
2269 default:
2270 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2271 }
2272 return sz;
2273}
2274
2275/*!
2276 \reimp
2277*/
2278QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
2279 const QWidget *widget) const
2280{
2281 return QCommonStyle::standardIcon(standardIcon, opt: option, widget);
2282}
2283
2284
2285
2286QT_END_NAMESPACE
2287
2288#include "moc_qwindowsstyle_p.cpp"
2289
2290#endif // style_windows
2291

source code of qtbase/src/widgets/styles/qwindowsstyle.cpp