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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/quick/items/qquickpalette.cpp