Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickpalette.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtQuick/private/qquickpalettecolorprovider_p.h>
8
10
11static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
12{
13 // use a switch to enable "unhandled enum" warnings:
14 switch (cg) {
15 case QPalette::Active:
16 case QPalette::Disabled:
17 case QPalette::Inactive:
18 return true;
19 case QPalette::NColorGroups:
20 case QPalette::Current:
21 case QPalette::All:
22 return false;
23 }
24
25 // GCC 8.x does not tread __builtin_unreachable() as constexpr
26#if defined(Q_CC_INTEL) || defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && Q_CC_GNU >= 900)
27 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
28 Q_UNREACHABLE();
29#endif
30 return false;
31}
32
33/*!
34 \internal
35
36 \class QQuickPalette
37 \brief Contains color groups for each QML item state.
38 \inmodule QtQuick
39 \since 6.0
40
41 This class is the wrapper around QPalette.
42
43 \sa QQuickColorGroup, QQuickAbstractPaletteProvider, QPalette
44 */
45
46/*!
47 \qmltype Palette
48 \nativetype QQuickPalette
49 \inherits ColorGroup
50 \inqmlmodule QtQuick
51 \ingroup qtquick-visual
52 \brief Contains color groups for each QML item state.
53
54 A palette consists of three color groups: \c active, \c disabled, and \c inactive.
55 The \c active color group is the default group: its colors are used for other groups
56 if colors of these groups aren't explicitly specified.
57
58 In the following example, color is applied for all color groups:
59 \code
60 ApplicationWindow {
61 palette.buttonText: "salmon"
62
63 ColumnLayout {
64 Button {
65 text: qsTr("Disabled button")
66 enabled: false
67 }
68
69 Button {
70 text: qsTr("Enabled button")
71 }
72 }
73 }
74 \endcode
75 It means that text color will be the same for both buttons.
76
77 In the following example, colors will be different for enabled and disabled states:
78 \code
79 ApplicationWindow {
80 palette.buttonText: "salmon"
81 palette.disabled.buttonText: "lavender"
82
83 ColumnLayout {
84 Button {
85 text: qsTr("Disabled button")
86 enabled: false
87 }
88
89 Button {
90 text: qsTr("Enabled button")
91 }
92 }
93 }
94 \endcode
95
96 It is also possible to specify colors like this:
97
98 \snippet qtquickcontrols-custom-palette-buttons.qml palette
99
100 This approach is especially convenient when you need to specify a whole
101 palette with all color groups; but as with the other cases above, the
102 colors that are not specified are initialized from SystemPalette, or
103 potentially the \l {Styling Qt Quick Controls}{Qt Quick Controls style},
104 if one is in use.
105
106 \note Some Controls styles use some palette colors, but many styles use
107 independent colors.
108
109 \sa Window::palette, Item::palette, Popup::palette, SystemPalette
110*/
111
112/*!
113 \qmlproperty ColorGroup QtQuick::Palette::active
114
115 The Active group is used for windows that are in focus.
116
117 \sa QPalette::Active
118*/
119
120/*!
121 \qmlproperty ColorGroup QtQuick::Palette::inactive
122
123 The Inactive group is used for windows that have no keyboard focus.
124
125 \sa QPalette::Inactive
126*/
127
128/*!
129 \qmlproperty ColorGroup QtQuick::Palette::disabled
130
131 The Disabled group is used for elements that are disabled for some reason.
132
133 \sa QPalette::Disabled
134*/
135
136QQuickPalette::QQuickPalette(QObject *parent)
137 : QQuickColorGroup(parent)
138 , m_currentGroup(defaultCurrentGroup())
139{
140}
141
142QQuickColorGroup *QQuickPalette::active() const
143{
144 return colorGroup(QPalette::Active);
145}
146
147QQuickColorGroup *QQuickPalette::inactive() const
148{
149 return colorGroup(QPalette::Inactive);
150}
151
152QQuickColorGroup *QQuickPalette::disabled() const
153{
154 return colorGroup(QPalette::Disabled);
155}
156
157void QQuickPalette::resetActive()
158{
159 if (colorProvider().resetColor(QPalette::Active))
160 Q_EMIT changed();
161}
162
163void QQuickPalette::resetInactive()
164{
165 if (colorProvider().resetColor(QPalette::Inactive))
166 Q_EMIT changed();
167}
168
169void QQuickPalette::resetDisabled()
170{
171 if (colorProvider().resetColor(QPalette::Disabled))
172 Q_EMIT changed();
173}
174
175/*!
176 \internal
177
178 Returns the palette's current color group.
179 The default value is Active.
180 */
181QPalette::ColorGroup QQuickPalette::currentColorGroup() const
182{
183 return m_currentGroup;
184}
185
186/*!
187 \internal
188
189 Sets \a currentGroup for this palette.
190
191 The current color group is used when accessing colors of this palette.
192 For example, if color group is Disabled, color accessors will be
193 returning colors form the respective group.
194 \code
195 QQuickPalette palette;
196
197 palette.setAlternateBase(Qt::green);
198 palette.disabled()->setAlternateBase(Qt::red);
199
200 auto color = palette.alternateBase(); // Qt::green
201
202 palette.setCurrentGroup(QPalette::Disabled);
203 color = palette.alternateBase(); // Qt::red
204 \endcode
205
206 Emits QColorGroup::changed().
207 */
208void QQuickPalette::setCurrentGroup(QPalette::ColorGroup currentGroup)
209{
210 if (m_currentGroup != currentGroup) {
211 m_currentGroup = currentGroup;
212 Q_EMIT changed();
213 }
214}
215
216void QQuickPalette::fromQPalette(QPalette palette)
217{
218 if (colorProvider().fromQPalette(std::move(palette))) {
219 Q_EMIT changed();
220 }
221}
222
223QPalette QQuickPalette::toQPalette() const
224{
225 return colorProvider().palette();
226}
227
228const QQuickAbstractPaletteProvider *QQuickPalette::paletteProvider() const
229{
230 return colorProvider().paletteProvider();
231}
232
233void QQuickPalette::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider)
234{
235 colorProvider().setPaletteProvider(paletteProvider);
236}
237
238void QQuickPalette::reset()
239{
240 if (colorProvider().reset()) {
241 Q_EMIT changed();
242 }
243}
244
245void QQuickPalette::inheritPalette(const QPalette &palette)
246{
247 if (colorProvider().inheritPalette(palette)) {
248 Q_EMIT changed();
249 }
250}
251
252void QQuickPalette::setActive(QQuickColorGroup *active)
253{
254 setColorGroup(QPalette::Active, active, &QQuickPalette::activeChanged);
255}
256
257void QQuickPalette::setInactive(QQuickColorGroup *inactive)
258{
259 setColorGroup(QPalette::Inactive, inactive, &QQuickPalette::inactiveChanged);
260}
261
262void QQuickPalette::setDisabled(QQuickColorGroup *disabled)
263{
264 setColorGroup(QPalette::Disabled, disabled, &QQuickPalette::disabledChanged);
265}
266
267
268void QQuickPalette::setColorGroup(QPalette::ColorGroup groupTag,
269 const QQuickColorGroup::GroupPtr &group,
270 void (QQuickPalette::*notifier)())
271{
272 if (isValidColorGroup(groupTag, group)) {
273 if (colorProvider().copyColorGroup(groupTag, group->colorProvider())) {
274 Q_EMIT (this->*notifier)();
275 Q_EMIT changed();
276 }
277 }
278}
279
280QQuickColorGroup::GroupPtr QQuickPalette::colorGroup(QPalette::ColorGroup groupTag) const
281{
282 if (auto group = findColorGroup(groupTag)) {
283 return group;
284 }
285
286 auto group = QQuickColorGroup::createWithParent(*const_cast<QQuickPalette*>(this));
287 const_cast<QQuickPalette*>(this)->registerColorGroup(group, groupTag);
288 return group;
289}
290
291QQuickColorGroup::GroupPtr QQuickPalette::findColorGroup(QPalette::ColorGroup groupTag) const
292{
293 Q_ASSERT(is_valid(groupTag));
294 return m_colorGroups[groupTag];
295}
296
297void QQuickPalette::registerColorGroup(QQuickColorGroup *group, QPalette::ColorGroup groupTag)
298{
299 Q_ASSERT(is_valid(groupTag));
300 auto &g = m_colorGroups[groupTag];
301 if (g) {
302 Q_ASSERT(g != group);
303 g->deleteLater();
304 }
305 g = group;
306
307 group->setGroupTag(groupTag);
308
309 QQuickColorGroup::connect(group, &QQuickColorGroup::changed, this, &QQuickPalette::changed);
310}
311
312bool QQuickPalette::isValidColorGroup(QPalette::ColorGroup groupTag,
313 const QQuickColorGroup::GroupPtr &colorGroup) const
314{
315 if (!colorGroup) {
316 qWarning("Color group cannot be null.");
317 return false;
318 }
319
320 if (!colorGroup->parent()) {
321 qWarning("Color group should have a parent.");
322 return false;
323 }
324
325 if (colorGroup->parent() && !qobject_cast<QQuickPalette*>(colorGroup->parent())) {
326 qWarning("Color group should be a part of QQuickPalette.");
327 return false;
328 }
329
330 if (groupTag == defaultGroupTag()) {
331 qWarning("Register %i color group is not allowed."
332 " QQuickPalette is %i color group itself.", groupTag, groupTag);
333 return false;
334 }
335
336 if (findColorGroup(groupTag) == colorGroup) {
337 qWarning("The color group is already a part of the current palette.");
338 return false;
339 }
340
341 return true;
342}
343
344QT_END_NAMESPACE
345
346#include "moc_qquickpalette_p.cpp"
static QT_BEGIN_NAMESPACE constexpr bool is_valid(QPalette::ColorGroup cg) noexcept