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(QPen(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(QPen(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(QPen(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(QPen(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().color());
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))
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().color());
828 p->drawPath(path: path1);
829 p->setPen(opt->palette.shadow().color());
830 p->setBrush(opt->palette.shadow().color());
831 p->drawPath(path: path2);
832
833 p->setClipRegion(QRegion(bottomRightPol));
834 p->setPen(opt->palette.light().color());
835 p->setBrush(opt->palette.light().color());
836 p->drawPath(path: path1);
837 p->setPen(opt->palette.midlight().color());
838 p->setBrush(opt->palette.midlight().color());
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(QPen(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 QPixmap pixmap;
1059 if (checked)
1060 pixmap = menuitem->icon.pixmap(extent: proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt, widget), mode, state: QIcon::On);
1061 else
1062 pixmap = menuitem->icon.pixmap(extent: proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt, widget), mode);
1063 QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize());
1064 pmr.moveCenter(p: vCheckRect.center());
1065 p->setPen(menuitem->palette.text().color());
1066 p->drawPixmap(p: pmr.topLeft(), pm: pixmap);
1067 } else if (checked) {
1068 QStyleOptionMenuItem newMi = *menuitem;
1069 newMi.state = State_None;
1070 if (!dis)
1071 newMi.state |= State_Enabled;
1072 if (act)
1073 newMi.state |= State_On | State_Selected;
1074 newMi.rect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
1075 menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
1076 checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
1077 menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
1078 proxy()->drawPrimitive(pe: PE_IndicatorMenuCheckMark, opt: &newMi, p, w: widget);
1079 }
1080 p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
1081
1082 QColor discol;
1083 if (dis) {
1084 discol = menuitem->palette.text().color();
1085 p->setPen(discol);
1086 }
1087
1088 int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
1089 int xpos = menuitem->rect.x() + xm;
1090 QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1091 w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1092 QRect vTextRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: textRect);
1093 QStringView s(menuitem->text);
1094 if (!s.isEmpty()) { // draw text
1095 p->save();
1096 qsizetype t = s.indexOf(c: u'\t');
1097 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1098 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: menuitem, widget))
1099 text_flags |= Qt::TextHideMnemonic;
1100 text_flags |= Qt::AlignLeft;
1101 if (t >= 0) {
1102 QRect vShortcutRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect,
1103 logicalRect: QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1104 const QString textToDraw = s.mid(pos: t + 1).toString();
1105 if (dis && !act && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget)) {
1106 p->setPen(menuitem->palette.light().color());
1107 p->drawText(r: vShortcutRect.adjusted(xp1: 1, yp1: 1, xp2: 1, yp2: 1), flags: text_flags, text: textToDraw);
1108 p->setPen(discol);
1109 }
1110 p->drawText(r: vShortcutRect, flags: text_flags, text: textToDraw);
1111 s = s.left(n: t);
1112 }
1113 QFont font = menuitem->font;
1114 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1115 font.setBold(true);
1116 p->setFont(font);
1117 const QString textToDraw = s.left(n: t).toString();
1118 if (dis && !act && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget)) {
1119 p->setPen(menuitem->palette.light().color());
1120 p->drawText(r: vTextRect.adjusted(xp1: 1, yp1: 1, xp2: 1, yp2: 1), flags: text_flags, text: textToDraw);
1121 p->setPen(discol);
1122 }
1123 p->drawText(r: vTextRect, flags: text_flags, text: textToDraw);
1124 p->restore();
1125 }
1126 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1127 int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
1128 PrimitiveElement arrow;
1129 arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1130 xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
1131 QRect vSubMenuRect = visualRect(direction: opt->direction, boundingRect: menuitem->rect, logicalRect: QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1132 QStyleOptionMenuItem newMI = *menuitem;
1133 newMI.rect = vSubMenuRect;
1134 newMI.state = dis ? State_None : State_Enabled;
1135 if (act)
1136 newMI.palette.setColor(acr: QPalette::ButtonText,
1137 acolor: newMI.palette.highlightedText().color());
1138 proxy()->drawPrimitive(pe: arrow, opt: &newMI, p, w: widget);
1139 }
1140
1141 }
1142 break;
1143#endif // QT_CONFIG(menu)
1144#if QT_CONFIG(menubar)
1145 case CE_MenuBarItem:
1146 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1147 bool active = mbi->state & State_Selected;
1148 bool hasFocus = mbi->state & State_HasFocus;
1149 bool down = mbi->state & State_Sunken;
1150 QStyleOptionMenuItem newMbi = *mbi;
1151 p->fillRect(mbi->rect, mbi->palette.brush(cr: QPalette::Button));
1152 if (active || hasFocus) {
1153 QBrush b = mbi->palette.brush(cr: QPalette::Button);
1154 if (active && down)
1155 p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
1156 if (active && hasFocus)
1157 qDrawShadeRect(p, x: mbi->rect.x(), y: mbi->rect.y(), w: mbi->rect.width(),
1158 h: mbi->rect.height(), pal: mbi->palette, sunken: active && down, lineWidth: 1, midLineWidth: 0, fill: &b);
1159 if (active && down) {
1160 newMbi.rect.translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: mbi, widget),
1161 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: mbi, widget));
1162 p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
1163 }
1164 }
1165 QCommonStyle::drawControl(element: ce, opt: &newMbi, p, w: widget);
1166 }
1167 break;
1168#endif // QT_CONFIG(menubar)
1169#if QT_CONFIG(tabbar)
1170 case CE_TabBarTabShape:
1171 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1172 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1173 && (tab->shape == QTabBar::RoundedNorth
1174 || tab->shape == QTabBar::RoundedSouth));
1175 bool selected = tab->state & State_Selected;
1176 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1177 || (rtlHorTabs
1178 && tab->position == QStyleOptionTab::Beginning));
1179 bool firstTab = ((!rtlHorTabs
1180 && tab->position == QStyleOptionTab::Beginning)
1181 || (rtlHorTabs
1182 && tab->position == QStyleOptionTab::End));
1183 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1184 bool previousSelected =
1185 ((!rtlHorTabs
1186 && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
1187 || (rtlHorTabs
1188 && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
1189 bool nextSelected =
1190 ((!rtlHorTabs
1191 && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
1192 || (rtlHorTabs
1193 && tab->selectedPosition
1194 == QStyleOptionTab::PreviousIsSelected));
1195 int tabBarAlignment = proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: tab, widget);
1196 bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
1197 || (rtlHorTabs
1198 && tabBarAlignment == Qt::AlignRight);
1199
1200 bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
1201 || (rtlHorTabs
1202 && tabBarAlignment == Qt::AlignLeft);
1203
1204 QColor light = tab->palette.light().color();
1205 QColor dark = tab->palette.dark().color();
1206 QColor shadow = tab->palette.shadow().color();
1207 int borderThinkness = proxy()->pixelMetric(metric: PM_TabBarBaseOverlap, option: tab, widget);
1208 if (selected)
1209 borderThinkness /= 2;
1210 QRect r2(opt->rect);
1211 int x1 = r2.left();
1212 int x2 = r2.right();
1213 int y1 = r2.top();
1214 int y2 = r2.bottom();
1215 switch (tab->shape) {
1216 default:
1217 QCommonStyle::drawControl(element: ce, opt: tab, p, w: widget);
1218 break;
1219 case QTabBar::RoundedNorth: {
1220 if (!selected) {
1221 y1 += 2;
1222 x1 += onlyOne || firstTab ? borderThinkness : 0;
1223 x2 -= onlyOne || lastTab ? borderThinkness : 0;
1224 }
1225
1226 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window());
1227
1228 // Delete border
1229 if (selected) {
1230 p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window());
1231 p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window());
1232 }
1233 // Left
1234 if (firstTab || selected || onlyOne || !previousSelected) {
1235 p->setPen(light);
1236 p->drawLine(x1, y1: y1 + 2, x2: x1, y2: y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1237 p->drawPoint(x: x1 + 1, y: y1 + 1);
1238 }
1239 // Top
1240 {
1241 int beg = x1 + (previousSelected ? 0 : 2);
1242 int end = x2 - (nextSelected ? 0 : 2);
1243 p->setPen(light);
1244 p->drawLine(x1: beg, y1, x2: end, y2: y1);
1245 }
1246 // Right
1247 if (lastTab || selected || onlyOne || !nextSelected) {
1248 p->setPen(shadow);
1249 p->drawLine(x1: x2, y1: y1 + 2, x2, y2: y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1250 p->drawPoint(x: x2 - 1, y: y1 + 1);
1251 p->setPen(dark);
1252 p->drawLine(x1: x2 - 1, y1: y1 + 2, x2: x2 - 1, y2: y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1253 }
1254 break; }
1255 case QTabBar::RoundedSouth: {
1256 if (!selected) {
1257 y2 -= 2;
1258 x1 += firstTab ? borderThinkness : 0;
1259 x2 -= lastTab ? borderThinkness : 0;
1260 }
1261
1262 p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1263
1264 // Delete border
1265 if (selected) {
1266 p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window());
1267 p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window());
1268 }
1269 // Left
1270 if (firstTab || selected || onlyOne || !previousSelected) {
1271 p->setPen(light);
1272 p->drawLine(x1, y1: y2 - 2, x2: x1, y2: y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1273 p->drawPoint(x: x1 + 1, y: y2 - 1);
1274 }
1275 // Bottom
1276 {
1277 int beg = x1 + (previousSelected ? 0 : 2);
1278 int end = x2 - (nextSelected ? 0 : 2);
1279 p->setPen(shadow);
1280 p->drawLine(x1: beg, y1: y2, x2: end, y2);
1281 p->setPen(dark);
1282 p->drawLine(x1: beg, y1: y2 - 1, x2: end, y2: y2 - 1);
1283 }
1284 // Right
1285 if (lastTab || selected || onlyOne || !nextSelected) {
1286 p->setPen(shadow);
1287 p->drawLine(x1: x2, y1: y2 - 2, x2, y2: y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1288 p->drawPoint(x: x2 - 1, y: y2 - 1);
1289 p->setPen(dark);
1290 p->drawLine(x1: x2 - 1, y1: y2 - 2, x2: x2 - 1, y2: y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1291 }
1292 break; }
1293 case QTabBar::RoundedWest: {
1294 if (!selected) {
1295 x1 += 2;
1296 y1 += firstTab ? borderThinkness : 0;
1297 y2 -= lastTab ? borderThinkness : 0;
1298 }
1299
1300 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window());
1301
1302 // Delete border
1303 if (selected) {
1304 p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window());
1305 p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window());
1306 }
1307 // Top
1308 if (firstTab || selected || onlyOne || !previousSelected) {
1309 p->setPen(light);
1310 p->drawLine(x1: x1 + 2, y1, x2: x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y2: y1);
1311 p->drawPoint(x: x1 + 1, y: y1 + 1);
1312 }
1313 // Left
1314 {
1315 int beg = y1 + (previousSelected ? 0 : 2);
1316 int end = y2 - (nextSelected ? 0 : 2);
1317 p->setPen(light);
1318 p->drawLine(x1, y1: beg, x2: x1, y2: end);
1319 }
1320 // Bottom
1321 if (lastTab || selected || onlyOne || !nextSelected) {
1322 p->setPen(shadow);
1323 p->drawLine(x1: x1 + 3, y1: y2, x2: x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1324 p->drawPoint(x: x1 + 2, y: y2 - 1);
1325 p->setPen(dark);
1326 p->drawLine(x1: x1 + 3, y1: y2 - 1, x2: x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2: y2 - 1);
1327 p->drawPoint(x: x1 + 1, y: y2 - 1);
1328 p->drawPoint(x: x1 + 2, y: y2);
1329 }
1330 break; }
1331 case QTabBar::RoundedEast: {
1332 if (!selected) {
1333 x2 -= 2;
1334 y1 += firstTab ? borderThinkness : 0;
1335 y2 -= lastTab ? borderThinkness : 0;
1336 }
1337
1338 p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1339
1340 // Delete border
1341 if (selected) {
1342 p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window());
1343 p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window());
1344 }
1345 // Top
1346 if (firstTab || selected || onlyOne || !previousSelected) {
1347 p->setPen(light);
1348 p->drawLine(x1: x2 - 2, y1, x2: x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y2: y1);
1349 p->drawPoint(x: x2 - 1, y: y1 + 1);
1350 }
1351 // Right
1352 {
1353 int beg = y1 + (previousSelected ? 0 : 2);
1354 int end = y2 - (nextSelected ? 0 : 2);
1355 p->setPen(shadow);
1356 p->drawLine(x1: x2, y1: beg, x2, y2: end);
1357 p->setPen(dark);
1358 p->drawLine(x1: x2 - 1, y1: beg, x2: x2 - 1, y2: end);
1359 }
1360 // Bottom
1361 if (lastTab || selected || onlyOne || !nextSelected) {
1362 p->setPen(shadow);
1363 p->drawLine(x1: x2 - 2, y1: y2, x2: x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1364 p->drawPoint(x: x2 - 1, y: y2 - 1);
1365 p->setPen(dark);
1366 p->drawLine(x1: x2 - 2, y1: y2 - 1, x2: x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2: y2 - 1);
1367 }
1368 break; }
1369 }
1370 }
1371 break;
1372#endif // QT_CONFIG(tabbar)
1373 case CE_ToolBoxTabShape:
1374 qDrawShadePanel(p, r: opt->rect, pal: opt->palette,
1375 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1,
1376 fill: &opt->palette.brush(cr: QPalette::Button));
1377 break;
1378#if QT_CONFIG(splitter)
1379 case CE_Splitter:
1380 p->eraseRect(rect: opt->rect);
1381 break;
1382#endif // QT_CONFIG(splitter)
1383#if QT_CONFIG(scrollbar)
1384 case CE_ScrollBarSubLine:
1385 case CE_ScrollBarAddLine: {
1386 if ((opt->state & State_Sunken)) {
1387 p->setPen(opt->palette.dark().color());
1388 p->setBrush(opt->palette.brush(cr: QPalette::Button));
1389 p->drawRect(r: opt->rect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1));
1390 } else {
1391 QStyleOption buttonOpt = *opt;
1392 if (!(buttonOpt.state & State_Sunken))
1393 buttonOpt.state |= State_Raised;
1394 QPalette pal(opt->palette);
1395 pal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
1396 pal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
1397 qDrawWinButton(p, r: opt->rect, pal, sunken: opt->state & (State_Sunken | State_On),
1398 fill: &opt->palette.brush(cr: QPalette::Button));
1399 }
1400 PrimitiveElement arrow;
1401 if (opt->state & State_Horizontal) {
1402 if (ce == CE_ScrollBarAddLine)
1403 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
1404 else
1405 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1406 } else {
1407 if (ce == CE_ScrollBarAddLine)
1408 arrow = PE_IndicatorArrowDown;
1409 else
1410 arrow = PE_IndicatorArrowUp;
1411 }
1412 QStyleOption arrowOpt = *opt;
1413 arrowOpt.rect = opt->rect.adjusted(xp1: 4, yp1: 4, xp2: -4, yp2: -4);
1414 proxy()->drawPrimitive(pe: arrow, opt: &arrowOpt, p, w: widget);
1415 break; }
1416 case CE_ScrollBarAddPage:
1417 case CE_ScrollBarSubPage: {
1418 QBrush br;
1419 QBrush bg = p->background();
1420 Qt::BGMode bg_mode = p->backgroundMode();
1421 p->setPen(Qt::NoPen);
1422 p->setBackgroundMode(Qt::OpaqueMode);
1423
1424 if (opt->state & State_Sunken) {
1425 br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
1426 p->setBackground(opt->palette.dark().color());
1427 p->setBrush(br);
1428 } else {
1429 const QBrush paletteBrush = opt->palette.brush(cr: QPalette::Light);
1430 if (paletteBrush.style() == Qt::TexturePattern) {
1431 if (qHasPixmapTexture(brush: paletteBrush))
1432 br = QBrush(paletteBrush.texture());
1433 else
1434 br = QBrush(paletteBrush.textureImage());
1435 } else
1436 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1437 p->setBackground(opt->palette.window().color());
1438 p->setBrush(br);
1439 }
1440 p->drawRect(r: opt->rect);
1441 p->setBackground(bg);
1442 p->setBackgroundMode(bg_mode);
1443 break; }
1444 case CE_ScrollBarSlider:
1445 if (!(opt->state & State_Enabled)) {
1446 QBrush br;
1447 const QBrush paletteBrush = opt->palette.brush(cr: QPalette::Light);
1448 if (paletteBrush.style() == Qt::TexturePattern) {
1449 if (qHasPixmapTexture(brush: paletteBrush))
1450 br = QBrush(paletteBrush.texture());
1451 else
1452 br = QBrush(paletteBrush.textureImage());
1453 } else
1454 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1455 p->setPen(Qt::NoPen);
1456 p->setBrush(br);
1457 p->setBackgroundMode(Qt::OpaqueMode);
1458 p->drawRect(r: opt->rect);
1459 } else {
1460 QStyleOptionButton buttonOpt;
1461 buttonOpt.QStyleOption::operator=(other: *opt);
1462 buttonOpt.state = State_Enabled | State_Raised;
1463
1464 QPalette pal(opt->palette);
1465 pal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
1466 pal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
1467 qDrawWinButton(p, r: opt->rect, pal, sunken: false, fill: &opt->palette.brush(cr: QPalette::Button));
1468 }
1469 break;
1470#endif // QT_CONFIG(scrollbar)
1471 case CE_HeaderSection: {
1472 QBrush fill;
1473 if (opt->state & State_On)
1474 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1475 else
1476 fill = opt->palette.brush(cr: QPalette::Button);
1477
1478 if (opt->state & (State_Raised | State_Sunken)) {
1479 qDrawWinButton(p, r: opt->rect, pal: opt->palette, sunken: opt->state & State_Sunken, fill: &fill);
1480 } else {
1481 p->fillRect(opt->rect, fill);
1482 }
1483 break; }
1484#if QT_CONFIG(toolbar)
1485 case CE_ToolBar:
1486 if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
1487 // Reserve the beveled appearance only for mainwindow toolbars
1488 if (!(widget && qobject_cast<const QMainWindow*> (object: widget->parentWidget())))
1489 break;
1490
1491 QRect rect = opt->rect;
1492 bool paintLeftBorder = true;
1493 bool paintRightBorder = true;
1494 bool paintBottomBorder = true;
1495
1496 switch (toolbar->toolBarArea){
1497 case Qt::BottomToolBarArea :
1498 switch(toolbar->positionOfLine){
1499 case QStyleOptionToolBar::Beginning:
1500 case QStyleOptionToolBar::OnlyOne:
1501 paintBottomBorder = false;
1502 break;
1503 default:
1504 break;
1505 }
1506 Q_FALLTHROUGH(); // It continues in the end of the next case
1507 case Qt::TopToolBarArea :
1508 switch(toolbar->positionWithinLine){
1509 case QStyleOptionToolBar::Beginning:
1510 paintLeftBorder = false;
1511 break;
1512 case QStyleOptionToolBar::End:
1513 paintRightBorder = false;
1514 break;
1515 case QStyleOptionToolBar::OnlyOne:
1516 paintRightBorder = false;
1517 paintLeftBorder = false;
1518 break;
1519 default:
1520 break;
1521 }
1522 if (opt->direction == Qt::RightToLeft) //reverse layout changes the order of Beginning/end
1523 std::swap(a&: paintLeftBorder, b&: paintRightBorder);
1524 break;
1525 case Qt::RightToolBarArea :
1526 switch (toolbar->positionOfLine){
1527 case QStyleOptionToolBar::Beginning:
1528 case QStyleOptionToolBar::OnlyOne:
1529 paintRightBorder = false;
1530 break;
1531 default:
1532 break;
1533 }
1534 break;
1535 case Qt::LeftToolBarArea :
1536 switch (toolbar->positionOfLine){
1537 case QStyleOptionToolBar::Beginning:
1538 case QStyleOptionToolBar::OnlyOne:
1539 paintLeftBorder = false;
1540 break;
1541 default:
1542 break;
1543 }
1544 break;
1545 default:
1546 break;
1547 }
1548
1549
1550 //draw top border
1551 p->setPen(QPen(opt->palette.light().color()));
1552 p->drawLine(x1: rect.topLeft().x(),
1553 y1: rect.topLeft().y(),
1554 x2: rect.topRight().x(),
1555 y2: rect.topRight().y());
1556
1557 if (paintLeftBorder){
1558 p->setPen(QPen(opt->palette.light().color()));
1559 p->drawLine(x1: rect.topLeft().x(),
1560 y1: rect.topLeft().y(),
1561 x2: rect.bottomLeft().x(),
1562 y2: rect.bottomLeft().y());
1563 }
1564
1565 if (paintRightBorder){
1566 p->setPen(QPen(opt->palette.dark().color()));
1567 p->drawLine(x1: rect.topRight().x(),
1568 y1: rect.topRight().y(),
1569 x2: rect.bottomRight().x(),
1570 y2: rect.bottomRight().y());
1571 }
1572
1573 if (paintBottomBorder){
1574 p->setPen(QPen(opt->palette.dark().color()));
1575 p->drawLine(x1: rect.bottomLeft().x(),
1576 y1: rect.bottomLeft().y(),
1577 x2: rect.bottomRight().x(),
1578 y2: rect.bottomRight().y());
1579 }
1580 }
1581 break;
1582
1583
1584#endif // QT_CONFIG(toolbar)
1585
1586 case CE_ProgressBarContents:
1587 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1588 QRect rect = pb->rect;
1589 if (!rect.isValid())
1590 return;
1591
1592 const bool vertical = !(pb->state & QStyle::State_Horizontal);
1593 const bool inverted = pb->invertedAppearance;
1594
1595 QTransform m;
1596 if (vertical) {
1597 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1598 m.rotate(a: 90);
1599 m.translate(dx: 0, dy: -(rect.height() + rect.y()*2));
1600 }
1601 QPalette pal2 = pb->palette;
1602 // Correct the highlight color if it is the same as the background
1603 if (pal2.highlight() == pal2.window())
1604 pal2.setColor(acr: QPalette::Highlight, acolor: pb->palette.color(cg: QPalette::Active,
1605 cr: QPalette::Highlight));
1606 bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1607 if (inverted)
1608 reverse = !reverse;
1609 int w = rect.width();
1610 Q_D(const QWindowsStyle);
1611 if (pb->minimum == 0 && pb->maximum == 0) {
1612 const int unit_width = proxy()->pixelMetric(metric: PM_ProgressBarChunkWidth, option: pb, widget);
1613 QStyleOptionProgressBar pbBits = *pb;
1614 Q_ASSERT(unit_width >0);
1615
1616 pbBits.rect = rect;
1617 pbBits.palette = pal2;
1618
1619 int step = 0;
1620 int chunkCount = w / unit_width + 1;
1621#if QT_CONFIG(animation)
1622 if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(object: d->animation(target: opt->styleObject)))
1623 step = (animation->animationStep() / 3) % chunkCount;
1624 else
1625 d->startAnimation(animation: new QProgressStyleAnimation(d->animationFps, opt->styleObject));
1626#else
1627 Q_UNUSED(d);
1628#endif
1629 int chunksInRow = 5;
1630 int myY = pbBits.rect.y();
1631 int myHeight = pbBits.rect.height();
1632 int chunksToDraw = chunksInRow;
1633
1634 if (step > chunkCount - 5)chunksToDraw = (chunkCount - step);
1635 p->save();
1636 p->setClipRect(m.mapRect(QRectF(rect)).toRect());
1637
1638 int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step;
1639 int x = 0;
1640
1641 for (int i = 0; i < chunksToDraw ; ++i) {
1642 pbBits.rect.setRect(ax: x0 + x, ay: myY, aw: unit_width, ah: myHeight);
1643 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1644 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p, w: widget);
1645 x += reverse ? -unit_width : unit_width;
1646 }
1647 //Draw wrap-around chunks
1648 if ( step > chunkCount-5){
1649 x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
1650 x = 0;
1651 int chunksToDraw = step - (chunkCount - chunksInRow);
1652 for (int i = 0; i < chunksToDraw ; ++i) {
1653 pbBits.rect.setRect(ax: x0 + x, ay: myY, aw: unit_width, ah: myHeight);
1654 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1655 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p, w: widget);
1656 x += reverse ? -unit_width : unit_width;
1657 }
1658 }
1659 p->restore(); //restore state
1660 }
1661 else {
1662#if QT_CONFIG(animation)
1663 d->stopAnimation(target: opt->styleObject);
1664#endif
1665 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1666 }
1667 }
1668 break;
1669
1670#if QT_CONFIG(dockwidget)
1671 case CE_DockWidgetTitle:
1672
1673 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
1674 Q_D(const QWindowsStyle);
1675
1676 const bool verticalTitleBar = dwOpt->verticalTitleBar;
1677
1678 QRect rect = dwOpt->rect;
1679 QRect r = rect;
1680
1681 if (verticalTitleBar) {
1682 r = r.transposed();
1683
1684 p->save();
1685 p->translate(dx: r.left(), dy: r.top() + r.width());
1686 p->rotate(a: -90);
1687 p->translate(dx: -r.left(), dy: -r.top());
1688 }
1689
1690 bool floating = false;
1691 bool active = dwOpt->state & State_Active;
1692 QColor inactiveCaptionTextColor = d->inactiveCaptionText;
1693 if (dwOpt->movable) {
1694 QColor left, right;
1695
1696 //Titlebar gradient
1697 if (opt->state & QStyle::State_Window) {
1698 floating = true;
1699 if (active) {
1700 left = d->activeCaptionColor;
1701 right = d->activeGradientCaptionColor;
1702 } else {
1703 left = d->inactiveCaptionColor;
1704 right = d->inactiveGradientCaptionColor;
1705 }
1706 QBrush fillBrush(left);
1707 if (left != right) {
1708 QPoint p1(r.x(), r.top() + r.height()/2);
1709 QPoint p2(rect.right(), r.top() + r.height()/2);
1710 QLinearGradient lg(p1, p2);
1711 lg.setColorAt(pos: 0, color: left);
1712 lg.setColorAt(pos: 1, color: right);
1713 fillBrush = lg;
1714 }
1715 p->fillRect(r.adjusted(xp1: 0, yp1: 0, xp2: 0, yp2: -3), fillBrush);
1716 }
1717 }
1718 if (!dwOpt->title.isEmpty()) {
1719 QFont oldFont = p->font();
1720 if (floating) {
1721 QFont font = oldFont;
1722 font.setBold(true);
1723 p->setFont(font);
1724 }
1725 QPalette palette = dwOpt->palette;
1726 palette.setColor(acr: QPalette::Window, acolor: inactiveCaptionTextColor);
1727 QRect titleRect = subElementRect(r: SE_DockWidgetTitleBarText, opt, widget);
1728 if (verticalTitleBar) {
1729 titleRect = QRect(r.left() + rect.bottom()
1730 - titleRect.bottom(),
1731 r.top() + titleRect.left() - rect.left(),
1732 titleRect.height(), titleRect.width());
1733 }
1734 proxy()->drawItemText(painter: p, rect: titleRect,
1735 flags: Qt::AlignLeft | Qt::AlignVCenter | Qt::TextHideMnemonic, pal: palette,
1736 enabled: dwOpt->state & State_Enabled, text: dwOpt->title,
1737 textRole: floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
1738 p->setFont(oldFont);
1739 }
1740 if (verticalTitleBar)
1741 p->restore();
1742 }
1743 return;
1744#endif // QT_CONFIG(dockwidget)
1745#if QT_CONFIG(combobox)
1746 case CE_ComboBoxLabel:
1747 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1748 if (cb->state & State_HasFocus) {
1749 p->setPen(cb->palette.highlightedText().color());
1750 p->setBackground(cb->palette.highlight());
1751 } else {
1752 p->setPen(cb->palette.text().color());
1753 p->setBackground(cb->palette.window());
1754 }
1755 }
1756 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1757 break;
1758#endif // QT_CONFIG(combobox)
1759 default:
1760 QCommonStyle::drawControl(element: ce, opt, p, w: widget);
1761 }
1762}
1763
1764/*! \reimp */
1765QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
1766{
1767 QRect r;
1768 switch (sr) {
1769 case SE_SliderFocusRect:
1770 case SE_ToolBoxTabContents:
1771 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: opt->rect);
1772 break;
1773 case SE_DockWidgetTitleBarText: {
1774 r = QCommonStyle::subElementRect(r: sr, opt, widget: w);
1775 const QStyleOptionDockWidget *dwOpt
1776 = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
1777 const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
1778 int m = proxy()->pixelMetric(metric: PM_DockWidgetTitleMargin, option: opt, widget: w);
1779 if (verticalTitleBar) {
1780 r.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -m);
1781 } else {
1782 if (opt->direction == Qt::LeftToRight)
1783 r.adjust(dx1: m, dy1: 0, dx2: 0, dy2: 0);
1784 else
1785 r.adjust(dx1: 0, dy1: 0, dx2: -m, dy2: 0);
1786 }
1787 break;
1788 }
1789 case SE_ProgressBarContents:
1790 r = QCommonStyle::subElementRect(r: SE_ProgressBarGroove, opt, widget: w);
1791 r.adjust(dx1: 3, dy1: 3, dx2: -3, dy2: -3);
1792 break;
1793 default:
1794 r = QCommonStyle::subElementRect(r: sr, opt, widget: w);
1795 }
1796 return r;
1797}
1798
1799
1800/*! \reimp */
1801void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
1802 QPainter *p, const QWidget *widget) const
1803{
1804 switch (cc) {
1805#if QT_CONFIG(slider)
1806 case CC_Slider:
1807 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1808 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: slider, widget);
1809 int len = proxy()->pixelMetric(metric: PM_SliderLength, option: slider, widget);
1810 int ticks = slider->tickPosition;
1811 QRect groove = proxy()->subControlRect(cc: CC_Slider, opt: slider, sc: SC_SliderGroove, widget);
1812 QRect handle = proxy()->subControlRect(cc: CC_Slider, opt: slider, sc: SC_SliderHandle, widget);
1813
1814 if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
1815 int mid = thickness / 2;
1816
1817 if (ticks & QSlider::TicksAbove)
1818 mid += len / 8;
1819 if (ticks & QSlider::TicksBelow)
1820 mid -= len / 8;
1821
1822 p->setPen(slider->palette.shadow().color());
1823 if (slider->orientation == Qt::Horizontal) {
1824 qDrawWinPanel(p, x: groove.x(), y: groove.y() + mid - 2,
1825 w: groove.width(), h: 4, pal: slider->palette, sunken: true);
1826 p->drawLine(x1: groove.x() + 1, y1: groove.y() + mid - 1,
1827 x2: groove.x() + groove.width() - 3, y2: groove.y() + mid - 1);
1828 } else {
1829 qDrawWinPanel(p, x: groove.x() + mid - 2, y: groove.y(),
1830 w: 4, h: groove.height(), pal: slider->palette, sunken: true);
1831 p->drawLine(x1: groove.x() + mid - 1, y1: groove.y() + 1,
1832 x2: groove.x() + mid - 1, y2: groove.y() + groove.height() - 3);
1833 }
1834 }
1835
1836 if (slider->subControls & SC_SliderTickmarks) {
1837 QStyleOptionSlider tmpSlider = *slider;
1838 tmpSlider.subControls = SC_SliderTickmarks;
1839 QCommonStyle::drawComplexControl(cc, opt: &tmpSlider, p, w: widget);
1840 }
1841
1842 if (slider->subControls & SC_SliderHandle) {
1843 // 4444440
1844 // 4333310
1845 // 4322210
1846 // 4322210
1847 // 4322210
1848 // 4322210
1849 // *43210*
1850 // **410**
1851 // ***0***
1852 const QColor c0 = slider->palette.shadow().color();
1853 const QColor c1 = slider->palette.dark().color();
1854 // const QColor c2 = g.button();
1855 const QColor c3 = slider->palette.midlight().color();
1856 const QColor c4 = slider->palette.light().color();
1857 QBrush handleBrush;
1858
1859 if (slider->state & State_Enabled) {
1860 handleBrush = slider->palette.color(cr: QPalette::Button);
1861 } else {
1862 handleBrush = QBrush(slider->palette.color(cr: QPalette::Button),
1863 Qt::Dense4Pattern);
1864 }
1865
1866
1867 int x = handle.x(), y = handle.y(),
1868 wi = handle.width(), he = handle.height();
1869
1870 int x1 = x;
1871 int x2 = x+wi-1;
1872 int y1 = y;
1873 int y2 = y+he-1;
1874
1875 Qt::Orientation orient = slider->orientation;
1876 bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
1877 bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
1878
1879 if (slider->state & State_HasFocus) {
1880 QStyleOptionFocusRect fropt;
1881 fropt.QStyleOption::operator=(other: *slider);
1882 fropt.rect = subElementRect(sr: SE_SliderFocusRect, opt: slider, w: widget);
1883 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p, w: widget);
1884 }
1885
1886 if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
1887 Qt::BGMode oldMode = p->backgroundMode();
1888 p->setBackgroundMode(Qt::OpaqueMode);
1889 qDrawWinButton(p, r: QRect(x, y, wi, he), pal: slider->palette, sunken: false,
1890 fill: &handleBrush);
1891 p->setBackgroundMode(oldMode);
1892 return;
1893 }
1894
1895 QSliderDirection dir;
1896
1897 if (orient == Qt::Horizontal)
1898 dir = tickAbove ? SlUp : SlDown;
1899 else
1900 dir = tickAbove ? SlLeft : SlRight;
1901
1902 std::array<QPoint, 5> points;
1903 int d = 0;
1904 switch (dir) {
1905 case SlUp:
1906 y1 = y1 + wi / 2;
1907 d = (wi + 1) / 2 - 1;
1908 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2),
1909 QPoint(x2, y1), QPoint(x1 + d, y1 - d)};
1910 break;
1911 case SlDown:
1912 y2 = y2 - wi / 2;
1913 d = (wi + 1) / 2 - 1;
1914 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x1 + d, y2 + d),
1915 QPoint(x2, y2), QPoint(x2, y1)};
1916 break;
1917 case SlLeft:
1918 d = (he + 1) / 2 - 1;
1919 x1 = x1 + he / 2;
1920 points = {QPoint(x1, y1), QPoint(x1 - d, y1 + d), QPoint(x1,y2),
1921 QPoint(x2, y2), QPoint(x2, y1)};
1922 break;
1923 case SlRight:
1924 d = (he + 1) / 2 - 1;
1925 x2 = x2 - he / 2;
1926 points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2),
1927 QPoint(x2 + d, y1 + d), QPoint(x2, y1)};
1928 break;
1929 }
1930
1931 QBrush oldBrush = p->brush();
1932 p->setPen(Qt::NoPen);
1933 p->setBrush(handleBrush);
1934 Qt::BGMode oldMode = p->backgroundMode();
1935 p->setBackgroundMode(Qt::OpaqueMode);
1936 p->drawRect(x: x1, y: y1, w: x2-x1+1, h: y2-y1+1);
1937 p->drawPolygon(points: points.data(), pointCount: static_cast<int>(points.size()));
1938 p->setBrush(oldBrush);
1939 p->setBackgroundMode(oldMode);
1940
1941 if (dir != SlUp) {
1942 p->setPen(c4);
1943 p->drawLine(x1, y1, x2, y2: y1);
1944 p->setPen(c3);
1945 p->drawLine(x1, y1: y1+1, x2, y2: y1+1);
1946 }
1947 if (dir != SlLeft) {
1948 p->setPen(c3);
1949 p->drawLine(x1: x1+1, y1: y1+1, x2: x1+1, y2);
1950 p->setPen(c4);
1951 p->drawLine(x1, y1, x2: x1, y2);
1952 }
1953 if (dir != SlRight) {
1954 p->setPen(c0);
1955 p->drawLine(x1: x2, y1, x2, y2);
1956 p->setPen(c1);
1957 p->drawLine(x1: x2-1, y1: y1+1, x2: x2-1, y2: y2-1);
1958 }
1959 if (dir != SlDown) {
1960 p->setPen(c0);
1961 p->drawLine(x1, y1: y2, x2, y2);
1962 p->setPen(c1);
1963 p->drawLine(x1: x1+1, y1: y2-1, x2: x2-1, y2: y2-1);
1964 }
1965
1966 switch (dir) {
1967 case SlUp:
1968 p->setPen(c4);
1969 p->drawLine(x1, y1, x2: x1+d, y2: y1-d);
1970 p->setPen(c0);
1971 d = wi - d - 1;
1972 p->drawLine(x1: x2, y1, x2: x2-d, y2: y1-d);
1973 d--;
1974 p->setPen(c3);
1975 p->drawLine(x1: x1+1, y1, x2: x1+1+d, y2: y1-d);
1976 p->setPen(c1);
1977 p->drawLine(x1: x2-1, y1, x2: x2-1-d, y2: y1-d);
1978 break;
1979 case SlDown:
1980 p->setPen(c4);
1981 p->drawLine(x1, y1: y2, x2: x1+d, y2: y2+d);
1982 p->setPen(c0);
1983 d = wi - d - 1;
1984 p->drawLine(x1: x2, y1: y2, x2: x2-d, y2: y2+d);
1985 d--;
1986 p->setPen(c3);
1987 p->drawLine(x1: x1+1, y1: y2, x2: x1+1+d, y2: y2+d);
1988 p->setPen(c1);
1989 p->drawLine(x1: x2-1, y1: y2, x2: x2-1-d, y2: y2+d);
1990 break;
1991 case SlLeft:
1992 p->setPen(c4);
1993 p->drawLine(x1, y1, x2: x1-d, y2: y1+d);
1994 p->setPen(c0);
1995 d = he - d - 1;
1996 p->drawLine(x1, y1: y2, x2: x1-d, y2: y2-d);
1997 d--;
1998 p->setPen(c3);
1999 p->drawLine(x1, y1: y1+1, x2: x1-d, y2: y1+1+d);
2000 p->setPen(c1);
2001 p->drawLine(x1, y1: y2-1, x2: x1-d, y2: y2-1-d);
2002 break;
2003 case SlRight:
2004 p->setPen(c4);
2005 p->drawLine(x1: x2, y1, x2: x2+d, y2: y1+d);
2006 p->setPen(c0);
2007 d = he - d - 1;
2008 p->drawLine(x1: x2, y1: y2, x2: x2+d, y2: y2-d);
2009 d--;
2010 p->setPen(c3);
2011 p->drawLine(x1: x2, y1: y1+1, x2: x2+d, y2: y1+1+d);
2012 p->setPen(c1);
2013 p->drawLine(x1: x2, y1: y2-1, x2: x2+d, y2: y2-1-d);
2014 break;
2015 }
2016 }
2017 }
2018 break;
2019#endif // QT_CONFIG(slider)
2020#if QT_CONFIG(scrollbar)
2021 case CC_ScrollBar:
2022 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2023 QStyleOptionSlider newScrollbar = *scrollbar;
2024 if (scrollbar->minimum == scrollbar->maximum)
2025 newScrollbar.state &= ~State_Enabled; //do not draw the slider.
2026 QCommonStyle::drawComplexControl(cc, opt: &newScrollbar, p, w: widget);
2027 }
2028 break;
2029#endif // QT_CONFIG(scrollbar)
2030#if QT_CONFIG(combobox)
2031 case CC_ComboBox:
2032 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2033 QBrush editBrush = cmb->palette.brush(cr: QPalette::Button);
2034 if ((cmb->subControls & SC_ComboBoxFrame)) {
2035 if (cmb->frame) {
2036 QPalette shadePal = opt->palette;
2037 shadePal.setColor(acr: QPalette::Midlight, acolor: shadePal.button().color());
2038 qDrawWinPanel(p, r: opt->rect, pal: shadePal, sunken: true, fill: &editBrush);
2039 }
2040 else {
2041 p->fillRect(opt->rect, editBrush);
2042 }
2043 }
2044 if (cmb->subControls & SC_ComboBoxArrow) {
2045 State flags = State_None;
2046
2047 QRect ar = proxy()->subControlRect(cc: CC_ComboBox, opt: cmb, sc: SC_ComboBoxArrow, widget);
2048 bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
2049 && cmb->state & State_Sunken;
2050 if (sunkenArrow) {
2051 p->setPen(cmb->palette.dark().color());
2052 p->setBrush(cmb->palette.brush(cr: QPalette::Button));
2053 p->drawRect(r: ar.adjusted(xp1: 0,yp1: 0,xp2: -1,yp2: -1));
2054 } else {
2055 // Make qDrawWinButton use the right colors for drawing the shade of the button
2056 QPalette pal(cmb->palette);
2057 pal.setColor(acr: QPalette::Button, acolor: cmb->palette.light().color());
2058 pal.setColor(acr: QPalette::Light, acolor: cmb->palette.button().color());
2059 qDrawWinButton(p, r: ar, pal, sunken: false,
2060 fill: &cmb->palette.brush(cr: QPalette::Button));
2061 }
2062
2063 ar.adjust(dx1: 2, dy1: 2, dx2: -2, dy2: -2);
2064 if (opt->state & State_Enabled)
2065 flags |= State_Enabled;
2066 if (opt->state & State_HasFocus)
2067 flags |= State_HasFocus;
2068
2069 if (sunkenArrow)
2070 flags |= State_Sunken;
2071 QStyleOption arrowOpt = *cmb;
2072 arrowOpt.rect = ar.adjusted(xp1: 1, yp1: 1, xp2: -1, yp2: -1);
2073 arrowOpt.state = flags;
2074 proxy()->drawPrimitive(pe: PE_IndicatorArrowDown, opt: &arrowOpt, p, w: widget);
2075 }
2076
2077 if (cmb->subControls & SC_ComboBoxEditField) {
2078 QRect re = proxy()->subControlRect(cc: CC_ComboBox, opt: cmb, sc: SC_ComboBoxEditField, widget);
2079 if (cmb->state & State_HasFocus && !cmb->editable)
2080 p->fillRect(x: re.x(), y: re.y(), w: re.width(), h: re.height(),
2081 b: cmb->palette.brush(cr: QPalette::Highlight));
2082
2083 if (cmb->state & State_HasFocus) {
2084 p->setPen(cmb->palette.highlightedText().color());
2085 p->setBackground(cmb->palette.highlight());
2086
2087 } else {
2088 p->setPen(cmb->palette.text().color());
2089 p->setBackground(cmb->palette.window());
2090 }
2091
2092 if (cmb->state & State_HasFocus && !cmb->editable) {
2093 QStyleOptionFocusRect focus;
2094 focus.QStyleOption::operator=(other: *cmb);
2095 focus.rect = subElementRect(sr: SE_ComboBoxFocusRect, opt: cmb, w: widget);
2096 focus.state |= State_FocusAtBorder;
2097 focus.backgroundColor = cmb->palette.highlight().color();
2098 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &focus, p, w: widget);
2099 }
2100 }
2101 }
2102 break;
2103#endif // QT_CONFIG(combobox)
2104#if QT_CONFIG(spinbox)
2105 case CC_SpinBox:
2106 if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
2107 QStyleOptionSpinBox copy = *sb;
2108 PrimitiveElement pe;
2109 bool enabled = opt->state & State_Enabled;
2110 if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
2111 QBrush editBrush = sb->palette.brush(cr: QPalette::Base);
2112 QRect r = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxFrame, widget);
2113 QPalette shadePal = sb->palette;
2114 shadePal.setColor(acr: QPalette::Midlight, acolor: shadePal.button().color());
2115 qDrawWinPanel(p, r, pal: shadePal, sunken: true, fill: &editBrush);
2116 }
2117
2118 QPalette shadePal(opt->palette);
2119 shadePal.setColor(acr: QPalette::Button, acolor: opt->palette.light().color());
2120 shadePal.setColor(acr: QPalette::Light, acolor: opt->palette.button().color());
2121
2122 if (sb->subControls & SC_SpinBoxUp) {
2123 copy.subControls = SC_SpinBoxUp;
2124 QPalette pal2 = sb->palette;
2125 if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
2126 pal2.setCurrentColorGroup(QPalette::Disabled);
2127 copy.state &= ~State_Enabled;
2128 }
2129
2130 copy.palette = pal2;
2131
2132 if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
2133 copy.state |= State_On;
2134 copy.state |= State_Sunken;
2135 } else {
2136 copy.state |= State_Raised;
2137 copy.state &= ~State_Sunken;
2138 }
2139 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
2140 : PE_IndicatorSpinUp);
2141
2142 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxUp, widget);
2143 qDrawWinButton(p, r: copy.rect, pal: shadePal, sunken: copy.state & (State_Sunken | State_On),
2144 fill: &copy.palette.brush(cr: QPalette::Button));
2145 copy.rect.adjust(dx1: 4, dy1: 1, dx2: -5, dy2: -1);
2146 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
2147 && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget) )
2148 {
2149 QStyleOptionSpinBox lightCopy = copy;
2150 lightCopy.rect.adjust(dx1: 1, dy1: 1, dx2: 1, dy2: 1);
2151 lightCopy.palette.setBrush(acr: QPalette::ButtonText, abrush: copy.palette.light());
2152 proxy()->drawPrimitive(pe, opt: &lightCopy, p, w: widget);
2153 }
2154 proxy()->drawPrimitive(pe, opt: &copy, p, w: widget);
2155 }
2156
2157 if (sb->subControls & SC_SpinBoxDown) {
2158 copy.subControls = SC_SpinBoxDown;
2159 copy.state = sb->state;
2160 QPalette pal2 = sb->palette;
2161 if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
2162 pal2.setCurrentColorGroup(QPalette::Disabled);
2163 copy.state &= ~State_Enabled;
2164 }
2165 copy.palette = pal2;
2166
2167 if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
2168 copy.state |= State_On;
2169 copy.state |= State_Sunken;
2170 } else {
2171 copy.state |= State_Raised;
2172 copy.state &= ~State_Sunken;
2173 }
2174 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
2175 : PE_IndicatorSpinDown);
2176
2177 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxDown, widget);
2178 qDrawWinButton(p, r: copy.rect, pal: shadePal, sunken: copy.state & (State_Sunken | State_On),
2179 fill: &copy.palette.brush(cr: QPalette::Button));
2180 copy.rect.adjust(dx1: 4, dy1: 0, dx2: -5, dy2: -1);
2181 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
2182 && proxy()->styleHint(stylehint: SH_EtchDisabledText, opt, widget) )
2183 {
2184 QStyleOptionSpinBox lightCopy = copy;
2185 lightCopy.rect.adjust(dx1: 1, dy1: 1, dx2: 1, dy2: 1);
2186 lightCopy.palette.setBrush(acr: QPalette::ButtonText, abrush: copy.palette.light());
2187 proxy()->drawPrimitive(pe, opt: &lightCopy, p, w: widget);
2188 }
2189 proxy()->drawPrimitive(pe, opt: &copy, p, w: widget);
2190 }
2191 }
2192 break;
2193#endif // QT_CONFIG(spinbox)
2194
2195 default:
2196 QCommonStyle::drawComplexControl(cc, opt, p, w: widget);
2197 }
2198}
2199
2200/*! \reimp */
2201QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
2202 const QSize &csz, const QWidget *widget) const
2203{
2204 QSize sz(csz);
2205 switch (ct) {
2206 case CT_PushButton:
2207 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2208 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2209 int w = sz.width(),
2210 h = sz.height();
2211 int defwidth = 0;
2212 if (btn->features & QStyleOptionButton::AutoDefaultButton)
2213 defwidth = 2 * proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn, widget);
2214 const qreal dpi = QStyleHelper::dpi(option: opt);
2215 int minwidth = int(QStyleHelper::dpiScaled(value: 75, dpi));
2216 int minheight = int(QStyleHelper::dpiScaled(value: 23, dpi));
2217
2218 if (w < minwidth + defwidth && !btn->text.isEmpty())
2219 w = minwidth + defwidth;
2220 if (h < minheight + defwidth)
2221 h = minheight + defwidth;
2222
2223 sz = QSize(w, h);
2224 }
2225 break;
2226#if QT_CONFIG(menu)
2227 case CT_MenuItem:
2228 if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
2229 int w = sz.width();
2230 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2231
2232 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
2233 sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
2234 }
2235 else if (mi->icon.isNull()) {
2236 sz.setHeight(sz.height() - 2);
2237 w -= 6;
2238 }
2239
2240 if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
2241 int iconExtent = proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt, widget);
2242 sz.setHeight(qMax(a: sz.height(),
2243 b: mi->icon.actualSize(size: QSize(iconExtent, iconExtent)).height()
2244 + 2 * QWindowsStylePrivate::windowsItemFrame));
2245 }
2246 int maxpmw = mi->maxIconWidth;
2247 int tabSpacing = 20;
2248 if (mi->text.contains(c: u'\t'))
2249 w += tabSpacing;
2250 else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
2251 w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
2252 else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
2253 // adjust the font and add the difference in size.
2254 // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
2255 QFontMetrics fm(mi->font);
2256 QFont fontBold = mi->font;
2257 fontBold.setBold(true);
2258 QFontMetrics fmBold(fontBold);
2259 w += fmBold.horizontalAdvance(mi->text) - fm.horizontalAdvance(mi->text);
2260 }
2261
2262 int checkcol = qMax<int>(a: maxpmw, b: QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
2263 w += checkcol;
2264 w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
2265 sz.setWidth(w);
2266 }
2267 break;
2268#endif // QT_CONFIG(menu)
2269#if QT_CONFIG(menubar)
2270 case CT_MenuBarItem:
2271 if (!sz.isEmpty())
2272 sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
2273 break;
2274#endif
2275 case CT_ToolButton:
2276 if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
2277 return sz += QSize(7, 6);
2278 Q_FALLTHROUGH();
2279
2280 default:
2281 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize: csz, widget);
2282 }
2283 return sz;
2284}
2285
2286/*!
2287 \reimp
2288*/
2289QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
2290 const QWidget *widget) const
2291{
2292 return QCommonStyle::standardIcon(standardIcon, opt: option, widget);
2293}
2294
2295
2296
2297QT_END_NAMESPACE
2298
2299#include "moc_qwindowsstyle_p.cpp"
2300
2301#endif // style_windows
2302

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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