Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindows11style.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwindows11style_p.h"
5#include <qstylehints.h>
6#include <private/qstyleanimation_p.h>
7#include <private/qstylehelper_p.h>
8#include <private/qapplication_p.h>
9#include <qstyleoption.h>
10#include <qpainter.h>
11#include <QGraphicsDropShadowEffect>
12#include <QtWidgets/qcombobox.h>
13#include <QtWidgets/qcommandlinkbutton.h>
14#include <QtWidgets/qgraphicsview.h>
15#include <QtWidgets/qlistview.h>
16#include <QtWidgets/qmenu.h>
17#include <QtWidgets/qmdiarea.h>
18#include <QtWidgets/qtextedit.h>
19#include <QtWidgets/qtreeview.h>
20
21#include "qdrawutil.h"
22#include <chrono>
23
25
26const static int topLevelRoundingRadius = 8; //Radius for toplevel items like popups for round corners
27const static int secondLevelRoundingRadius = 4; //Radius for second level items like hovered menu item round corners
28
30 subtleHighlightColor, //Subtle highlight based on alpha used for hovered elements
31 subtlePressedColor, //Subtle highlight based on alpha used for pressed elements
32 frameColorLight, //Color of frame around flyouts and controls except for Checkbox and Radiobutton
33 frameColorStrong, //Color of frame around Checkbox and Radiobuttons
34 controlStrongFill, //Color of controls with strong filling such as the right side of a slider
37 controlFillTertiary, //Color of filled sunken controls
38 controlFillSecondary, //Color of filled hovered controls
39 menuPanelFill, //Color of menu panel
40 textOnAccentPrimary, //Color of text on controls filled in accent color
41 textOnAccentSecondary, //Color of text of sunken controls in accent color
42 controlTextSecondary, //Color of text of sunken controls
43 controlStrokeOnAccentSecondary, //Color of frame around Buttons in accent color
44 controlFillSolid, //Color for solid fill
45 surfaceStroke, //Color of MDI window frames
46};
47
48const static QColor WINUI3ColorsLight [] {
49 QColor(0x00,0x00,0x00,0x09), //subtleHighlightColor
50 QColor(0x00,0x00,0x00,0x06), //subtlePressedColor
51 QColor(0x00,0x00,0x00,0x0F), //frameColorLight
52 QColor(0x00,0x00,0x00,0x9c), //frameColorStrong
53 QColor(0x00,0x00,0x00,0x72), //controlStrongFill
54 QColor(0x00,0x00,0x00,0x29), //controlStrokeSecondary
55 QColor(0x00,0x00,0x00,0x14), //controlStrokePrimary
56 QColor(0xF9,0xF9,0xF9,0x00), //controlFillTertiary
57 QColor(0xF9,0xF9,0xF9,0x80), //controlFillSecondary
58 QColor(0xFF,0xFF,0xFF,0xFF), //menuPanelFill
59 QColor(0xFF,0xFF,0xFF,0xFF), //textOnAccentPrimary
60 QColor(0xFF,0xFF,0xFF,0x7F), //textOnAccentSecondary
61 QColor(0x00,0x00,0x00,0x7F), //controlTextSecondary
62 QColor(0x00,0x00,0x00,0x66), //controlStrokeOnAccentSecondary
63 QColor(0xFF,0xFF,0xFF,0xFF), //controlFillSolid
64 QColor(0x75,0x75,0x75,0x66), //surfaceStroke
65};
66
67const static QColor WINUI3ColorsDark[] {
68 QColor(0xFF,0xFF,0xFF,0x0F), //subtleHighlightColor
69 QColor(0xFF,0xFF,0xFF,0x0A), //subtlePressedColor
70 QColor(0xFF,0xFF,0xFF,0x12), //frameColorLight
71 QColor(0xFF,0xFF,0xFF,0x8B), //frameColorStrong
72 QColor(0xFF,0xFF,0xFF,0x8B), //controlStrongFill
73 QColor(0xFF,0xFF,0xFF,0x18), //controlStrokeSecondary
74 QColor(0xFF,0xFF,0xFF,0x12), //controlStrokePrimary
75 QColor(0xF9,0xF9,0xF9,0x00), //controlFillTertiary
76 QColor(0xF9,0xF9,0xF9,0x80), //controlFillSecondary
77 QColor(0x0F,0x0F,0x0F,0xFF), //menuPanelFill
78 QColor(0x00,0x00,0x00,0xFF), //textOnAccentPrimary
79 QColor(0x00,0x00,0x00,0x80), //textOnAccentSecondary
80 QColor(0xFF,0xFF,0xFF,0x87), //controlTextSecondary
81 QColor(0xFF,0xFF,0xFF,0x14), //controlStrokeOnAccentSecondary
82 QColor(0x45,0x45,0x45,0xFF), //controlFillSolid
83 QColor(0x75,0x75,0x75,0x66), //surfaceStroke
84};
85
90
91const QColor shellCloseButtonColor(0xC4,0x2B,0x1C,0xFF); //Color of close Button in Titlebar
92
93#if QT_CONFIG(toolbutton)
94static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
95 const QRect &rect, QPainter *painter, const QWidget *widget = nullptr)
96{
98 switch (toolbutton->arrowType) {
99 case Qt::LeftArrow:
101 break;
102 case Qt::RightArrow:
104 break;
105 case Qt::UpArrow:
107 break;
108 case Qt::DownArrow:
110 break;
111 default:
112 return;
113 }
114 QStyleOption arrowOpt = *toolbutton;
115 arrowOpt.rect = rect;
116 style->drawPrimitive(pe, &arrowOpt, painter, widget);
117}
118#endif // QT_CONFIG(toolbutton)
135QWindows11Style::QWindows11Style() : QWindowsVistaStyle(*new QWindows11StylePrivate)
136{
137}
138
146
151
158 QPainter *painter, const QWidget *widget) const
159{
160 QWindows11StylePrivate *d = const_cast<QWindows11StylePrivate*>(d_func());
161
162 State state = option->state;
163 SubControls sub = option->subControls;
164 State flags = option->state;
166 flags |= State_MouseOver;
167
168 painter->save();
170 if (d->transitionsEnabled()) {
171 if (control == CC_Slider) {
172 if (const auto *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
173 QObject *styleObject = option->styleObject; // Can be widget or qquickitem
174
175 QRectF thumbRect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
176 auto center = thumbRect.center();
177 const qreal outerRadius = qMin(8.0, (slider->orientation == Qt::Horizontal ? thumbRect.height() / 2.0 : thumbRect.width() / 2.0) - 1);
178
179 thumbRect.setWidth(outerRadius);
180 thumbRect.setHeight(outerRadius);
181 thumbRect.moveCenter(center);
183 bool isInsideHandle = thumbRect.contains(cursorPos);
184
185 bool oldIsInsideHandle = styleObject->property("_q_insidehandle").toBool();
186 int oldState = styleObject->property("_q_stylestate").toInt();
187 int oldActiveControls = styleObject->property("_q_stylecontrols").toInt();
188
189 QRectF oldRect = styleObject->property("_q_stylerect").toRect();
190 styleObject->setProperty("_q_insidehandle", isInsideHandle);
191 styleObject->setProperty("_q_stylestate", int(option->state));
192 styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls));
193 styleObject->setProperty("_q_stylerect", option->rect);
194 if (option->styleObject->property("_q_end_radius").isNull())
195 option->styleObject->setProperty("_q_end_radius", outerRadius * 0.43);
196
197 bool doTransition = (((state & State_Sunken) != (oldState & State_Sunken)
198 || ((oldIsInsideHandle) != (isInsideHandle))
199 || oldActiveControls != int(option->activeSubControls))
200 && state & State_Enabled);
201
202 if (oldRect != option->rect) {
203 doTransition = false;
204 d->stopAnimation(styleObject);
205 styleObject->setProperty("_q_inner_radius", outerRadius * 0.43);
206 }
207
208 if (doTransition) {
210 t->setStartValue(styleObject->property("_q_inner_radius").toFloat());
211 if (state & State_Sunken)
212 t->setEndValue(outerRadius * 0.29);
213 else if (isInsideHandle)
214 t->setEndValue(outerRadius * 0.71);
215 else
216 t->setEndValue(outerRadius * 0.43);
217
218 styleObject->setProperty("_q_end_radius", t->endValue());
219
220 t->setStartTime(d->animationTime());
221 t->setDuration(150);
222 d->startAnimation(t);
223 }
224 }
225 }
226 }
227
228 switch (control) {
229#if QT_CONFIG(spinbox)
230 case CC_SpinBox:
231 if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
232 if (sb->frame && (sub & SC_SpinBoxFrame)) {
233 painter->save();
234 QRegion clipRegion = option->rect;
235 clipRegion -= option->rect.adjusted(2, 2, -2, -2);
236 painter->setClipRegion(clipRegion);
237 QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0);
238 painter->setPen(QPen(lineColor));
239 painter->drawLine(option->rect.bottomLeft() + QPointF(7,-0.5), option->rect.bottomRight() + QPointF(-7,-0.5));
240 painter->restore();
241 }
242 QRectF frameRect = option->rect;
243 frameRect.adjust(0.5,0.5,-0.5,-0.5);
244 QBrush fillColor = option->palette.brush(QPalette::Base);
245 painter->setBrush(fillColor);
246 painter->setPen(QPen(highContrastTheme == true ? sb->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]));
249 QColor hoverColor = WINUI3Colors[colorSchemeIndex][subtleHighlightColor];
250 if (sub & SC_SpinBoxEditField) {
251 QRect rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget).adjusted(0, 0, 0, 1);
252 if (rect.contains(mousePos) && !(state & State_HasFocus)) {
253 QBrush fillColor = QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
254 painter->setBrush(fillColor);
257 }
258 }
259 if (sub & SC_SpinBoxUp) {
260 QRect rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
261 float scale = rect.width() >= 16 ? 1.0 : rect.width()/16.0;
262 if (rect.contains(mousePos)) {
264 painter->setBrush(QBrush(hoverColor));
266 }
267 painter->save();
268 painter->translate(rect.center());
270 painter->translate(-rect.center());
271 painter->setFont(assetFont);
272 painter->setPen(sb->palette.buttonText().color());
275 painter->restore();
276 }
277 if (sub & SC_SpinBoxDown) {
278 QRect rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
279 float scale = rect.width() >= 16 ? 1.0 : rect.width()/16.0;
280 if (rect.contains(mousePos)) {
282 painter->setBrush(QBrush(hoverColor));
284 }
285 painter->save();
286 painter->translate(rect.center());
288 painter->translate(-rect.center());
289 painter->setFont(assetFont);
290 painter->setPen(sb->palette.buttonText().color());
293 painter->restore();
294 }
295 }
296 break;
297#endif // QT_CONFIG(spinbox)
298#if QT_CONFIG(slider)
299 case CC_Slider:
300 if (const auto *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
301 QRectF slrect = slider->rect;
302 QRegion tickreg = slrect.toRect();
303
304 if (sub & SC_SliderGroove) {
305 QRectF rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
306 QRectF handleRect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
307 QPointF handlePos = handleRect.center();
308 QRectF leftRect;
309 QRectF rightRect;
310
311 if (slider->orientation == Qt::Horizontal) {
312 rect = QRect(slrect.left(), rect.center().y() - 2, slrect.width() - 5, 4);
313 leftRect = QRect(rect.left(), rect.top(), (handlePos.x() - rect.left()), rect.height());
314 rightRect = QRect(handlePos.x(), rect.top(), (rect.width() - handlePos.x()), rect.height());
315 } else {
316 rect = QRect(rect.center().x() - 2, slrect.top(), 4, slrect.height() - 5);
317 rightRect = QRect(rect.left(), rect.top(), rect.width(), (handlePos.y() - rect.top()));
318 leftRect = QRect(rect.left(), handlePos.y(), rect.width(), (rect.height() - handlePos.y()));
319 }
320
322 painter->setBrush(option->palette.accent());
323 painter->drawRoundedRect(leftRect,1,1);
325 painter->drawRoundedRect(rightRect,1,1);
326
327 painter->setPen(QPen(highContrastTheme == true ? slider->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]));
329 painter->drawRoundedRect(leftRect,1.5,1.5);
330 painter->drawRoundedRect(rightRect,1.5,1.5);
331
332 tickreg -= rect.toRect();
333 }
334 if (sub & SC_SliderTickmarks) {
335 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
336 int ticks = slider->tickPosition;
337 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
338 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
339 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
340 int interval = slider->tickInterval;
341 if (interval <= 0) {
342 interval = slider->singleStep;
343 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
344 available)
345 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
346 0, available) < 3)
347 interval = slider->pageStep;
348 }
349 if (!interval)
350 interval = 1;
351 int fudge = len / 2;
352 int pos;
353 int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
354 painter->setPen(slider->palette.text().color());
355 QVarLengthArray<QLine, 32> lines;
356 int v = slider->minimum;
357 while (v <= slider->maximum + 1) {
358 if (v == slider->maximum + 1 && interval == 1)
359 break;
360 const int v_ = qMin(v, slider->maximum);
361 int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
362 pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
363 v_, available) + fudge;
364 if (slider->orientation == Qt::Horizontal) {
365 if (ticks & QSlider::TicksAbove) {
366 lines.append(QLine(pos, tickOffset - 1 - bothOffset,
367 pos, tickOffset - 1 - bothOffset - tickLength));
368 }
369
370 if (ticks & QSlider::TicksBelow) {
371 lines.append(QLine(pos, tickOffset + thickness + bothOffset,
372 pos, tickOffset + thickness + bothOffset + tickLength));
373 }
374 } else {
375 if (ticks & QSlider::TicksAbove) {
376 lines.append(QLine(tickOffset - 1 - bothOffset, pos,
377 tickOffset - 1 - bothOffset - tickLength, pos));
378 }
379
380 if (ticks & QSlider::TicksBelow) {
381 lines.append(QLine(tickOffset + thickness + bothOffset, pos,
382 tickOffset + thickness + bothOffset + tickLength, pos));
383 }
384 }
385 // in the case where maximum is max int
386 int nextInterval = v + interval;
387 if (nextInterval < v)
388 break;
389 v = nextInterval;
390 }
391 if (!lines.isEmpty()) {
392 painter->save();
393 painter->translate(slrect.topLeft());
394 painter->drawLines(lines.constData(), lines.size());
395 painter->restore();
396 }
397 }
398 if (sub & SC_SliderHandle) {
399 if (const auto *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
400 const QRectF rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
401 const QPointF center = rect.center();
402
403 const QNumberStyleAnimation* animation = qobject_cast<QNumberStyleAnimation*>(d->animation(option->styleObject));
404
405 if (animation != nullptr)
406 option->styleObject->setProperty("_q_inner_radius", animation->currentValue());
407 else
408 option->styleObject->setProperty("_q_inner_radius", option->styleObject->property("_q_end_radius"));
409
410 const qreal outerRadius = qMin(8.0,(slider->orientation == Qt::Horizontal ? rect.height() / 2.0 : rect.width() / 2.0) - 1);
411 const float innerRadius = option->styleObject->property("_q_inner_radius").toFloat();
415 painter->drawEllipse(center, outerRadius, outerRadius);
416 painter->setBrush(option->palette.accent());
417 painter->drawEllipse(center, innerRadius, innerRadius);
418
421 painter->drawEllipse(center, outerRadius + 0.5, outerRadius + 0.5);
422 painter->drawEllipse(center, innerRadius + 0.5, innerRadius + 0.5);
423 }
424 }
425 if (slider->state & State_HasFocus) {
427 fropt.QStyleOption::operator=(*slider);
428 fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
429 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
430 }
431 }
432 break;
433#endif
434#if QT_CONFIG(combobox)
435 case CC_ComboBox:
436 if (const QStyleOptionComboBox *combobox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
437 QBrush fillColor = combobox->palette.brush(QPalette::Base);
438 QRectF rect = option->rect.adjusted(2,2,-2,-2);
439 painter->setBrush(fillColor);
442
443 // In case the QComboBox is hovered overdraw the background with a alpha mask to
444 // highlight the QComboBox.
445 if (state & State_MouseOver) {
446 fillColor = QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
447 painter->setBrush(fillColor);
450 }
451
452 rect.adjust(0.5,0.5,-0.5,-0.5);
454 painter->setPen(highContrastTheme == true ? combobox->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
456 if (sub & SC_ComboBoxArrow) {
457 QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(-4, 0, -4, 1);
458 painter->setFont(assetFont);
459 painter->setPen(combobox->palette.text().color());
461 }
462 if (combobox->editable) {
463 QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0);
464 painter->setPen(QPen(lineColor));
465 painter->drawLine(rect.bottomLeft() + QPoint(2,1), rect.bottomRight() + QPoint(-2,1));
466 if (state & State_HasFocus)
467 painter->drawLine(rect.bottomLeft() + QPoint(3,2), rect.bottomRight() + QPoint(-3,2));
468 }
469 }
470 break;
471#endif // QT_CONFIG(combobox)
473 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
474 QRectF rect = scrollbar->rect;
475 QPointF center = rect.center();
476
477 if (scrollbar->orientation == Qt::Vertical && rect.width()>24)
478 rect.marginsRemoved(QMargins(0,2,2,2));
479 else if (scrollbar->orientation == Qt::Horizontal && rect.height()>24)
480 rect.marginsRemoved(QMargins(2,0,2,2));
481
482 if (state & State_MouseOver) {
483 if (scrollbar->orientation == Qt::Vertical && rect.width()>24)
484 rect.setWidth(rect.width()/2);
485 else if (scrollbar->orientation == Qt::Horizontal && rect.height()>24)
486 rect.setHeight(rect.height()/2);
487 rect.moveCenter(center);
488 painter->setBrush(scrollbar->palette.base());
491
493 painter->setPen(WINUI3Colors[colorSchemeIndex][frameColorLight]);
494 painter->drawRoundedRect(rect.marginsRemoved(QMarginsF(0.5,0.5,0.5,0.5)), topLevelRoundingRadius + 0.5, topLevelRoundingRadius + 0.5);
495 }
496 if (sub & SC_ScrollBarSlider) {
497 QRectF rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
498 QPointF center = rect.center();
499 if (flags & State_MouseOver) {
500 if (scrollbar->orientation == Qt::Vertical)
501 rect.setWidth(rect.width()/2);
502 else
503 rect.setHeight(rect.height()/2);
504 }
505 else {
506 if (scrollbar->orientation == Qt::Vertical)
507 rect.setWidth(1);
508 else
509 rect.setHeight(1);
510
511 }
512 rect.moveCenter(center);
516 }
517 if (sub & SC_ScrollBarAddLine) {
518 QRectF rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
519 if (flags & State_MouseOver) {
520 painter->setFont(QFont("Segoe Fluent Icons",6));
522 if (scrollbar->orientation == Qt::Vertical)
524 else
526 }
527 }
528 if (sub & SC_ScrollBarSubLine) {
529 QRectF rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
530 if (flags & State_MouseOver) {
532 if (scrollbar->orientation == Qt::Vertical)
534 else
536 }
537 }
538 }
539 break;
540 case CC_TitleBar:
541 if (const auto* titlebar = qstyleoption_cast<const QStyleOptionTitleBar*>(option)) {
543 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][surfaceStroke]));
544 painter->setBrush(titlebar->palette.button());
545 painter->drawRect(titlebar->rect);
546
547 // draw title
548 QRect textRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarLabel, widget);
549 painter->setPen(titlebar->palette.text().color());
550 // Note workspace also does elliding but it does not use the correct font
553
554 QFont buttonFont = QFont(assetFont);
555 buttonFont.setPointSize(8);
556 // min button
557 if ((titlebar->subControls & SC_TitleBarMinButton) && (titlebar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
558 !(titlebar->titleBarState& Qt::WindowMinimized)) {
559 const QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMinButton, widget);
560 if (minButtonRect.isValid()) {
561 bool hover = (titlebar->activeSubControls & SC_TitleBarMinButton) && (titlebar->state & State_MouseOver);
562 if (hover)
563 painter->fillRect(minButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
564 const QString textToDraw("\uE921");
565 painter->setPen(QPen(titlebar->palette.text().color()));
566 painter->setFont(buttonFont);
567 painter->drawText(minButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
568 }
569 }
570 // max button
571 if ((titlebar->subControls & SC_TitleBarMaxButton) && (titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
572 !(titlebar->titleBarState & Qt::WindowMaximized)) {
573 const QRectF maxButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMaxButton, widget);
574 if (maxButtonRect.isValid()) {
575 bool hover = (titlebar->activeSubControls & SC_TitleBarMaxButton) && (titlebar->state & State_MouseOver);
576 if (hover)
577 painter->fillRect(maxButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
578 const QString textToDraw("\uE922");
579 painter->setPen(QPen(titlebar->palette.text().color()));
580 painter->setFont(buttonFont);
581 painter->drawText(maxButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
582 }
583 }
584
585 // close button
586 if ((titlebar->subControls & SC_TitleBarCloseButton) && (titlebar->titleBarFlags & Qt::WindowSystemMenuHint)) {
587 const QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarCloseButton, widget);
588 if (closeButtonRect.isValid()) {
589 bool hover = (titlebar->activeSubControls & SC_TitleBarCloseButton) && (titlebar->state & State_MouseOver);
590 if (hover)
591 painter->fillRect(closeButtonRect,shellCloseButtonColor);
592 const QString textToDraw("\uE8BB");
593 painter->setPen(QPen(hover ? titlebar->palette.highlightedText().color() : titlebar->palette.text().color()));
594 painter->setFont(buttonFont);
595 painter->drawText(closeButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
596 }
597 }
598
599 // normalize button
600 if ((titlebar->subControls & SC_TitleBarNormalButton) &&
601 (((titlebar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
602 (titlebar->titleBarState & Qt::WindowMinimized)) ||
603 ((titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
604 (titlebar->titleBarState & Qt::WindowMaximized)))) {
605 const QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarNormalButton, widget);
606 if (normalButtonRect.isValid()) {
607 bool hover = (titlebar->activeSubControls & SC_TitleBarNormalButton) && (titlebar->state & State_MouseOver);
608 if (hover)
609 painter->fillRect(normalButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
610 const QString textToDraw("\uE923");
611 painter->setPen(QPen(titlebar->palette.text().color()));
612 painter->setFont(buttonFont);
613 painter->drawText(normalButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
614 }
615 }
616
617 // context help button
618 if (titlebar->subControls & SC_TitleBarContextHelpButton
619 && (titlebar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
620 const QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarContextHelpButton, widget);
621 if (contextHelpButtonRect.isValid()) {
622 bool hover = (titlebar->activeSubControls & SC_TitleBarCloseButton) && (titlebar->state & State_MouseOver);
623 if (hover)
624 painter->fillRect(contextHelpButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
625 const QString textToDraw("\uE897");
626 painter->setPen(QPen(titlebar->palette.text().color()));
627 painter->setFont(buttonFont);
628 painter->drawText(contextHelpButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
629 }
630 }
631
632 // shade button
633 if (titlebar->subControls & SC_TitleBarShadeButton && (titlebar->titleBarFlags & Qt::WindowShadeButtonHint)) {
634 const QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarShadeButton, widget);
635 if (shadeButtonRect.isValid()) {
636 bool hover = (titlebar->activeSubControls & SC_TitleBarShadeButton) && (titlebar->state & State_MouseOver);
637 if (hover)
638 painter->fillRect(shadeButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
639 const QString textToDraw("\uE010");
640 painter->setPen(QPen(titlebar->palette.text().color()));
641 painter->setFont(buttonFont);
642 painter->drawText(shadeButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
643 }
644 }
645
646 // unshade button
647 if (titlebar->subControls & SC_TitleBarUnshadeButton && (titlebar->titleBarFlags & Qt::WindowShadeButtonHint)) {
648 const QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarUnshadeButton, widget);
649 if (unshadeButtonRect.isValid()) {
650 bool hover = (titlebar->activeSubControls & SC_TitleBarUnshadeButton) && (titlebar->state & State_MouseOver);
651 if (hover)
652 painter->fillRect(unshadeButtonRect,WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
653 const QString textToDraw("\uE011");
654 painter->setPen(QPen(titlebar->palette.text().color()));
655 painter->setFont(buttonFont);
656 painter->drawText(unshadeButtonRect, Qt::AlignVCenter | Qt::AlignHCenter, textToDraw);
657 }
658 }
659
660 // window icon for system menu
661 if ((titlebar->subControls & SC_TitleBarSysMenu) && (titlebar->titleBarFlags & Qt::WindowSystemMenuHint)) {
662 const QRect iconRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarSysMenu, widget);
663 if (iconRect.isValid()) {
664 if (!titlebar->icon.isNull()) {
665 titlebar->icon.paint(painter, iconRect);
666 } else {
667 QStyleOption tool = *titlebar;
668 QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
669 tool.rect = iconRect;
670 painter->save();
671 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
672 painter->restore();
673 }
674 }
675 }
676 }
677 break;
678 default:
680 }
681 painter->restore();
682}
683
684void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
686 const QWidget *widget) const {
687 QWindows11StylePrivate *d = const_cast<QWindows11StylePrivate*>(d_func());
688
689 int state = option->state;
690 painter->save();
692 if (d->transitionsEnabled() && (element == PE_IndicatorCheckBox || element == PE_IndicatorRadioButton)) {
693 QObject *styleObject = option->styleObject; // Can be widget or qquickitem
694 if (styleObject) {
695 int oldState = styleObject->property("_q_stylestate").toInt();
696 styleObject->setProperty("_q_stylestate", int(option->state));
697 styleObject->setProperty("_q_stylerect", option->rect);
698 bool doTransition = (((state & State_Sunken) != (oldState & State_Sunken)
699 || ((state & State_MouseOver) != (oldState & State_MouseOver))
700 || (state & State_On) != (oldState & State_On))
701 && state & State_Enabled);
702 if (doTransition) {
703 if (element == PE_IndicatorRadioButton) {
705 t->setStartValue(styleObject->property("_q_inner_radius").toFloat());
706 t->setEndValue(7.0f);
707 if (option->state & State_Sunken)
708 t->setEndValue(2.0f);
709 else if (option->state & State_MouseOver && !(option->state & State_On))
710 t->setEndValue(7.0f);
711 else if (option->state & State_MouseOver && (option->state & State_On))
712 t->setEndValue(5.0f);
713 else if (option->state & State_On)
714 t->setEndValue(4.0f);
715 styleObject->setProperty("_q_end_radius", t->endValue());
716 t->setStartTime(d->animationTime());
717 t->setDuration(150);
718 d->startAnimation(t);
719 }
720 else if (element == PE_IndicatorCheckBox) {
721 if ((oldState & State_Off && state & State_On) || (oldState & State_NoChange && state & State_On)) {
723 t->setStartValue(0.0f);
724 t->setEndValue(1.0f);
725 t->setStartTime(d->animationTime());
726 t->setDuration(150);
727 d->startAnimation(t);
728 }
729 }
730 }
731 }
732 } else if (!d->transitionsEnabled() && element == PE_IndicatorRadioButton) {
733 QObject *styleObject = option->styleObject; // Can be widget or qquickitem
734 if (styleObject) {
735 styleObject->setProperty("_q_end_radius",7.0);
736 if (option->state & State_Sunken)
737 styleObject->setProperty("_q_end_radius",2.0);
738 else if (option->state & State_MouseOver && !(option->state & State_On))
739 styleObject->setProperty("_q_end_radius",7.0);
740 else if (option->state & State_MouseOver && (option->state & State_On))
741 styleObject->setProperty("_q_end_radius",5.0);
742 else if (option->state & State_On)
743 styleObject->setProperty("_q_end_radius",4.0);
744 }
745 }
746
747 switch (element) {
748 case PE_PanelTipLabel: {
749 QRectF tipRect = option->rect.marginsRemoved(QMargins(1,1,1,1));
751 painter->setBrush(option->palette.toolTipBase());
753
754 painter->setPen(highContrastTheme == true ? option->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
757 break;
758 }
759 case PE_FrameTabWidget:
760 if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
761 QRectF frameRect = frame->rect.marginsRemoved(QMargins(0,0,0,0));
765
766 painter->setPen(highContrastTheme == true ? frame->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
769 }
770 break;
771 case PE_FrameGroupBox:
772 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
773 QRectF frameRect = frame->rect;
774 frameRect.adjust(0.5,0.5,-0.5,-0.5);
775 painter->setPen(highContrastTheme == true ? frame->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorStrong]);
777 if (frame->features & QStyleOptionFrame::Flat) {
778 QRect fr = frame->rect;
779 QPoint p1(fr.x(), fr.y() + 1);
780 QPoint p2(fr.x() + fr.width(), p1.y());
782 } else {
784 }
785 }
786 break;
787 case PE_IndicatorCheckBox:
788 {
789 QNumberStyleAnimation* animation = qobject_cast<QNumberStyleAnimation*>(d->animation(option->styleObject));
790 QFontMetrics fm(assetFont);
791
792 QRectF rect = option->rect;
793 QPointF center = QPointF(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
794 rect.setWidth(15);
795 rect.setHeight(15);
796 rect.moveCenter(center);
797
798 float clipWidth = animation != nullptr ? animation->currentValue() : 1.0f;
799 QRectF clipRect = fm.boundingRect("\uE001");
800 clipRect.moveCenter(center);
801 clipRect.setLeft(rect.x() + (rect.width() - clipRect.width()) / 2.0);
802 clipRect.setWidth(clipWidth * clipRect.width());
803
804
805 QBrush fillBrush = (option->state & State_On || option->state & State_NoChange) ? option->palette.accent() : option->palette.window();
806 if (state & State_MouseOver && (option->state & State_On || option->state & State_NoChange))
807 fillBrush.setColor(fillBrush.color().lighter(107));
808 else if (state & State_MouseOver && !(option->state & State_On || option->state & State_NoChange))
809 fillBrush.setColor(fillBrush.color().darker(107));
811 painter->setBrush(fillBrush);
813
814 painter->setPen(QPen(highContrastTheme == true ? option->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorStrong]));
817
818 painter->setFont(assetFont);
819 painter->setPen(option->palette.highlightedText().color());
820 painter->setBrush(option->palette.highlightedText().color());
821 if (option->state & State_On)
822 painter->drawText(clipRect, Qt::AlignVCenter | Qt::AlignLeft,"\uE001");
823 else if (option->state & State_NoChange)
825 }
826 break;
827
828 case PE_IndicatorRadioButton:
829 {
830 if (option->styleObject->property("_q_end_radius").isNull())
831 option->styleObject->setProperty("_q_end_radius", option->state & State_On ? 4.0f :7.0f);
832 QNumberStyleAnimation* animation = qobject_cast<QNumberStyleAnimation*>(d->animation(option->styleObject));
833 if (animation != nullptr)
834 option->styleObject->setProperty("_q_inner_radius", animation->currentValue());
835 else
836 option->styleObject->setProperty("_q_inner_radius", option->styleObject->property("_q_end_radius"));
837 int innerRadius = option->styleObject->property("_q_inner_radius").toFloat();
838
839 QRectF rect = option->rect;
840 QPointF center = QPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
841 rect.setWidth(15);
842 rect.setHeight(15);
843 rect.moveCenter(center);
844 QRectF innerRect = rect;
845 innerRect.setWidth(8);
846 innerRect.setHeight(8);
847 innerRect.moveCenter(center);
848
850 painter->setBrush(option->palette.accent());
851 if (option->state & State_MouseOver && option->state & State_Enabled)
852 painter->setBrush(QBrush(option->palette.accent().color().lighter(107)));
853 painter->drawEllipse(center, 7, 7);
854
855 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][frameColorStrong]));
857 painter->drawEllipse(center, 7.5, 7.5);
858
860 painter->setBrush(QBrush(option->palette.window()));
861 painter->drawEllipse(center,innerRadius, innerRadius);
862
863 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][frameColorStrong]));
865 painter->drawEllipse(center,innerRadius + 0.5, innerRadius + 0.5);
866
868 painter->setBrush(QBrush(option->palette.window()));
869 if (option->state & State_MouseOver && option->state & State_Enabled)
870 painter->setBrush(QBrush(option->palette.window().color().darker(107)));
871 painter->drawEllipse(center,innerRadius, innerRadius);
872 }
873 break;
874 case PE_PanelButtonBevel:{
875 QRectF rect = option->rect.marginsRemoved(QMargins(2,2,2,2));
876 rect.adjust(-0.5,-0.5,0.5,0.5);
880
881 rect = option->rect.marginsRemoved(QMargins(2,2,2,2));
883 if (!(state & (State_Raised)))
885 else if (state & State_MouseOver)
887 else
888 painter->setBrush(option->palette.button());
891 if (state & State_Raised)
892 painter->drawLine(rect.bottomLeft() + QPoint(2,1), rect.bottomRight() + QPoint(-2,1));
893 }
894 break;
895 case PE_FrameDefaultButton:
896 painter->setPen(option->palette.accent().color());
899 break;
901 break;
903 QRect rect = option->rect;
904 QPen pen(WINUI3Colors[colorSchemeIndex][frameColorLight]);
905 painter->save();
906 painter->setPen(pen);
907 painter->setBrush(QBrush(WINUI3Colors[colorSchemeIndex][menuPanelFill]));
910 painter->restore();
911 break;
912 }
913 case PE_PanelLineEdit:
914 if (widget && widget->objectName() == "qt_spinbox_lineedit")
915 break;
916 if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
917 QRectF frameRect = option->rect;
918 frameRect.adjust(0.5,0.5,-0.5,-0.5);
919 QBrush fillColor = option->palette.brush(QPalette::Base);
920 painter->setBrush(fillColor);
923 // In case the QLineEdit is hovered overdraw the background with a alpha mask to
924 // highlight the QLineEdit.
925 if (state & State_MouseOver && !(state & State_HasFocus)) {
926 fillColor = QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
927 painter->setBrush(fillColor);
930 }
931 if (panel->lineWidth > 0)
932 proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
933 }
934 break;
935 case PE_FrameLineEdit: {
937 painter->setPen(highContrastTheme == true ? option->palette.buttonText().color() : QPen(WINUI3Colors[colorSchemeIndex][frameColorLight]));
939 QRegion clipRegion = option->rect;
940 clipRegion -= option->rect.adjusted(2, 2, -2, -2);
941 painter->setClipRegion(clipRegion);
942 QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0);
943 painter->setPen(QPen(lineColor));
944 painter->drawLine(option->rect.bottomLeft() + QPointF(1,0.5), option->rect.bottomRight() + QPointF(-1,0.5));
945 }
946 break;
947 case PE_Frame: {
948 if (const auto *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
950 break;
951 QRectF rect = option->rect.adjusted(1,1,-1,-1);
952 if (widget && widget->inherits("QComboBoxPrivateContainer")) {
954 painter->setBrush(WINUI3Colors[colorSchemeIndex][menuPanelFill]);
956
957 }
958 painter->setBrush(option->palette.base());
961
963 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][frameColorLight]));
965
966 if (qobject_cast<const QTextEdit *>(widget)) {
967 QRegion clipRegion = option->rect;
968 QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0,255);
969 painter->setPen(QPen(lineColor));
970 painter->drawLine(option->rect.bottomLeft() + QPoint(1,-1), option->rect.bottomRight() + QPoint(-1,-1));
971 }
972 }
973 break;
974 }
976 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
977 if ((vopt->state & State_Selected || vopt->state & State_MouseOver) && vopt->showDecorationSelected) {
980 painter->drawRoundedRect(vopt->rect.marginsRemoved(QMargins(0,2,-2,2)),2,2);
981 const int offset = qobject_cast<const QTreeView *>(widget) ? 2 : 0;
982 if (vopt->viewItemPosition == QStyleOptionViewItem::Beginning && option->state & State_Selected) {
983 painter->setPen(QPen(option->palette.accent().color()));
984 painter->drawLine(option->rect.x(),option->rect.y()+offset,option->rect.x(),option->rect.y() + option->rect.height()-2);
985 painter->drawLine(option->rect.x()+1,option->rect.y()+2,option->rect.x()+1,option->rect.y() + option->rect.height()-2);
986 }
987 }
988 }
989 break;
990 case QStyle::PE_Widget: {
991#if QT_CONFIG(dialogbuttonbox)
992 const QDialogButtonBox *buttonBox = nullptr;
993 if (qobject_cast<const QMessageBox *> (widget))
994 buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
995#if QT_CONFIG(inputdialog)
996 else if (qobject_cast<const QInputDialog *> (widget))
997 buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
998#endif // QT_CONFIG(inputdialog)
999 if (buttonBox) {
1000 painter->fillRect(option->rect,option->palette.window());
1001 }
1002#endif
1003 break;
1004 }
1006 if (const auto *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
1007
1008 QRectF rect= option->rect;
1009 int fwidth = int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(widget));
1010
1011 QRectF bottomLeftCorner = QRectF(rect.left() + 1.0,
1012 rect.bottom() - 1.0 - secondLevelRoundingRadius,
1015 QRectF bottomRightCorner = QRectF(rect.right() - 1.0 - secondLevelRoundingRadius,
1016 rect.bottom() - 1.0 - secondLevelRoundingRadius,
1019
1020 //Draw Mask
1021 if (widget != nullptr) {
1023 mask.clear();
1024
1025 QPainter maskPainter(&mask);
1026 maskPainter.setRenderHint(QPainter::Antialiasing);
1027 maskPainter.setBrush(Qt::color1);
1028 maskPainter.setPen(Qt::NoPen);
1029 maskPainter.drawRoundedRect(option->rect,secondLevelRoundingRadius,secondLevelRoundingRadius);
1030 const_cast<QWidget*>(widget)->setMask(mask);
1031 }
1032
1033 //Draw Window
1034 painter->setPen(QPen(frm->palette.base(), fwidth));
1035 painter->drawLine(QPointF(rect.left(), rect.top()),
1036 QPointF(rect.left(), rect.bottom() - fwidth));
1037 painter->drawLine(QPointF(rect.left() + fwidth, rect.bottom()),
1038 QPointF(rect.right() - fwidth, rect.bottom()));
1039 painter->drawLine(QPointF(rect.right(), rect.top()),
1040 QPointF(rect.right(), rect.bottom() - fwidth));
1041
1042 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][surfaceStroke]));
1043 painter->drawLine(QPointF(rect.left() + 0.5, rect.top() + 0.5),
1044 QPointF(rect.left() + 0.5, rect.bottom() - 0.5 - secondLevelRoundingRadius));
1045 painter->drawLine(QPointF(rect.left() + 0.5 + secondLevelRoundingRadius, rect.bottom() - 0.5),
1046 QPointF(rect.right() - 0.5 - secondLevelRoundingRadius, rect.bottom() - 0.5));
1047 painter->drawLine(QPointF(rect.right() - 0.5, rect.top() + 1.5),
1048 QPointF(rect.right() - 0.5, rect.bottom() - 0.5 - secondLevelRoundingRadius));
1049
1051 painter->setBrush(frm->palette.base());
1052 painter->drawPie(bottomRightCorner.marginsAdded(QMarginsF(2.5,2.5,0.0,0.0)),
1053 270 * 16,90 * 16);
1054 painter->drawPie(bottomLeftCorner.marginsAdded(QMarginsF(0.0,2.5,2.5,0.0)),
1055 -90 * 16,-90 * 16);
1056
1057 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][surfaceStroke]));
1059 painter->drawArc(bottomRightCorner,
1060 0 * 16,-90 * 16);
1061 painter->drawArc(bottomLeftCorner,
1062 -90 * 16,-90 * 16);
1063 }
1064 break;
1065 default:
1067 }
1068 painter->restore();
1069}
1070
1074void QWindows11Style::drawControl(ControlElement element, const QStyleOption *option,
1075 QPainter *painter, const QWidget *widget) const
1076{
1077 Q_D(const QWindows11Style);
1078 QRect rect(option->rect);
1079 State flags = option->state;
1080
1081 painter->save();
1083 switch (element) {
1085 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
1086 QRectF tabRect = tab->rect.marginsRemoved(QMargins(2,2,0,0));
1088 painter->setBrush(tab->palette.base());
1089 if (tab->state & State_MouseOver){
1091 } else if (tab->state & State_Selected) {
1092 painter->setBrush(tab->palette.base());
1093 } else {
1094 painter->setBrush(tab->palette.window());
1095 }
1096 painter->drawRoundedRect(tabRect,2,2);
1097
1099 painter->setPen(highContrastTheme == true ? tab->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
1100 painter->drawRoundedRect(tabRect.adjusted(0.5,0.5,-0.5,-0.5),2,2);
1101
1102 }
1103 break;
1104 case CE_ToolButtonLabel:
1105 if (const QStyleOptionToolButton *toolbutton
1106 = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
1107 QRect rect = toolbutton->rect;
1108 int shiftX = 0;
1109 int shiftY = 0;
1110 if (toolbutton->state & (State_Sunken | State_On)) {
1111 shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton, widget);
1112 shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton, widget);
1113 }
1114 // Arrow type always overrules and is always shown
1115 bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
1116 if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
1117 || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
1119 if (!proxy()->styleHint(SH_UnderlineShortcut, toolbutton, widget))
1121 rect.translate(shiftX, shiftY);
1122 painter->setFont(toolbutton->font);
1123 const QString text = d->toolButtonElideText(toolbutton, rect, alignment);
1124 if (toolbutton->state & State_Raised || toolbutton->palette.isBrushSet(QPalette::Current, QPalette::ButtonText))
1125 painter->setPen(QPen(toolbutton->palette.buttonText().color()));
1126 else
1127 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][controlTextSecondary]));
1128 proxy()->drawItemText(painter, rect, alignment, toolbutton->palette,
1129 toolbutton->state & State_Enabled, text);
1130 } else {
1131 QPixmap pm;
1132 QSize pmSize = toolbutton->iconSize;
1133 if (!toolbutton->icon.isNull()) {
1134 QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
1136 if (!(toolbutton->state & State_Enabled))
1138 else if ((toolbutton->state & State_MouseOver) && (toolbutton->state & State_AutoRaise))
1140 else
1142 pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize), painter->device()->devicePixelRatio(),
1143 mode, state);
1144 pmSize = pm.size() / pm.devicePixelRatio();
1145 }
1146
1147 if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
1148 painter->setFont(toolbutton->font);
1149 QRect pr = rect,
1150 tr = rect;
1152 if (!proxy()->styleHint(SH_UnderlineShortcut, toolbutton, widget))
1154
1155 if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
1156 pr.setHeight(pmSize.height() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1157 tr.adjust(0, pr.height() - 1, 0, -1);
1158 pr.translate(shiftX, shiftY);
1159 if (!hasArrow) {
1160 proxy()->drawItemPixmap(painter, pr, Qt::AlignCenter, pm);
1161 } else {
1162 drawArrow(proxy(), toolbutton, pr, painter, widget);
1163 }
1165 } else {
1166 pr.setWidth(pmSize.width() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1167 tr.adjust(pr.width(), 0, 0, 0);
1168 pr.translate(shiftX, shiftY);
1169 if (!hasArrow) {
1170 proxy()->drawItemPixmap(painter, QStyle::visualRect(toolbutton->direction, rect, pr), Qt::AlignCenter, pm);
1171 } else {
1172 drawArrow(proxy(), toolbutton, pr, painter, widget);
1173 }
1175 }
1176 tr.translate(shiftX, shiftY);
1177 const QString text = d->toolButtonElideText(toolbutton, tr, alignment);
1178 if (toolbutton->state & State_Raised || toolbutton->palette.isBrushSet(QPalette::Current, QPalette::ButtonText))
1179 painter->setPen(QPen(toolbutton->palette.buttonText().color()));
1180 else
1181 painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][controlTextSecondary]));
1182 proxy()->drawItemText(painter, QStyle::visualRect(toolbutton->direction, rect, tr), alignment, toolbutton->palette,
1183 toolbutton->state & State_Enabled, text);
1184 } else {
1185 rect.translate(shiftX, shiftY);
1186 if (hasArrow) {
1187 drawArrow(proxy(), toolbutton, rect, painter, widget);
1188 } else {
1189 proxy()->drawItemPixmap(painter, rect, Qt::AlignCenter, pm);
1190 }
1191 }
1192 }
1193 }
1194 break;
1196 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
1197 int frameShape = f->frameShape;
1198 int frameShadow = QFrame::Plain;
1199 if (f->state & QStyle::State_Sunken)
1200 frameShadow = QFrame::Sunken;
1201 else if (f->state & QStyle::State_Raised)
1202 frameShadow = QFrame::Raised;
1203
1204 int lw = f->lineWidth;
1205 int mlw = f->midLineWidth;
1206
1207 switch (frameShape) {
1208 case QFrame::Box:
1209 if (frameShadow == QFrame::Plain)
1210 qDrawPlainRoundedRect(painter, f->rect, secondLevelRoundingRadius, secondLevelRoundingRadius, highContrastTheme == true ? f->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorStrong], lw);
1211 else
1212 qDrawShadeRect(painter, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
1213 break;
1214 case QFrame::Panel:
1215 if (frameShadow == QFrame::Plain)
1216 qDrawPlainRoundedRect(painter, f->rect, secondLevelRoundingRadius, secondLevelRoundingRadius, highContrastTheme == true ? f->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorStrong], lw);
1217 else
1218 qDrawShadePanel(painter, f->rect, f->palette, frameShadow == QFrame::Sunken, lw);
1219 break;
1220 default:
1222 }
1223 }
1224 break;
1226 if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
1227 QRect rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
1228 QPointF center = rect.center();
1229 if (progbaropt->state & QStyle::State_Horizontal) {
1230 rect.setHeight(1);
1231 rect.moveTop(center.y());
1232 } else {
1233 rect.setWidth(1);
1234 rect.moveLeft(center.x());
1235 }
1239 }
1240 break;
1241 }
1243 if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
1244 const qreal progressBarThickness = 3;
1245 const qreal progressBarHalfThickness = progressBarThickness / 2.0;
1246 QRectF rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
1247 QRectF originalRect = rect;
1248 QPointF center = rect.center();
1249 bool isIndeterminate = progbaropt->maximum == 0 && progbaropt->minimum == 0;
1250 float fillPercentage = 0;
1251 const Qt::Orientation orientation = (progbaropt->state & QStyle::State_Horizontal) ? Qt::Horizontal : Qt::Vertical;
1252 const qreal offset = (orientation == Qt::Horizontal && int(rect.height()) % 2 == 0)
1253 || (orientation == Qt::Vertical && int(rect.width()) % 2 == 0) ? 0.5 : 0.0;
1254
1255 if (!isIndeterminate) {
1256 fillPercentage = ((float(progbaropt->progress) - float(progbaropt->minimum)) / (float(progbaropt->maximum) - float(progbaropt->minimum)));
1257 if (orientation == Qt::Horizontal) {
1258 rect.setHeight(progressBarThickness);
1259 rect.moveTop(center.y() - progressBarHalfThickness - offset);
1260 rect.setWidth(rect.width() * fillPercentage);
1261 } else {
1262 float oldHeight = rect.height();
1263 rect.setWidth(progressBarThickness);
1264 rect.moveLeft(center.x() - progressBarHalfThickness - offset);
1265 rect.moveTop(oldHeight * (1.0f - fillPercentage));
1266 rect.setHeight(oldHeight * fillPercentage);
1267 }
1268 } else {
1269 auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
1270 fillPercentage = (elapsedTime.time_since_epoch().count() % 5000)/(5000.0f*0.75);
1271 if (orientation == Qt::Horizontal) {
1272 float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.width(), float(rect.width()));
1273 float barEnd = qMin(fillPercentage * rect.width(), float(rect.width()));
1274 rect = QRect(QPoint(rect.left() + barBegin, rect.top()), QPoint(rect.left() + barEnd, rect.bottom()));
1275 rect.setHeight(progressBarThickness);
1276 rect.moveTop(center.y() - progressBarHalfThickness - offset);
1277 } else {
1278 float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.height(), float(rect.height()));
1279 float barEnd = qMin(fillPercentage * rect.height(), float(rect.height()));
1280 rect = QRect(QPoint(rect.left(), rect.bottom() - barEnd), QPoint(rect.right(), rect.bottom() - barBegin));
1281 rect.setWidth(progressBarThickness);
1282 rect.moveLeft(center.x() - progressBarHalfThickness - offset);
1283 }
1284 const_cast<QWidget*>(widget)->update();
1285 }
1286 if (progbaropt->invertedAppearance && orientation == Qt::Horizontal)
1287 rect.moveLeft(originalRect.width() * (1.0 - fillPercentage));
1288 else if (progbaropt->invertedAppearance && orientation == Qt::Vertical)
1289 rect.moveBottom(originalRect.height() * fillPercentage);
1291 painter->setBrush(progbaropt->palette.accent());
1293 }
1294 break;
1296 if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
1297 QRect rect = subElementRect(SE_ProgressBarLabel, progbaropt, widget);
1298 painter->setPen(progbaropt->palette.text().color());
1300 }
1301 break;
1302 case CE_PushButtonLabel:
1303 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1305
1307 if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
1309
1311 int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
1313 textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
1314 else
1315 textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
1316 }
1317 if (!btn->icon.isNull()) {
1318 //Center both icon and text
1319 QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
1320 if (mode == QIcon::Normal && btn->state & State_HasFocus)
1323 if (btn->state & State_On)
1324 state = QIcon::On;
1325
1327 int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
1328 int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
1329 int labelWidth = pixmapWidth;
1330 int labelHeight = pixmapHeight;
1331 int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
1332 if (!btn->text.isEmpty()) {
1333 int textWidth = btn->fontMetrics.boundingRect(option->rect, tf, btn->text).width();
1334 labelWidth += (textWidth + iconSpacing);
1335 }
1336
1337 QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
1338 textRect.y() + (textRect.height() - labelHeight) / 2,
1339 pixmapWidth, pixmapHeight);
1340
1341 iconRect = visualRect(btn->direction, textRect, iconRect);
1342
1343 if (btn->direction == Qt::RightToLeft) {
1344 tf |= Qt::AlignRight;
1345 textRect.setRight(iconRect.left() - iconSpacing / 2);
1346 } else {
1347 tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
1348 textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing / 2);
1349 }
1350
1351 if (btn->state & (State_On | State_Sunken))
1352 iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget),
1353 proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
1354 painter->drawPixmap(iconRect, pixmap);
1355 } else {
1356 tf |= Qt::AlignHCenter;
1357 }
1358
1359
1360 if (btn->state & State_Sunken)
1361 painter->setPen(flags & State_On ? QPen(WINUI3Colors[colorSchemeIndex][textOnAccentSecondary]) : QPen(WINUI3Colors[colorSchemeIndex][controlTextSecondary]));
1362 else
1363 painter->setPen(flags & State_On ? QPen(WINUI3Colors[colorSchemeIndex][textOnAccentPrimary]) : QPen(btn->palette.buttonText().color()));
1364 proxy()->drawItemText(painter, textRect, tf, option->palette,btn->state & State_Enabled, btn->text);
1365 }
1366 break;
1367 case CE_PushButtonBevel:
1368 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1369 if (btn->features.testFlag(QStyleOptionButton::Flat)) {
1371 if (flags & (State_Sunken | State_On)) {
1372 painter->setBrush(WINUI3Colors[colorSchemeIndex][subtlePressedColor]);
1373 }
1374 else if (flags & State_MouseOver) {
1376 }
1378 } else {
1381 painter->setBrush(flags & State_On ? option->palette.accent() : option->palette.button());
1383 if (flags.testFlags(State_Sunken | State_MouseOver)) {
1384 if (flags & (State_Sunken))
1385 painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(120) : WINUI3Colors[colorSchemeIndex][controlFillTertiary]);
1386 else if (flags & State_MouseOver)
1387 painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(110) : WINUI3Colors[colorSchemeIndex][controlFillSecondary]);
1389 }
1390
1391 rect.adjust(0.5,0.5,-0.5,-0.5);
1393 painter->setPen(btn->features.testFlag(QStyleOptionButton::DefaultButton) ? QPen(option->palette.accent().color()) : QPen(WINUI3Colors[colorSchemeIndex][controlStrokePrimary]));
1395
1397 if (flags & State_Raised)
1398 painter->drawLine(rect.bottomLeft() + QPointF(4.0,0.0), rect.bottomRight() + QPointF(-4,0.0));
1399 }
1400 }
1401 break;
1402 case CE_MenuBarItem:
1403 if (const auto *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1404 constexpr int hPadding = 11;
1405 constexpr int topPadding = 4;
1406 constexpr int bottomPadding = 6;
1407 bool active = mbi->state & State_Selected;
1408 bool hasFocus = mbi->state & State_HasFocus;
1409 bool down = mbi->state & State_Sunken;
1410 bool enabled = mbi->state & State_Enabled;
1411 QStyleOptionMenuItem newMbi = *mbi;
1412 newMbi.font.setPointSize(10);
1413 if (enabled && (active || hasFocus)) {
1414 if (active && down)
1416 if (active && hasFocus) {
1419 QRect rect = mbi->rect.marginsRemoved(QMargins(5,0,5,0));
1421 }
1422 }
1423 newMbi.rect.adjust(hPadding,topPadding,-hPadding,-bottomPadding);
1424 painter->setFont(newMbi.font);
1425 QCommonStyle::drawControl(element, &newMbi, painter, widget);
1426 }
1427 break;
1428
1429#if QT_CONFIG(menu)
1430 case CE_MenuEmptyArea:
1431 break;
1432
1433 case CE_MenuItem:
1434 if (const auto *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1435 int x, y, w, h;
1436 menuitem->rect.getRect(&x, &y, &w, &h);
1437 int tab = menuitem->reservedShortcutWidth;
1438 bool dis = !(menuitem->state & State_Enabled);
1439 bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
1440 ? menuitem->checked : false;
1441 bool act = menuitem->state & State_Selected;
1442
1443 // windows always has a check column, regardless whether we have an icon or not
1444 int checkcol = qMax<int>(menuitem->maxIconWidth, 32);
1445
1446 QBrush fill = (act == true && dis == false) ? QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]) : menuitem->palette.brush(QPalette::Button);
1449 QRect rect = menuitem->rect;
1450 rect = rect.marginsRemoved(QMargins(2,2,2,2));
1451 if (act && dis == false)
1453
1454 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
1455 int yoff = 4;
1456 painter->setPen(highContrastTheme == true ? menuitem->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
1457 painter->drawLine(x, y + yoff, x + w, y + yoff );
1458 break;
1459 }
1460
1461 QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
1462 if (!menuitem->icon.isNull() && checked) {
1463 if (act) {
1464 qDrawShadePanel(painter, vCheckRect,
1465 menuitem->palette, true, 1,
1466 &menuitem->palette.brush(QPalette::Button));
1467 } else {
1468 QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
1469 qDrawShadePanel(painter, vCheckRect, menuitem->palette, true, 1, &fill);
1470 }
1471 }
1472 // On Windows Style, if we have a checkable item and an icon we
1473 // draw the icon recessed to indicate an item is checked. If we
1474 // have no icon, we draw a checkmark instead.
1475 if (!menuitem->icon.isNull()) {
1477 if (act && !dis)
1480 if (checked)
1481 pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
1482 else
1483 pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
1484 QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize());
1485 pmr.moveCenter(vCheckRect.center());
1486 painter->setPen(menuitem->palette.text().color());
1487 painter->drawPixmap(pmr.topLeft(), pixmap);
1488 } else if (checked) {
1489 QStyleOptionMenuItem newMi = *menuitem;
1490 newMi.state = State_None;
1491 if (!dis)
1492 newMi.state |= State_Enabled;
1493 if (act)
1494 newMi.state |= State_On | State_Selected;
1495 newMi.rect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
1496 menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
1497 checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
1498 menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
1499
1500 QColor discol;
1501 if (dis) {
1502 discol = menuitem->palette.text().color();
1503 painter->setPen(discol);
1504 }
1505 int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol / 4 + int(QWindowsStylePrivate::windowsItemHMargin);
1506 int xpos = menuitem->rect.x() + xm;
1507 QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1508 w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1509 QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
1510
1511 painter->save();
1512 painter->setFont(assetFont);
1514 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1515 text_flags |= Qt::TextHideMnemonic;
1516 text_flags |= Qt::AlignLeft;
1517
1518 const QString textToDraw("\uE001");
1519 painter->setPen(option->palette.text().color());
1520 painter->drawText(vTextRect, text_flags, textToDraw);
1521 painter->restore();
1522 }
1523 painter->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
1524
1525 QColor discol = menuitem->palette.text().color();
1526 if (dis) {
1527 discol = menuitem->palette.color(QPalette::Disabled, QPalette::WindowText);
1528 painter->setPen(discol);
1529 }
1530
1531 int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
1532 int xpos = menuitem->rect.x() + xm;
1533 QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1534 w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1535 QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
1536 QStringView s(menuitem->text);
1537 if (!s.isEmpty()) { // draw text
1538 painter->save();
1539 qsizetype t = s.indexOf(u'\t');
1541 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1542 text_flags |= Qt::TextHideMnemonic;
1543 text_flags |= Qt::AlignLeft;
1544 if (t >= 0) {
1545 QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
1546 QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1547 const QString textToDraw = s.mid(t + 1).toString();
1548 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
1549 painter->setPen(menuitem->palette.light().color());
1550 painter->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1551 painter->setPen(discol);
1552 }
1553 painter->setPen(menuitem->palette.color(QPalette::Disabled, QPalette::Text));
1554 painter->drawText(vShortcutRect, text_flags, textToDraw);
1555 s = s.left(t);
1556 }
1557 QFont font = menuitem->font;
1558 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1559 font.setBold(true);
1561 const QString textToDraw = s.left(t).toString();
1562 painter->setPen(discol);
1563 painter->drawText(vTextRect, text_flags, textToDraw);
1564 painter->restore();
1565 }
1566 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1567 int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
1568 xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
1569 QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1570 QStyleOptionMenuItem newMI = *menuitem;
1571 newMI.rect = vSubMenuRect;
1572 newMI.state = dis ? State_None : State_Enabled;
1573 if (act)
1574 newMI.palette.setColor(QPalette::ButtonText,
1575 newMI.palette.highlightedText().color());
1576 painter->save();
1577 painter->setFont(assetFont);
1579 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1580 text_flags |= Qt::TextHideMnemonic;
1581 text_flags |= Qt::AlignLeft;
1582 const QString textToDraw("\uE013");
1583 painter->setPen(option->palette.text().color());
1584 painter->drawText(vSubMenuRect, text_flags, textToDraw);
1585 painter->restore();
1586 }
1587 }
1588 break;
1589#endif // QT_CONFIG(menu)
1590 case CE_MenuBarEmptyArea: {
1591 break;
1592 }
1593 case CE_HeaderEmptyArea:
1594 break;
1595 case CE_HeaderSection: {
1596 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1598 painter->setBrush(header->palette.button());
1599 painter->drawRect(header->rect);
1600
1601 painter->setPen(highContrastTheme == true ? header->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
1603
1604 if (header->position == QStyleOptionHeader::OnlyOneSection) {
1605 break;
1606 }
1607 else if (header->position == QStyleOptionHeader::Beginning) {
1608 painter->drawLine(QPointF(option->rect.topRight()) + QPointF(0.5,0.0),
1609 QPointF(option->rect.bottomRight()) + QPointF(0.5,0.0));
1610 }
1611 else if (header->position == QStyleOptionHeader::End) {
1612 painter->drawLine(QPointF(option->rect.topLeft()) - QPointF(0.5,0.0),
1613 QPointF(option->rect.bottomLeft()) - QPointF(0.5,0.0));
1614 } else {
1615 painter->drawLine(QPointF(option->rect.topRight()) + QPointF(0.5,0.0),
1616 QPointF(option->rect.bottomRight()) + QPointF(0.5,0.0));
1617 painter->drawLine(QPointF(option->rect.topLeft()) - QPointF(0.5,0.0),
1618 QPointF(option->rect.bottomLeft()) - QPointF(0.5,0.0));
1619 }
1620 painter->drawLine(QPointF(option->rect.bottomLeft()) + QPointF(0.0,0.5),
1621 QPointF(option->rect.bottomRight()) + QPointF(0.0,0.5));
1622 }
1623 break;
1624 }
1626 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
1627 if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) {
1628 QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
1629 QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
1630 QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
1631
1632 QRect rect = vopt->rect;
1633
1634 painter->setPen(highContrastTheme == true ? vopt->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
1635 if (vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne || vopt->viewItemPosition == QStyleOptionViewItem::Invalid) {
1636 } else if (vopt->viewItemPosition == QStyleOptionViewItem::Beginning) {
1637 painter->drawLine(QPointF(option->rect.topRight()) + QPointF(0.5,0.0),
1638 QPointF(option->rect.bottomRight()) + QPointF(0.5,0.0));
1639 } else if (vopt->viewItemPosition == QStyleOptionViewItem::End) {
1640 painter->drawLine(QPointF(option->rect.topLeft()) - QPointF(0.5,0.0),
1641 QPointF(option->rect.bottomLeft()) - QPointF(0.5,0.0));
1642 } else {
1643 painter->drawLine(QPointF(option->rect.topRight()) + QPointF(0.5,0.0),
1644 QPointF(option->rect.bottomRight()) + QPointF(0.5,0.0));
1645 painter->drawLine(QPointF(option->rect.topLeft()) - QPointF(0.5,0.0),
1646 QPointF(option->rect.bottomLeft()) - QPointF(0.5,0.0));
1647 }
1648 painter->setPen(QPen(option->palette.buttonText().color()));
1649
1650 const bool isTreeView = qobject_cast<const QTreeView *>(widget);
1651
1652 if ((vopt->state & State_Selected || vopt->state & State_MouseOver) && !(isTreeView && vopt->state & State_MouseOver) && vopt->showDecorationSelected) {
1654 QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr;
1655 if (editorWidget) {
1656 QPalette pal = editorWidget->palette();
1657 QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color();
1658 editorBgColor.setAlpha(255);
1659 pal.setColor(editorWidget->backgroundRole(),editorBgColor);
1660 editorWidget->setPalette(pal);
1661 }
1662 } else {
1663 painter->setBrush(vopt->backgroundBrush);
1664 }
1666
1667 if (vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne || vopt->viewItemPosition == QStyleOptionViewItem::Invalid) {
1669 } else if (vopt->viewItemPosition == QStyleOptionViewItem::Beginning) {
1671 } else if (vopt->viewItemPosition == QStyleOptionViewItem::End) {
1673 } else {
1674 painter->drawRect(vopt->rect.marginsRemoved(QMargins(0,2,0,2)));
1675 }
1676
1677 // draw the check mark
1678 if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
1679 QStyleOptionViewItem option(*vopt);
1680 option.rect = checkRect;
1681 option.state = option.state & ~QStyle::State_HasFocus;
1682
1683 switch (vopt->checkState) {
1684 case Qt::Unchecked:
1685 option.state |= QStyle::State_Off;
1686 break;
1689 break;
1690 case Qt::Checked:
1691 option.state |= QStyle::State_On;
1692 break;
1693 }
1695 }
1696
1697 // draw the icon
1699 if (!(vopt->state & QStyle::State_Enabled))
1701 else if (vopt->state & QStyle::State_Selected)
1704 vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state);
1705
1706 painter->setPen(QPen(option->palette.buttonText().color()));
1707 if (!view || !view->isPersistentEditorOpen(vopt->index))
1708 d->viewItemDrawText(painter, vopt, textRect);
1709 if (vopt->state & State_Selected
1710 && (vopt->viewItemPosition == QStyleOptionViewItem::Beginning
1711 || vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne
1712 || vopt->viewItemPosition == QStyleOptionViewItem::Invalid)) {
1713 if (const QListView *lv = qobject_cast<const QListView *>(widget);
1714 lv && lv->viewMode() != QListView::IconMode) {
1715 painter->setPen(QPen(vopt->palette.accent().color()));
1716 painter->drawLine(option->rect.x(), option->rect.y() + 2,
1717 option->rect.x(),option->rect.y() + option->rect.height() - 2);
1718 painter->drawLine(option->rect.x() + 1, option->rect.y() + 2,
1719 option->rect.x() + 1,option->rect.y() + option->rect.height() - 2);
1720 }
1721 }
1722 }
1723 }
1724 break;
1725 }
1726 default:
1728 }
1729 painter->restore();
1730}
1731
1733 const QWidget *widget, QStyleHintReturn *returnData) const {
1734 switch (hint) {
1735 case SH_GroupBox_TextLabelColor:
1736 if (opt!=nullptr && widget!=nullptr)
1737 return opt->palette.text().color().rgba();
1738 return 0;
1740 return 1;
1742 return Qt::LeftButton;
1744 return 0;
1745 default:
1746 return QWindowsVistaStyle::styleHint(hint, opt, widget, returnData);
1747 }
1748}
1749
1751 const QWidget *widget) const
1752{
1753 QRect ret;
1754 switch (element) {
1756 ret = option->rect.adjusted(8,0,-8,0);
1757 break;
1759 if (const auto *item = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
1760 const int decorationOffset = item->features.testFlag(QStyleOptionViewItem::HasDecoration) ? item->decorationSize.width() : 0;
1761 if (widget && widget->parentWidget()
1762 && widget->parentWidget()->inherits("QComboBoxPrivateContainer")) {
1763 ret = option->rect.adjusted(decorationOffset + 5, 0, -5, 0);
1764 } else {
1766 }
1767 } else {
1769 }
1770 break;
1771 default:
1773 }
1774 return ret;
1775}
1776
1781 SubControl subControl, const QWidget *widget) const
1782{
1783 QRect ret;
1784
1785 switch (control) {
1786#if QT_CONFIG(spinbox)
1787 case CC_SpinBox:
1788 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
1789 QSize bs;
1790 int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
1791 bs.setHeight(qMax(8, spinbox->rect.height() - fw));
1792 bs.setWidth(qMin(24.0, spinbox->rect.width()*(1.0/4.0)));
1793 int y = fw + spinbox->rect.y();
1794 int x, lx, rx;
1795 x = spinbox->rect.x() + spinbox->rect.width() - fw - 2 * bs.width();
1796 lx = fw;
1797 rx = x - fw;
1798 switch (subControl) {
1799 case SC_SpinBoxUp:
1800 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
1801 return QRect();
1802 ret = QRect(x, y, bs.width(), bs.height());
1803 break;
1804 case SC_SpinBoxDown:
1805 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
1806 return QRect();
1807 ret = QRect(x + bs.width(), y, bs.width(), bs.height());
1808 break;
1809 case SC_SpinBoxEditField:
1810 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
1811 ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
1812 } else {
1813 ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw);
1814 }
1815 break;
1816 case SC_SpinBoxFrame:
1817 ret = spinbox->rect;
1818 default:
1819 break;
1820 }
1821 ret = visualRect(spinbox->direction, spinbox->rect, ret);
1822 }
1823 break;
1824 case CC_TitleBar:
1825 if (const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
1826 SubControl sc = subControl;
1827 ret = QCommonStyle::subControlRect(control, option, subControl, widget);
1828 static constexpr int indent = 3;
1829 static constexpr int controlWidthMargin = 2;
1830 const int controlHeight = titlebar->rect.height();
1831 const int controlWidth = 46;
1832 const int iconSize = proxy()->pixelMetric(QStyle::PM_TitleBarButtonIconSize, option, widget);
1833 int offset = -(controlWidthMargin + indent);
1834
1835 bool isMinimized = titlebar->titleBarState & Qt::WindowMinimized;
1836 bool isMaximized = titlebar->titleBarState & Qt::WindowMaximized;
1837
1838 switch (sc) {
1839 case SC_TitleBarLabel:
1840 if (titlebar->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
1841 ret = titlebar->rect;
1842 if (titlebar->titleBarFlags & Qt::WindowSystemMenuHint)
1843 ret.adjust(iconSize + controlWidthMargin + indent, 0, -controlWidth, 0);
1844 if (titlebar->titleBarFlags & Qt::WindowMinimizeButtonHint)
1845 ret.adjust(0, 0, -controlWidth, 0);
1846 if (titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint)
1847 ret.adjust(0, 0, -controlWidth, 0);
1848 if (titlebar->titleBarFlags & Qt::WindowShadeButtonHint)
1849 ret.adjust(0, 0, -controlWidth, 0);
1850 if (titlebar->titleBarFlags & Qt::WindowContextHelpButtonHint)
1851 ret.adjust(0, 0, -controlWidth, 0);
1852 }
1853 break;
1854 case SC_TitleBarContextHelpButton:
1855 if (titlebar->titleBarFlags & Qt::WindowContextHelpButtonHint)
1856 offset += controlWidth;
1857 Q_FALLTHROUGH();
1858 case SC_TitleBarMinButton:
1859 if (!isMinimized && (titlebar->titleBarFlags & Qt::WindowMinimizeButtonHint))
1860 offset += controlWidth;
1861 else if (sc == SC_TitleBarMinButton)
1862 break;
1863 Q_FALLTHROUGH();
1864 case SC_TitleBarNormalButton:
1865 if (isMinimized && (titlebar->titleBarFlags & Qt::WindowMinimizeButtonHint))
1866 offset += controlWidth;
1867 else if (isMaximized && (titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint))
1868 offset += controlWidth;
1869 else if (sc == SC_TitleBarNormalButton)
1870 break;
1871 Q_FALLTHROUGH();
1872 case SC_TitleBarMaxButton:
1873 if (!isMaximized && (titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint))
1874 offset += controlWidth;
1875 else if (sc == SC_TitleBarMaxButton)
1876 break;
1877 Q_FALLTHROUGH();
1878 case SC_TitleBarShadeButton:
1879 if (!isMinimized && (titlebar->titleBarFlags & Qt::WindowShadeButtonHint))
1880 offset += controlWidth;
1881 else if (sc == SC_TitleBarShadeButton)
1882 break;
1883 Q_FALLTHROUGH();
1884 case SC_TitleBarUnshadeButton:
1885 if (isMinimized && (titlebar->titleBarFlags & Qt::WindowShadeButtonHint))
1886 offset += controlWidth;
1887 else if (sc == SC_TitleBarUnshadeButton)
1888 break;
1889 Q_FALLTHROUGH();
1890 case SC_TitleBarCloseButton:
1891 if (titlebar->titleBarFlags & Qt::WindowSystemMenuHint)
1892 offset += controlWidth;
1893 else if (sc == SC_TitleBarCloseButton)
1894 break;
1895 ret.setRect(titlebar->rect.right() - offset, titlebar->rect.top(),
1896 controlWidth, controlHeight);
1897 break;
1898 case SC_TitleBarSysMenu:
1899 if (titlebar->titleBarFlags & Qt::WindowSystemMenuHint) {
1900 ret.setRect(titlebar->rect.left() + controlWidthMargin + indent, titlebar->rect.top() + iconSize/2,
1902 }
1903 break;
1904 default:
1905 break;
1906 }
1907 if (widget && isMinimized && titlebar->rect.width() < offset)
1908 const_cast<QWidget*>(widget)->resize(controlWidthMargin + indent + offset + iconSize + controlWidthMargin, controlWidth);
1909 ret = visualRect(titlebar->direction, titlebar->rect, ret);
1910 }
1911 break;
1912#endif // Qt_NO_SPINBOX
1913 case CC_ScrollBar:
1914 {
1915 ret = QCommonStyle::subControlRect(control, option, subControl, widget);
1916
1917 switch (subControl) {
1919 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
1920 if (scrollbar->orientation == Qt::Vertical) {
1921 ret = ret.adjusted(2,2,-2,-3);
1922 } else {
1923 ret = ret.adjusted(3,2,-2,-2);
1924 }
1925 }
1926 break;
1928 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
1929 if (scrollbar->orientation == Qt::Vertical) {
1930 ret = ret.adjusted(2,2,-2,-3);
1931 } else {
1932 ret = ret.adjusted(3,2,-2,-2);
1933 }
1934 }
1935 break;
1936 default:
1937 break;
1938 }
1939 break;
1940 }
1941 default:
1942 ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
1943 }
1944 return ret;
1945}
1946
1951 const QSize &size, const QWidget *widget) const
1952{
1953 QSize contentSize(size);
1954
1955 switch (type) {
1956
1957 case CT_Menu:
1958 contentSize += QSize(10, 0);
1959 break;
1960
1961#if QT_CONFIG(menubar)
1962 case CT_MenuBarItem:
1963 if (!contentSize.isEmpty()) {
1964 constexpr int hMargin = 2 * 6;
1965 constexpr int hPadding = 2 * 11;
1966 constexpr int itemHeight = 32;
1967 contentSize.setWidth(contentSize.width() + hMargin + hPadding);
1968 contentSize.setHeight(itemHeight);
1969 }
1970 break;
1971#endif
1972
1973 default:
1975 break;
1976 }
1977
1978 return contentSize;
1979}
1980
1981
1985int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
1986{
1987 int res = 0;
1988
1989 switch (metric) {
1994 res = 16;
1995 break;
1998 break;
2000 res = 16;
2001 break;
2003 res = 32;
2004 break;
2006 res = 12;
2007 break;
2008 default:
2010 }
2011
2012 return res;
2013}
2014
2016{
2018 const bool isScrollBar = qobject_cast<QScrollBar *>(widget);
2019 if (isScrollBar || qobject_cast<QMenu *>(widget) || widget->inherits("QComboBoxPrivateContainer")) {
2020 bool wasCreated = widget->testAttribute(Qt::WA_WState_Created);
2021 bool layoutDirection = widget->testAttribute(Qt::WA_RightToLeft);
2026 widget->setAttribute(Qt::WA_RightToLeft, layoutDirection);
2028 auto pal = widget->palette();
2030 widget->setPalette(pal);
2031 if (!isScrollBar) { // for menus and combobox containers...
2033 dropshadow->setBlurRadius(3);
2034 dropshadow->setXOffset(3);
2035 dropshadow->setYOffset(3);
2036 widget->setGraphicsEffect(dropshadow);
2037 }
2038 } else if (QComboBox* cb = qobject_cast<QComboBox*>(widget)) {
2039 if (cb->isEditable()) {
2040 QLineEdit *le = cb->lineEdit();
2041 le->setFrame(false);
2042 }
2043 } else if (widget->inherits("QAbstractButton") || widget->inherits("QToolButton")) {
2045 } else if (qobject_cast<QGraphicsView *>(widget) && !qobject_cast<QTextEdit *>(widget)) {
2046 QPalette pal = widget->palette();
2047 pal.setColor(QPalette::Base, pal.window().color());
2048 widget->setPalette(pal);
2049 } else if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
2050 scrollarea && !qobject_cast<QMdiArea *>(widget)) {
2051 QPalette pal = scrollarea->viewport()->palette();
2052 const QPalette originalPalette = pal;
2053 pal.setColor(scrollarea->viewport()->backgroundRole(), Qt::transparent);
2054 scrollarea->viewport()->setPalette(pal);
2055 scrollarea->viewport()->setProperty("_q_original_background_palette", originalPalette);
2056 } else if (qobject_cast<QCommandLinkButton *>(widget)) {
2057 widget->setProperty("_qt_usingVistaStyle",false);
2058 QPalette pal = widget->palette();
2061 widget->setPalette(pal);
2062 }
2063}
2064
2066{
2068 if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
2069 scrollarea && !qobject_cast<QMdiArea *>(widget)) {
2070 const QPalette pal = scrollarea->viewport()->property("_q_original_background_palette").value<QPalette>();
2071 scrollarea->viewport()->setPalette(pal);
2072 scrollarea->viewport()->setProperty("_q_original_background_palette", QVariant());
2073 }
2074}
2075
2076/*
2077The colors for Windows 11 are taken from the official WinUI3 Figma style at
2078https://www.figma.com/community/file/1159947337437047524
2079*/
2080#define SET_IF_UNRESOLVED(GROUP, ROLE, VALUE) \
2081 if (!result.isBrushSet(QPalette::Inactive, ROLE) || styleSheetChanged) \
2082 result.setColor(GROUP, ROLE, VALUE)
2083
2085{
2086 static QString oldStyleSheet;
2087 const bool styleSheetChanged = oldStyleSheet != qApp->styleSheet();
2088
2089 const QColor textColor = QColor(0x00,0x00,0x00,0xE4);
2090 const QColor btnFace = QColor(0xFF,0xFF,0xFF,0xB3);
2091 const QColor btnHighlight = result.accent().color();
2092 const QColor btnColor = result.button().color();
2093
2097 SET_IF_UNRESOLVED(QPalette::All, QPalette::Light, btnColor.lighter(150));
2098 SET_IF_UNRESOLVED(QPalette::All, QPalette::Dark, btnColor.darker(200));
2099 SET_IF_UNRESOLVED(QPalette::All, QPalette::Mid, btnColor.darker(150));
2105 SET_IF_UNRESOLVED(QPalette::All, QPalette::Midlight, btnColor.lighter(125));
2109
2110 if (result.midlight() == result.button())
2111 result.setColor(QPalette::Midlight, btnColor.lighter(110));
2112 oldStyleSheet = qApp->styleSheet();
2113}
2114
2119{
2120 highContrastTheme = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Unknown;
2121 colorSchemeIndex = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
2122
2123 if (!highContrastTheme && colorSchemeIndex == 0)
2125
2126 const bool styleSheetChanged = false; // so the macro works
2127
2137
2138 if (highContrastTheme)
2139 result.setColor(QPalette::Active, QPalette::HighlightedText, result.windowText().color());
2140}
2141
2142#undef SET_IF_UNRESOLVED
2143
The QAbstractItemView class provides the basic functionality for item view classes.
\inmodule QtGui
Definition qbitmap.h:16
\inmodule QtGui
Definition qbrush.h:30
void setColor(const QColor &color)
Sets the brush color to the given color.
Definition qbrush.cpp:687
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
Definition qcolor.cpp:1376
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1481
The QComboBox widget combines a button with a dropdown list.
Definition qcombobox.h:24
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const override
\reimp
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w=nullptr) const override
\reimp
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
Definition qcursor.cpp:188
The QDialogButtonBox class is a widget that presents buttons in a layout that is appropriate to the c...
\reentrant \inmodule QtGui
QRect boundingRect(QChar) const
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the co...
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags=0) const
\reentrant
Definition qfont.h:22
void setPointSize(int)
Sets the point size to pointSize.
Definition qfont.cpp:985
void setBold(bool)
If enable is true sets the font's weight to \l{Weight}{QFont::Bold}; otherwise sets the weight to \l{...
Definition qfont.h:373
@ Plain
Definition qframe.h:49
@ Raised
Definition qframe.h:50
@ Sunken
Definition qframe.h:51
@ Panel
Definition qframe.h:41
@ NoFrame
Definition qframe.h:39
@ Box
Definition qframe.h:40
Shape frameShape
the frame shape value from the frame style
Definition qframe.h:20
The QGraphicsDropShadowEffect class provides a drop shadow effect.
static QStyleHints * styleHints()
Returns the application's style hints.
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition qicon.cpp:1019
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Disabled
Definition qicon.h:22
@ Selected
Definition qicon.h:22
@ Normal
Definition qicon.h:22
@ Active
Definition qicon.h:22
State
This enum describes the state for which a pixmap is intended to be used.
Definition qicon.h:23
@ Off
Definition qicon.h:23
@ On
Definition qicon.h:23
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition qicon.cpp:834
The QLineEdit widget is a one-line text editor.
Definition qlineedit.h:28
\inmodule QtCore\compares equality \compareswith equality QLineF \endcompareswith
Definition qline.h:18
The QListView class provides a list or icon view onto a model.
Definition qlistview.h:17
ViewMode viewMode
the view mode of the QListView.
Definition qlistview.h:26
\inmodule QtCore
Definition qmargins.h:270
\inmodule QtCore
Definition qmargins.h:24
\inmodule QtCore
Definition qobject.h:103
T findChild(QAnyStringView aName, Qt::FindChildOptions options=Qt::FindChildrenRecursively) const
Returns the child of this object that can be cast into type T and that is called name,...
Definition qobject.h:155
QString objectName
the name of this object
Definition qobject.h:107
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4323
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:348
qreal devicePixelRatio() const
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition qpainter.h:519
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or \nullptr if the painter is n...
void drawPie(const QRectF &rect, int a, int alen)
Draws a pie defined by the given rectangle, startAngle and spanAngle.
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void drawLine(const QLineF &line)
Draws a line defined by line.
Definition qpainter.h:442
void setBrushOrigin(int x, int y)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qpainter.h:698
void restore()
Restores the current painter state (pops a saved state off the stack).
void scale(qreal sx, qreal sy)
Scales the coordinate system by ({sx}, {sy}).
const QBrush & brush() const
Returns the painter's current brush.
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
void drawLines(const QLineF *lines, int lineCount)
Draws the first lineCount lines in the array lines using the current pen.
void save()
Saves the current painter state (pushes the state onto a stack).
void setFont(const QFont &f)
Sets the painter's font to the given font.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
void drawArc(const QRectF &rect, int a, int alen)
Draws the arc defined by the given rectangle, startAngle and spanAngle.
QPoint brushOrigin() const
Returns the currently set brush origin.
void drawEllipse(const QRectF &r)
Draws the ellipse defined by the given rectangle.
void setBrush(const QBrush &brush)
Sets the painter's brush to the given brush.
@ Antialiasing
Definition qpainter.h:52
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint.
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode=Qt::AbsoluteSize)
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & text() const
Returns the text foreground brush of the current color group.
Definition qpalette.h:88
@ Current
Definition qpalette.h:49
@ Inactive
Definition qpalette.h:49
@ Disabled
Definition qpalette.h:49
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition qpalette.h:146
const QBrush & window() const
Returns the window (general background) brush of the current color group.
Definition qpalette.h:93
const QBrush & base() const
Returns the base brush of the current color group.
Definition qpalette.h:89
@ HighlightedText
Definition qpalette.h:53
@ ToolTipBase
Definition qpalette.h:57
@ BrightText
Definition qpalette.h:52
@ ButtonText
Definition qpalette.h:52
@ WindowText
Definition qpalette.h:51
@ Highlight
Definition qpalette.h:53
@ ToolTipText
Definition qpalette.h:57
@ Midlight
Definition qpalette.h:51
const QBrush & buttonText() const
Returns the button text foreground brush of the current color group.
Definition qpalette.h:96
\inmodule QtGui
Definition qpen.h:28
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
QSize size() const
Returns the size of the pixmap.
Definition qpixmap.cpp:493
int width() const
Returns the width of the pixmap.
Definition qpixmap.cpp:468
qreal devicePixelRatio() const
Returns the device pixel ratio for the pixmap.
Definition qpixmap.cpp:576
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr void moveCenter(const QPointF &p) noexcept
Moves the rectangle, leaving the center point at the given position.
Definition qrect.h:726
constexpr void setLeft(qreal pos) noexcept
Sets the left edge of the rectangle to the given finite x coordinate.
Definition qrect.h:675
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr QRectF marginsRemoved(const QMarginsF &margins) const noexcept
Definition qrect.h:895
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:813
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:818
constexpr void adjust(qreal x1, qreal y1, qreal x2, qreal y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:805
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:170
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr QRect marginsRemoved(const QMargins &margins) const noexcept
Removes the margins from the rectangle, shrinking it.
Definition qrect.h:454
constexpr void setRight(int pos) noexcept
Sets the right edge of the rectangle to the given x coordinate.
Definition qrect.h:197
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
constexpr QPoint topRight() const noexcept
Returns the position of the rectangle's top-right corner.
Definition qrect.h:227
constexpr void setLeft(int pos) noexcept
Sets the left edge of the rectangle to the given x coordinate.
Definition qrect.h:191
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
\inmodule QtCore
Definition qsize.h:25
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:124
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
@ TicksAbove
Definition qslider.h:27
@ TicksBelow
Definition qslider.h:29
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\variable QStyleOptionGraphicsItem::exposedRect
\variable QStyleOptionHeaderV2::textElideMode
ButtonFeatures features
\variable QStyleOptionToolButton::features
\variable QStyleOptionMenuItem::menuItemType
\variable QStyleOption::palette
\variable QStyleOptionFocusRect::backgroundColor
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
\variable QStyleOptionProgressBar::minimum
\variable QStyleOptionButton::features
\variable QStyleOptionToolBox::selectedPosition
\variable QStyleOptionDockWidget::title
The QStyleOption class stores the parameters used by QStyle functions.
QFontMetrics fontMetrics
QStyle::State state
QPalette palette
Qt::LayoutDirection direction
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ State_Sunken
Definition qstyle.h:69
@ State_Off
Definition qstyle.h:70
@ State_Open
Definition qstyle.h:85
@ State_NoChange
Definition qstyle.h:71
@ State_Enabled
Definition qstyle.h:67
@ State_Horizontal
Definition qstyle.h:74
@ State_On
Definition qstyle.h:72
@ State_Raised
Definition qstyle.h:68
@ State_Selected
Definition qstyle.h:82
@ SH_Slider_PageSetButtons
Definition qstyle.h:650
@ SH_Slider_AbsoluteSetButtons
Definition qstyle.h:649
@ SH_ItemView_ShowDecorationSelected
Definition qstyle.h:645
@ CE_ProgressBarLabel
Definition qstyle.h:188
@ CE_ShapedFrame
Definition qstyle.h:232
@ CE_ItemViewItem
Definition qstyle.h:230
@ CE_TabBarTabShape
Definition qstyle.h:182
@ CE_ProgressBarContents
Definition qstyle.h:187
@ CE_ProgressBarGroove
Definition qstyle.h:186
static int sliderPositionFromValue(int min, int max, int val, int space, bool upsideDown=false)
Converts the given logicalValue to a pixel position.
Definition qstyle.cpp:2222
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction.
Definition qstyle.cpp:2143
@ PM_ScrollBarExtent
Definition qstyle.h:426
@ PM_TitleBarButtonIconSize
Definition qstyle.h:533
@ PM_TitleBarButtonSize
Definition qstyle.h:534
@ PM_ExclusiveIndicatorHeight
Definition qstyle.h:465
@ PM_IndicatorWidth
Definition qstyle.h:462
@ PM_IndicatorHeight
Definition qstyle.h:463
@ PM_SliderLength
Definition qstyle.h:431
@ PM_ExclusiveIndicatorWidth
Definition qstyle.h:464
@ CC_ScrollBar
Definition qstyle.h:334
PrimitiveElement
This enum describes the various primitive elements.
Definition qstyle.h:102
@ PE_PanelMenu
Definition qstyle.h:159
@ PE_IndicatorArrowLeft
Definition qstyle.h:125
@ PE_IndicatorArrowRight
Definition qstyle.h:126
@ PE_PanelItemViewRow
Definition qstyle.h:154
@ PE_IndicatorArrowDown
Definition qstyle.h:124
@ PE_FrameWindow
Definition qstyle.h:112
@ PE_Widget
Definition qstyle.h:148
@ PE_IndicatorArrowUp
Definition qstyle.h:127
@ PE_FrameMenu
Definition qstyle.h:109
@ PE_IndicatorItemViewItemCheck
Definition qstyle.h:130
SubElement
This enum represents a sub-area of a widget.
Definition qstyle.h:242
@ SE_LineEditContents
Definition qstyle.h:281
@ SE_ItemViewItemText
Definition qstyle.h:305
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
@ SC_ScrollBarSubLine
Definition qstyle.h:351
@ SC_ScrollBarAddLine
Definition qstyle.h:350
\reentrant
Definition qtextoption.h:18
QVariant currentValue
the current value of the animation.
\inmodule QtCore
Definition qvariant.h:65
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
float toFloat(bool *ok=nullptr) const
Returns the variant as a float if the variant has userType() \l QMetaType::Double,...
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
QRect toRect() const
Returns the variant as a QRect if the variant has userType() \l QMetaType::QRect; otherwise returns a...
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAutoFillBackground(bool enabled)
Definition qwidget.cpp:330
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
void setWindowFlag(Qt::WindowType, bool on=true)
void setPalette(const QPalette &)
Definition qwidget.cpp:4530
QPalette palette
the widget's palette
Definition qwidget.h:132
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
bool isActiveWindow
whether this widget's window is the active window
Definition qwidget.h:139
QPalette::ColorRole backgroundRole() const
Returns the background role of the widget.
Definition qwidget.cpp:4360
QPointF mapFromGlobal(const QPointF &) const
Translates the global screen coordinate pos to widget coordinates.
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition qwidget.h:910
The QWindows11Style class provides a look and feel suitable for applications on Microsoft Windows 11.
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override
QWindows11Style()
Constructs a QWindows11Style object.
void unpolish(QWidget *widget) override
void polish(QWidget *widget) override
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const override
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override
QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const override
int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const override
int styleHint(StyleHint hint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const override
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override
QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget=nullptr) const override
~QWindows11Style() override
Destructor.
The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows ...
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override
int styleHint(StyleHint hint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const override
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override
void polish(QWidget *widget) override
int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const override
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget=nullptr) const override
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const override
void unpolish(QWidget *widget) override
QOpenGLWidget * widget
[1]
a resize(100000)
QPixmap p2
QPixmap p1
[0]
QString text
opt iconSize
rect
[4]
uint alignment
QStyleOptionButton opt
else opt state
[0]
QRect textRect
const QStyleOptionButton * btn
[3]
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
Combined button and popup list for selecting options.
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
@ Unchecked
@ Checked
@ PartiallyChecked
@ AlignRight
Definition qnamespace.h:146
@ AlignVCenter
Definition qnamespace.h:155
@ AlignHCenter
Definition qnamespace.h:148
@ AlignCenter
Definition qnamespace.h:163
@ AlignLeft
Definition qnamespace.h:144
@ AbsoluteSize
@ LeftButton
Definition qnamespace.h:58
@ WA_UnderMouse
Definition qnamespace.h:284
@ WA_RightToLeft
Definition qnamespace.h:322
@ WA_TranslucentBackground
Definition qnamespace.h:402
@ WA_WState_Created
Definition qnamespace.h:327
@ WA_OpaquePaintEvent
Definition qnamespace.h:287
@ LeftToRight
@ RightToLeft
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ UpArrow
@ RightArrow
@ LeftArrow
@ DownArrow
@ TextSingleLine
Definition qnamespace.h:170
@ TextDontClip
Definition qnamespace.h:171
@ TextHideMnemonic
Definition qnamespace.h:178
@ TextShowMnemonic
Definition qnamespace.h:173
@ color1
Definition qnamespace.h:29
@ gray
Definition qnamespace.h:33
@ transparent
Definition qnamespace.h:47
@ black
Definition qnamespace.h:30
@ NoPen
@ Dense4Pattern
@ NoBrush
@ FramelessWindowHint
Definition qnamespace.h:225
@ WindowContextHelpButtonHint
Definition qnamespace.h:231
@ WindowMaximizeButtonHint
Definition qnamespace.h:229
@ WindowMinimizeButtonHint
Definition qnamespace.h:228
@ NoDropShadowWindowHint
Definition qnamespace.h:244
@ WindowShadeButtonHint
Definition qnamespace.h:232
@ WindowTitleHint
Definition qnamespace.h:226
@ WindowSystemMenuHint
Definition qnamespace.h:227
@ ElideRight
Definition qnamespace.h:190
@ ToolButtonTextOnly
@ ToolButtonTextUnderIcon
@ ToolButtonIconOnly
#define Q_FALLTHROUGH()
#define qApp
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter * sub
static QString header(const QString &name)
void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, const QBrush *fill)
void qDrawPlainRoundedRect(QPainter *p, int x, int y, int w, int h, qreal rx, qreal ry, const QColor &c, int lineWidth, const QBrush *fill)
void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
return ret
static const QStyle::SubControl SubControls[]
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLenum type
GLbitfield flags
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLuint GLenum option
GLenum GLsizei len
GLenum GLenum GLenum GLenum GLenum scale
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define tr(X)
ptrdiff_t qsizetype
Definition qtypes.h:165
double qreal
Definition qtypes.h:187
static const int hMargin
#define SET_IF_UNRESOLVED(GROUP, ROLE, VALUE)
static const QColor * WINUI3Colors[]
static void populateLightSystemBasePalette(QPalette &result)
QT_BEGIN_NAMESPACE static const int topLevelRoundingRadius
static const int secondLevelRoundingRadius
static const QColor WINUI3ColorsDark[]
static const QColor WINUI3ColorsLight[]
const QColor shellCloseButtonColor(0xC4, 0x2B, 0x1C, 0xFF)
WINUI3Color
@ frameColorStrong
@ surfaceStroke
@ subtleHighlightColor
@ controlFillSolid
@ textOnAccentSecondary
@ textOnAccentPrimary
@ subtlePressedColor
@ controlFillSecondary
@ controlTextSecondary
@ controlStrokeOnAccentSecondary
@ frameColorLight
@ menuPanelFill
@ controlStrongFill
@ controlStrokePrimary
@ controlStrokeSecondary
@ controlFillTertiary
QObject * styleObject(const QStyleOption *option)
QWidget * panel
Definition settings.cpp:7
QString title
[35]
ba fill(true)
QPropertyAnimation animation
[0]
p rx()++
QGraphicsItem * item
QPointer< QLineEdit > le
widget render & pixmap
QPainter painter(this)
[7]
QFrame frame
[0]
QNetworkProxy proxy
[0]
QQuickView * view
[0]