Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqstylekitvariation.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 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
"qqstylekitvariation_p.h"
5
#
include
"qqstylekitstyleandthemebase_p.h"
6
#
include
"qqstylekitstyle_p.h"
7
#
include
"qqstylekittheme_p.h"
8
9
QT_BEGIN_NAMESPACE
10
11
/*!
12
\qmltype StyleVariation
13
\inqmlmodule Qt.labs.StyleKit
14
\inherits StylableControls
15
\brief Defines alternative styling for specific controls.
16
17
18
A StyleVariation lets you define alternative styling that can be applied
19
to specific controls in the application (\e{instance variations}),
20
or to all descendants of a particular parent control type
21
(\e{type variations}). For example, you can give controls in a sidebar a
22
compact appearance, or make buttons inside all \l {ToolBar}{toolbars} look
23
different from buttons elsewhere.
24
25
\section2 Instance Variations
26
27
Instance variations are activated by setting the \l {StyleVariation::}{variations}
28
attached property on any item in the application — all StyleKit controls that are
29
children or descendants of that item will receive the alternative styling. Variations
30
can also be set at multiple levels of the hierarchy simultaneously; when they conflict,
31
the variation closest to the control takes precedence.
32
33
Instance variations are defined in the \l Style or \l Theme that they affect:
34
35
\snippet InstanceVariationSnippets.qml instance variations in style
36
37
And they are applied from the application using the
38
\l {StyleVariation::}{variations} attached property:
39
40
\snippet InstanceVariationSnippets.qml apply instance variation
41
42
Variation names referred to from the application that are not defined in the active
43
style (or theme) are silently ignored — they act as hints that the style author can
44
choose to implement or leave unhandled.
45
46
\section2 Type Variations
47
48
Type variations are assigned to the \l {ControlStyle::}{variations} property of a
49
specific \l ControlStyle, without requiring a \l name. Unlike instance variations —
50
which require the application to explicitly opt in — type variations are applied
51
automatically to all controls of a given type whenever they are descendants of the
52
specified parent control type.
53
54
The following snippet shows how to make all \l {Button}{Buttons} inside a \l Frame look
55
distinct from buttons elsewhere:
56
57
\snippet TypeVariationSnippets.qml frame with variation
58
59
Because \l {StylableControls::}{groupBox} falls back to
60
\l {StylableControls::}{frame} in the style hierarchy, type variations
61
set on \c frame are automatically inherited by \c groupBox as well. To opt out,
62
reset the variations for the subtype.
63
64
\section2 Propagation order
65
66
A StyleVariation is local to the \l Style or \l Theme where it is defined. A Theme
67
cannot shadow an entire StyleVariation defined in the Style — only individual
68
properties within it can be overridden, just like any other style property.
69
70
For example, if both the \l Style and the active \l Theme define \c {frame.variations},
71
both type variation arrays take effect for a \l Frame. The resolution order for
72
individual properties is: the Theme's variation properties take precedence over the
73
Theme's direct properties, which take precedence over the Style's variation properties,
74
which take precedence over the Style's direct properties.
75
76
The same applies to instance variations. A StyleVariation defined in a \l Theme takes
77
precedence over the Theme's direct properties. If a StyleVariation with the same
78
\l name is also defined in the \l Style, both take effect, following the same
79
resolution order as described above.
80
81
In the following snippet, a button with \c {StyleVariation.variations: ["alert"]}
82
will be red in the light theme and cyan in the dark theme, with a 4-pixel border in
83
both. Because the dark theme overrides \c {button.background.radius} to be \c 6,
84
that property takes precedence over the \c {background.radius} set in the Style's
85
variation. As a result, the button's radius ends up being \c 6 in the dark theme, but \c 0
86
in the light theme:
87
88
\snippet VariationPropagation.qml propagation
89
90
\labs
91
92
\sa Style, Theme, {ControlStyle::variations}{ControlStyle.variations},
93
{StyleVariation::variations}{StyleVariation.variations, {StyleKit Property Resolution}}
94
*/
95
96
/*!
97
\qmlproperty string StyleVariation::name
98
99
The name of this variation.
100
101
The name identifies this variation when used as an
102
\l {Instance Variations}{instance variation}.
103
104
\sa {StyleVariation::variations}{variations}, {Instance Variations}
105
*/
106
107
/*!
108
\qmlattachedproperty list<string> StyleVariation::variations
109
110
This property holds the list of \l{StyleVariation}{instance variations}
111
to activate for a \l Control, and its descendant controls.
112
113
If multiple variations in the list sets the same property, the first
114
one in the list takes precedence.
115
116
If variations are set on both a parent item and a descendant control, both
117
sets apply, with the control's own variations taking precedence
118
over those inherited from the parent.
119
120
\snippet InstanceVariationSnippets.qml apply instance variation
121
122
\sa name
123
*/
124
125
/*!
126
\qmlattachedproperty int StyleVariation::controlType
127
128
This property identifies the \l {StyleReader::controlType}{control type} of
129
the item it is attached to.
130
131
StyleKit uses it to resolve \l {Type Variations}{type variations} for descendant
132
controls — if a parent item's \c controlType matches a control type that has
133
\l {ControlStyle::}{variations} defined in the \l Style, those variations apply
134
to all descendant controls.
135
136
Built-in controls set this property automatically. Custom controls
137
must set it explicitly to participate in type variation resolution.
138
139
\sa {ControlStyle::variations}{ControlStyle.variations},
140
{StyleReader::controlType}{StyleReader.controlType}
141
*/
142
143
QQStyleKitVariation
::
QQStyleKitVariation
(
QObject
*
parent
)
144
:
QQStyleKitControls
(
parent
)
145
{
146
}
147
148
void
QQStyleKitVariation
::
componentComplete
()
149
{
150
QQStyleKitControls
::
componentComplete
();
151
152
/* Whenever there is a Style or Theme change, the list of StyleVariations that affects a
153
* StyleReader needs to be rebuilt. And in order to know which StyleVariations that should
154
* be taken into consideration, we need to know which Style each StyleVariation belongs to. */
155
bool
styleOrThemeFound =
false
;
156
for
(QObject *current = parent(); current; current = current->parent()) {
157
if
(
auto
*styleOrTheme = qobject_cast<QQStyleKitStyleAndThemeBase *>(current)) {
158
styleOrTheme->m_styleVariations.append(
this
);
159
styleOrThemeFound =
true
;
160
break
;
161
}
162
}
163
if
(!styleOrThemeFound)
164
qmlWarning(
this
) <<
"A StyleVariation needs to be a descendant of the Style it belongs to!"
;
165
}
166
167
QQStyleKitVariationAttached
*
QQStyleKitVariation
::qmlAttachedProperties(QObject *object)
168
{
169
return
new
QQStyleKitVariationAttached(object);
170
}
171
172
QString
QQStyleKitVariation
::
name
()
const
173
{
174
return
m_name;
175
}
176
177
void
QQStyleKitVariation
::
setName
(
const
QString &name)
178
{
179
if
(m_name == name)
180
return
;
181
182
m_name = name;
183
emit nameChanged();
184
}
185
186
QQStyleKitVariationAttached
::QQStyleKitVariationAttached(QObject *parent)
187
: QObject(parent)
188
{
189
}
190
191
QStringList
QQStyleKitVariationAttached
::
variations
()
const
192
{
193
return
m_variations;
194
}
195
196
void
QQStyleKitVariationAttached
::
setVariations
(
const
QStringList &variations)
197
{
198
if
(m_variations == variations)
199
return
;
200
201
m_variations = variations;
202
emit variationsChanged();
203
}
204
205
QQStyleKitExtendableControlType
QQStyleKitVariationAttached
::
controlType
()
const
206
{
207
return
m_controlType;
208
}
209
210
void
QQStyleKitVariationAttached
::
setControlType
(QQStyleKitExtendableControlType type)
211
{
212
if
(m_controlType == type)
213
return
;
214
215
m_controlType = type;
216
emit controlTypeChanged();
217
}
218
219
void
QQStyleKitVariation
::resetVariationsForStyle(QQStyleKitStyle *style)
220
{
221
/* The usage context stored in a StyleVariation tells which Style or Theme uses it.
222
* After a theme change, we therefore need to rebuild this context list, since the
223
* old theme needs to be removed, and the new theme might need to be added.
224
* Since we also need to update which variations will now be effective for the existing
225
* StyleReaders, we simply clear the context here, and leave it to QQStyleKitPropertyResolver
226
* to rebuild both the effective variations and the context in one pass later.
227
* (QQStyleKitReader::resetReadersForStyle() will set the m_effectiveVariationsDirty
228
* flag, which will trigger the rebuild).
229
*
230
* As an optimization, we also update m_hasVariations to reflect whether any variations
231
* exist at all. If not, variations don't need to be taken into consideration during
232
* style property look-up. */
233
style->m_hasVariations =
false
;
234
235
for
(QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
236
if
(!current->m_styleVariations.isEmpty()) {
237
style->m_hasVariations =
true
;
238
for
(QQStyleKitVariation *variation : current->m_styleVariations)
239
variation->m_usageContext.clear();
240
}
241
242
if
(
QQStyleKitTheme
*theme = current->theme()) {
243
if
(!theme->m_styleVariations.isEmpty()) {
244
style->m_hasVariations =
true
;
245
for
(QQStyleKitVariation *variation : theme->m_styleVariations)
246
variation->m_usageContext.clear();
247
}
248
}
249
}
250
}
251
252
QT_END_NAMESPACE
253
254
#
include
"moc_qqstylekitvariation_p.cpp"
QObjectData::parent
QObject * parent
Definition
qobject.h:74
QObject
\inmodule QtCore
Definition
qobject.h:106
QQStyleKitControls
Definition
qqstylekitcontrols_p.h:30
QQStyleKitControls::componentComplete
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
Definition
qqstylekitcontrols.cpp:806
QQStyleKitTheme
Definition
qqstylekittheme_p.h:30
QQStyleKitVariationAttached
Definition
qqstylekitvariation_p.h:62
QQStyleKitVariationAttached::variations
QStringList variations() const
Definition
qqstylekitvariation.cpp:191
QQStyleKitVariationAttached::setControlType
void setControlType(QQStyleKitExtendableControlType type)
Definition
qqstylekitvariation.cpp:210
QQStyleKitVariationAttached::controlType
QQStyleKitExtendableControlType controlType() const
Definition
qqstylekitvariation.cpp:205
QQStyleKitVariationAttached::setVariations
void setVariations(const QStringList &variations)
Definition
qqstylekitvariation.cpp:196
QQStyleKitVariation
Definition
qqstylekitvariation_p.h:29
QQStyleKitVariation::componentComplete
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
Definition
qqstylekitvariation.cpp:148
QQStyleKitVariation::setName
void setName(const QString &name)
Definition
qqstylekitvariation.cpp:177
QQStyleKitVariation::name
QString name() const
Definition
qqstylekitvariation.cpp:172
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
labs
stylekit
qqstylekitvariation.cpp
Generated on
for Qt by
1.18.0