Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsstyle.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7
8#if QT_CONFIG(style_windows) || defined(QT_PLUGIN)
9
10#include "qapplication.h"
11#include "qbitmap.h"
12#include "qdrawutil.h" // for now
13#include "qevent.h"
14#if QT_CONFIG(menu)
15#include "qmenu.h"
16#endif
17#if QT_CONFIG(menubar)
18#include "qmenubar.h"
19#include <private/qmenubar_p.h>
20#endif
21#include "qpaintengine.h"
22#include "qpainter.h"
23#include "qpainterstateguard.h"
24#if QT_CONFIG(rubberband)
25#include "qrubberband.h"
26#endif
27#include "qstyleoption.h"
28#if QT_CONFIG(tabbar)
29#include "qtabbar.h"
30#endif
31#include "qwidget.h"
32#include "qdebug.h"
33#if QT_CONFIG(mainwindow)
34#include "qmainwindow.h"
35#endif
36#include "qfile.h"
37#include "qtextstream.h"
38#include "qpixmapcache.h"
39#if QT_CONFIG(wizard)
40#include "qwizard.h"
41#endif
42#if QT_CONFIG(listview)
43#include "qlistview.h"
44#endif
45#include <private/qmath_p.h>
46#include <qmath.h>
47#include <QtGui/qpainterpath.h>
48#include <QtGui/qscreen.h>
49#include <QtGui/qwindow.h>
50#include <qpa/qplatformtheme.h>
51#include <qpa/qplatformscreen.h>
52#include <private/qguiapplication_p.h>
53#include <private/qhighdpiscaling_p.h>
54#include <qpa/qplatformintegration.h>
55#include <private/qwidget_p.h>
56
57#include <private/qstylehelper_p.h>
58#if QT_CONFIG(animation)
59#include <private/qstyleanimation_p.h>
60#endif
61
62#include <algorithm>
63
64QT_BEGIN_NAMESPACE
65
66#if defined(Q_OS_WIN)
67
68QT_BEGIN_INCLUDE_NAMESPACE
69#include "qt_windows.h"
70QT_END_INCLUDE_NAMESPACE
71# ifndef COLOR_GRADIENTACTIVECAPTION
72# define COLOR_GRADIENTACTIVECAPTION 27
73# endif
74# ifndef COLOR_GRADIENTINACTIVECAPTION
75# define COLOR_GRADIENTINACTIVECAPTION 28
76# endif
77
78Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &);
79#endif //Q_OS_WIN
80
81QT_BEGIN_INCLUDE_NAMESPACE
82#include <limits.h>
83QT_END_INCLUDE_NAMESPACE
84
85enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
86
87/*
88 \internal
89*/
90
91QWindowsStylePrivate::QWindowsStylePrivate() = default;
92
93// Returns \c true if the toplevel parent of \a widget has seen the Alt-key
94bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
95{
96 widget = widget->window();
97 return seenAlt.contains(widget);
98}
99
100/*!
101 \reimp
102*/
103bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
104{
105 // Records Alt- and Focus events
106 if (!o->isWidgetType())
107 return QObject::eventFilter(o, e);
108
109 QWidget *widget = qobject_cast<QWidget*>(o);
110 Q_D(QWindowsStyle);
111 switch(e->type()) {
112 case QEvent::KeyPress:
113 if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
114 widget = widget->window();
115
116 // Alt has been pressed - find all widgets that care
117 const QList<QWidget *> children = widget->findChildren<QWidget *>();
118 auto ignorable = [](QWidget *w) {
119 return w->isWindow() || !w->isVisible()
120 || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w);
121 };
122 // Update states before repainting
123 d->seenAlt.append(widget);
124 d->alt_down = true;
125
126 // Repaint all relevant widgets
127 for (QWidget *w : children) {
128 if (!ignorable(w))
129 w->update();
130 }
131 }
132 break;
133 case QEvent::KeyRelease:
134 if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
135 widget = widget->window();
136
137 // Update state and repaint the menu bars.
138 d->alt_down = false;
139#if QT_CONFIG(menubar)
140 const QList<QMenuBar *> menuBars = widget->findChildren<QMenuBar *>();
141 for (QWidget *w : menuBars)
142 w->update();
143#endif
144 }
145 break;
146 case QEvent::Close:
147 // Reset widget when closing
148 d->seenAlt.removeAll(widget);
149 d->seenAlt.removeAll(widget->window());
150 break;
151 default:
152 break;
153 }
154 return QCommonStyle::eventFilter(o, e);
155}
156
157/*!
158 \class QWindowsStyle
159 \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
160
161 \ingroup appearance
162 \inmodule QtWidgets
163 \internal
164
165 This style is Qt's default GUI style on Windows.
166
167 \image qwindowsstyle.png {Gallery of widgets using the default GUI style}
168 \sa QWindowsVistaStyle, QMacStyle, QFusionStyle
169*/
170
171/*!
172 Constructs a QWindowsStyle object.
173*/
174QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
175{
176}
177
178/*!
179 \internal
180
181 Constructs a QWindowsStyle object.
182*/
183QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
184{
185}
186
187
188/*! Destroys the QWindowsStyle object. */
189QWindowsStyle::~QWindowsStyle()
190{
191}
192
193#ifdef Q_OS_WIN
194static inline QRgb colorref2qrgb(COLORREF col)
195{
196 return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
197}
198#endif
199
200/*! \reimp */
201void QWindowsStyle::polish(QApplication *app)
202{
203 QCommonStyle::polish(app);
204 QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
205 // We only need the overhead when shortcuts are sometimes hidden
206 if (!proxy()->styleHint(SH_UnderlineShortcut, nullptr) && app)
207 app->installEventFilter(this);
208
209 const auto &palette = QGuiApplication::palette();
210 d->activeGradientCaptionColor = palette.highlight().color();
211 d->activeCaptionColor = d->activeGradientCaptionColor;
212 d->inactiveGradientCaptionColor = palette.dark().color();
213 d->inactiveCaptionColor = d->inactiveGradientCaptionColor;
214 d->inactiveCaptionText = palette.window().color();
215
216#if defined(Q_OS_WIN) //fetch native title bar colors
217 if (app->desktopSettingsAware()){
218 DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
219 DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
220 DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
221 DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
222 DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
223 d->activeCaptionColor = colorref2qrgb(activeCaption);
224 d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
225 d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
226 d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
227 d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
228 }
229#endif
230}
231
232/*! \reimp */
233void QWindowsStyle::unpolish(QApplication *app)
234{
235 QCommonStyle::unpolish(app);
236 app->removeEventFilter(this);
237}
238
239/*! \reimp */
240void QWindowsStyle::polish(QWidget *widget)
241{
242 QCommonStyle::polish(widget);
243}
244
245/*! \reimp */
246void QWindowsStyle::unpolish(QWidget *widget)
247{
248 QCommonStyle::unpolish(widget);
249}
250
251/*!
252 \reimp
253*/
254void QWindowsStyle::polish(QPalette &pal)
255{
256 QCommonStyle::polish(pal);
257}
258
259int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget)
260{
261#if defined(Q_OS_WIN)
262 // The pixel metrics are in device indepentent pixels;
263 // hardcode DPI to 1x 96 DPI.
264 const int dpi = 96;
265
266 switch (pm) {
267 case QStyle::PM_DockWidgetFrameWidth:
268 return GetSystemMetricsForDpi(SM_CXFRAME, dpi);
269
270 case QStyle::PM_TitleBarHeight: {
271 const int resizeBorderThickness =
272 GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
273 if (widget && (widget->windowType() == Qt::Tool))
274 return GetSystemMetricsForDpi(SM_CYSMCAPTION, dpi) + resizeBorderThickness;
275 return GetSystemMetricsForDpi(SM_CYCAPTION, dpi) + resizeBorderThickness;
276 }
277
278 case QStyle::PM_ScrollBarExtent:
279 {
280 NONCLIENTMETRICS ncm;
281 ncm.cbSize = sizeof(NONCLIENTMETRICS);
282 if (SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpi))
283 return qMax(ncm.iScrollHeight, ncm.iScrollWidth);
284 }
285 break;
286
287 case QStyle::PM_MdiSubWindowFrameWidth:
288 return GetSystemMetricsForDpi(SM_CYFRAME, dpi);
289
290 default:
291 break;
292 }
293#else // Q_OS_WIN
294 Q_UNUSED(pm);
295 Q_UNUSED(widget);
296#endif
297 return QWindowsStylePrivate::InvalidMetric;
298}
299
300int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
301{
302 switch (pm) {
303 case QStyle::PM_ToolBarItemSpacing:
304 return 0;
305 case QStyle::PM_ButtonDefaultIndicator:
306 case QStyle::PM_ButtonShiftHorizontal:
307 case QStyle::PM_ButtonShiftVertical:
308 case QStyle::PM_MenuHMargin:
309 case QStyle::PM_MenuVMargin:
310 case QStyle::PM_ToolBarItemMargin:
311 return 1;
312 case QStyle::PM_DockWidgetSeparatorExtent:
313 return 4;
314#if QT_CONFIG(tabbar)
315 case QStyle::PM_TabBarTabShiftHorizontal:
316 return 0;
317 case QStyle::PM_TabBarTabShiftVertical:
318 return 2;
319#endif
320
321#if QT_CONFIG(slider)
322 case QStyle::PM_SliderLength:
323 return 11;
324#endif // QT_CONFIG(slider)
325
326#if QT_CONFIG(menu)
327 case QStyle::PM_MenuBarHMargin:
328 case QStyle::PM_MenuBarVMargin:
329 case QStyle::PM_MenuBarPanelWidth:
330 return 0;
331 case QStyle::PM_SmallIconSize:
332 return 16;
333 case QStyle::PM_LargeIconSize:
334 return 32;
335 case QStyle::PM_DockWidgetTitleMargin:
336 return 2;
337 case QStyle::PM_DockWidgetTitleBarButtonMargin:
338 case QStyle::PM_DockWidgetFrameWidth:
339 return 4;
340
341#endif // QT_CONFIG(menu)
342 case QStyle::PM_ToolBarHandleExtent:
343 return 10;
344 default:
345 break;
346 }
347 return QWindowsStylePrivate::InvalidMetric;
348}
349
350static QScreen *screenOf(const QWidget *w)
351{
352 if (w) {
353 if (auto screen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen())
354 return screen;
355 }
356 return QGuiApplication::primaryScreen();
357}
358
359// Calculate the overall scale factor to obtain Qt Device Independent
360// Pixels from a native Windows size.
361qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
362{
363 return qreal(1) / QHighDpiScaling::factor(screenOf(widget));
364}
365
366/*!
367 \reimp
368*/
369int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
370{
371 int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget);
372 if (ret != QWindowsStylePrivate::InvalidMetric)
373 return ret;
374
375 ret = QWindowsStylePrivate::fixedPixelMetric(pm);
376 if (ret != QWindowsStylePrivate::InvalidMetric)
377 return int(QStyleHelper::dpiScaled(ret, opt));
378
379 ret = 0;
380
381 switch (pm) {
382 case PM_MaximumDragDistance:
383 ret = QCommonStyle::pixelMetric(PM_MaximumDragDistance, opt, widget);
384 if (ret == -1)
385 ret = 60;
386 break;
387
388#if QT_CONFIG(slider)
389 // Returns the number of pixels to use for the business part of the
390 // slider (i.e., the non-tickmark portion). The remaining space is shared
391 // equally between the tickmark regions.
392 case PM_SliderControlThickness:
393 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
394 int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
395 int ticks = sl->tickPosition;
396 int n = 0;
397 if (ticks & QSlider::TicksAbove)
398 ++n;
399 if (ticks & QSlider::TicksBelow)
400 ++n;
401 if (!n) {
402 ret = space;
403 break;
404 }
405
406 int thick = 6; // Magic constant to get 5 + 16 + 5
407 if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
408 thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
409
410 space -= thick;
411 if (space > 0)
412 thick += (space * 2) / (n + 2);
413 ret = thick;
414 }
415 break;
416#endif // QT_CONFIG(slider)
417
418 case PM_IconViewIconSize:
419 ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
420 break;
421
422 case PM_SplitterWidth:
423 ret = QStyleHelper::dpiScaled(4, opt);
424 break;
425
426 default:
427 ret = QCommonStyle::pixelMetric(pm, opt, widget);
428 break;
429 }
430
431 return ret;
432}
433
434/*!
435 \reimp
436 */
437QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
438 const QWidget *widget) const
439{
440 return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
441}
442
443/*! \reimp */
444int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
445 QStyleHintReturn *returnData) const
446{
447 int ret = 0;
448
449 switch (hint) {
450 case SH_EtchDisabledText: {
451 const QPalette pal = opt ? opt->palette
452 : widget ? widget->palette()
453 : QPalette();
454 ret = pal.window().color().lightness() > pal.text().color().lightness()
455 ? 1 : 0;
456 break;
457 }
458 case SH_Slider_SnapToValue:
459 case SH_PrintDialog_RightAlignButtons:
460 case SH_FontDialog_SelectAssociatedText:
461 case SH_Menu_AllowActiveAndDisabled:
462 case SH_MenuBar_AltKeyNavigation:
463 case SH_MenuBar_MouseTracking:
464 case SH_Menu_MouseTracking:
465 case SH_ComboBox_ListMouseTracking_Current:
466 case SH_Slider_StopMouseOverSlider:
467 case SH_MainWindow_SpaceBelowMenuBar:
468 ret = 1;
469
470 break;
471 case SH_ItemView_ShowDecorationSelected:
472#if QT_CONFIG(listview)
473 if (qobject_cast<const QListView*>(widget))
474 ret = 1;
475#endif
476 break;
477 case SH_ItemView_ChangeHighlightOnFocus:
478 ret = 1;
479 break;
480 case SH_ToolBox_SelectedPageTitleBold:
481 ret = 0;
482 break;
483
484#if defined(Q_OS_WIN)
485 case SH_UnderlineShortcut:
486 {
487 ret = 1;
488 BOOL cues = false;
489 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
490 ret = int(cues);
491 // Do nothing if we always paint underlines
492 Q_D(const QWindowsStyle);
493 if (!ret && widget && d) {
494#if QT_CONFIG(menubar)
495 const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
496 if (!menuBar && qobject_cast<const QMenu *>(widget)) {
497 QWidget *w = QApplication::activeWindow();
498 if (w && w != widget)
499 menuBar = w->findChild<QMenuBar *>();
500 }
501 // If we paint a menu bar draw underlines if is in the keyboardState
502 if (menuBar) {
503 if (menuBar->d_func()->keyboardState || d->altDown())
504 ret = 1;
505 // Otherwise draw underlines if the toplevel widget has seen an alt-press
506 } else
507#endif // QT_CONFIG(menubar)
508 if (d->hasSeenAlt(widget)) {
509 ret = 1;
510 }
511 }
512#if QT_CONFIG(accessibility)
513 if (!ret && opt && opt->type == QStyleOption::SO_MenuItem
514 && QStyleHelper::isInstanceOf(opt->styleObject, QAccessible::MenuItem)
515 && opt->styleObject->property("_q_showUnderlined").toBool())
516 ret = 1;
517#endif // QT_CONFIG(accessibility)
518 break;
519 }
520#endif // Q_OS_WIN
521 case SH_Menu_SubMenuSloppyCloseTimeout:
522 case SH_Menu_SubMenuPopupDelay: {
523#if defined(Q_OS_WIN)
524 DWORD delay;
525 if (SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0))
526 ret = delay;
527 else
528#endif // Q_OS_WIN
529 ret = 400;
530 break;
531 }
532#if QT_CONFIG(rubberband)
533 case SH_RubberBand_Mask:
534 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
535 ret = 0;
536 if (rbOpt->shape == QRubberBand::Rectangle) {
537 ret = true;
538 if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
539 mask->region = opt->rect;
540 int size = 1;
541 if (widget && widget->isWindow())
542 size = 4;
543 mask->region -= opt->rect.adjusted(size, size, -size, -size);
544 }
545 }
546 }
547 break;
548#endif // QT_CONFIG(rubberband)
549#if QT_CONFIG(wizard)
550 case SH_WizardStyle:
551 ret = QWizard::ModernStyle;
552 break;
553#endif
554 case SH_ItemView_ArrowKeysNavigateIntoChildren:
555 ret = true;
556 break;
557 case SH_DialogButtonBox_ButtonsHaveIcons:
558 ret = 0;
559 break;
560 default:
561 ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
562 break;
563 }
564 return ret;
565}
566
567/*! \reimp */
568void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
569 const QWidget *w) const
570{
571 // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
572 bool doRestore = false;
573
574 switch (pe) {
575#if QT_CONFIG(toolbar)
576 case PE_IndicatorToolBarSeparator: {
577 QPainterStateGuard psg(p);
578 const QRect &rect = opt->rect;
579 constexpr int margin = 2;
580 if (opt->state & State_Horizontal){
581 const int offset = rect.width() / 2;
582 const auto &tl = rect.topLeft();
583 const auto &bl = rect.bottomLeft();
584 p->setPen(opt->palette.dark().color());
585 p->drawLine(QLine(bl.x() + offset, bl.y() - margin,
586 tl.x() + offset, tl.y() + margin));
587 p->setPen(opt->palette.light().color());
588 p->drawLine(QLine(bl.x() + offset + 1, bl.y() - margin,
589 tl.x() + offset + 1, tl.y() + margin));
590 }
591 else{ //Draw vertical separator
592 const int offset = rect.height() / 2;
593 const auto &tl = rect.topLeft();
594 const auto &tr = rect.topRight();
595 p->setPen(opt->palette.dark().color());
596 p->drawLine(QLine(tl.x() + margin, tl.y() + offset,
597 tr.x() - margin, tr.y() + offset));
598 p->setPen(opt->palette.light().color());
599 p->drawLine(QLine(tl.x() + margin, tl.y() + offset + 1,
600 tr.x() - margin, tr.y() + offset + 1));
601 }
602 break;
603 }
604 case PE_IndicatorToolBarHandle: {
605 QPainterStateGuard psg(p);
606 p->translate(opt->rect.x(), opt->rect.y());
607 if (opt->state & State_Horizontal) {
608 if (opt->rect.height() > 4) {
609 int x = opt->rect.width() / 2 - 4;
610 if (opt->direction == Qt::RightToLeft)
611 x -= 2;
612 qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
613 opt->palette, false, 1, nullptr);
614 qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
615 opt->palette, false, 1, nullptr);
616 }
617 } else {
618 if (opt->rect.width() > 4) {
619 int y = opt->rect.height() / 2 - 4;
620 qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
621 opt->palette, false, 1, nullptr);
622 qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
623 opt->palette, false, 1, nullptr);
624 }
625 }
626 break;
627 }
628#endif // QT_CONFIG(toolbar)
629 case PE_FrameButtonTool:
630 case PE_PanelButtonTool: {
631 QPen oldPen = p->pen();
632#if QT_CONFIG(dockwidget)
633 if (w && w->inherits("QDockWidgetTitleButton")) {
634 if (const QWidget *dw = w->parentWidget())
635 if (dw->isWindow()){
636 qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On),
637 &opt->palette.button());
638
639 return;
640 }
641 }
642#endif // QT_CONFIG(dockwidget)
643 QBrush fill;
644 bool stippled;
645 bool panel = (pe == PE_PanelButtonTool);
646 if ((!(opt->state & State_Sunken ))
647 && (!(opt->state & State_Enabled)
648 || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
649 && (opt->state & State_On)) {
650 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
651 stippled = true;
652 } else {
653 fill = opt->palette.brush(QPalette::Button);
654 stippled = false;
655 }
656
657 if (opt->state & (State_Raised | State_Sunken | State_On)) {
658 if (opt->state & State_AutoRaise) {
659 if (opt->state & (State_Enabled | State_Sunken | State_On)){
660 if (panel)
661 qDrawShadePanel(p, opt->rect, opt->palette,
662 opt->state & (State_Sunken | State_On), 1, &fill);
663 else
664 qDrawShadeRect(p, opt->rect, opt->palette,
665 opt->state & (State_Sunken | State_On), 1);
666 }
667 if (stippled) {
668 p->setPen(opt->palette.button().color());
669 p->drawRect(opt->rect.adjusted(1,1,-2,-2));
670 }
671 } else {
672 qDrawWinButton(p, opt->rect, opt->palette,
673 opt->state & (State_Sunken | State_On), panel ? &fill : nullptr);
674 }
675 } else {
676 p->fillRect(opt->rect, fill);
677 }
678 p->setPen(oldPen);
679 break; }
680 case PE_PanelButtonCommand:
681 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
682 QBrush fill;
683 State flags = opt->state;
684 QPalette pal = opt->palette;
685 QRect r = opt->rect;
686 if (! (flags & State_Sunken) && (flags & State_On))
687 fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
688 else
689 fill = pal.brush(QPalette::Button);
690
691 if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
692 p->setPen(pal.dark().color());
693 p->setBrush(fill);
694 p->drawRect(r.adjusted(0, 0, -1, -1));
695 } else if (flags & (State_Raised | State_On | State_Sunken)) {
696 qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On),
697 &fill);
698 } else {
699 p->fillRect(r, fill);
700 }
701 }
702 break;
703 case PE_FrameDefaultButton: {
704 QPen oldPen = p->pen();
705 p->setPen(QPen(opt->palette.shadow().color(), 0));
706 QRectF rect = opt->rect;
707 const qreal dpi = QStyleHelper::dpi(opt);
708 const qreal topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
709 const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(-1.5, dpi);
710 rect.adjust(topLevelAdjustment, topLevelAdjustment,
711 bottomRightAdjustment, bottomRightAdjustment);
712 p->drawRect(rect);
713 p->setPen(oldPen);
714 break;
715 }
716 case PE_IndicatorCheckBox: {
717 QBrush fill;
718 if (opt->state & State_NoChange)
719 fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
720 else if (opt->state & State_Sunken)
721 fill = opt->palette.button();
722 else if (opt->state & State_Enabled)
723 fill = opt->palette.base();
724 else
725 fill = opt->palette.window();
726 p->save();
727 doRestore = true;
728 qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
729 if (opt->state & State_NoChange)
730 p->setPen(opt->palette.dark().color());
731 else
732 p->setPen(opt->palette.text().color());
733 }
734 Q_FALLTHROUGH();
735 case PE_IndicatorItemViewItemCheck:
736 if (!doRestore) {
737 p->save();
738 doRestore = true;
739 }
740#if QT_CONFIG(itemviews)
741 if (pe == PE_IndicatorItemViewItemCheck) {
742 const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
743 p->setPen(itemViewOpt
744 && itemViewOpt->showDecorationSelected
745 && opt->state & State_Selected
746 ? opt->palette.highlightedText().color()
747 : opt->palette.text().color());
748 if (opt->state & State_NoChange)
749 p->setBrush(opt->palette.brush(QPalette::Button));
750 p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, opt->rect.width() - 2, opt->rect.height() - 2);
751 }
752#endif // QT_CONFIG(itemviews)
753 if (!(opt->state & State_Off)) {
754 std::array<QPointF, 6> points;
755 qreal scaleh = opt->rect.width() / 12.0;
756 qreal scalev = opt->rect.height() / 12.0;
757 points[0] = { opt->rect.x() + qreal(3.5) * scaleh, opt->rect.y() + qreal(5.5) * scalev };
758 points[1] = { points[0].x(), points[0].y() + 2 * scalev };
759 points[2] = { points[1].x() + 2 * scaleh, points[1].y() + 2 * scalev };
760 points[3] = { points[2].x() + 4 * scaleh, points[2].y() - 4 * scalev };
761 points[4] = { points[3].x(), points[3].y() - 2 * scalev };
762 points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev };
763 p->setPen(QPen(opt->palette.text().color(), 0));
764 p->setBrush(opt->palette.text());
765 p->drawPolygon(points.data(), static_cast<int>(points.size()));
766 }
767 if (doRestore)
768 p->restore();
769 break;
770 case PE_FrameFocusRect:
771 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
772 //### check for d->alt_down
773 if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt, w))
774 return;
775 QRect r = opt->rect;
776 p->save();
777 p->setBackgroundMode(Qt::TransparentMode);
778 QColor bg_col = fropt->backgroundColor;
779 if (!bg_col.isValid())
780 bg_col = p->background().color();
781 // Create an "XOR" color.
782 QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
783 (bg_col.green() ^ 0xff) & 0xff,
784 (bg_col.blue() ^ 0xff) & 0xff);
785 p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
786 p->setBrushOrigin(r.topLeft());
787 p->setPen(Qt::NoPen);
788 p->drawRect(r.left(), r.top(), r.width(), 1); // Top
789 p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
790 p->drawRect(r.left(), r.top(), 1, r.height()); // Left
791 p->drawRect(r.right(), r.top(), 1, r.height()); // Right
792 p->restore();
793 }
794 break;
795 case PE_IndicatorRadioButton:
796 {
797 QRect r = opt->rect;
798 p->save();
799 p->setRenderHint(QPainter::Antialiasing, true);
800
801 QPointF circleCenter = r.center() + QPoint(1, 1);
802 qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1;
803
804 QPainterPath path1;
805 path1.addEllipse(circleCenter, radius, radius);
806 radius *= 0.85;
807 QPainterPath path2;
808 path2.addEllipse(circleCenter, radius, radius);
809 radius *= 0.85;
810 QPainterPath path3;
811 path3.addEllipse(circleCenter, radius, radius);
812 radius *= 0.5;
813 QPainterPath path4;
814 path4.addEllipse(circleCenter, radius, radius);
815
816 QPolygon topLeftPol, bottomRightPol;
817 topLeftPol.setPoints(3, r.x(), r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y());
818 bottomRightPol.setPoints(3, r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y());
819
820 p->setClipRegion(QRegion(topLeftPol));
821 p->setPen(opt->palette.dark().color());
822 p->setBrush(opt->palette.dark());
823 p->drawPath(path1);
824 p->setPen(opt->palette.shadow().color());
825 p->setBrush(opt->palette.shadow());
826 p->drawPath(path2);
827
828 p->setClipRegion(QRegion(bottomRightPol));
829 p->setPen(opt->palette.light().color());
830 p->setBrush(opt->palette.light());
831 p->drawPath(path1);
832 p->setPen(opt->palette.midlight().color());
833 p->setBrush(opt->palette.midlight());
834 p->drawPath(path2);
835
836 QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ?
837 opt->palette.button().color() : opt->palette.base().color();
838
839 p->setClipping(false);
840 p->setPen(fillColor);
841 p->setBrush(fillColor);
842 p->drawPath(path3);
843
844 if (opt->state & State_On) {
845 p->setPen(opt->palette.text().color());
846 p->setBrush(opt->palette.text());
847 p->drawPath(path4);
848 }
849 p->restore();
850 break;
851 }
852#ifndef QT_NO_FRAME
853 case PE_Frame:
854 if (w && w->inherits("QComboBoxPrivateContainer")){
855 QStyleOption copy = *opt;
856 copy.state |= State_Raised;
857 proxy()->drawPrimitive(PE_PanelMenu, &copy, p, w);
858 break;
859 }
860 Q_FALLTHROUGH();
861 case PE_FrameMenu:
862 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
863 if (frame->lineWidth == 2 || pe == PE_Frame) {
864 QPalette popupPal = frame->palette;
865 if (pe == PE_FrameMenu) {
866 popupPal.setColor(QPalette::Light, frame->palette.window().color());
867 popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
868 }
869 if (pe == PE_Frame && (frame->state & State_Raised))
870 qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
871 else if (pe == PE_Frame && (frame->state & State_Sunken))
872 {
873 popupPal.setColor(QPalette::Midlight, frame->palette.window().color());
874 qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
875 }
876 else
877 qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
878 } else {
879 QCommonStyle::drawPrimitive(pe, opt, p, w);
880 }
881 } else {
882 QPalette popupPal = opt->palette;
883 p->drawRect(opt->rect);
884 popupPal.setColor(QPalette::Light, opt->palette.window().color());
885 popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
886 qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
887 }
888 break;
889#endif // QT_NO_FRAME
890 case PE_FrameButtonBevel:
891 case PE_PanelButtonBevel: {
892 QBrush fill;
893 bool panel = pe != PE_FrameButtonBevel;
894 p->setBrushOrigin(opt->rect.topLeft());
895 if (!(opt->state & State_Sunken) && (opt->state & State_On))
896 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
897 else
898 fill = opt->palette.brush(QPalette::Button);
899
900 if (opt->state & (State_Raised | State_On | State_Sunken)) {
901 qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
902 panel ? &fill : nullptr);
903 } else {
904 if (panel)
905 p->fillRect(opt->rect, fill);
906 else
907 p->drawRect(opt->rect);
908 }
909 break; }
910 case PE_PanelMenu:
911 if (w && w->inherits("QComboBoxPrivateContainer")){
912 const QBrush menuBackground = opt->palette.base().color();
913 QColor borderColor = opt->palette.window().color();
914 qDrawPlainRect(p, opt->rect, borderColor, 1, &menuBackground);
915 } else {
916 QCommonStyle::drawPrimitive(pe, opt, p, w);
917 }
918 break;
919 case PE_FrameWindow: {
920 QPalette popupPal = opt->palette;
921 popupPal.setColor(QPalette::Light, opt->palette.window().color());
922 popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
923 qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
924 break; }
925#if QT_CONFIG(dockwidget)
926 case PE_IndicatorDockWidgetResizeHandle:
927 break;
928 case PE_FrameDockWidget:
929 if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
930 proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w);
931 }
932 break;
933#endif // QT_CONFIG(dockwidget)
934
935 case PE_FrameStatusBarItem:
936 qDrawShadePanel(p, opt->rect, opt->palette, true, 1, nullptr);
937 break;
938
939 case PE_IndicatorProgressChunk:
940 {
941 bool vertical = false, inverted = false;
942 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
943 vertical = !(pb->state & QStyle::State_Horizontal);
944 inverted = pb->invertedAppearance;
945 }
946
947 int space = 2;
948 int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, w) - space;
949 if (!vertical) {
950 if (opt->rect.width() <= chunksize)
951 space = 0;
952
953 if (inverted)
954 p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
955 opt->palette.brush(QPalette::Highlight));
956 else
957 p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
958 opt->palette.brush(QPalette::Highlight));
959 } else {
960 if (opt->rect.height() <= chunksize)
961 space = 0;
962
963 if (inverted)
964 p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space,
965 opt->palette.brush(QPalette::Highlight));
966 else
967 p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space,
968 opt->palette.brush(QPalette::Highlight));
969 }
970 }
971 break;
972
973 case PE_FrameTabWidget: {
974 qDrawWinButton(p, opt->rect, opt->palette, false, nullptr);
975 break;
976 }
977 default:
978 QCommonStyle::drawPrimitive(pe, opt, p, w);
979 }
980}
981
982/*! \reimp */
983void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
984 const QWidget *widget) const
985{
986 switch (ce) {
987#if QT_CONFIG(rubberband)
988 case CE_RubberBand:
989 if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
990 // ### workaround for slow general painter path
991 QPixmap tiledPixmap(16, 16);
992 QPainter pixmapPainter(&tiledPixmap);
993 pixmapPainter.setPen(Qt::NoPen);
994 pixmapPainter.setBrush(Qt::Dense4Pattern);
995 pixmapPainter.setBackground(Qt::white);
996 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
997 pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
998 pixmapPainter.end();
999 tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
1000 p->save();
1001 QRect r = opt->rect;
1002 QStyleHintReturnMask mask;
1003 if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
1004 p->setClipRegion(mask.region);
1005 p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
1006 p->restore();
1007 return;
1008 }
1009 break;
1010#endif // QT_CONFIG(rubberband)
1011
1012#if QT_CONFIG(menu) && QT_CONFIG(mainwindow)
1013 case CE_MenuBarEmptyArea:
1014 if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
1015 p->fillRect(opt->rect, opt->palette.button());
1016 QPen oldPen = p->pen();
1017 p->setPen(opt->palette.dark().color());
1018 p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
1019 p->setPen(oldPen);
1020 }
1021 break;
1022#endif
1023#if QT_CONFIG(menu)
1024 case CE_MenuItem:
1025 if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1026 int x, y, w, h;
1027 menuitem->rect.getRect(&x, &y, &w, &h);
1028 int tab = menuitem->reservedShortcutWidth;
1029 bool dis = !(menuitem->state & State_Enabled);
1030 bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
1031 ? menuitem->checked : false;
1032 bool act = menuitem->state & State_Selected;
1033
1034 // windows always has a check column, regardless whether we have an icon or not
1035 int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
1036
1037 QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
1038 p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
1039
1040 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
1041 int yoff = y-1 + h / 2;
1042 p->setPen(menuitem->palette.dark().color());
1043 p->drawLine(x + 2, yoff, x + w - 4, yoff);
1044 p->setPen(menuitem->palette.light().color());
1045 p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1);
1046 return;
1047 }
1048
1049 QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
1050 if (!menuitem->icon.isNull() && checked) {
1051 if (act) {
1052 qDrawShadePanel(p, vCheckRect,
1053 menuitem->palette, true, 1,
1054 &menuitem->palette.brush(QPalette::Button));
1055 } else {
1056 QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
1057 qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill);
1058 }
1059 } else if (!act) {
1060 p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
1061 }
1062
1063 // On Windows Style, if we have a checkable item and an icon we
1064 // draw the icon recessed to indicate an item is checked. If we
1065 // have no icon, we draw a checkmark instead.
1066 if (!menuitem->icon.isNull()) {
1067 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1068 if (act && !dis)
1069 mode = QIcon::Active;
1070 const auto size = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
1071 const auto dpr = QStyleHelper::getDpr(p);
1072 const auto state = checked ? QIcon::On : QIcon::Off;
1073 const auto pixmap = menuitem->icon.pixmap(QSize(size, size), dpr, mode, state);
1074 QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize());
1075 pmr.moveCenter(vCheckRect.center());
1076 p->setPen(menuitem->palette.text().color());
1077 p->drawPixmap(pmr.topLeft(), pixmap);
1078 } else if (checked) {
1079 QStyleOptionMenuItem newMi = *menuitem;
1080 newMi.state = State_None;
1081 if (!dis)
1082 newMi.state |= State_Enabled;
1083 if (act)
1084 newMi.state |= State_On | State_Selected;
1085 newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
1086 menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
1087 checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
1088 menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
1089 proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
1090 }
1091 p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
1092
1093 QColor discol;
1094 if (dis) {
1095 discol = menuitem->palette.text().color();
1096 p->setPen(discol);
1097 }
1098
1099 int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
1100 int xpos = menuitem->rect.x() + xm;
1101 QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1102 w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1103 QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
1104 QStringView s(menuitem->text);
1105 if (!s.isEmpty()) { // draw text
1106 p->save();
1107 qsizetype t = s.indexOf(u'\t');
1108 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1109 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1110 text_flags |= Qt::TextHideMnemonic;
1111 text_flags |= Qt::AlignLeft;
1112 if (t >= 0) {
1113 QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
1114 QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1115 const QString textToDraw = s.mid(t + 1).toString();
1116 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
1117 p->setPen(menuitem->palette.light().color());
1118 p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1119 p->setPen(discol);
1120 }
1121 p->drawText(vShortcutRect, text_flags, textToDraw);
1122 s = s.left(t);
1123 }
1124 QFont font = menuitem->font;
1125 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1126 font.setBold(true);
1127 p->setFont(font);
1128 const QString textToDraw = s.left(t).toString();
1129 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
1130 p->setPen(menuitem->palette.light().color());
1131 p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1132 p->setPen(discol);
1133 }
1134 p->drawText(vTextRect, text_flags, textToDraw);
1135 p->restore();
1136 }
1137 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1138 int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
1139 PrimitiveElement arrow;
1140 arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1141 xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
1142 QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1143 QStyleOptionMenuItem newMI = *menuitem;
1144 newMI.rect = vSubMenuRect;
1145 newMI.state = dis ? State_None : State_Enabled;
1146 if (act)
1147 newMI.palette.setColor(QPalette::ButtonText,
1148 newMI.palette.highlightedText().color());
1149 proxy()->drawPrimitive(arrow, &newMI, p, widget);
1150 }
1151
1152 }
1153 break;
1154#endif // QT_CONFIG(menu)
1155#if QT_CONFIG(menubar)
1156 case CE_MenuBarItem:
1157 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1158 const bool active = mbi->state & State_Selected;
1159 const QBrush buttonBrush = mbi->palette.brush(QPalette::Button);
1160 QStyleOptionMenuItem newMbi = *mbi;
1161 p->fillRect(mbi->rect, buttonBrush);
1162 if (active) {
1163 const bool hasFocus = mbi->state & State_HasFocus;
1164 const bool down = mbi->state & State_Sunken;
1165 QPainterStateGuard psg(p, QPainterStateGuard::InitialState::NoSave);
1166 if (down) {
1167 psg.save();
1168 p->setBrushOrigin(p->brushOriginF() + QPointF(1, 1));
1169 }
1170 if (hasFocus)
1171 qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(),
1172 mbi->rect.height(), mbi->palette, active && down, 1, 0, &buttonBrush);
1173 if (down)
1174 newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget),
1175 proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget));
1176 }
1177 QCommonStyle::drawControl(ce, &newMbi, p, widget);
1178 }
1179 break;
1180#endif // QT_CONFIG(menubar)
1181#if QT_CONFIG(tabbar)
1182 case CE_TabBarTabShape:
1183 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1184 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1185 && (tab->shape == QTabBar::RoundedNorth
1186 || tab->shape == QTabBar::RoundedSouth));
1187 bool selected = tab->state & State_Selected;
1188 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1189 || (rtlHorTabs
1190 && tab->position == QStyleOptionTab::Beginning));
1191 bool firstTab = ((!rtlHorTabs
1192 && tab->position == QStyleOptionTab::Beginning)
1193 || (rtlHorTabs
1194 && tab->position == QStyleOptionTab::End));
1195 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1196 bool previousSelected =
1197 ((!rtlHorTabs
1198 && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
1199 || (rtlHorTabs
1200 && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
1201 bool nextSelected =
1202 ((!rtlHorTabs
1203 && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
1204 || (rtlHorTabs
1205 && tab->selectedPosition
1206 == QStyleOptionTab::PreviousIsSelected));
1207 int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
1208 bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
1209 || (rtlHorTabs
1210 && tabBarAlignment == Qt::AlignRight);
1211
1212 bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
1213 || (rtlHorTabs
1214 && tabBarAlignment == Qt::AlignLeft);
1215
1216 QColor light = tab->palette.light().color();
1217 QColor dark = tab->palette.dark().color();
1218 QColor shadow = tab->palette.shadow().color();
1219 int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
1220 if (selected)
1221 borderThinkness /= 2;
1222 QRect r2(opt->rect);
1223 int x1 = r2.left();
1224 int x2 = r2.right();
1225 int y1 = r2.top();
1226 int y2 = r2.bottom();
1227 switch (tab->shape) {
1228 default:
1229 QCommonStyle::drawControl(ce, tab, p, widget);
1230 break;
1231 case QTabBar::RoundedNorth: {
1232 if (!selected) {
1233 y1 += 2;
1234 x1 += onlyOne || firstTab ? borderThinkness : 0;
1235 x2 -= onlyOne || lastTab ? borderThinkness : 0;
1236 }
1237
1238 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window());
1239
1240 // Delete border
1241 if (selected) {
1242 p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window());
1243 p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window());
1244 }
1245 // Left
1246 if (firstTab || selected || onlyOne || !previousSelected) {
1247 p->setPen(light);
1248 p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1249 p->drawPoint(x1 + 1, y1 + 1);
1250 }
1251 // Top
1252 {
1253 int beg = x1 + (previousSelected ? 0 : 2);
1254 int end = x2 - (nextSelected ? 0 : 2);
1255 p->setPen(light);
1256 p->drawLine(beg, y1, end, y1);
1257 }
1258 // Right
1259 if (lastTab || selected || onlyOne || !nextSelected) {
1260 p->setPen(shadow);
1261 p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1262 p->drawPoint(x2 - 1, y1 + 1);
1263 p->setPen(dark);
1264 p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1265 }
1266 break; }
1267 case QTabBar::RoundedSouth: {
1268 if (!selected) {
1269 y2 -= 2;
1270 x1 += firstTab ? borderThinkness : 0;
1271 x2 -= lastTab ? borderThinkness : 0;
1272 }
1273
1274 p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1275
1276 // Delete border
1277 if (selected) {
1278 p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window());
1279 p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window());
1280 }
1281 // Left
1282 if (firstTab || selected || onlyOne || !previousSelected) {
1283 p->setPen(light);
1284 p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1285 p->drawPoint(x1 + 1, y2 - 1);
1286 }
1287 // Bottom
1288 {
1289 int beg = x1 + (previousSelected ? 0 : 2);
1290 int end = x2 - (nextSelected ? 0 : 2);
1291 p->setPen(shadow);
1292 p->drawLine(beg, y2, end, y2);
1293 p->setPen(dark);
1294 p->drawLine(beg, y2 - 1, end, y2 - 1);
1295 }
1296 // Right
1297 if (lastTab || selected || onlyOne || !nextSelected) {
1298 p->setPen(shadow);
1299 p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1300 p->drawPoint(x2 - 1, y2 - 1);
1301 p->setPen(dark);
1302 p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1303 }
1304 break; }
1305 case QTabBar::RoundedWest: {
1306 if (!selected) {
1307 x1 += 2;
1308 y1 += firstTab ? borderThinkness : 0;
1309 y2 -= lastTab ? borderThinkness : 0;
1310 }
1311
1312 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window());
1313
1314 // Delete border
1315 if (selected) {
1316 p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window());
1317 p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window());
1318 }
1319 // Top
1320 if (firstTab || selected || onlyOne || !previousSelected) {
1321 p->setPen(light);
1322 p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
1323 p->drawPoint(x1 + 1, y1 + 1);
1324 }
1325 // Left
1326 {
1327 int beg = y1 + (previousSelected ? 0 : 2);
1328 int end = y2 - (nextSelected ? 0 : 2);
1329 p->setPen(light);
1330 p->drawLine(x1, beg, x1, end);
1331 }
1332 // Bottom
1333 if (lastTab || selected || onlyOne || !nextSelected) {
1334 p->setPen(shadow);
1335 p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1336 p->drawPoint(x1 + 2, y2 - 1);
1337 p->setPen(dark);
1338 p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
1339 p->drawPoint(x1 + 1, y2 - 1);
1340 p->drawPoint(x1 + 2, y2);
1341 }
1342 break; }
1343 case QTabBar::RoundedEast: {
1344 if (!selected) {
1345 x2 -= 2;
1346 y1 += firstTab ? borderThinkness : 0;
1347 y2 -= lastTab ? borderThinkness : 0;
1348 }
1349
1350 p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1351
1352 // Delete border
1353 if (selected) {
1354 p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window());
1355 p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window());
1356 }
1357 // Top
1358 if (firstTab || selected || onlyOne || !previousSelected) {
1359 p->setPen(light);
1360 p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
1361 p->drawPoint(x2 - 1, y1 + 1);
1362 }
1363 // Right
1364 {
1365 int beg = y1 + (previousSelected ? 0 : 2);
1366 int end = y2 - (nextSelected ? 0 : 2);
1367 p->setPen(shadow);
1368 p->drawLine(x2, beg, x2, end);
1369 p->setPen(dark);
1370 p->drawLine(x2 - 1, beg, x2 - 1, end);
1371 }
1372 // Bottom
1373 if (lastTab || selected || onlyOne || !nextSelected) {
1374 p->setPen(shadow);
1375 p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1376 p->drawPoint(x2 - 1, y2 - 1);
1377 p->setPen(dark);
1378 p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
1379 }
1380 break; }
1381 }
1382 }
1383 break;
1384#endif // QT_CONFIG(tabbar)
1385 case CE_ToolBoxTabShape:
1386 qDrawShadePanel(p, opt->rect, opt->palette,
1387 opt->state & (State_Sunken | State_On), 1,
1388 &opt->palette.brush(QPalette::Button));
1389 break;
1390#if QT_CONFIG(splitter)
1391 case CE_Splitter:
1392 p->eraseRect(opt->rect);
1393 break;
1394#endif // QT_CONFIG(splitter)
1395#if QT_CONFIG(scrollbar)
1396 case CE_ScrollBarSubLine:
1397 case CE_ScrollBarAddLine: {
1398 if ((opt->state & State_Sunken)) {
1399 p->setPen(opt->palette.dark().color());
1400 p->setBrush(opt->palette.brush(QPalette::Button));
1401 p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
1402 } else {
1403 QStyleOption buttonOpt = *opt;
1404 if (!(buttonOpt.state & State_Sunken))
1405 buttonOpt.state |= State_Raised;
1406 QPalette pal(opt->palette);
1407 pal.setColor(QPalette::Button, opt->palette.light().color());
1408 pal.setColor(QPalette::Light, opt->palette.button().color());
1409 qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On),
1410 &opt->palette.brush(QPalette::Button));
1411 }
1412 PrimitiveElement arrow;
1413 if (opt->state & State_Horizontal) {
1414 if (ce == CE_ScrollBarAddLine)
1415 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
1416 else
1417 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1418 } else {
1419 if (ce == CE_ScrollBarAddLine)
1420 arrow = PE_IndicatorArrowDown;
1421 else
1422 arrow = PE_IndicatorArrowUp;
1423 }
1424 QStyleOption arrowOpt = *opt;
1425 arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4);
1426 proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
1427 break; }
1428 case CE_ScrollBarAddPage:
1429 case CE_ScrollBarSubPage: {
1430 QBrush br;
1431 QBrush bg = p->background();
1432 Qt::BGMode bg_mode = p->backgroundMode();
1433 p->setPen(Qt::NoPen);
1434 p->setBackgroundMode(Qt::OpaqueMode);
1435
1436 if (opt->state & State_Sunken) {
1437 br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
1438 p->setBackground(opt->palette.dark().color());
1439 p->setBrush(br);
1440 } else {
1441 const QBrush paletteBrush = opt->palette.brush(QPalette::Light);
1442 if (paletteBrush.style() == Qt::TexturePattern) {
1443 if (qHasPixmapTexture(paletteBrush))
1444 br = QBrush(paletteBrush.texture());
1445 else
1446 br = QBrush(paletteBrush.textureImage());
1447 } else
1448 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1449 p->setBackground(opt->palette.window().color());
1450 p->setBrush(br);
1451 }
1452 p->drawRect(opt->rect);
1453 p->setBackground(bg);
1454 p->setBackgroundMode(bg_mode);
1455 break; }
1456 case CE_ScrollBarSlider:
1457 if (!(opt->state & State_Enabled)) {
1458 QBrush br;
1459 const QBrush paletteBrush = opt->palette.brush(QPalette::Light);
1460 if (paletteBrush.style() == Qt::TexturePattern) {
1461 if (qHasPixmapTexture(paletteBrush))
1462 br = QBrush(paletteBrush.texture());
1463 else
1464 br = QBrush(paletteBrush.textureImage());
1465 } else
1466 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1467 p->setPen(Qt::NoPen);
1468 p->setBrush(br);
1469 p->setBackgroundMode(Qt::OpaqueMode);
1470 p->drawRect(opt->rect);
1471 } else {
1472 QStyleOptionButton buttonOpt;
1473 buttonOpt.QStyleOption::operator=(*opt);
1474 buttonOpt.state = State_Enabled | State_Raised;
1475
1476 QPalette pal(opt->palette);
1477 pal.setColor(QPalette::Button, opt->palette.light().color());
1478 pal.setColor(QPalette::Light, opt->palette.button().color());
1479 qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button));
1480 }
1481 break;
1482#endif // QT_CONFIG(scrollbar)
1483 case CE_HeaderSection: {
1484 QBrush fill;
1485 if (opt->state & State_On)
1486 fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1487 else
1488 fill = opt->palette.brush(QPalette::Button);
1489
1490 if (opt->state & (State_Raised | State_Sunken)) {
1491 qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill);
1492 } else {
1493 p->fillRect(opt->rect, fill);
1494 }
1495 break; }
1496#if QT_CONFIG(toolbar)
1497 case CE_ToolBar:
1498 if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
1499 // Reserve the beveled appearance only for mainwindow toolbars
1500 if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
1501 break;
1502
1503 QRect rect = opt->rect;
1504 bool paintLeftBorder = true;
1505 bool paintRightBorder = true;
1506 bool paintBottomBorder = true;
1507
1508 switch (toolbar->toolBarArea){
1509 case Qt::BottomToolBarArea :
1510 switch(toolbar->positionOfLine){
1511 case QStyleOptionToolBar::Beginning:
1512 case QStyleOptionToolBar::OnlyOne:
1513 paintBottomBorder = false;
1514 break;
1515 default:
1516 break;
1517 }
1518 Q_FALLTHROUGH(); // It continues in the end of the next case
1519 case Qt::TopToolBarArea :
1520 switch(toolbar->positionWithinLine){
1521 case QStyleOptionToolBar::Beginning:
1522 paintLeftBorder = false;
1523 break;
1524 case QStyleOptionToolBar::End:
1525 paintRightBorder = false;
1526 break;
1527 case QStyleOptionToolBar::OnlyOne:
1528 paintRightBorder = false;
1529 paintLeftBorder = false;
1530 break;
1531 default:
1532 break;
1533 }
1534 if (opt->direction == Qt::RightToLeft) //reverse layout changes the order of Beginning/end
1535 std::swap(paintLeftBorder, paintRightBorder);
1536 break;
1537 case Qt::RightToolBarArea :
1538 switch (toolbar->positionOfLine){
1539 case QStyleOptionToolBar::Beginning:
1540 case QStyleOptionToolBar::OnlyOne:
1541 paintRightBorder = false;
1542 break;
1543 default:
1544 break;
1545 }
1546 break;
1547 case Qt::LeftToolBarArea :
1548 switch (toolbar->positionOfLine){
1549 case QStyleOptionToolBar::Beginning:
1550 case QStyleOptionToolBar::OnlyOne:
1551 paintLeftBorder = false;
1552 break;
1553 default:
1554 break;
1555 }
1556 break;
1557 default:
1558 break;
1559 }
1560
1561
1562 //draw top border
1563 p->setPen(opt->palette.light().color());
1564 p->drawLine(rect.topLeft(), rect.topRight());
1565
1566 if (paintLeftBorder){
1567 p->setPen(opt->palette.light().color());
1568 p->drawLine(rect.topLeft(), rect.bottomLeft());
1569 }
1570
1571 if (paintRightBorder){
1572 p->setPen(opt->palette.dark().color());
1573 p->drawLine(rect.topRight(), rect.bottomRight());
1574 }
1575
1576 if (paintBottomBorder){
1577 p->setPen(opt->palette.dark().color());
1578 p->drawLine(rect.bottomLeft(), rect.bottomRight());
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(90);
1599 m.translate(0, -(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(QPalette::Highlight, pb->palette.color(QPalette::Active,
1605 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(PM_ProgressBarChunkWidth, 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*>(d->animation(opt->styleObject)))
1623 step = (animation->animationStep() / 3) % chunkCount;
1624 else
1625 d->startAnimation(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(x0 + x, myY, unit_width, myHeight);
1643 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1644 proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, 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(x0 + x, myY, unit_width, myHeight);
1654 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1655 proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, 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(opt->styleObject);
1664#endif
1665 QCommonStyle::drawControl(ce, opt, p, 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(r.left(), r.top() + r.width());
1686 p->rotate(-90);
1687 p->translate(-r.left(), -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(0, left);
1712 lg.setColorAt(1, right);
1713 fillBrush = lg;
1714 }
1715 p->fillRect(r.adjusted(0, 0, 0, -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(QPalette::Window, inactiveCaptionTextColor);
1727 QRect titleRect = subElementRect(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(p, titleRect,
1735 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextHideMnemonic, palette,
1736 dwOpt->state & State_Enabled, dwOpt->title,
1737 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(ce, opt, p, widget);
1757 break;
1758#endif // QT_CONFIG(combobox)
1759 default:
1760 QCommonStyle::drawControl(ce, opt, p, 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(opt->direction, opt->rect, opt->rect);
1772 break;
1773 case SE_DockWidgetTitleBarText: {
1774 r = QCommonStyle::subElementRect(sr, opt, w);
1775 const QStyleOptionDockWidget *dwOpt
1776 = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
1777 const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
1778 int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt, w);
1779 if (verticalTitleBar) {
1780 r.adjust(0, 0, 0, -m);
1781 } else {
1782 if (opt->direction == Qt::LeftToRight)
1783 r.adjust(m, 0, 0, 0);
1784 else
1785 r.adjust(0, 0, -m, 0);
1786 }
1787 break;
1788 }
1789 case SE_ProgressBarContents:
1790 r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt, w);
1791 r.adjust(3, 3, -3, -3);
1792 break;
1793 default:
1794 r = QCommonStyle::subElementRect(sr, opt, 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(PM_SliderControlThickness, slider, widget);
1809 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
1810 int ticks = slider->tickPosition;
1811 QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
1812 QRect handle = proxy()->subControlRect(CC_Slider, slider, 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, groove.x(), groove.y() + mid - 2,
1825 groove.width(), 4, slider->palette, true);
1826 p->drawLine(groove.x() + 1, groove.y() + mid - 1,
1827 groove.x() + groove.width() - 3, groove.y() + mid - 1);
1828 } else {
1829 qDrawWinPanel(p, groove.x() + mid - 2, groove.y(),
1830 4, groove.height(), slider->palette, true);
1831 p->drawLine(groove.x() + mid - 1, groove.y() + 1,
1832 groove.x() + mid - 1, 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, &tmpSlider, p, 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(QPalette::Button);
1861 } else {
1862 handleBrush = QBrush(slider->palette.color(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=(*slider);
1882 fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
1883 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1884 }
1885
1886 if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
1887 Qt::BGMode oldMode = p->backgroundMode();
1888 p->setBackgroundMode(Qt::OpaqueMode);
1889 qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false,
1890 &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(x1, y1, x2-x1+1, y2-y1+1);
1937 p->drawPolygon(points.data(), 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, y1);
1944 p->setPen(c3);
1945 p->drawLine(x1, y1+1, x2, y1+1);
1946 }
1947 if (dir != SlLeft) {
1948 p->setPen(c3);
1949 p->drawLine(x1+1, y1+1, x1+1, y2);
1950 p->setPen(c4);
1951 p->drawLine(x1, y1, x1, y2);
1952 }
1953 if (dir != SlRight) {
1954 p->setPen(c0);
1955 p->drawLine(x2, y1, x2, y2);
1956 p->setPen(c1);
1957 p->drawLine(x2-1, y1+1, x2-1, y2-1);
1958 }
1959 if (dir != SlDown) {
1960 p->setPen(c0);
1961 p->drawLine(x1, y2, x2, y2);
1962 p->setPen(c1);
1963 p->drawLine(x1+1, y2-1, x2-1, y2-1);
1964 }
1965
1966 switch (dir) {
1967 case SlUp:
1968 p->setPen(c4);
1969 p->drawLine(x1, y1, x1+d, y1-d);
1970 p->setPen(c0);
1971 d = wi - d - 1;
1972 p->drawLine(x2, y1, x2-d, y1-d);
1973 d--;
1974 p->setPen(c3);
1975 p->drawLine(x1+1, y1, x1+1+d, y1-d);
1976 p->setPen(c1);
1977 p->drawLine(x2-1, y1, x2-1-d, y1-d);
1978 break;
1979 case SlDown:
1980 p->setPen(c4);
1981 p->drawLine(x1, y2, x1+d, y2+d);
1982 p->setPen(c0);
1983 d = wi - d - 1;
1984 p->drawLine(x2, y2, x2-d, y2+d);
1985 d--;
1986 p->setPen(c3);
1987 p->drawLine(x1+1, y2, x1+1+d, y2+d);
1988 p->setPen(c1);
1989 p->drawLine(x2-1, y2, x2-1-d, y2+d);
1990 break;
1991 case SlLeft:
1992 p->setPen(c4);
1993 p->drawLine(x1, y1, x1-d, y1+d);
1994 p->setPen(c0);
1995 d = he - d - 1;
1996 p->drawLine(x1, y2, x1-d, y2-d);
1997 d--;
1998 p->setPen(c3);
1999 p->drawLine(x1, y1+1, x1-d, y1+1+d);
2000 p->setPen(c1);
2001 p->drawLine(x1, y2-1, x1-d, y2-1-d);
2002 break;
2003 case SlRight:
2004 p->setPen(c4);
2005 p->drawLine(x2, y1, x2+d, y1+d);
2006 p->setPen(c0);
2007 d = he - d - 1;
2008 p->drawLine(x2, y2, x2+d, y2-d);
2009 d--;
2010 p->setPen(c3);
2011 p->drawLine(x2, y1+1, x2+d, y1+1+d);
2012 p->setPen(c1);
2013 p->drawLine(x2, y2-1, x2+d, 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, &newScrollbar, p, 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(QPalette::Button);
2034 if ((cmb->subControls & SC_ComboBoxFrame)) {
2035 if (cmb->frame) {
2036 QPalette shadePal = opt->palette;
2037 shadePal.setColor(QPalette::Midlight, shadePal.button().color());
2038 qDrawWinPanel(p, opt->rect, shadePal, true, &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_ComboBox, cmb, 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(QPalette::Button));
2053 p->drawRect(ar.adjusted(0,0,-1,-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(QPalette::Button, cmb->palette.light().color());
2058 pal.setColor(QPalette::Light, cmb->palette.button().color());
2059 qDrawWinButton(p, ar, pal, false,
2060 &cmb->palette.brush(QPalette::Button));
2061 }
2062
2063 ar.adjust(2, 2, -2, -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(1, 1, -1, -1);
2073 arrowOpt.state = flags;
2074 proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
2075 }
2076
2077 if (cmb->subControls & SC_ComboBoxEditField) {
2078 QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
2079 if (cmb->state & State_HasFocus && !cmb->editable)
2080 p->fillRect(re.x(), re.y(), re.width(), re.height(),
2081 cmb->palette.brush(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=(*cmb);
2095 focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
2096 focus.state |= State_FocusAtBorder;
2097 focus.backgroundColor = cmb->palette.highlight().color();
2098 proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, 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(QPalette::Base);
2112 QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
2113 QPalette shadePal = sb->palette;
2114 shadePal.setColor(QPalette::Midlight, shadePal.button().color());
2115 qDrawWinPanel(p, r, shadePal, true, &editBrush);
2116 }
2117
2118 QPalette shadePal(opt->palette);
2119 shadePal.setColor(QPalette::Button, opt->palette.light().color());
2120 shadePal.setColor(QPalette::Light, 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_SpinBox, sb, SC_SpinBoxUp, widget);
2143 qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
2144 &copy.palette.brush(QPalette::Button));
2145 copy.rect.adjust(4, 1, -5, -1);
2146 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
2147 && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
2148 {
2149 QStyleOptionSpinBox lightCopy = copy;
2150 lightCopy.rect.adjust(1, 1, 1, 1);
2151 lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
2152 proxy()->drawPrimitive(pe, &lightCopy, p, widget);
2153 }
2154 proxy()->drawPrimitive(pe, &copy, p, 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_SpinBox, sb, SC_SpinBoxDown, widget);
2178 qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
2179 &copy.palette.brush(QPalette::Button));
2180 copy.rect.adjust(4, 0, -5, -1);
2181 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
2182 && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
2183 {
2184 QStyleOptionSpinBox lightCopy = copy;
2185 lightCopy.rect.adjust(1, 1, 1, 1);
2186 lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
2187 proxy()->drawPrimitive(pe, &lightCopy, p, widget);
2188 }
2189 proxy()->drawPrimitive(pe, &copy, p, widget);
2190 }
2191 }
2192 break;
2193#endif // QT_CONFIG(spinbox)
2194
2195 default:
2196 QCommonStyle::drawComplexControl(cc, opt, p, 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, 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(PM_ButtonDefaultIndicator, btn, widget);
2214 const qreal dpi = QStyleHelper::dpi(opt);
2215 int minwidth = int(QStyleHelper::dpiScaled(75, dpi));
2216 int minheight = int(QStyleHelper::dpiScaled(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, 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(PM_SmallIconSize, opt, widget);
2242 sz.setHeight(qMax(sz.height(),
2243 mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
2244 + 2 * QWindowsStylePrivate::windowsItemFrame));
2245 }
2246 int maxpmw = mi->maxIconWidth;
2247 int tabSpacing = 20;
2248 if (mi->text.contains(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>(maxpmw, 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 QT_CONFIG(toolbutton)
2277 if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
2278 return sz += QSize(7, 6);
2279#endif // QT_CONFIG(toolbutton)
2280 Q_FALLTHROUGH();
2281
2282 default:
2283 sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
2284 }
2285 return sz;
2286}
2287
2288/*!
2289 \reimp
2290*/
2291QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
2292 const QWidget *widget) const
2293{
2294 return QCommonStyle::standardIcon(standardIcon, option, widget);
2295}
2296
2297
2298
2299QT_END_NAMESPACE
2300
2301#include "moc_qwindowsstyle_p.cpp"
2302
2303#endif // style_windows