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