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