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
qqstylekitcontrolproperties.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
8
10
11// ************* ControlStyleProperties ****************
12
13/*!
14 \qmltype ControlStyleProperties
15 \nativetype QQStyleKitControlProperties
16 \inqmlmodule Qt.labs.StyleKit
17 \brief Defines the stylable properties for a control.
18
19 ControlStyleProperties defines the stylable properties for a
20 control: the visual building blocks \l background, \l indicator, \l handle,
21 and \l text, as well as layout properties like \l padding, \l spacing,
22 and \l transition.
23
24 The style properties are accessed through inherited types such as
25 \l ControlStyle and \l StyleReader.
26
27 \labs
28
29 \sa ControlStyle, StyleReader, ControlStateStyle, DelegateStyle
30*/
31
32/*!
33 \qmlproperty DelegateStyle ControlStyleProperties::background
34
35 Grouped property for styling the background of a control.
36
37 The background delegate is typically the main visual rectangle behind
38 the control. Use it to set \l {DelegateStyle::color}{colors},
39 \l {DelegateStyle::border}{borders},
40 \l {DelegateStyle::radius}{radii},
41 \l {DelegateStyle::shadow}{shadows},
42 \l {DelegateStyle::gradient}{gradients},
43 and \l {DelegateStyle::image}{images}.
44
45 \note The default \l {Style.fallbackStyle}{fallback style} sets \c {background.visible}
46 to \c false for controls that typically should not draw a background,
47 such as \l [QtQuickControls]{CheckBox}, \l [QtQuickControls]{RadioButton},
48 and \l [QtQuickControls]{Slider}. To show their background, set
49 \c {background.visible} to \c true explicitly.
50*/
51
52/*!
53 \qmlproperty real ControlStyleProperties::bottomPadding
54
55 The \l [QtQuickControls]{Control Layout}{bottom padding}
56 of the control. If not set, falls back to \l padding.
57
58 \sa padding, topPadding, leftPadding, rightPadding
59*/
60
61/*!
62 \qmlproperty HandleStyle ControlStyleProperties::handle
63
64 Grouped property for styling the handle of a control.
65
66 The handle is used by controls such as \l [QtQuickControls]{Switch},
67 \l [QtQuickControls]{Slider}, and \l [QtQuickControls]{RangeSlider}.
68 For a RangeSlider, the two handles can be styled individually through
69 \l {HandleStyle.first}{handle.first} and \l {HandleStyle.second}{handle.second}.
70
71 \sa HandleStyle, DelegateStyle
72*/
73
74/*!
75 \qmlproperty IndicatorStyle ControlStyleProperties::indicator
76
77 Grouped property for styling the indicator of a control. For a
78 \l {StylableControls::}{checkBox}, the indicator is the
79 frame, and its \l {IndicatorStyle::}{foreground} is the check mark.
80 For a \l {StylableControls::}{slider}, the indicator is
81 the groove, and the foreground is the fill.
82
83 \sa DelegateStyle
84*/
85
86/*!
87 \qmlproperty real ControlStyleProperties::leftPadding
88
89 The \l [QtQuickControls]{Control Layout}{left padding} of the control. If not set, falls back to
90 \l padding.
91
92 \sa padding, rightPadding, topPadding, bottomPadding
93*/
94
95/*!
96 \qmlproperty real ControlStyleProperties::padding
97
98 The uniform spacing between the
99 \l [QtQuickControls]{Control Layout}{control's content area and the
100 bounds of the control}. Setting this provides a default value for
101 \l leftPadding, \l rightPadding, \l topPadding, and \l bottomPadding.
102 Each side can be overridden individually.
103
104 \sa leftPadding, rightPadding, topPadding, bottomPadding
105*/
106
107/*!
108 \qmlproperty real ControlStyleProperties::rightPadding
109
110 The \l [QtQuickControls]{Control Layout}{right padding} of the control.
111 If not set, falls back to \l padding.
112
113 \sa padding, leftPadding, topPadding, bottomPadding
114*/
115
116/*!
117 \qmlproperty real ControlStyleProperties::spacing
118
119 The spacing between visual elements inside the control, for example
120 between an indicator and a label.
121*/
122
123/*!
124 \qmlproperty TextStyle ControlStyleProperties::text
125
126 Grouped property for styling the text label of a control.
127*/
128
129/*!
130 \qmlproperty real ControlStyleProperties::topPadding
131
132 The \l [QtQuickControls]{Control Layout}{top padding}
133 of the control. If not set, falls back to \l padding.
134
135 \sa padding, bottomPadding, leftPadding, rightPadding
136*/
137
138/*!
139 \qmlproperty Transition ControlStyleProperties::transition
140
141 A \l [QtQuick]{Transition} used to animate style properties when the
142 control enters a new state, such as \l {ControlStateStyle::}{hovered}
143 or \l {ControlStateStyle::}{pressed}. If set
144 to \c null (the default), property changes are applied immediately
145 without animation.
146
147 \snippet DelegateStyle_transitions.qml custom transition
148
149 To avoid repeating the same target properties for each delegate,
150 StyleKit provides \l StyleAnimation for convenience, which can be
151 used instead of, or in combination with, the
152 \l {Animation and Transitions in Qt Quick}{standard animations:}
153
154 \snippet DelegateStyle_transitions.qml transition
155
156 \note For color properties that participate in a transition, prefer
157 \l {Qt.alpha} over \c "transparent"
158 (e.g. \c {menuBarItem.background.color: Qt.alpha(palette.accent, 0)}).
159 \c "transparent" is \c {Qt.rgba(0, 0, 0, 0)}, which can pull interpolated
160 colors toward black during the transition.
161*/
162
163// ************* DelegateStyle ****************
164
165/*!
166 \qmltype DelegateStyle
167 \nativetype QQStyleKitDelegateProperties
168 \inqmlmodule Qt.labs.StyleKit
169 \brief Defines the visual appearance of an element within a control.
170
171 DelegateStyle describes the visual appearance of a visual element
172 within a \l ControlStyle, such as its \l {ControlStyleProperties::}{background},
173 \l {ControlStyleProperties::}{indicator}, or a sub-element like
174 \l {IndicatorStyle::foreground}{indicator.foreground}.
175 It provides properties for controlling
176 \l {DelegateStyle::width}{size},
177 \l {DelegateStyle::}{color}, \l {DelegateStyle::}{border},
178 \l {DelegateStyle::}{radius}, \l {DelegateStyle::}{shadow},
179 \l {DelegateStyle::}{image}, \l {DelegateStyle::}{opacity}, and more.
180
181 \labs
182
183 \sa ControlStyle, ControlStateStyle,
184 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
185*/
186
187/*!
188 \qmlproperty Qt::Alignment DelegateStyle::alignment
189
190 The alignment of the delegate within its parent. The default
191 value is \c {Qt.AlignLeft | Qt.AlignVCenter}.
192*/
193
194/*!
195 \qmlproperty BorderStyle DelegateStyle::border
196
197 Grouped property for styling the border of this delegate.
198*/
199
200/*!
201 \qmlproperty real DelegateStyle::bottomLeftRadius
202
203 The bottom-left corner radius. If not set, falls back to \l radius.
204
205 \sa radius, topLeftRadius, topRightRadius, bottomRightRadius
206*/
207
208/*!
209 \qmlproperty real DelegateStyle::bottomMargin
210
211 The bottom margin of this delegate. If not set, falls back to
212 \l margins.
213
214 \sa margins, topMargin, leftMargin, rightMargin
215*/
216
217/*!
218 \qmlproperty real DelegateStyle::bottomRightRadius
219
220 The bottom-right corner radius. If not set, falls back to \l radius.
221
222 \sa radius, topLeftRadius, topRightRadius, bottomLeftRadius
223*/
224
225/*!
226 \qmlproperty bool DelegateStyle::clip
227
228 Whether the delegate clips its contents. The default value is \c false.
229*/
230
231/*!
232 \qmlproperty color DelegateStyle::color
233
234 The fill color of this delegate. The default value is \c transparent.
235
236 Unlike a Quick \l [QtQuick]{Rectangle}, where a gradient replaces
237 the color, StyleKit draws the \l gradient on top of the color. This
238 means you can use a semi-transparent gradient as an overlay (for
239 example, a subtle shading effect) while the color shows through
240 underneath.
241
242 \snippet ControlStateStyle_properties.qml color and gradient
243
244 \sa gradient, opacity
245*/
246
247/*!
248 \qmlproperty QObject DelegateStyle::data
249
250 An arbitrary object that can be used for passing
251 custom data from the style to a custom \l delegate component.
252
253 This allows you to define custom style properties beyond what the
254 StyleKit API provides. The data object can vary between states and
255 themes, making it possible to style elements in a custom \l delegate
256 that are not covered by the built-in properties.
257
258 The following snippet uses a custom delegate that draws an overlay
259 \l Text whose color varies depending on the control's state. The delegate
260 inherits \l StyledItem, which is optional but ensures the rest of
261 the button background is rendered normally.
262
263 \snippet DelegateStyle_delegates.qml data
264
265 \note The \c data object is propagated as a whole. Unlike regular style
266 properties, individual properties \e inside the data object do not
267 propagate separately.
268
269 \sa delegate
270*/
271
272/*!
273 \qmlproperty Component DelegateStyle::delegate
274
275 The delegate used to render the DelegateStyle in a
276 \l {Qt Quick Controls}{Qt Quick Control}.
277
278 The default value is \c null, in which case \l StyledItem is used
279 for rendering instead. If you want to hide the delegate altogether
280 (and prevent if from being created), set \l visible to \c false.
281
282 The delegate needs to define the following required properties:
283 \qml
284 required property DelegateStyle delegateStyle
285 required property QtObject control
286 \endqml
287
288 \c delegateStyle points to the DelegateStyle that describes how the
289 delegate should be styled. \c control points to the
290 \l {Qt Quick Controls}{Qt Quick Control} that owns the delegate. The latter
291 can be used to resolve additional information about the control not
292 available from the style.
293
294 If you know the specific type of the owning control, you can use it
295 instead of \l QtObject for the \c control property. For example, since
296 a handle delegate in the snippet below is always used inside a Slider, the
297 type can be set to \l {Qt Quick Templates 2 QML Types}{T.Slider}:
298
299 \snippet DelegateStyle_delegates.qml delegate
300
301 \note If a DelegateStyle has a \l {shadow}{drop shadow} defined, it will be
302 drawn separately by a \l {ShadowStyle::delegate}{shadow delegate.}
303
304 \sa data, visible, StyledItem
305*/
306
307/*!
308 \qmlproperty Gradient DelegateStyle::gradient
309
310 The gradient of this delegate. The default value is \c null (no gradient).
311
312 Unlike a Quick \l [QtQuick]{Rectangle}, where a gradient replaces
313 the color, StyleKit draws the \l gradient on top of the color. This
314 means you can use a semi-transparent gradient as an overlay (for
315 example, a subtle shading effect) while the color shows through
316 underneath.
317
318 \snippet ControlStateStyle_properties.qml color and gradient
319
320 \sa color
321*/
322
323/*!
324 \qmlproperty ImageStyle DelegateStyle::image
325
326 Grouped property for placing an image inside this delegate.
327
328 \sa ImageStyle
329*/
330
331/*!
332 \qmlproperty real DelegateStyle::width
333
334 The width of this delegate.
335
336 \note This property will only set the delegate width when \l fillWidth is \c false. This also
337 applies when \l fillWidth is set higher up in the style hierarchy, for example
338 in the \l {Style::fallbackStyle}{fallback style}.
339
340 If this delegate is at the root of the control — for example the
341 \l {ControlStyleProperties::background}{background} or the
342 \l {ControlStyleProperties::indicator}{indicator} — it will also be included when
343 calculating the \l [QtQuick]{Item::implicitWidth}{implicit width} of the control, even when \l fillWidth is \c true.
344
345 \sa height, fillWidth, minimumWidth, {StyleKit Property Resolution}
346*/
347
348/*!
349 \qmlproperty real DelegateStyle::height
350
351 The height of this delegate.
352
353 \note This property will only set the delegate height when \l fillHeight is \c false. This also
354 applies when \l fillHeight is set higher up in the style hierarchy, for example
355 in the \l {Style::fallbackStyle}{fallback style}.
356
357 If this delegate is at the root of the control — for example the
358 \l {ControlStyleProperties::background}{background} or the
359 \l {ControlStyleProperties::indicator}{indicator} — it will also be included when
360 calculating the \l [QtQuick]{Item::implicitHeight}{implicit height} of the control, even when \l fillHeight is \c true.
361
362 \sa width, fillHeight, minimumHeight, {StyleKit Property Resolution}
363*/
364
365/*!
366 \qmlproperty real DelegateStyle::leftMargin
367
368 The left margin of this delegate. If not set, falls back to
369 \l margins.
370
371 \sa margins, rightMargin, topMargin, bottomMargin
372*/
373
374/*!
375 \qmlproperty real DelegateStyle::margins
376
377 The uniform margin around this delegate. Setting this provides a
378 default value for \l leftMargin, \l rightMargin, \l topMargin,
379 and \l bottomMargin. Each side can be overridden individually.
380
381 \sa leftMargin, rightMargin, topMargin, bottomMargin
382*/
383
384/*!
385 \qmlproperty real DelegateStyle::minimumWidth
386
387 The minimum width of this delegate. The delegate will not be sized
388 smaller than this value.
389*/
390
391/*!
392 \qmlproperty real DelegateStyle::minimumHeight
393
394 The minimum height of this delegate. The delegate will not be sized
395 smaller than this value.
396*/
397
398/*!
399 \qmlproperty bool DelegateStyle::fillWidth
400
401 Whether the delegate should fill the available width of the parent item.
402
403 Some delegates, such as the groove of a \l [QtQuickControls]{Slider}, are
404 often expected to fill the available width of the control, rather than
405 having a fixed implicit width. This can be achieved by setting
406 \c fillWidth to \c true. To add some space between the delegate and the
407 edges of its parent, use the \l margins properties.
408
409 If \c fillWidth is \c false, the delegate's width is determined by its \l width.
410
411 \sa fillHeight, width
412*/
413
414/*!
415 \qmlproperty bool DelegateStyle::fillHeight
416
417 Whether the delegate should fill the available height of the parent item.
418
419 Some delegates, such as the foreground of a checkbox indicator, are often expected
420 to fill the available height (and width) of the indicator, rather than
421 having a fixed height. This can be achieved by setting
422 \c fillHeight to \c true. To add some space between the delegate and the
423 edges of its parent, use the \l margins properties.
424
425 If \c fillHeight is \c false, the delegate's height is determined by its \l height.
426
427 \sa fillWidth, height
428*/
429
430/*!
431 \qmlproperty real DelegateStyle::opacity
432
433 The opacity of this delegate, from \c 0.0 (fully transparent) to
434 \c 1.0 (fully opaque). The default value is \c 1.0.
435
436 \sa visible, color
437*/
438
439/*!
440 \qmlproperty real DelegateStyle::radius
441
442 The corner radius applied to all four corners of this delegate.
443 Individual corners can be overridden with \l topLeftRadius,
444 \l topRightRadius, \l bottomLeftRadius, and \l bottomRightRadius.
445
446 \sa topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius
447*/
448
449/*!
450 \qmlproperty real DelegateStyle::rightMargin
451
452 The right margin of this delegate. If not set, falls back to
453 \l margins.
454
455 \sa margins, leftMargin, topMargin, bottomMargin
456*/
457
458/*!
459 \qmlproperty real DelegateStyle::rotation
460
461 The rotation of this delegate, in degrees.
462*/
463
464/*!
465 \qmlproperty real DelegateStyle::scale
466
467 The scale factor of this delegate. The default value is \c 1.0.
468*/
469
470/*!
471 \qmlproperty ShadowStyle DelegateStyle::shadow
472
473 Grouped property for styling a drop shadow behind this delegate.
474
475 \sa ShadowStyle
476*/
477
478/*!
479 \qmlproperty real DelegateStyle::topLeftRadius
480
481 The top-left corner radius. If not set, falls back to \l radius.
482
483 \sa radius, topRightRadius, bottomLeftRadius, bottomRightRadius
484*/
485
486/*!
487 \qmlproperty real DelegateStyle::topMargin
488
489 The top margin of this delegate. If not set, falls back to
490 \l margins.
491
492 \sa margins, bottomMargin, leftMargin, rightMargin
493*/
494
495/*!
496 \qmlproperty real DelegateStyle::topRightRadius
497
498 The top-right corner radius. If not set, falls back to \l radius.
499
500 \sa radius, topLeftRadius, bottomLeftRadius, bottomRightRadius
501*/
502
503/*!
504 \qmlproperty bool DelegateStyle::visible
505
506 Whether this delegate is visible. The default value is \c true.
507
508 \note Although the default value is \c true, the
509 \l {Style::fallbackStyle}{fallback style} (which overrides many of the default
510 values) sets \c {background.visible} to \c false for controls that typically
511 should not draw a background, such as \l [QtQuickControls]{CheckBox},
512 \l [QtQuickControls]{RadioButton}, and \l [QtQuickControls]{Slider}.
513
514 When \c visible is \c false, the \l delegate will not be created. If you need
515 a hidden delegate to be created, consider setting \l opacity to \c 0 instead.
516
517 \sa opacity
518*/
519
520// ************* ImageStyle ****************
521
522/*!
523 \qmltype ImageStyle
524 \nativetype QQStyleKitImageProperties
525 \inqmlmodule Qt.labs.StyleKit
526 \brief Defines the image style for a delegate.
527
528 ImageStyle provides properties for placing an image inside a
529 \l DelegateStyle. It is available as the
530 \l {DelegateStyle::image}{image} grouped property on any delegate.
531
532 \labs
533
534 \sa DelegateStyle, ControlStyle, ControlStateStyle,
535 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
536*/
537
538/*!
539 \qmlproperty color ImageStyle::color
540
541 A color overlay applied to the image. This is typically used to tint
542 monochrome icons to match the style's color scheme.
543*/
544
545/*!
546 \qmlproperty enumeration ImageStyle::fillMode
547
548 How the image should be scaled or tiled within the delegate. The
549 value is one of the \l [QtQuick]{Image::fillMode}{Image.fillMode}
550 enum values.
551*/
552
553/*!
554 \qmlproperty url ImageStyle::source
555
556 The URL of the image to display inside the delegate.
557*/
558
559// ************* BorderStyle ****************
560
561/*!
562 \qmltype BorderStyle
563 \nativetype QQStyleKitBorderProperties
564 \inqmlmodule Qt.labs.StyleKit
565 \brief Defines the border style for a delegate.
566
567 BorderStyle provides properties for the border drawn around a
568 \l DelegateStyle. It is available as the
569 \l {DelegateStyle::border}{border} grouped property on any delegate.
570
571 \labs
572
573 \sa DelegateStyle, ControlStyle, ControlStateStyle,
574 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
575*/
576
577/*!
578 \qmlproperty color BorderStyle::color
579
580 The color of the border. The default value is \c transparent.
581*/
582
583/*!
584 \qmlproperty real BorderStyle::width
585
586 The width of the border in pixels.
587*/
588
589// ************* ShadowStyle ****************
590
591/*!
592 \qmltype ShadowStyle
593 \nativetype QQStyleKitShadowProperties
594 \inqmlmodule Qt.labs.StyleKit
595 \brief Defines the drop shadow style for a delegate.
596
597 ShadowStyle provides properties for rendering a drop shadow behind
598 a \l DelegateStyle. It is available as the
599 \l {DelegateStyle::shadow}{shadow} grouped property on any delegate.
600
601 \snippet DelegateStyle_shadow.qml drop shadow
602
603 By adjusting scale and color, shadows can also be used to create
604 glow effects. The following snippet adds a diffuse white glow to
605 the handle of a \l [QtQuickControls]{Switch} that intensifies
606 when checked:
607
608 \snippet DelegateStyle_shadow.qml glow
609
610 \labs
611
612 \sa DelegateStyle, ControlStyle, ControlStateStyle,
613 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
614*/
615
616/*!
617 \qmlproperty real ShadowStyle::blur
618
619 The blur of the shadow. A value of \c 0.0 produces a sharp shadow, while
620 larger values produce a softer, more diffuse shadow.
621 The default value is \c 10.0.
622*/
623
624/*!
625 \qmlproperty color ShadowStyle::color
626
627 The color of the shadow. The default value is \c transparent, which
628 means that no shadow will be drawn by default.
629
630 \sa visible, opacity
631*/
632
633/*!
634 \qmlproperty Component ShadowStyle::delegate
635
636 A custom QML \l [QML]{Component} that replaces the default shadow
637 rendering. When set, StyleKit instantiates this component instead
638 of drawing the default shadow.
639*/
640
641/*!
642 \qmlproperty real ShadowStyle::horizontalOffset
643
644 The horizontal offset of the shadow from the delegate, in pixels.
645*/
646
647/*!
648 \qmlproperty real ShadowStyle::opacity
649
650 The opacity of the shadow, from \c 0.0 (fully transparent) to
651 \c 1.0 (fully opaque). The default value is \c 1.0.
652
653 \sa visible, color
654*/
655
656/*!
657 \qmlproperty real ShadowStyle::scale
658
659 The scale factor of the shadow relative to the delegate.
660 The default value is \c 1.0.
661*/
662
663/*!
664 \qmlproperty real ShadowStyle::verticalOffset
665
666 The vertical offset of the shadow from the delegate, in pixels.
667*/
668
669/*!
670 \qmlproperty bool ShadowStyle::visible
671
672 Whether the shadow is visible. The default value is \c true.
673
674 However, since the default shadow \l color is \c transparent,
675 the shadow will not be visible unless a different color is set.
676
677 \sa opacity
678*/
679
680// ************* HandleStyle ****************
681
682/*!
683 \qmltype HandleStyle
684 \nativetype QQStyleKitHandleProperties
685 \inqmlmodule Qt.labs.StyleKit
686 \inherits DelegateStyle
687 \brief Defines the handle style for controls such as \l [QtQuickControls]{Switch},
688 \l [QtQuickControls]{Slider} and \l [QtQuickControls]{RangeSlider}.
689
690 HandleStyle extends \l DelegateStyle with properties that are specific to
691 styling a handle.
692
693 Some controls have more than one handle. For example,
694 \l [QtQuickControls]{RangeSlider} has both a \l [QtQuickControls]{RangeSlider::}{first} and a \l [QtQuickControls]{RangeSlider::}{second} handle.
695 These can be styled independently using the \l first and \l second
696 sub-handles, \c {slider.handle.first} and \c {slider.handle.second}.
697 Properties not set on a sub-handle fall back to the handle itself.
698
699 \labs
700
701 \sa DelegateStyle, ControlStyle, ControlStateStyle,
702 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
703*/
704
705/*!
706 \qmlproperty DelegateStyle HandleStyle::first
707
708 Grouped property for styling the first handle of for example a
709 \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
710 the HandleStyle itself.
711*/
712
713/*!
714 \qmlproperty DelegateStyle HandleStyle::second
715
716 Grouped property for styling the second handle of for example a
717 \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
718 the HandleStyle itself.
719*/
720
721// ************* SubIndicatorStyle ****************
722
723/*!
724 \qmltype SubIndicatorStyle
725 \nativetype QQStyleKitIndicatorProperties
726 \inqmlmodule Qt.labs.StyleKit
727 \inherits DelegateStyle
728 \brief Defines the style for a sub-indicator delegate.
729
730 SubIndicatorStyle extends \l DelegateStyle with a \l foreground
731 property. It is used for styling sub-indicator delegates such as
732 \l {IndicatorStyle::first}{indicator.first} and
733 \l {IndicatorStyle::second}{indicator.second} in controls
734 with multiple indicators, like \l [QtQuickControls]{SpinBox}.
735 For SpinBox, \c {indicator.first} styles the increment button, and
736 \c {indicator.second} styles the decrement button.
737 It is equivalent to \l IndicatorStyle, but does not itself
738 contain sub-indicators.
739
740 \labs
741
742 \sa IndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
743 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
744*/
745
746/*!
747 \qmlproperty DelegateStyle SubIndicatorStyle::foreground
748
749 Grouped property for styling the foreground element of this
750 indicator. The foreground typically represents a checkmark, icon
751 or arrow rendered inside the indicator.
752*/
753
754// ************* IndicatorStyle ****************
755
756/*!
757 \qmltype IndicatorStyle
758 \nativetype QQStyleKitIndicatorWithSubTypes
759 \inqmlmodule Qt.labs.StyleKit
760 \inherits DelegateStyle
761 \brief Defines the style for a control's indicator.
762
763 IndicatorStyle extends \l DelegateStyle with properties that are specific to
764 styling an indicator.
765
766 The IndicatorStyle itself describes the indicator background, while the
767 \l foreground describes the content drawn inside it. For example,
768 \c {checkBox.indicator} styles the check box frame and
769 \c {checkBox.indicator.foreground} styles the check mark. For
770 \l {StylableControls::}{switchControl},
771 \l {StylableControls::}{slider} and
772 \l {StylableControls::}{progressBar}, the indicator styles
773 the groove and the foreground styles the fill.
774
775 \snippet DelegateStyle_indicator.qml checkBox
776
777 Some controls have more than one indicator. For example,
778 \l [QtQuickControls]{SpinBox} has both an increment and a decrement
779 button. These can be styled independently using the \l first and \l second
780 sub-indicators, \c {spinBox.indicator.first} and
781 \c {spinBox.indicator.second}. For SpinBox, \c {indicator.first} styles
782 the increment button, and \c {indicator.second} styles the decrement
783 button. Properties not set on a sub-indicator fall back to the indicator
784 itself.
785
786 \note The \c up and \c down properties are kept as aliases for
787 \c first and \c second for backward compatibility. New code
788 should use \c first and \c second, as these names are generic and can be
789 used by controls with sub-indicators that do not represent up/down actions.
790 The compatibility aliases may be removed in a future version.
791
792 \snippet DelegateStyle_indicator.qml up and down indicator
793
794 \labs
795
796 \sa SubIndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
797 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
798*/
799
800/*!
801 \qmlproperty DelegateStyle IndicatorStyle::foreground
802
803 Grouped property for styling the foreground element of this
804 indicator. For example, \c {checkBox.indicator} describes
805 the check box frame, while \c {checkBox.indicator.foreground} is the check mark.
806
807 For controls like \l {StylableControls::}{slider},
808 \l {StylableControls::}{progressBar}, and
809 \l {StylableControls::}{switchControl}, the \c {indicator.foreground}
810 represents the progress track or fill within the groove, while the \c indicator
811 itself represents the groove.
812*/
813
814/*!
815 \qmlproperty SubIndicatorStyle IndicatorStyle::first
816
817 Grouped property for styling the first sub-indicator of controls that
818 expose multiple indicators. For \l [QtQuickControls]{SpinBox}, this
819 styles the increment button.
820 Unset properties fall back to the indicator itself.
821
822 \note The \c up property is kept as an alias for \c first for backward
823 compatibility. New code should use \c first, as this name is generic
824 and can be used by controls with sub-indicators that do not represent
825 up actions. The compatibility alias may be removed in a future version.
826
827 \sa second
828*/
829
830/*!
831 \qmlproperty SubIndicatorStyle IndicatorStyle::second
832
833 Grouped property for styling the second sub-indicator of for example a
834 \l [QtQuickControls]{SpinBox}.
835 Unset properties fall back to the indicator itself.
836
837 \note The \c down property is kept as an alias for \c second for backward
838 compatibility. New code should use \c second, as this name is generic
839 and can be used by controls with sub-indicators that do not represent
840 down actions. The compatibility alias may be removed in a future version.
841
842 \sa first
843*/
844
845// ************* TextStyle ****************
846
847/*!
848 \qmltype TextStyle
849 \nativetype QQStyleKitTextProperties
850 \inqmlmodule Qt.labs.StyleKit
851 \brief Defines the text style for a control's label.
852
853 TextStyle provides properties for controlling the appearance of
854 text labels within a control, such as
855 \l color, \l alignment and \l padding,
856 and certain font-related properties such as
857 \l {TextStyle::}{bold},
858 \l {TextStyle::}{italic}, and
859 \l {TextStyle::pointSize}{font size}.
860
861 It is available as the \l {ControlStyleProperties::text}{text}
862 grouped property on every \l ControlStateStyle.
863
864 \labs
865
866 \sa DelegateStyle, ControlStyle, ControlStateStyle,
867 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
868*/
869
870/*!
871 \qmlproperty Qt::Alignment TextStyle::alignment
872
873 The alignment of the text within its available area.
874*/
875
876/*!
877 \qmlproperty bool TextStyle::bold
878
879 Whether the text should be rendered in bold. The default value
880 is \c false.
881
882 \sa italic
883*/
884
885/*!
886 \qmlproperty real TextStyle::bottomPadding
887
888 The bottom padding around the text. If not set, falls back to
889 \l padding.
890
891 \sa padding, topPadding, leftPadding, rightPadding
892*/
893
894/*!
895 \qmlproperty color TextStyle::color
896
897 The color of the text.
898*/
899
900/*!
901 \qmlproperty bool TextStyle::italic
902
903 Whether the text should be rendered in italic. The default value
904 is \c false.
905
906 \sa bold
907*/
908
909/*!
910 \qmlproperty real TextStyle::leftPadding
911
912 The left padding around the text. If not set, falls back to
913 \l padding.
914
915 \sa padding, rightPadding, topPadding, bottomPadding
916*/
917
918/*!
919 \qmlproperty real TextStyle::padding
920
921 The uniform padding around the text. Setting this provides a
922 default value for \l leftPadding, \l rightPadding, \l topPadding,
923 and \l bottomPadding. Each side can be overridden individually.
924
925 \sa leftPadding, rightPadding, topPadding, bottomPadding
926*/
927
928/*!
929 \qmlproperty real TextStyle::pointSize
930
931 The point size of the text font.
932*/
933
934/*!
935 \qmlproperty real TextStyle::rightPadding
936
937 The right padding around the text. If not set, falls back to
938 \l padding.
939
940 \sa padding, leftPadding, topPadding, bottomPadding
941*/
942
943/*!
944 \qmlproperty real TextStyle::topPadding
945
946 The top padding around the text. If not set, falls back to
947 \l padding.
948
949 \sa padding, bottomPadding, leftPadding, rightPadding
950*/
951
952/*!
953 \qmlproperty TextStyle TextStyle::first
954
955 Grouped property for styling the first text element in controls that
956 expose two separate text labels. Unset properties fall back to
957 \l {ControlStyleProperties::text}{text} itself.
958
959 \sa second
960*/
961
962/*!
963 \qmlproperty TextStyle TextStyle::second
964
965 Grouped property for styling the second text element in controls that
966 expose two separate text labels. Unset properties fall back to
967 \l {ControlStyleProperties::text}{text} itself.
968
969 \sa first
970*/
971
972// ************* QQStyleKitPropertyGroup ****************
973
974QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent)
975 : QObject(parent)
976{
977}
978
979QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const
980{
982 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(this));
983 auto *self = const_cast<QQStyleKitPropertyGroup *>(this);
984 return static_cast<QQStyleKitControlProperties *>(self);
985 }
986 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(parent()));
987 return static_cast<QQStyleKitControlProperties *>(parent());
988}
989
990template<typename T>
991T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup group) const
992{
993 T *nestedGroup = QQSK::lazyCreate(ptr, controlProperties(), group);
994
995 // Nested groups inherit path flags from their parents
996 nestedGroup->m_pathFlags = m_pathFlags;
997
998 if (group == QQSK::PropertyGroup::DelegateSubtype1) {
999 /* The subtype is stripped from a group's core path, and stored as a flag. This is because
1000 * during style property look-up, we want to check many different alternative paths where
1001 * the core group path can occur, some with, and some without, the subtype included.
1002 * Whether or not to include a subtype is therefore decided as late as possible, when
1003 * creating a QQStyleKitPropertyPath, and then depending on the usage. */
1004 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype1);
1005 nestedGroup->m_groupSpace = m_groupSpace;
1006 } else if (group == QQSK::PropertyGroup::DelegateSubtype2) {
1007 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype2);
1008 nestedGroup->m_groupSpace = m_groupSpace;
1009 } else {
1010 /* Calculate the available property ID space for the nested group. This is done by
1011 * dividing the available space inside _this_ group on the number of potential groups
1012 * that _this_ group can potentially contain. */
1013 const PropertyPathId nestedGroupIndex = PropertyPathId(group);
1014 const PropertyPathId nestedGroupSize = m_groupSpace.size / nestedGroupCount;
1015 nestedGroup->m_groupSpace.size = nestedGroupSize;
1016 nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize);
1017 /* Ensure that we haven’t exhausted the available PropertyPathId space. There must be
1018 * enough room remaining to assign IDs for all properties defined in QQSK::Property.
1019 * If this assertion triggers, consider switching to a wider PropertyPathId type or
1020 * optimizing how the space is allocated. For example, certain nested paths (such as
1021 * control.handle.indicator) can never occur, yet we currently reserve INNER_GROUP_COUNT
1022 * for every nesting level, which is wasteful. */
1023 Q_ASSERT(nestedGroupSize >= PropertyPathId(QQSK::Property::COUNT));
1024 }
1025 return nestedGroup;
1026}
1027
1028/* This macro will check if the caller has the same group path as \a GROUP_PATH.
1029 * This is needed since a QQSK::Property (e.g Color) can sometimes be a
1030 * property in several different subclasses of QQStyleKitPropertyGroup.
1031 * For example, both control.background.color and control.indicator.color has a
1032 * color property. But the group path differs, so they are in reality two completely
1033 * different properties. And in that case, when the former changes value, we want to
1034 * emit changes globally only to that property, and not the latter.
1035 * The caller of this macro will therefore need to go through all the usages of its
1036 * subclass in the API, to figure out which group itself is an instance of. For the
1037 * one that is a match, the macro will go through all readers and emit the same
1038 * signal for them. */
1039#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH) if
1040 (this == CONTROL_PROPERTIES -> GROUP_PATH ) {
1041 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
1042 const auto baseTypes = QQStyleKitPropertyResolver::baseTypesForType(reader->controlType());
1043 if (reader->controlType() != controlType && !baseTypes.contains(controlType))
1044 continue;
1045 reader->clearLocalStorage();
1046 ((reader-> GROUP_PATH ->*changedSignals)(), ...);
1047 }
1048 return; \
1049}
1050
1051template<typename SUBCLASS>
1052void QQStyleKitPropertyGroup::handleStylePropertyChanged(void (SUBCLASS::*changedSignal)()) {
1053 handleStylePropertiesChanged<SUBCLASS>(changedSignal);
1054}
1055
1056template <typename SUBCLASS, typename... CHANGED_SIGNALS>
1057void QQStyleKitPropertyGroup::handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
1058{
1059 /* This function will check which subclass of QQStyleKitProperties this
1060 * group is (nested) inside. Based on that, it will decide if the signals
1061 * should be emitted locally or not, and if the changed properties affects
1062 * all existing QQStyleKitReaders, and therefore will need to be
1063 * emitted 'globally'. Note that it only makes sense to call this function
1064 * for changed properties that are available from a QQStyleKitReader.
1065 * Properities only available from e.g QQStyleKitControl (such as
1066 * variations), are anyway not readable from a QQStyleKitReader. */
1067 static_assert(std::is_base_of<QQStyleKitPropertyGroup, SUBCLASS>::value,
1068 "SUBCLASS must inherit QQStyleKitPropertyGroup");
1069
1070 auto *group = static_cast<SUBCLASS *>(this);
1071 const QQSK::Subclass objectWrittenTo = controlProperties()->subclass();
1072
1073 if (objectWrittenTo == QQSK::Subclass::QQStyleKitState) {
1074 ((group->*changedSignals)(), ...);
1075
1076 if (shouldEmitGlobally()) {
1077 const QQStyleKitControl *control = controlProperties()->asQQStyleKitState()->control();
1078 const QQStyleKitExtendableControlType type = control->controlType();
1079 group->emitGlobally(type, changedSignals...);
1080 }
1081 return;
1082 }
1083
1084 if (objectWrittenTo == QQSK::Subclass::QQStyleKitReader) {
1085 /* Unless the StyleReader has told us not to emit any signals (because it's only
1086 * syncing it's own local storage with old values before starting a transition), we
1087 * emit the signal like normal. This will cause the control to repaint (perhaps
1088 * using a transition). */
1089 if (shouldEmitLocally()) {
1090 QQStyleKitReader *reader = controlProperties()->asQQStyleKitReader();
1091 /* Readers notify their consumer in two different ways depending on who is
1092 * consuming them. A QML control binds to the reader's change signals, so we
1093 * emit those directly. A widget consumer (m_target set) doesn't listen on
1094 * signals; it repaints in response to a QEvent::StyleAnimationUpdate posted
1095 * to the widget, and only while a transition is actually running. */
1096 if (!reader->m_target)
1097 ((group->*changedSignals)(), ...);
1098 else
1099 QCoreApplication::postEvent(reader->m_target, new QEvent(QEvent::StyleAnimationUpdate));
1100 }
1101 return;
1102 }
1103
1104 Q_UNREACHABLE();
1105}
1106
1108{
1109 /* This function will emit changed signals for all style properties in the
1110 * StyleKit API (for a single QQStyleKitReader), which is needed after
1111 * doing a style-, or theme change. */
1112 const QMetaObject *meta = metaObject();
1113 if (meta->inherits(&QQStyleKitControlProperties::staticMetaObject)) {
1114 /* Subclasses of QQStyleKitControlProperties, such as QQStyleKitReader, add
1115 * properties that describe the state of the control (hovered, checked, etc.)
1116 * rather than its style. Those should not be emitted from here. */
1117 meta = &QQStyleKitControlProperties::staticMetaObject;
1118 }
1119
1120 const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
1121 for (int i = startIndex; i < meta->propertyCount(); ++i) {
1122 const QMetaProperty prop = meta->property(i);
1123 const QMetaObject* propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
1124 if (propMetaObject && propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject)) {
1125 /* Nested groups are handled by forEachExistingNestedGroup() below. Reading them
1126 * through their property getters from here would lazily create them. */
1127 continue;
1128 }
1129
1130 if (!emitFlags.testFlag(EmitFlag::AllProperties)) {
1131 // Only emit for color properties when the Colors flag is set
1132 if (emitFlags.testFlag(EmitFlag::Colors)) {
1133 if (prop.metaType() != QMetaType::fromType<QColor>())
1134 continue;
1135 }
1136 }
1137
1138 /* Emit the changed signal for the property.
1139 * Note: even if we call invoke() for every style property, only the signals that
1140 * are connected to something (e.g. a binding) end up doing any real work. If
1141 * isSignalConnected() is false, the emit will exit early. */
1142 Q_ASSERT(prop.hasNotifySignal());
1143 QMetaMethod notify = prop.notifySignal();
1144 notify.invoke(this, Qt::DirectConnection);
1145 }
1146
1147 /* Recurse into the nested groups, but only the ones that have been created. Since
1148 * nested groups are lazily created when first read, a group that doesn't exist has
1149 * never been read, so there are no bindings to it that would need to be notified. */
1150 forEachExistingNestedGroup([emitFlags](QQStyleKitPropertyGroup *group) {
1151 group->emitChangedForAllStylePropertiesRecursive(emitFlags);
1152 });
1153}
1154
1156 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1157{
1158 /* Subclasses with nested groups should override this function and call f for
1159 * each nested group that has been created, mirroring the groups that the subclass
1160 * creates with lazyCreateGroup(). Nested groups are lazily created when read, so a
1161 * group that hasn't been created has never been read either. Using the member
1162 * pointers directly (as opposed to the property getters) avoids creating them by
1163 * accident. Overrides should not call this base implementation. */
1164 Q_UNUSED(f);
1165
1166#ifdef QT_DEBUG
1167 /* Verify that this group has no nested groups, since it would otherwise need to
1168 * override this function. */
1169 const QMetaObject *meta = metaObject();
1170 const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
1171 for (int i = startIndex; i < meta->propertyCount(); ++i) {
1172 const QMetaProperty prop = meta->property(i);
1173 const QMetaObject *propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
1174 Q_ASSERT_X(!propMetaObject || !propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject),
1175 meta->className(), "Classes with nested property groups must override forEachExistingNestedGroup()");
1176 }
1177#endif
1178}
1179
1180bool QQStyleKitPropertyGroup::shouldEmitLocally()
1181{
1182 return !controlProperties()->asQQStyleKitReader()->dontEmitChangedSignals();
1183}
1184
1185bool QQStyleKitPropertyGroup::shouldEmitGlobally()
1186{
1187 QQStyleKitStyle *parentStyle = controlProperties()->style();
1188 if (!parentStyle)
1189 return false;
1190
1191 if (parentStyle->loaded() && !parentStyle->m_isUpdatingPalette) {
1192 /* When a property has changed in the 'global' QQStyleKitStyle itself, it can
1193 * potentially affect all control instances. We therefore need to go through all
1194 * QQStyleKitReaders and inform that their own local property that matches the
1195 * 'global' property needs to be re-read. We emit the signals directly, omitting any
1196 * applied transitions in the QQStyleKitReaders, to optimize for speed. The exception
1197 * is if we're just updating the palette in the Style to match the palette in the current
1198 * control / QQStyleKitReader. Such a change will only affect a single control. */
1199 return parentStyle == QQStyleKitStyle::current();
1200 }
1201 return false;
1202}
1203
1204// ************* QQStyleKitImageProperties ****************
1205
1206QQStyleKitImageProperties::QQStyleKitImageProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1207 : QQStyleKitPropertyGroup(group, parent)
1208{
1209}
1210
1211template <typename... CHANGED_SIGNALS>
1212void QQStyleKitImageProperties::emitGlobally(
1213 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1214{
1215 // Go through all instances of QQStyleKitImageProperties
1216 const QQStyleKitControlProperties *cp = controlProperties();
1217 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->image());
1218 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->image());
1219 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->image());
1220 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->image());
1221}
1222
1223QUrl QQStyleKitImageProperties::source() const
1224{
1225 return styleProperty<QUrl>(QQSK::Property::Source);
1226}
1227
1228void QQStyleKitImageProperties::setSource(const QUrl &source)
1229{
1230 if (setStyleProperty(QQSK::Property::Source, source))
1231 handleStylePropertyChanged(&QQStyleKitImageProperties::sourceChanged);
1232}
1233
1234QColor QQStyleKitImageProperties::color() const
1235{
1236 return styleProperty<QColor>(QQSK::Property::Color);
1237}
1238
1239void QQStyleKitImageProperties::setColor(const QColor &color)
1240{
1241 if (setStyleProperty(QQSK::Property::Color, color))
1242 handleStylePropertyChanged(&QQStyleKitImageProperties::colorChanged);
1243}
1244
1245QQuickImage::FillMode QQStyleKitImageProperties::fillMode() const
1246{
1247 return styleProperty<QQuickImage::FillMode>(QQSK::Property::FillMode);
1248}
1249
1250void QQStyleKitImageProperties::setFillMode(QQuickImage::FillMode fillMode)
1251{
1252 if (setStyleProperty(QQSK::Property::FillMode, fillMode))
1253 handleStylePropertyChanged(&QQStyleKitImageProperties::fillModeChanged);
1254}
1255
1256// ************* QQStyleKitBorderProperties ****************
1257
1258QQStyleKitBorderProperties::QQStyleKitBorderProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1259 : QQStyleKitPropertyGroup(group, parent)
1260{
1261}
1262
1263template <typename... CHANGED_SIGNALS>
1264void QQStyleKitBorderProperties::emitGlobally(
1265 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1266{
1267 // Go through all instances of QQStyleKitBorderProperties
1268 const QQStyleKitControlProperties *cp = controlProperties();
1269 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->border());
1270 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->border());
1271 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->border());
1272 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->border());
1273}
1274
1275qreal QQStyleKitBorderProperties::width() const
1276{
1277 return styleProperty<qreal>(QQSK::Property::Width);
1278}
1279
1280void QQStyleKitBorderProperties::setWidth(qreal width)
1281{
1282 if (setStyleProperty(QQSK::Property::Width, width))
1283 handleStylePropertyChanged(&QQStyleKitBorderProperties::widthChanged);
1284}
1285
1286QColor QQStyleKitBorderProperties::color() const
1287{
1288 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1289}
1290
1291void QQStyleKitBorderProperties::setColor(const QColor &color)
1292{
1293 if (setStyleProperty(QQSK::Property::Color, color))
1294 handleStylePropertyChanged(&QQStyleKitBorderProperties::colorChanged);
1295}
1296
1297// ************* QQStyleKitShadowProperties ****************
1298
1299QQStyleKitShadowProperties::QQStyleKitShadowProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1300 : QQStyleKitPropertyGroup(group, parent)
1301{
1302}
1303
1304template <typename... CHANGED_SIGNALS>
1305void QQStyleKitShadowProperties::emitGlobally(
1306 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1307{
1308 // Go through all instances of QQStyleKitShadowProperties
1309 const QQStyleKitControlProperties *cp = controlProperties();
1310 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->shadow());
1311 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->shadow());
1312 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->shadow());
1313 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->shadow());
1314}
1315
1316QColor QQStyleKitShadowProperties::color() const
1317{
1318 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1319}
1320
1321void QQStyleKitShadowProperties::setColor(QColor color)
1322{
1323 if (setStyleProperty(QQSK::Property::Color, color))
1324 handleStylePropertyChanged(&QQStyleKitShadowProperties::colorChanged);
1325}
1326
1327qreal QQStyleKitShadowProperties::opacity() const
1328{
1329 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1330}
1331
1332void QQStyleKitShadowProperties::setOpacity(qreal opacity)
1333{
1334 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1335 handleStylePropertyChanged(&QQStyleKitShadowProperties::opacityChanged);
1336}
1337
1338qreal QQStyleKitShadowProperties::scale() const
1339{
1340 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1341}
1342
1343void QQStyleKitShadowProperties::setScale(qreal scale)
1344{
1345 if (setStyleProperty(QQSK::Property::Scale, scale))
1346 handleStylePropertyChanged(&QQStyleKitShadowProperties::scaleChanged);
1347}
1348
1349qreal QQStyleKitShadowProperties::verticalOffset() const
1350{
1351 return styleProperty<qreal>(QQSK::Property::VOffset);
1352}
1353
1354void QQStyleKitShadowProperties::setVerticalOffset(qreal verticalOffset)
1355{
1356 if (setStyleProperty(QQSK::Property::VOffset, verticalOffset))
1357 handleStylePropertyChanged(&QQStyleKitShadowProperties::verticalOffsetChanged);
1358}
1359
1360qreal QQStyleKitShadowProperties::horizontalOffset() const
1361{
1362 return styleProperty<qreal>(QQSK::Property::HOffset);
1363}
1364
1365void QQStyleKitShadowProperties::setHorizontalOffset(qreal horizontalOffset)
1366{
1367 if (setStyleProperty(QQSK::Property::HOffset, horizontalOffset))
1368 handleStylePropertyChanged(&QQStyleKitShadowProperties::horizontalOffsetChanged);
1369}
1370
1371qreal QQStyleKitShadowProperties::blur() const
1372{
1373 return styleProperty<qreal>(QQSK::Property::Blur, 10.0);
1374}
1375
1376void QQStyleKitShadowProperties::setBlur(qreal blur)
1377{
1378 if (setStyleProperty(QQSK::Property::Blur, blur))
1379 handleStylePropertyChanged(&QQStyleKitShadowProperties::blurChanged);
1380}
1381
1382bool QQStyleKitShadowProperties::visible() const
1383{
1384 return styleProperty<bool>(QQSK::Property::Visible, true);
1385}
1386
1387void QQStyleKitShadowProperties::setVisible(bool visible)
1388{
1389 if (setStyleProperty(QQSK::Property::Visible, visible))
1390 handleStylePropertyChanged(&QQStyleKitShadowProperties::visibleChanged);
1391}
1392
1393QQmlComponent *QQStyleKitShadowProperties::delegate() const
1394{
1395 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1396}
1397
1398void QQStyleKitShadowProperties::setDelegate(QQmlComponent *delegate)
1399{
1400 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1401 handleStylePropertyChanged(&QQStyleKitShadowProperties::delegateChanged);
1402}
1403
1404// ************* QQStyleKitDelegateProperties ****************
1405
1406QQStyleKitDelegateProperties::QQStyleKitDelegateProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1407 : QQStyleKitPropertyGroup(group, parent)
1408{
1409}
1410
1411template <typename... CHANGED_SIGNALS>
1412void QQStyleKitDelegateProperties::emitGlobally(
1413 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1414{
1415 // Go through all instances of QQStyleKitDelegateProperties
1416 const QQStyleKitControlProperties *cp = controlProperties();
1420 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground());
1421}
1422
1423void QQStyleKitDelegateProperties::forEachExistingNestedGroup(
1424 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1425{
1426 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1427 if (m_image)
1428 f(m_image);
1429 if (m_border)
1430 f(m_border);
1431 if (m_shadow)
1432 f(m_shadow);
1433}
1434
1435qreal QQStyleKitDelegateProperties::radius() const
1436{
1437 return styleProperty<qreal>(QQSK::Property::Radius);
1438}
1439
1440void QQStyleKitDelegateProperties::setRadius(qreal radius)
1441{
1442 if (setStyleProperty(QQSK::Property::Radius, radius))
1443 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1444 &QQStyleKitDelegateProperties::radiusChanged,
1445 &QQStyleKitDelegateProperties::topLeftRadiusChanged,
1446 &QQStyleKitDelegateProperties::topRightRadiusChanged,
1447 &QQStyleKitDelegateProperties::bottomLeftRadiusChanged,
1448 &QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1449}
1450
1451qreal QQStyleKitDelegateProperties::topLeftRadius() const
1452{
1453 return styleProperty<qreal>(QQSK::Property::TopLeftRadius, QQSK::Property::Radius);
1454}
1455
1456void QQStyleKitDelegateProperties::setTopLeftRadius(qreal radius)
1457{
1458 if (setStyleProperty(QQSK::Property::TopLeftRadius, radius))
1459 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topLeftRadiusChanged);
1460}
1461
1462qreal QQStyleKitDelegateProperties::topRightRadius() const
1463{
1464 return styleProperty<qreal>(QQSK::Property::TopRightRadius, QQSK::Property::Radius);
1465}
1466
1467void QQStyleKitDelegateProperties::setTopRightRadius(qreal radius)
1468{
1469 if (setStyleProperty(QQSK::Property::TopRightRadius, radius))
1470 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topRightRadiusChanged);
1471}
1472
1473qreal QQStyleKitDelegateProperties::bottomLeftRadius() const
1474{
1475 return styleProperty<qreal>(QQSK::Property::BottomLeftRadius, QQSK::Property::Radius);
1476}
1477
1478void QQStyleKitDelegateProperties::setBottomLeftRadius(qreal radius)
1479{
1480 if (setStyleProperty(QQSK::Property::BottomLeftRadius, radius))
1481 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomLeftRadiusChanged);
1482}
1483
1484qreal QQStyleKitDelegateProperties::bottomRightRadius() const
1485{
1486 return styleProperty<qreal>(QQSK::Property::BottomRightRadius, QQSK::Property::Radius);
1487}
1488
1489void QQStyleKitDelegateProperties::setBottomRightRadius(qreal radius)
1490{
1491 if (setStyleProperty(QQSK::Property::BottomRightRadius, radius))
1492 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1493}
1494
1495qreal QQStyleKitDelegateProperties::scale() const
1496{
1497 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1498}
1499
1500void QQStyleKitDelegateProperties::setScale(qreal scale)
1501{
1502 if (setStyleProperty(QQSK::Property::Scale, scale))
1503 handleStylePropertyChanged(&QQStyleKitDelegateProperties::scaleChanged);
1504}
1505
1506qreal QQStyleKitDelegateProperties::rotation() const
1507{
1508 return styleProperty<qreal>(QQSK::Property::Rotation);
1509}
1510
1511void QQStyleKitDelegateProperties::setRotation(qreal rotation)
1512{
1513 if (setStyleProperty(QQSK::Property::Rotation, rotation))
1514 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rotationChanged);
1515}
1516
1517qreal QQStyleKitDelegateProperties::width() const
1518{
1519 return styleProperty<qreal>(QQSK::Property::Width);
1520}
1521
1522void QQStyleKitDelegateProperties::setWidth(qreal width)
1523{
1524 if (setStyleProperty(QQSK::Property::Width, width))
1525 handleStylePropertyChanged(&QQStyleKitDelegateProperties::widthChanged);
1526}
1527
1528qreal QQStyleKitDelegateProperties::height() const
1529{
1530 return styleProperty<qreal>(QQSK::Property::Height);
1531}
1532
1533void QQStyleKitDelegateProperties::setHeight(qreal height)
1534{
1535 if (setStyleProperty(QQSK::Property::Height, height))
1536 handleStylePropertyChanged(&QQStyleKitDelegateProperties::heightChanged);
1537}
1538
1539qreal QQStyleKitDelegateProperties::minimumWidth() const
1540{
1541 return styleProperty<qreal>(QQSK::Property::MinimumWidth);
1542}
1543
1544void QQStyleKitDelegateProperties::setMinimumWidth(qreal width)
1545{
1546 if (setStyleProperty(QQSK::Property::MinimumWidth, width))
1547 handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumWidthChanged);
1548}
1549
1550qreal QQStyleKitDelegateProperties::minimumHeight() const
1551{
1552 return styleProperty<qreal>(QQSK::Property::MinimumHeight);
1553}
1554
1555void QQStyleKitDelegateProperties::setMinimumHeight(qreal height)
1556{
1557 if (setStyleProperty(QQSK::Property::MinimumHeight, height))
1558 handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumHeightChanged);
1559}
1560
1561bool QQStyleKitDelegateProperties::fillWidth() const
1562{
1563 return styleProperty<bool>(QQSK::Property::FillWidth);
1564}
1565
1566void QQStyleKitDelegateProperties::setFillWidth(bool fill)
1567{
1568 if (setStyleProperty(QQSK::Property::FillWidth, fill))
1569 handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillWidthChanged);
1570}
1571
1572bool QQStyleKitDelegateProperties::fillHeight() const
1573{
1574 return styleProperty<bool>(QQSK::Property::FillHeight);
1575}
1576
1577void QQStyleKitDelegateProperties::setFillHeight(bool fill)
1578{
1579 if (setStyleProperty(QQSK::Property::FillHeight, fill))
1580 handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillHeightChanged);
1581}
1582
1583qreal QQStyleKitDelegateProperties::margins() const
1584{
1585 return styleProperty<qreal>(QQSK::Property::Margins);
1586}
1587
1588void QQStyleKitDelegateProperties::setMargins(qreal margins)
1589{
1590 if (setStyleProperty(QQSK::Property::Margins, margins))
1591 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1592 &QQStyleKitDelegateProperties::marginsChanged,
1593 &QQStyleKitDelegateProperties::leftMarginChanged,
1594 &QQStyleKitDelegateProperties::rightMarginChanged,
1595 &QQStyleKitDelegateProperties::topMarginChanged,
1596 &QQStyleKitDelegateProperties::bottomMarginChanged);
1597}
1598
1599qreal QQStyleKitDelegateProperties::leftMargin() const
1600{
1601 return styleProperty<qreal>(QQSK::Property::LeftMargin, QQSK::Property::Margins);
1602}
1603
1604void QQStyleKitDelegateProperties::setLeftMargin(qreal margin)
1605{
1606 if (setStyleProperty(QQSK::Property::LeftMargin, margin))
1607 handleStylePropertyChanged(&QQStyleKitDelegateProperties::leftMarginChanged);
1608}
1609
1610qreal QQStyleKitDelegateProperties::rightMargin() const
1611{
1612 return styleProperty<qreal>(QQSK::Property::RightMargin, QQSK::Property::Margins);
1613}
1614
1615void QQStyleKitDelegateProperties::setRightMargin(qreal margin)
1616{
1617 if (setStyleProperty(QQSK::Property::RightMargin, margin))
1618 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rightMarginChanged);
1619}
1620
1621qreal QQStyleKitDelegateProperties::topMargin() const
1622{
1623 return styleProperty<qreal>(QQSK::Property::TopMargin, QQSK::Property::Margins);
1624}
1625
1626void QQStyleKitDelegateProperties::setTopMargin(qreal margin)
1627{
1628 if (setStyleProperty(QQSK::Property::TopMargin, margin))
1629 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topMarginChanged);
1630}
1631
1632qreal QQStyleKitDelegateProperties::bottomMargin() const
1633{
1634 return styleProperty<qreal>(QQSK::Property::BottomMargin, QQSK::Property::Margins);
1635}
1636
1637void QQStyleKitDelegateProperties::setBottomMargin(qreal margin)
1638{
1639 if (setStyleProperty(QQSK::Property::BottomMargin, margin))
1640 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomMarginChanged);
1641}
1642
1643Qt::Alignment QQStyleKitDelegateProperties::alignment() const
1644{
1645 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment, Qt::AlignLeft | Qt::AlignVCenter);
1646}
1647
1648void QQStyleKitDelegateProperties::setAlignment(Qt::Alignment alignment)
1649{
1650 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1651 handleStylePropertyChanged(&QQStyleKitDelegateProperties::alignmentChanged);
1652}
1653
1654qreal QQStyleKitDelegateProperties::opacity() const
1655{
1656 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1657}
1658
1659void QQStyleKitDelegateProperties::setOpacity(qreal opacity)
1660{
1661 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1662 handleStylePropertyChanged(&QQStyleKitDelegateProperties::opacityChanged);
1663}
1664
1665QColor QQStyleKitDelegateProperties::color() const
1666{
1667 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1668}
1669
1670void QQStyleKitDelegateProperties::setColor(const QColor &color)
1671{
1672 if (setStyleProperty(QQSK::Property::Color, color))
1673 handleStylePropertyChanged(&QQStyleKitDelegateProperties::colorChanged);
1674}
1675
1676bool QQStyleKitDelegateProperties::visible() const
1677{
1678 return styleProperty<bool>(QQSK::Property::Visible, true);
1679}
1680
1681void QQStyleKitDelegateProperties::setVisible(bool visible)
1682{
1683 if (setStyleProperty(QQSK::Property::Visible, visible))
1684 handleStylePropertyChanged(&QQStyleKitDelegateProperties::visibleChanged);
1685}
1686
1687bool QQStyleKitDelegateProperties::clip() const
1688{
1689 return styleProperty<bool>(QQSK::Property::Clip, false);
1690}
1691
1692void QQStyleKitDelegateProperties::setClip(bool clip)
1693{
1694 if (setStyleProperty(QQSK::Property::Clip, clip))
1695 handleStylePropertyChanged(&QQStyleKitDelegateProperties::clipChanged);
1696}
1697
1698QQuickGradient *QQStyleKitDelegateProperties::gradient() const
1699{
1700 return styleProperty<QQuickGradient *>(QQSK::Property::Gradient);
1701}
1702
1703void QQStyleKitDelegateProperties::setGradient(QQuickGradient *gradient)
1704{
1705 if (setStyleProperty(QQSK::Property::Gradient, gradient))
1706 handleStylePropertyChanged(&QQStyleKitDelegateProperties::gradientChanged);
1707}
1708
1709QObject *QQStyleKitDelegateProperties::data() const
1710{
1711 return styleProperty<QObject *>(QQSK::Property::Data);
1712}
1713
1714void QQStyleKitDelegateProperties::setData(QObject *data)
1715{
1716 if (setStyleProperty(QQSK::Property::Data, data))
1717 handleStylePropertyChanged(&QQStyleKitDelegateProperties::dataChanged);
1718}
1719
1720QQmlComponent *QQStyleKitDelegateProperties::delegate() const
1721{
1722 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1723}
1724
1725void QQStyleKitDelegateProperties::setDelegate(QQmlComponent *delegate)
1726{
1727 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1728 handleStylePropertyChanged(&QQStyleKitDelegateProperties::delegateChanged);
1729}
1730
1731QQStyleKitBorderProperties *QQStyleKitDelegateProperties::border() const
1732{
1733 return lazyCreateGroup(m_border, QQSK::PropertyGroup::Border);
1734}
1735
1736QQStyleKitShadowProperties *QQStyleKitDelegateProperties::shadow() const
1737{
1738 return lazyCreateGroup(m_shadow, QQSK::PropertyGroup::Shadow);
1739}
1740
1741QQStyleKitImageProperties *QQStyleKitDelegateProperties::image() const
1742{
1743 return lazyCreateGroup(m_image, QQSK::PropertyGroup::Image);
1744}
1745
1746// ************* QQStyleKitHandleProperties ****************
1747
1748QQStyleKitHandleProperties::QQStyleKitHandleProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1749 : QQStyleKitDelegateProperties(group, parent)
1750{
1751}
1752
1754 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1755{
1756 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1757 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1758 if (m_first)
1759 f(m_first);
1760 if (m_second)
1761 f(m_second);
1762}
1763
1764QQStyleKitDelegateProperties *QQStyleKitHandleProperties::first() const
1765{
1766 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1767}
1768
1769QQStyleKitDelegateProperties *QQStyleKitHandleProperties::second() const
1770{
1771 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
1772}
1773
1774// ************* QQStyleKitIndicatorProperties ****************
1775
1776QQStyleKitIndicatorProperties::QQStyleKitIndicatorProperties(
1777 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1778 : QQStyleKitDelegateProperties(group, parent)
1779{
1780}
1781
1782template <typename... CHANGED_SIGNALS>
1784 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1785{
1786 // Go through all instances of QQStyleKitIndicatorProperties
1787 const QQStyleKitControlProperties *cp = controlProperties();
1788 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->first());
1789 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->second());
1790}
1791
1793 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1794{
1795 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1796 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1797 if (m_foreground)
1798 f(m_foreground);
1799}
1800
1801QQStyleKitDelegateProperties *QQStyleKitIndicatorProperties::foreground() const
1802{
1803 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1804}
1805
1806// ************* QQStyleKitIndicatorWithSubTypes ****************
1807
1808QQStyleKitIndicatorWithSubTypes::QQStyleKitIndicatorWithSubTypes(
1809 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1810 : QQStyleKitDelegateProperties(group, parent)
1811{
1812}
1813
1814template <typename... CHANGED_SIGNALS>
1816 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1817{
1818 // Go through all instances of QQStyleKitIndicatorWithSubTypes
1819 const QQStyleKitControlProperties *cp = controlProperties();
1821}
1822
1824 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1825{
1826 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1827 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1828 if (m_foreground)
1829 f(m_foreground);
1830 if (m_first)
1831 f(m_first);
1832 if (m_second)
1833 f(m_second);
1834}
1835
1836QQStyleKitDelegateProperties *QQStyleKitIndicatorWithSubTypes::foreground() const
1837{
1838 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1839}
1840
1845
1850
1852{
1853 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1854}
1855
1857{
1858 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
1859}
1860
1861// ************* QQStyleKitTextProperties ****************
1862QQStyleKitTextProperties::QQStyleKitTextProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1863 : QQStyleKitPropertyGroup(group, parent)
1864{
1865}
1866
1867template <typename... CHANGED_SIGNALS>
1869 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1870{
1871 const QQStyleKitControlProperties *cp = controlProperties();
1873 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->first());
1874 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->second());
1875}
1876
1878 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1879{
1880 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1881 if (m_first)
1882 f(m_first);
1883 if (m_second)
1884 f(m_second);
1885}
1886
1888{
1889 return styleProperty<QColor>(QQSK::Property::Color);
1890}
1891
1892void QQStyleKitTextProperties::setColor(const QColor &color)
1893{
1894 if (setStyleProperty(QQSK::Property::Color, color))
1895 handleStylePropertyChanged(&QQStyleKitTextProperties::colorChanged);
1896}
1897
1899{
1900 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment);
1901}
1902
1903void QQStyleKitTextProperties::setAlignment(Qt::Alignment alignment)
1904{
1905 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1906 handleStylePropertyChanged(&QQStyleKitTextProperties::alignmentChanged);
1907}
1908
1910{
1911 return styleProperty<bool>(QQSK::Property::Bold, false);
1912}
1913
1915{
1916 if (setStyleProperty(QQSK::Property::Bold, bold))
1917 handleStylePropertyChanged(&QQStyleKitTextProperties::boldChanged);
1918}
1919
1921{
1922 return styleProperty<bool>(QQSK::Property::Italic, false);
1923}
1924
1926{
1927 if (setStyleProperty(QQSK::Property::Italic, italic))
1928 handleStylePropertyChanged(&QQStyleKitTextProperties::italicChanged);
1929}
1930
1932{
1933 return styleProperty<qreal>(QQSK::Property::PointSize, QFont().pointSize());
1934}
1935
1937{
1938 if (setStyleProperty(QQSK::Property::PointSize, pointSize))
1939 handleStylePropertyChanged(&QQStyleKitTextProperties::pointSizeChanged);
1940}
1941
1943{
1944 return styleProperty<qreal>(QQSK::Property::Padding);
1945}
1946
1957
1959{
1960 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
1961}
1962
1964{
1965 if (setStyleProperty(QQSK::Property::LeftPadding, padding))
1966 handleStylePropertyChanged(&QQStyleKitTextProperties::leftPaddingChanged);
1967}
1968
1970{
1971 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
1972}
1973
1975{
1976 if (setStyleProperty(QQSK::Property::RightPadding, padding))
1977 handleStylePropertyChanged(&QQStyleKitTextProperties::rightPaddingChanged);
1978}
1979
1981{
1982 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
1983}
1984
1986{
1987 if (setStyleProperty(QQSK::Property::TopPadding, padding))
1988 handleStylePropertyChanged(&QQStyleKitTextProperties::topPaddingChanged);
1989}
1990
1992{
1993 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
1994}
1995
1997{
1998 if (setStyleProperty(QQSK::Property::BottomPadding, padding))
1999 handleStylePropertyChanged(&QQStyleKitTextProperties::bottomPaddingChanged);
2000}
2001
2003{
2004 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
2005}
2006
2008{
2009 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
2010}
2011
2012// ************* QQStyleKitControlProperties ****************
2013
2014QQStyleKitControlProperties::QQStyleKitControlProperties(QQSK::PropertyGroup group, QObject *parent)
2015 : QQStyleKitPropertyGroup(group, parent)
2016{
2017 /* Calculate the free space storage ID space that can accommodate all unique style
2018 * properties that may be applied to a control. Since we'll prepend different states
2019 * and subtypes during the property propagation lookup phase later, we need to reserve
2020 * ID space for them both already now. More docs about the property space is written in
2021 * the implementation of QQStyleKitPropertyPath. */
2022 m_groupSpace.size = nestedGroupsStartSize;
2023 m_groupSpace.start = 0;
2024
2025 if (group == QQSK::PropertyGroup::GlobalFlag) {
2026 /* A property path may include pseudo-groups that offers a convenient API for
2027 * reading properties with specific options applied. The 'global' group is one such
2028 * pseudo-group. When it is prefixed to a property path, it indicates that the property
2029 * should be read directly from the style, bypassing any active transitions that might
2030 * otherwise affect its value.
2031 * Note: The global group should be ignored when computing a PropertyPathId, as it
2032 * only affect _where_ the property should be read from, not its ID. */
2033 m_pathFlags.setFlag(QQSK::PropertyPathFlag::Global);
2034 }
2035}
2036
2037QQStyleKitStyle *QQStyleKitControlProperties::style() const
2038{
2039 if (subclass() == QQSK::Subclass::QQStyleKitState) {
2040 /* A QQStyleKitControlState (and its subclasses) should always be a (grand)child of a
2041 * QQStyleKitStyle. And it belongs to that style, even it that style is not the
2042 * currently active application style. This is opposed to a QQStyleKitReader,
2043 * that normally belongs / communicates with the currently active style.
2044 * NOTE: a style can also be a fallback style for another style (which can be recursive,
2045 * meaning that a fallback style can also have its own fallback style, and so on). But
2046 * this function will return the nearest style, and not the root style */
2047 QObject *obj = parent();
2048 while (obj && !obj->metaObject()->inherits(&QQStyleKitStyle::staticMetaObject))
2049 obj = obj->parent();
2050 return obj ? static_cast<QQStyleKitStyle *>(obj) : nullptr;
2051 }
2052
2053 if (subclass() == QQSK::Subclass::QQStyleKitReader) {
2054 const auto *reader = static_cast<const QQStyleKitReader *>(this);
2055 if (reader->m_explicitStyle)
2056 return reader->m_explicitStyle;
2057 }
2058
2059 // For a QQStyleKitReader without an explicit style, we return the currently active style for now
2060 return QQStyleKitStyle::current();
2061}
2062
2063QQSK::Subclass QQStyleKitControlProperties::subclass() const
2064{
2065 /* QQStyleKitControlProperties is subclassed by several different classes in this
2066 * framework. As such, it's basically just an interface because it only declares the
2067 * different properties that can be read or written to in a QQStyleKitStyle, such as
2068 * hovered.background.color or pressed.indicator.foreground.color. It says nothing
2069 * about how those properties are stored, instead that is up to each individual
2070 * subclass to decide */
2071 if (metaObject()->inherits(&QQStyleKitReader::staticMetaObject))
2072 return QQSK::Subclass::QQStyleKitReader;
2073 if (metaObject()->inherits(&QQStyleKitControlState::staticMetaObject))
2074 return QQSK::Subclass::QQStyleKitState;
2075 Q_UNREACHABLE();
2076}
2077
2078QQStyleKitReader *QQStyleKitControlProperties::asQQStyleKitReader() const
2079{
2080 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitReader);
2081 return static_cast<QQStyleKitReader *>(const_cast<QQStyleKitControlProperties *>(this));
2082}
2083
2084QQStyleKitControlState *QQStyleKitControlProperties::asQQStyleKitState() const
2085{
2086 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitState);
2087 Q_ASSERT(metaObject()->inherits(&QQStyleKitControlState::staticMetaObject));
2088 return static_cast<QQStyleKitControlState *>(const_cast<QQStyleKitControlProperties *>(this));
2089}
2090
2091void QQStyleKitControlProperties::forEachUsedDelegate(
2092 std::function<void (QQStyleKitDelegateProperties *, QQSK::Delegate, const QString &)> f)
2093{
2094 // If adding more delegates here, remember to keep StyleAnimation.qml in sync
2095 if (m_background)
2096 f(m_background, QQSK::Delegate::Background, "background"_L1);
2097
2098 if (m_indicator) {
2099 f(m_indicator, QQSK::Delegate::Indicator, "indicator"_L1);
2100 if (m_indicator->m_foreground)
2101 f(m_indicator->m_foreground, QQSK::Delegate::IndicatorForeground, "indicator.foreground"_L1);
2102 if (m_indicator->m_first) {
2103 f(m_indicator->m_first, QQSK::Delegate::IndicatorFirst, "indicator.first"_L1);
2104 if (m_indicator->m_first->m_foreground)
2105 f(m_indicator->m_first->m_foreground, QQSK::Delegate::IndicatorFirstForeground, "indicator.first.foreground"_L1);
2106 }
2107 if (m_indicator->m_second) {
2108 f(m_indicator->m_second, QQSK::Delegate::IndicatorSecond, "indicator.second"_L1);
2109 if (m_indicator->m_second->m_foreground)
2110 f(m_indicator->m_second->m_foreground, QQSK::Delegate::IndicatorSecondForeground, "indicator.second.foreground"_L1);
2111 }
2112 }
2113
2114 if (m_handle) {
2115 f(m_handle, QQSK::Delegate::Handle, "handle"_L1);
2116 if (m_handle->m_first)
2117 f(m_handle->m_first, QQSK::Delegate::HandleFirst, "handle.first"_L1);
2118 if (m_handle->m_second)
2119 f(m_handle->m_second, QQSK::Delegate::HandleSecond, "handle.second"_L1);
2120 }
2121}
2122
2123void QQStyleKitControlProperties::emitChangedForAllStyleProperties(EmitFlags emitFlags)
2124{
2125 /* This brute-force function will emit update signals for _all_ style properties
2126 * in the QQStyleKitStyle API. Doing so is typically needed after a style-, or theme
2127 * change, as we don't know which properties are affected by such a big change. */
2128 emitChangedForAllStylePropertiesRecursive(emitFlags);
2129}
2130
2131template <typename... CHANGED_SIGNALS>
2132void QQStyleKitControlProperties::emitGlobally(
2133 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
2134{
2135 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
2136 if (reader->controlType() != controlType)
2137 continue;
2138 ((reader->*changedSignals)(), ...);
2139 }
2140}
2141
2142void QQStyleKitControlProperties::forEachExistingNestedGroup(
2143 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
2144{
2145 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
2146 if (m_background)
2147 f(m_background);
2148 if (m_handle)
2149 f(m_handle);
2150 if (m_indicator)
2151 f(m_indicator);
2152 if (m_text)
2153 f(m_text);
2154}
2155
2156qreal QQStyleKitControlProperties::spacing() const
2157{
2158 return styleProperty<qreal>(QQSK::Property::Spacing);
2159}
2160
2161void QQStyleKitControlProperties::setSpacing(qreal spacing)
2162{
2163 if (setStyleProperty(QQSK::Property::Spacing, spacing))
2164 handleStylePropertyChanged(&QQStyleKitControlProperties::spacingChanged);
2165}
2166
2167qreal QQStyleKitControlProperties::padding() const
2168{
2169 return styleProperty<qreal>(QQSK::Property::Padding);
2170}
2171
2172void QQStyleKitControlProperties::setPadding(qreal padding)
2173{
2174 if (setStyleProperty(QQSK::Property::Padding, padding))
2175 handleStylePropertiesChanged<QQStyleKitControlProperties>(
2176 &QQStyleKitControlProperties::paddingChanged,
2177 &QQStyleKitControlProperties::leftPaddingChanged,
2178 &QQStyleKitControlProperties::rightPaddingChanged,
2179 &QQStyleKitControlProperties::topPaddingChanged,
2180 &QQStyleKitControlProperties::bottomPaddingChanged);
2181}
2182
2183qreal QQStyleKitControlProperties::leftPadding() const
2184{
2185 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
2186}
2187
2188void QQStyleKitControlProperties::setLeftPadding(qreal leftPadding)
2189{
2190 if (setStyleProperty(QQSK::Property::LeftPadding, leftPadding))
2191 handleStylePropertyChanged(&QQStyleKitControlProperties::leftPaddingChanged);
2192}
2193
2194qreal QQStyleKitControlProperties::rightPadding() const
2195{
2196 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
2197}
2198
2199void QQStyleKitControlProperties::setRightPadding(qreal rightPadding)
2200{
2201 if (setStyleProperty(QQSK::Property::RightPadding, rightPadding))
2202 handleStylePropertyChanged(&QQStyleKitControlProperties::rightPaddingChanged);
2203}
2204
2205qreal QQStyleKitControlProperties::topPadding() const
2206{
2207 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
2208}
2209
2210void QQStyleKitControlProperties::setTopPadding(qreal topPadding)
2211{
2212 if (setStyleProperty(QQSK::Property::TopPadding, topPadding))
2213 handleStylePropertyChanged(&QQStyleKitControlProperties::topPaddingChanged);
2214}
2215
2216qreal QQStyleKitControlProperties::bottomPadding() const
2217{
2218 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
2219}
2220
2221void QQStyleKitControlProperties::setBottomPadding(qreal bottomPadding)
2222{
2223 if (setStyleProperty(QQSK::Property::BottomPadding, bottomPadding))
2224 handleStylePropertyChanged(&QQStyleKitControlProperties::bottomPaddingChanged);
2225}
2226
2227QQuickTransition *QQStyleKitControlProperties::transition() const
2228{
2229 return styleProperty<QQuickTransition *>(QQSK::Property::Transition);
2230}
2231
2232void QQStyleKitControlProperties::setTransition(QQuickTransition *transition)
2233{
2234 if (setStyleProperty(QQSK::Property::Transition, transition))
2235 handleStylePropertyChanged(&QQStyleKitControlProperties::transitionChanged);
2236}
2237
2238QQStyleKitTextProperties *QQStyleKitControlProperties::text() const
2239{
2240 return lazyCreateGroup(m_text, QQSK::PropertyGroup::Text);
2241}
2242
2243QQStyleKitDelegateProperties *QQStyleKitControlProperties::background() const
2244{
2245 return lazyCreateGroup(m_background, QQSK::PropertyGroup::Background);
2246}
2247
2248QQStyleKitHandleProperties *QQStyleKitControlProperties::handle() const
2249{
2250 return lazyCreateGroup(m_handle, QQSK::PropertyGroup::Handle);
2251}
2252
2253QQStyleKitIndicatorWithSubTypes *QQStyleKitControlProperties::indicator() const
2254{
2255 return lazyCreateGroup(m_indicator, QQSK::PropertyGroup::Indicator);
2256}
2257
2258QT_END_NAMESPACE
2259
2260#include "moc_qqstylekitcontrolproperties_p.cpp"
QObject * parent
Definition qobject.h:74
QQStyleKitDelegateProperties * first() const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
QQStyleKitDelegateProperties * second() const
QQStyleKitDelegateProperties * foreground() const
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
QQStyleKitDelegateProperties * foreground() const
QQStyleKitIndicatorProperties * down() const
QQStyleKitIndicatorProperties * up() const
QQStyleKitIndicatorProperties * second() const
QQStyleKitIndicatorProperties * first() const
void emitChangedForAllStylePropertiesRecursive(EmitFlags emitFlags)
T * lazyCreateGroup(T *const &ptr, QQSK::PropertyGroup group) const
void handleStylePropertyChanged(void(SUBCLASS::*changedSignal)())
virtual void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const
void handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
QQStyleKitControlProperties * controlProperties() const
void setBottomPadding(qreal bottomPadding)
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
QQStyleKitTextProperties * first() const
QQStyleKitTextProperties * second() const
Combined button and popup list for selecting options.
#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH)