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

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