1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qquickfluentwinui3theme_p.h"
#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
#include <QtGui/QAccessibilityHints>
#include <QtGui/qcolor.h>
#include <QtGui/qfontdatabase.h>
#include <QtQuickTemplates2/private/qquicktheme_p.h>
QT_BEGIN_NAMESPACE
// If on a Windows11 or above, the platform theme will be used to populate the palette
// We need to fallback to hardcoded colors when using the style on other platforms,
// that's why we need the following
// The colors for Windows 11 are taken from the official WinUI3 Figma style at
// https://www.figma.com/community/file/1159947337437047524
// Try to keep these consistent with the widget windows11 style
enum WinUI3Color {
solidBackground, // Solid background color used for the bottom most layer
acrylicBackgroundDefault, // Acrylic background for popups/tooltips
textPrimary, // Color for UI labels and static text
textSecondary, // Color for text in pressed controls
textDisabled, // Color for disabled text
textOnAccentPrimary, // Color of text on controls filled in accent color
textOnAccentSecondary, // Color of text on sunken controls in accent color
textOnAccentDisabled, // Color of text on disabled controls in accent color
controlDefault, // Color for standard controls
controlDisabled, // Color for disabled controls
controlStrokeDefault, // Color for gradient stops in elevations (pressed or disabled state)
controlStrokeSecondary, // Color for gradient stops in elevations
controlStrokeAccentDefault, // Color for gradient stops in elevations for accent controls
controlStrokeAccentSecondary, // Color for gradient stops in elevations for accent controls
accentDefault, // Default color for accent fills on controls
accentDisabled, // Default color for accent fills on disabled controls
accentSecondary, // Color for accent fills on hovered controls
inputActive, // Color for active text input backgrounds
};
const static QColor WINUI3ColorsLight [] {
QColor(0xF3,0xF3,0xF3,0xFF), //solidBackgroundColor
QColor(0xFC,0xFC,0xFC,0xFF), //acrylicBackgroundDefault
QColor(0x00,0x00,0x00,0xE4), //textPrimary
QColor(0x00,0x00,0x00,0x9E), //textSecondary
QColor(0x00,0x00,0x00,0x5C), //textDisabled
QColor(0xFF,0xFF,0xFF,0xFF), //textOnAccentPrimary
QColor(0xFF,0xFF,0xFF,0x7F), //textOnAccentSecondary
QColor(0xFF,0xFF,0xFF,0xFF), //textOnAccentDisabled
QColor(0xFF,0xFF,0xFF,0xB3), //controlDefault
QColor(0xF9,0xF9,0xF9,0x4D), //controlDisabled
QColor(0x00,0x00,0x00,0x0F), //controlStrokeDefault
QColor(0x00,0x00,0x00,0x29), //controlStrokeSecondary
QColor(0xFF,0xFF,0xFF,0x14), //controlStrokeAccentDefault
QColor(0x00,0x00,0x00,0x66), //controlStrokeAccentSecondary
QColor(0x00,0x5F,0xB8,0xFF), //accentDefault
QColor(0x00,0x00,0x00,0x37), //accentDisabled
QColor(0x00,0x5F,0xB8,0xE6), //accentSecondary
QColor(0xFF,0xFF,0xFF,0xFF) //inputActive
};
const static QColor WINUI3ColorsDark[] {
QColor(0x20,0x20,0x20,0xFF), //solidBackgroundColor
QColor(0x2C,0x2C,0x2C,0xFF), //acrylicBackgroundDefault
QColor(0xFF,0xFF,0xFF,0xFF), //textPrimary
QColor(0xFF,0xFF,0xFF,0xC5), //textSecondary
QColor(0xFF,0xFF,0xFF,0x5D), //textDisabled
QColor(0x00,0x00,0x00,0xFF), //textOnAccentPrimary
QColor(0x00,0x00,0x00,0x80), //textOnAccentSecondary
QColor(0xFF,0xFF,0xFF,0x87), //textOnAccentDisabled
QColor(0xFF,0xFF,0xFF,0x0F), //controlDefault
QColor(0xFF,0xFF,0xFF,0x11), //controlDisabled
QColor(0xFF,0xFF,0xFF,0x12), //controlStrokeDefault
QColor(0xFF,0xFF,0xFF,0x18), //controlStrokeSecondary
QColor(0xFF,0xFF,0xFF,0x14), //controlStrokeAccentDefault
QColor(0x00,0x00,0x00,0x23), //controlStrokeAccentSecondary
QColor(0x60,0xCD,0xFF,0xFF), //accentDefault
QColor(0xFF,0xFF,0xFF,0x28), //accentDisabled
QColor(0x60,0xCD,0xFF,0xE6), // accentSecondary
QColor(0x1E,0x1E,0x1E,0xB3) // inputActive
};
const static QColor* WINUI3Colors[] {
WINUI3ColorsLight,
WINUI3ColorsDark
};
// Function to populate the palette with WinUI3 theme-specific colors
static void populateWinUI3Palette(QPalette &palette)
{
const auto colorSchemeIndex = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
palette.setColor(QPalette::All, QPalette::Window, WINUI3Colors[colorSchemeIndex][solidBackground]);
palette.setColor(QPalette::All, QPalette::Base, WINUI3Colors[colorSchemeIndex][controlDefault]);
palette.setColor(QPalette::Active, QPalette::Base, WINUI3Colors[colorSchemeIndex][inputActive]);
palette.setColor(QPalette::Disabled, QPalette::Base, WINUI3Colors[colorSchemeIndex][controlDisabled]);
palette.setColor(QPalette::All, QPalette::WindowText, WINUI3Colors[colorSchemeIndex][textPrimary]);
palette.setColor(QPalette::Disabled, QPalette::WindowText, WINUI3Colors[colorSchemeIndex][textDisabled]);
palette.setColor(QPalette::All, QPalette::Text, WINUI3Colors[colorSchemeIndex][textPrimary]);
palette.setColor(QPalette::Disabled, QPalette::Text, WINUI3Colors[colorSchemeIndex][textDisabled]);
palette.setColor(QPalette::All, QPalette::PlaceholderText, WINUI3Colors[colorSchemeIndex][textSecondary]);
palette.setColor(QPalette::Disabled, QPalette::PlaceholderText, WINUI3Colors[colorSchemeIndex][textDisabled]);
palette.setColor(QPalette::All, QPalette::Button, WINUI3Colors[colorSchemeIndex][controlDefault]);
palette.setColor(QPalette::Disabled, QPalette::Button, WINUI3Colors[colorSchemeIndex][controlDisabled]);
palette.setColor(QPalette::All, QPalette::ButtonText, WINUI3Colors[colorSchemeIndex][textPrimary]);
palette.setColor(QPalette::Disabled, QPalette::ButtonText, WINUI3Colors[colorSchemeIndex][textDisabled]);
palette.setColor(QPalette::All, QPalette::ToolTipBase, WINUI3Colors[colorSchemeIndex][acrylicBackgroundDefault]);
palette.setColor(QPalette::All, QPalette::ToolTipText, WINUI3Colors[colorSchemeIndex][textPrimary]);
palette.setColor(QPalette::Disabled, QPalette::ToolTipText, WINUI3Colors[colorSchemeIndex][textDisabled]);
palette.setColor(QPalette::Disabled, QPalette::Accent, WINUI3Colors[colorSchemeIndex][accentDisabled]);
palette.setColor(QPalette::Disabled, QPalette::Highlight, WINUI3Colors[colorSchemeIndex][accentDisabled]);
palette.setColor(QPalette::All, QPalette::HighlightedText, Qt::white);
palette.setColor(QPalette::All, QPalette::Light, WINUI3Colors[colorSchemeIndex][controlStrokeAccentDefault]);
palette.setColor(QPalette::All, QPalette::Midlight, WINUI3Colors[colorSchemeIndex][controlStrokeDefault]);
palette.setColor(QPalette::All, QPalette::Dark, WINUI3Colors[colorSchemeIndex][controlStrokeSecondary]);
palette.setColor(QPalette::All, QPalette::Mid, WINUI3Colors[colorSchemeIndex][controlStrokeAccentSecondary]);
}
static void populateWinUI3Fonts(QQuickTheme *theme)
{
QFont systemFont;
QFont toolBarFont;
QFont toolTipFont;
const QLatin1String segoeUiFamilyName("Segoe UI Variable");
if (QFontDatabase::families().contains(segoeUiFamilyName)) {
const QFont segoeFont(segoeUiFamilyName);
const QStringList families{segoeFont.family()};
systemFont.setFamilies(families);
toolBarFont.setFamilies(families);
}
systemFont.setWeight(QFont::Weight::Normal);
toolBarFont.setWeight(QFont::Weight::Normal);
toolTipFont.setWeight(QFont::Weight::Normal);
systemFont.setPixelSize(14);
toolBarFont.setPixelSize(12);
toolTipFont.setPixelSize(12);
theme->setFont(QQuickTheme::System, systemFont);
theme->setFont(QQuickTheme::ToolBar, toolBarFont);
theme->setFont(QQuickTheme::ToolTip, toolTipFont);
}
QPalette QQuickFluentWinUI3Theme::initializeDefaultPalette()
{
QPalette palette;
const auto *styleHints = QGuiApplication::styleHints();
const auto highContrastTheme = styleHints->accessibility()->contrastPreference() == Qt::ContrastPreference::HighContrast;
// HighContrast themes use system colors only
if (!highContrastTheme) {
populateWinUI3Palette(palette);
// Resolve against the platform palette
if (auto platformTheme = QGuiApplicationPrivate::platformTheme()) {
const auto platformPalette = platformTheme->palette();
if (platformPalette)
palette = palette.resolve(*platformPalette);
}
const auto colorSchemeIndex = styleHints->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
// Ensure specific roles are set
if (!palette.isBrushSet(QPalette::Active, QPalette::Accent))
palette.setColor(QPalette::Active, QPalette::Accent, WINUI3Colors[colorSchemeIndex][accentDefault]);
if (!palette.isBrushSet(QPalette::Inactive, QPalette::Highlight))
palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.accent().color());
palette.setColor(QPalette::Disabled, QPalette::Accent, WINUI3Colors[colorSchemeIndex][accentDisabled]);
palette.setColor(QPalette::Disabled, QPalette::Highlight, WINUI3Colors[colorSchemeIndex][accentDisabled]);
}
// WinUI3 sets the inactive accent color to the same as the active one
palette.setColor(QPalette::Inactive, QPalette::Accent, palette.accent().color());
palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.highlight().color());
// Finally QGuiApp::palette() should take precedence over style palette
palette = QGuiApplication::palette().resolve(palette);
return palette;
}
void QQuickFluentWinUI3Theme::initialize(QQuickTheme *theme)
{
populateWinUI3Fonts(theme);
QPalette systemPalette = initializeDefaultPalette();
theme->setPalette(QQuickTheme::System, systemPalette);
}
QT_END_NAMESPACE
|