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
3
9
11
12// ************* ControlStyleProperties ****************
13
14/*!
15 \qmltype ControlStyleProperties
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 {AbstractStylableControls::}{checkBox}, the indicator is the
79 frame, and its \l {IndicatorStyle::}{foreground} is the check mark.
80 For a \l {AbstractStylableControls::}{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 Also note that \l ColorAnimation has a special feature that
157 animates \e all color properties that changed during a
158 state change if \l {PropertyAnimation::}{property} and
159 \l {PropertyAnimation::}{properties} are left unset.
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.
278
279 The delegate needs to define the following required properties:
280 \qml
281 required property DelegateStyle delegateStyle
282 required property QtObject control
283 \endqml
284
285 \c delegateStyle points to the DelegateStyle that describes how the
286 delegate should be styled. \c control points to the
287 \l {Qt Quick Controls}{Qt Quick Control} that owns the delegate. The latter
288 can be used to resolve additional information about the control not
289 available from the style.
290
291 If you know the specific type of the owning control, you can use it
292 instead of \l QtObject for the \c control property. For example, since
293 a handle delegate in the snippet below is always used inside a Slider, the
294 type can be set to \l {Qt Quick Templates 2 QML Types}{T.Slider}:
295
296 \snippet DelegateStyle_delegates.qml delegate
297
298 \note If a DelegateStyle has a \l {shadow}{drop shadow} defined, it will be
299 drawn separately by a \l {ShadowStyle::delegate}{shadow delegate.}
300
301 \sa data, StyledItem
302*/
303
304/*!
305 \qmlproperty Gradient DelegateStyle::gradient
306
307 The gradient of this delegate. The default value is \c null (no gradient).
308
309 Unlike a Quick \l [QtQuick]{Rectangle}, where a gradient replaces
310 the color, StyleKit draws the \l gradient on top of the color. This
311 means you can use a semi-transparent gradient as an overlay (for
312 example, a subtle shading effect) while the color shows through
313 underneath.
314
315 \snippet ControlStateStyle_properties.qml color and gradient
316
317 \sa color
318*/
319
320/*!
321 \qmlproperty ImageStyle DelegateStyle::image
322
323 Grouped property for placing an image inside this delegate.
324
325 \sa ImageStyle
326*/
327
328/*!
329 \qmlproperty real DelegateStyle::implicitHeight
330
331 The implicit height of this delegate.
332*/
333
334/*!
335 \qmlproperty real DelegateStyle::implicitWidth
336
337 The implicit width of this delegate. Set this to \l {Style::Stretch}{Style.Stretch}
338 to make the delegate fill the available width of the control.
339*/
340
341/*!
342 \qmlproperty real DelegateStyle::leftMargin
343
344 The left margin of this delegate. If not set, falls back to
345 \l margins.
346
347 \sa margins, rightMargin, topMargin, bottomMargin
348*/
349
350/*!
351 \qmlproperty real DelegateStyle::margins
352
353 The uniform margin around this delegate. Setting this provides a
354 default value for \l leftMargin, \l rightMargin, \l topMargin,
355 and \l bottomMargin. Each side can be overridden individually.
356
357 \sa leftMargin, rightMargin, topMargin, bottomMargin
358*/
359
360/*!
361 \qmlproperty real DelegateStyle::minimumWidth
362
363 The minimum width of this delegate. The delegate will not be sized
364 smaller than this value.
365*/
366
367/*!
368 \qmlproperty real DelegateStyle::opacity
369
370 The opacity of this delegate, from \c 0.0 (fully transparent) to
371 \c 1.0 (fully opaque). The default value is \c 1.0.
372
373 \sa visible, color
374*/
375
376/*!
377 \qmlproperty real DelegateStyle::radius
378
379 The corner radius applied to all four corners of this delegate.
380 Individual corners can be overridden with \l topLeftRadius,
381 \l topRightRadius, \l bottomLeftRadius, and \l bottomRightRadius.
382
383 \sa topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius
384*/
385
386/*!
387 \qmlproperty real DelegateStyle::rightMargin
388
389 The right margin of this delegate. If not set, falls back to
390 \l margins.
391
392 \sa margins, leftMargin, topMargin, bottomMargin
393*/
394
395/*!
396 \qmlproperty real DelegateStyle::rotation
397
398 The rotation of this delegate, in degrees.
399*/
400
401/*!
402 \qmlproperty real DelegateStyle::scale
403
404 The scale factor of this delegate. The default value is \c 1.0.
405*/
406
407/*!
408 \qmlproperty ShadowStyle DelegateStyle::shadow
409
410 Grouped property for styling a drop shadow behind this delegate.
411
412 \sa ShadowStyle
413*/
414
415/*!
416 \qmlproperty real DelegateStyle::topLeftRadius
417
418 The top-left corner radius. If not set, falls back to \l radius.
419
420 \sa radius, topRightRadius, bottomLeftRadius, bottomRightRadius
421*/
422
423/*!
424 \qmlproperty real DelegateStyle::topMargin
425
426 The top margin of this delegate. If not set, falls back to
427 \l margins.
428
429 \sa margins, bottomMargin, leftMargin, rightMargin
430*/
431
432/*!
433 \qmlproperty real DelegateStyle::topRightRadius
434
435 The top-right corner radius. If not set, falls back to \l radius.
436
437 \sa radius, topLeftRadius, bottomLeftRadius, bottomRightRadius
438*/
439
440/*!
441 \qmlproperty bool DelegateStyle::visible
442
443 Whether this delegate is visible. The default value is \c true.
444
445 \note Although the default value is \c true, the
446 \l {Style::fallbackStyle}{fallback style} (which overrides many of the default
447 values) sets \c {background.visible} to \c false for controls that typically
448 should not draw a background, such as \l [QtQuickControls]{CheckBox},
449 \l [QtQuickControls]{RadioButton}, and \l [QtQuickControls]{Slider}.
450
451 \sa opacity
452*/
453
454// ************* ImageStyle ****************
455
456/*!
457 \qmltype ImageStyle
458 \inqmlmodule Qt.labs.StyleKit
459 \brief Defines the image style for a delegate.
460
461 ImageStyle provides properties for placing an image inside a
462 \l DelegateStyle. It is available as the
463 \l {DelegateStyle::image}{image} grouped property on any delegate.
464
465 \labs
466
467 \sa DelegateStyle, ControlStyle, ControlStateStyle,
468 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
469*/
470
471/*!
472 \qmlproperty color ImageStyle::color
473
474 A color overlay applied to the image. This is typically used to tint
475 monochrome icons to match the style's color scheme.
476*/
477
478/*!
479 \qmlproperty enumeration ImageStyle::fillMode
480
481 How the image should be scaled or tiled within the delegate. The
482 value is one of the \l [QtQuick]{Image::fillMode}{Image.fillMode}
483 enum values.
484*/
485
486/*!
487 \qmlproperty url ImageStyle::source
488
489 The URL of the image to display inside the delegate.
490*/
491
492// ************* BorderStyle ****************
493
494/*!
495 \qmltype BorderStyle
496 \inqmlmodule Qt.labs.StyleKit
497 \brief Defines the border style for a delegate.
498
499 BorderStyle provides properties for the border drawn around a
500 \l DelegateStyle. It is available as the
501 \l {DelegateStyle::border}{border} grouped property on any delegate.
502
503 \labs
504
505 \sa DelegateStyle, ControlStyle, ControlStateStyle,
506 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
507*/
508
509/*!
510 \qmlproperty color BorderStyle::color
511
512 The color of the border. The default value is \c transparent.
513*/
514
515/*!
516 \qmlproperty real BorderStyle::width
517
518 The width of the border in pixels.
519*/
520
521// ************* ShadowStyle ****************
522
523/*!
524 \qmltype ShadowStyle
525 \inqmlmodule Qt.labs.StyleKit
526 \brief Defines the drop shadow style for a delegate.
527
528 ShadowStyle provides properties for rendering a drop shadow behind
529 a \l DelegateStyle. It is available as the
530 \l {DelegateStyle::shadow}{shadow} grouped property on any delegate.
531
532 \snippet DelegateStyle_shadow.qml drop shadow
533
534 By adjusting scale and color, shadows can also be used to create
535 glow effects. The following snippet adds a diffuse white glow to
536 the handle of a \l [QtQuickControls]{Switch} that intensifies
537 when checked:
538
539 \snippet DelegateStyle_shadow.qml glow
540
541 \labs
542
543 \sa DelegateStyle, ControlStyle, ControlStateStyle,
544 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
545*/
546
547/*!
548 \qmlproperty real ShadowStyle::blur
549
550 The blur of the shadow. A value of \c 0.0 produces a sharp shadow, while
551 larger values produce a softer, more diffuse shadow.
552 The default value is \c 10.0.
553*/
554
555/*!
556 \qmlproperty color ShadowStyle::color
557
558 The color of the shadow. The default value is \c transparent, which
559 means that no shadow will be drawn by default.
560
561 \sa visible, opacity
562*/
563
564/*!
565 \qmlproperty Component ShadowStyle::delegate
566
567 A custom QML \l [QML]{Component} that replaces the default shadow
568 rendering. When set, StyleKit instantiates this component instead
569 of drawing the default shadow.
570*/
571
572/*!
573 \qmlproperty real ShadowStyle::horizontalOffset
574
575 The horizontal offset of the shadow from the delegate, in pixels.
576*/
577
578/*!
579 \qmlproperty real ShadowStyle::opacity
580
581 The opacity of the shadow, from \c 0.0 (fully transparent) to
582 \c 1.0 (fully opaque). The default value is \c 1.0.
583
584 \sa visible, color
585*/
586
587/*!
588 \qmlproperty real ShadowStyle::scale
589
590 The scale factor of the shadow relative to the delegate.
591 The default value is \c 1.0.
592*/
593
594/*!
595 \qmlproperty real ShadowStyle::verticalOffset
596
597 The vertical offset of the shadow from the delegate, in pixels.
598*/
599
600/*!
601 \qmlproperty bool ShadowStyle::visible
602
603 Whether the shadow is visible. The default value is \c true.
604
605 However, since the default shadow \l color is \c transparent,
606 the shadow will not be visible unless a different color is set.
607
608 \sa opacity
609*/
610
611// ************* HandleStyle ****************
612
613/*!
614 \qmltype HandleStyle
615 \inqmlmodule Qt.labs.StyleKit
616 \inherits DelegateStyle
617 \brief Defines the handle style for controls such as \l [QtQuickControls]{Switch},
618 \l [QtQuickControls]{Slider} and \l [QtQuickControls]{RangeSlider}.
619
620 HandleStyle extends \l DelegateStyle with properties that are specific to
621 styling a handle.
622
623 Some controls have more than one handle. For example,
624 \l [QtQuickControls]{RangeSlider} has both a \l [QtQuickControls]{RangeSlider::}{first} and a \l [QtQuickControls]{RangeSlider::}{second} handle.
625 These can be styled independently using the \l first and \l second
626 sub-handles, \c {slider.handle.first} and \c {slider.handle.second}.
627 Properties not set on a sub-handle fall back to the handle itself.
628
629 \labs
630
631 \sa DelegateStyle, ControlStyle, ControlStateStyle,
632 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
633*/
634
635/*!
636 \qmlproperty DelegateStyle HandleStyle::first
637
638 Grouped property for styling the first handle of for example a
639 \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
640 the HandleStyle itself.
641*/
642
643/*!
644 \qmlproperty DelegateStyle HandleStyle::second
645
646 Grouped property for styling the second handle of for example a
647 \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
648 the HandleStyle itself.
649*/
650
651// ************* SubIndicatorStyle ****************
652
653/*!
654 \qmltype SubIndicatorStyle
655 \inqmlmodule Qt.labs.StyleKit
656 \inherits DelegateStyle
657 \brief Defines the style for a sub-indicator delegate.
658
659 SubIndicatorStyle extends \l DelegateStyle with a \l foreground
660 property. It is used for styling sub-indicator delegates such as
661 \l {IndicatorStyle::up}{indicator.up} and
662 \l {IndicatorStyle::down}{indicator.down} in controls
663 like \l [QtQuickControls]{SpinBox}.
664 It is equivalent to \l IndicatorStyle, but does not itself
665 contain sub-indicators.
666
667 \labs
668
669 \sa IndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
670 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
671*/
672
673/*!
674 \qmlproperty DelegateStyle SubIndicatorStyle::foreground
675
676 Grouped property for styling the foreground element of this
677 indicator. The foreground typically represents a checkmark, icon
678 or arrow rendered inside the indicator.
679*/
680
681// ************* IndicatorStyle ****************
682
683/*!
684 \qmltype IndicatorStyle
685 \inqmlmodule Qt.labs.StyleKit
686 \inherits DelegateStyle
687 \brief Defines the style for a control's indicator.
688
689 IndicatorStyle extends \l DelegateStyle with properties that are specific to
690 styling an indicator.
691
692 The IndicatorStyle itself describes the indicator background, while the
693 \l foreground describes the content drawn inside it. For example,
694 \c {checkBox.indicator} styles the check box frame and
695 \c {checkBox.indicator.foreground} styles the check mark. For
696 \l {AbstractStylableControls::}{switchControl},
697 \l {AbstractStylableControls::}{slider} and
698 \l {AbstractStylableControls::}{progressBar}, the indicator styles
699 the groove and the foreground styles the fill.
700
701 \snippet DelegateStyle_indicator.qml checkBox
702
703 Some controls have more than one indicator. For example,
704 \l [QtQuickControls]{SpinBox} has both an increment and a decrement
705 button. These can be styled independently using the \l up and \l down
706 sub-indicators, \c {spinBox.indicator.up} and
707 \c {spinBox.indicator.down}. Properties not set on a sub-indicator
708 fall back to the indicator itself.
709
710 \snippet DelegateStyle_indicator.qml up and down indicator
711
712 \labs
713
714 \sa SubIndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
715 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
716*/
717
718/*!
719 \qmlproperty SubIndicatorStyle IndicatorStyle::down
720
721 Grouped property for styling the down (decrement) sub-indicator.
722 This is used by controls such as \l [QtQuickControls]{SpinBox}.
723 Unset properties fall back to the indicator itself.
724
725 \sa up
726*/
727
728/*!
729 \qmlproperty DelegateStyle IndicatorStyle::foreground
730
731 Grouped property for styling the foreground element of this
732 indicator. For example, \c {checkBox.indicator} describes
733 the check box frame, while \c {checkBox.indicator.foreground} is the check mark.
734
735 For controls like \l {AbstractStylableControls::}{slider},
736 \l {AbstractStylableControls::}{progressBar}, and
737 \l {AbstractStylableControls::}{switchControl}, the \c {indicator.foreground}
738 represents the progress track or fill within the groove, while the \c indicator
739 itself represents the groove.
740*/
741
742/*!
743 \qmlproperty SubIndicatorStyle IndicatorStyle::up
744
745 Grouped property for styling the up (increment) sub-indicator.
746 This is used by controls such as \l [QtQuickControls]{SpinBox}.
747 Unset properties fall back to the indicator itself.
748
749 \sa down
750*/
751
752// ************* TextStyle ****************
753
754/*!
755 \qmltype TextStyle
756 \inqmlmodule Qt.labs.StyleKit
757 \brief Defines the text style for a control's label.
758
759 TextStyle provides properties for controlling the appearance of
760 text labels within a control, such as
761 \l color, \l alignment and \l padding,
762 and certain font-related properties such as
763 \l {TextStyle::}{bold},
764 \l {TextStyle::}{italic}, and
765 \l {TextStyle::pointSize}{font size}.
766
767 It is available as the \l {ControlStyleProperties::text}{text}
768 grouped property on every \l ControlStateStyle.
769
770 \labs
771
772 \sa DelegateStyle, ControlStyle, ControlStateStyle,
773 {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
774*/
775
776/*!
777 \qmlproperty Qt::Alignment TextStyle::alignment
778
779 The alignment of the text within its available area.
780*/
781
782/*!
783 \qmlproperty bool TextStyle::bold
784
785 Whether the text should be rendered in bold. The default value
786 is \c false.
787
788 \sa italic
789*/
790
791/*!
792 \qmlproperty real TextStyle::bottomPadding
793
794 The bottom padding around the text. If not set, falls back to
795 \l padding.
796
797 \sa padding, topPadding, leftPadding, rightPadding
798*/
799
800/*!
801 \qmlproperty color TextStyle::color
802
803 The color of the text.
804*/
805
806/*!
807 \qmlproperty bool TextStyle::italic
808
809 Whether the text should be rendered in italic. The default value
810 is \c false.
811
812 \sa bold
813*/
814
815/*!
816 \qmlproperty real TextStyle::leftPadding
817
818 The left padding around the text. If not set, falls back to
819 \l padding.
820
821 \sa padding, rightPadding, topPadding, bottomPadding
822*/
823
824/*!
825 \qmlproperty real TextStyle::padding
826
827 The uniform padding around the text. Setting this provides a
828 default value for \l leftPadding, \l rightPadding, \l topPadding,
829 and \l bottomPadding. Each side can be overridden individually.
830
831 \sa leftPadding, rightPadding, topPadding, bottomPadding
832*/
833
834/*!
835 \qmlproperty real TextStyle::pointSize
836
837 The point size of the text font.
838*/
839
840/*!
841 \qmlproperty real TextStyle::rightPadding
842
843 The right padding around the text. If not set, falls back to
844 \l padding.
845
846 \sa padding, leftPadding, topPadding, bottomPadding
847*/
848
849/*!
850 \qmlproperty real TextStyle::topPadding
851
852 The top padding around the text. If not set, falls back to
853 \l padding.
854
855 \sa padding, bottomPadding, leftPadding, rightPadding
856*/
857
858// ************* QQStyleKitPropertyGroup ****************
859
860QHash<PropertyPathId_t, QString> QQStyleKitPropertyGroup::s_pathStrings;
861
862QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent)
863 : QObject(parent)
864{
865}
866
867PropertyPathId QQStyleKitPropertyGroup::propertyPathId(QQSK::Property property, PropertyPathId::Flag flag) const
868{
869 if (flag == PropertyPathId::Flag::IncludeSubtype) {
870 if (m_pathFlags.testFlag(QQSK::PropertyPathFlag::DelegateSubtype1))
871 return PropertyPathId(property, m_groupSpace.start, QQSK::PropertyGroup::DelegateSubtype1);
872 else if (m_pathFlags.testFlag(QQSK::PropertyPathFlag::DelegateSubtype2))
873 return PropertyPathId(property, m_groupSpace.start, QQSK::PropertyGroup::DelegateSubtype2);
874 }
875 return PropertyPathId(property, m_groupSpace.start, QQSK::PropertyGroup::DelegateSubtype0);
876}
877
879{
880 /* Start from the root of the path and build the path down to this group. This
881 * mirrors how the groups were originally created and avoids rounding issues
882 * that can arise if attempting to reconstruct the path “backwards”.
883 * Note: For each group, m_groupSpace.start is stored relative to the root,
884 * while m_groupSpace.size is relative to the parent group. However, when
885 * calculating the group index, the group-space start must be computed
886 * relative to the parent group.
887 * We cache the requested paths, as the same paths are typically requested
888 * repeatedly. The number of possible paths (and thus leaf groups) is well below
889 * 100, and in practice the cache usually ends up with fewer than 20 entries. */
890 if (s_pathStrings.contains(m_groupSpace.start))
891 return s_pathStrings[m_groupSpace.start];
892
893 constexpr PropertyPathId_t rootGroupsSize = nestedGroupsStartSize / nestedGroupCount;
894 const auto metaEnum = QMetaEnum::fromType<QQSK::PropertyGroup>();
895
896 PropertyPathId_t nestedGroupStart = m_groupSpace.start;
897 PropertyPathId_t nestedGroupSize = rootGroupsSize;
898 PropertyPathId_t nestedGroupIndex = nestedGroupStart / nestedGroupSize;
899 auto groupType = QQSK::PropertyGroup(nestedGroupIndex);
900 if (groupType == QQSK::PropertyGroup::Control)
901 return {};
902
903 QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType)));
904 groupName[0] = groupName[0].toLower();
905 QString pathString = groupName;
906
907 while (true) {
908 nestedGroupStart -= nestedGroupIndex * nestedGroupSize;
909 nestedGroupSize /= nestedGroupCount;
910 nestedGroupIndex = nestedGroupStart / nestedGroupSize;
911 groupType = QQSK::PropertyGroup(nestedGroupIndex);
912 if (groupType == QQSK::PropertyGroup::Control)
913 break;
914
915 QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType)));
916 groupName[0] = groupName[0].toLower();
917 pathString += '.'_L1 + groupName;
918 }
919
920 s_pathStrings.insert(m_groupSpace.start, pathString);
921 return pathString;
922}
923
924QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const
925{
927 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(this));
928 auto *self = const_cast<QQStyleKitPropertyGroup *>(this);
929 return static_cast<QQStyleKitControlProperties *>(self);
930 }
931 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(parent()));
932 return static_cast<QQStyleKitControlProperties *>(parent());
933}
934
935template<typename T>
936T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup group) const
937{
938 T *nestedGroup = QQSK::lazyCreate(ptr, controlProperties(), group);
939
940 // Nested groups inherit path flags from their parents
941 nestedGroup->m_pathFlags = m_pathFlags;
942
943 if (group == QQSK::PropertyGroup::DelegateSubtype1) {
944 /* Subtypes, like states, are not part of a property's path ID—they belong to the
945 * storage ID instead. They are therefore prefixed later, during lookup, when
946 * propagation determines which value to read.
947 * For now, we simply record which subtype this group (and any nested groups) is
948 * associated with. The subtype will then be taken into account later when reading
949 * properties from the group. Setting aside space for the sub types was already
950 * taken care of during the construction of the root QQStyleKitControlProperties. */
951 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype1);
952 nestedGroup->m_groupSpace = m_groupSpace;
953 } else if (group == QQSK::PropertyGroup::DelegateSubtype2) {
954 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype2);
955 nestedGroup->m_groupSpace = m_groupSpace;
956 } else {
957 /* Calculate the available property ID space for the nested group. This is done by
958 * dividing the available space inside _this_ group on the number of potential groups
959 * that _this_ group can potentially contain. */
960 const PropertyPathId_t nestedGroupIndex = PropertyPathId_t(group);
961 const PropertyPathId_t nestedGroupSize = m_groupSpace.size / nestedGroupCount;
962 nestedGroup->m_groupSpace.size = nestedGroupSize;
963 nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize);
964 /* Ensure that we haven’t exhausted the available PropertyPathId space. There must be
965 * enough room remaining to assign IDs for all properties defined in QQSK::Property.
966 * If this assertion triggers, consider switching to a wider PropertyPathId_t type or
967 * optimizing how the space is allocated. For example, certain nested paths (such as
968 * control.handle.indicator) can never occur, yet we currently reserve INNER_GROUP_COUNT
969 * for every nesting level, which is wasteful. */
970 Q_ASSERT(nestedGroupSize >= PropertyPathId_t(QQSK::Property::COUNT));
971 }
972 return nestedGroup;
973}
974
975/* This macro will check if the caller has the same group path as \a GROUP_PATH.
976 * This is needed since a QQSK::Property (e.g Color) can sometimes be a
977 * property in several different subclasses of QQStyleKitPropertyGroup.
978 * For example, both control.background.color and control.indicator.color has a
979 * color property. But the group path differs, so they are in reality two completely
980 * different properties. And in that case, when the former changes value, we want to
981 * emit changes globally only to that property, and not the latter.
982 * The caller of this macro will therefore need to go through all the usages of its
983 * subclass in the API, to figure out which group itself is an instance of. For the
984 * one that is a match, the macro will go through all readers and emit the same
985 * signal for them. */
986#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH) if
987 (this == CONTROL_PROPERTIES -> GROUP_PATH ) {
988 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
989 const auto baseTypes = QQStyleKitPropertyResolver::baseTypesForType(reader->controlType());
990 if (reader->controlType() != controlType && !baseTypes.contains(controlType))
991 continue;
992 reader->clearLocalStorage();
993 ((reader-> GROUP_PATH ->*changedSignals)(), ...);
994 }
995 return; \
996}
997
998template<typename SUBCLASS>
999void QQStyleKitPropertyGroup::handleStylePropertyChanged(void (SUBCLASS::*changedSignal)()) {
1000 handleStylePropertiesChanged<SUBCLASS>(changedSignal);
1001}
1002
1003template <typename SUBCLASS, typename... CHANGED_SIGNALS>
1004void QQStyleKitPropertyGroup::handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
1005{
1006 /* This function will check which subclass of QQStyleKitProperties this
1007 * group is (nested) inside. Based on that, it will decide if the signals
1008 * should be emitted locally or not, and if the changed properties affects
1009 * all existing QQStyleKitReaders, and therefore will need to be
1010 * emitted 'globally'. Note that it only makes sense to call this function
1011 * for changed properties that are available from a QQStyleKitReader.
1012 * Properities only available from e.g QQStyleKitControl (such as
1013 * variations), are anyway not readable from a QQStyleKitReader. */
1014 static_assert(std::is_base_of<QQStyleKitPropertyGroup, SUBCLASS>::value,
1015 "SUBCLASS must inherit QQStyleKitPropertyGroup");
1016
1017 auto *group = static_cast<SUBCLASS *>(this);
1018 const QQSK::Subclass objectWrittenTo = controlProperties()->subclass();
1019
1020 if (objectWrittenTo == QQSK::Subclass::QQStyleKitState) {
1021 ((group->*changedSignals)(), ...);
1022
1023 if (shouldEmitGlobally()) {
1024 const QQStyleKitControl *control = controlProperties()->asQQStyleKitState()->control();
1025 const QQStyleKitExtendableControlType type = control->controlType();
1026 group->emitGlobally(type, changedSignals...);
1027 }
1028 return;
1029 }
1030
1031 if (objectWrittenTo == QQSK::Subclass::QQStyleKitReader) {
1032 /* Unless the StyleReader has told us not to emit any signals (because it's only
1033 * syncing it's own local storage with old values before starting a transition), we
1034 * emit the signal like normal. This will cause the control to repaint (perhaps
1035 * using a transition). */
1036 if (shouldEmitLocally())
1037 ((group->*changedSignals)(), ...);
1038 return;
1039 }
1040
1041 Q_UNREACHABLE();
1042}
1043
1045{
1046 /* This function will emit changed signals for all style properties in the
1047 * StyleKit API (for a single QQStyleKitReader), which is needed after
1048 * doing a style-, or theme change. */
1049 const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
1050 const QMetaObject* meta = metaObject();
1051 for (int i = startIndex; i < meta->propertyCount(); ++i) {
1052 const QMetaProperty prop = meta->property(i);
1053 const QMetaObject* propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
1054 if (propMetaObject) {
1055 if (propMetaObject->inherits(&QQStyleKitDelegateProperties::staticMetaObject)) {
1056 /* Skip recursing into QQStyleKitDelegateProperties, because those are lazy
1057 * created when read, and reading them from here would accidentally
1058 * create them. */
1059 continue;
1060 }
1061 if (propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject)) {
1062 // The property is of type QQStyleKitPropertyGroup, so recurse into it
1063 QObject *childObj = qvariant_cast<QObject *>(property(prop.name()));
1064 if (auto *child = qobject_cast<QQStyleKitPropertyGroup *>(childObj))
1065 child->emitChangedForAllStylePropertiesRecursive(emitFlags);
1066 continue;
1067 }
1068 }
1069
1070 if (!emitFlags.testFlag(EmitFlag::AllProperties)) {
1071 // Only emit for color properties when the Colors flag is set
1072 if (emitFlags.testFlag(EmitFlag::Colors)) {
1073 if (prop.metaType() != QMetaType::fromType<QColor>())
1074 continue;
1075 }
1076 }
1077
1078 // Emit the changed signal for the property
1079 Q_ASSERT(prop.hasNotifySignal());
1080 QMetaMethod notify = prop.notifySignal();
1081 notify.invoke(this, Qt::DirectConnection);
1082 }
1083}
1084
1085bool QQStyleKitPropertyGroup::shouldEmitLocally()
1086{
1087 return !controlProperties()->asQQStyleKitReader()->dontEmitChangedSignals();
1088}
1089
1090bool QQStyleKitPropertyGroup::shouldEmitGlobally()
1091{
1092 QQStyleKitStyle *parentStyle = controlProperties()->style();
1093 if (!parentStyle)
1094 return false;
1095
1096 if (parentStyle->loaded() && !parentStyle->m_isUpdatingPalette) {
1097 /* When a property has changed in the 'global' QQStyleKitStyle itself, it can
1098 * potentially affect all control instances. We therefore need to go through all
1099 * QQStyleKitReaders and inform that their own local property that matches the
1100 * 'global' property needs to be re-read. We emit the signals directly, omitting any
1101 * applied transitions in the QQStyleKitReaders, to optimize for speed. The exception
1102 * is if we're just updating the palette in the Style to match the palette in the current
1103 * control / QQStyleKitReader. Such a change will only affect a single control. */
1104 return parentStyle == QQStyleKitStyle::current();
1105 }
1106 return false;
1107}
1108
1109// ************* QQStyleKitImageProperties ****************
1110
1111QQStyleKitImageProperties::QQStyleKitImageProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1112 : QQStyleKitPropertyGroup(group, parent)
1113{
1114}
1115
1116template <typename... CHANGED_SIGNALS>
1117void QQStyleKitImageProperties::emitGlobally(
1118 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1119{
1120 // Go through all instances of QQStyleKitImageProperties
1121 const QQStyleKitControlProperties *cp = controlProperties();
1122 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->image());
1123 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->image());
1124 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->image());
1125 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->image());
1126}
1127
1128QUrl QQStyleKitImageProperties::source() const
1129{
1130 return styleProperty<QUrl>(QQSK::Property::Source);
1131}
1132
1133void QQStyleKitImageProperties::setSource(const QUrl &source)
1134{
1135 if (setStyleProperty(QQSK::Property::Source, source))
1136 handleStylePropertyChanged(&QQStyleKitImageProperties::sourceChanged);
1137}
1138
1139QColor QQStyleKitImageProperties::color() const
1140{
1141 return styleProperty<QColor>(QQSK::Property::Color);
1142}
1143
1144void QQStyleKitImageProperties::setColor(const QColor &color)
1145{
1146 if (setStyleProperty(QQSK::Property::Color, color))
1147 handleStylePropertyChanged(&QQStyleKitImageProperties::colorChanged);
1148}
1149
1150QQuickImage::FillMode QQStyleKitImageProperties::fillMode() const
1151{
1152 return styleProperty<QQuickImage::FillMode>(QQSK::Property::FillMode);
1153}
1154
1155void QQStyleKitImageProperties::setFillMode(QQuickImage::FillMode fillMode)
1156{
1157 if (setStyleProperty(QQSK::Property::FillMode, fillMode))
1158 handleStylePropertyChanged(&QQStyleKitImageProperties::fillModeChanged);
1159}
1160
1161// ************* QQStyleKitBorderProperties ****************
1162
1163QQStyleKitBorderProperties::QQStyleKitBorderProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1164 : QQStyleKitPropertyGroup(group, parent)
1165{
1166}
1167
1168template <typename... CHANGED_SIGNALS>
1169void QQStyleKitBorderProperties::emitGlobally(
1170 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1171{
1172 // Go through all instances of QQStyleKitBorderProperties
1173 const QQStyleKitControlProperties *cp = controlProperties();
1174 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->border());
1175 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->border());
1176 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->border());
1177 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->border());
1178}
1179
1180qreal QQStyleKitBorderProperties::width() const
1181{
1182 return styleProperty<qreal>(QQSK::Property::Width);
1183}
1184
1185void QQStyleKitBorderProperties::setWidth(qreal width)
1186{
1187 if (setStyleProperty(QQSK::Property::Width, width))
1188 handleStylePropertyChanged(&QQStyleKitBorderProperties::widthChanged);
1189}
1190
1191QColor QQStyleKitBorderProperties::color() const
1192{
1193 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1194}
1195
1196void QQStyleKitBorderProperties::setColor(const QColor &color)
1197{
1198 if (setStyleProperty(QQSK::Property::Color, color))
1199 handleStylePropertyChanged(&QQStyleKitBorderProperties::colorChanged);
1200}
1201
1202// ************* QQStyleKitShadowProperties ****************
1203
1204QQStyleKitShadowProperties::QQStyleKitShadowProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1205 : QQStyleKitPropertyGroup(group, parent)
1206{
1207}
1208
1209template <typename... CHANGED_SIGNALS>
1210void QQStyleKitShadowProperties::emitGlobally(
1211 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1212{
1213 // Go through all instances of QQStyleKitShadowProperties
1214 const QQStyleKitControlProperties *cp = controlProperties();
1215 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->shadow());
1216 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->shadow());
1217 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->shadow());
1218 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->shadow());
1219}
1220
1221QColor QQStyleKitShadowProperties::color() const
1222{
1223 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1224}
1225
1226void QQStyleKitShadowProperties::setColor(QColor color)
1227{
1228 if (setStyleProperty(QQSK::Property::Color, color))
1229 handleStylePropertyChanged(&QQStyleKitShadowProperties::colorChanged);
1230}
1231
1232qreal QQStyleKitShadowProperties::opacity() const
1233{
1234 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1235}
1236
1237void QQStyleKitShadowProperties::setOpacity(qreal opacity)
1238{
1239 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1240 handleStylePropertyChanged(&QQStyleKitShadowProperties::opacityChanged);
1241}
1242
1243qreal QQStyleKitShadowProperties::scale() const
1244{
1245 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1246}
1247
1248void QQStyleKitShadowProperties::setScale(qreal scale)
1249{
1250 if (setStyleProperty(QQSK::Property::Scale, scale))
1251 handleStylePropertyChanged(&QQStyleKitShadowProperties::scaleChanged);
1252}
1253
1254qreal QQStyleKitShadowProperties::verticalOffset() const
1255{
1256 return styleProperty<qreal>(QQSK::Property::VOffset);
1257}
1258
1259void QQStyleKitShadowProperties::setVerticalOffset(qreal verticalOffset)
1260{
1261 if (setStyleProperty(QQSK::Property::VOffset, verticalOffset))
1262 handleStylePropertyChanged(&QQStyleKitShadowProperties::verticalOffsetChanged);
1263}
1264
1265qreal QQStyleKitShadowProperties::horizontalOffset() const
1266{
1267 return styleProperty<qreal>(QQSK::Property::HOffset);
1268}
1269
1270void QQStyleKitShadowProperties::setHorizontalOffset(qreal horizontalOffset)
1271{
1272 if (setStyleProperty(QQSK::Property::HOffset, horizontalOffset))
1273 handleStylePropertyChanged(&QQStyleKitShadowProperties::horizontalOffsetChanged);
1274}
1275
1276qreal QQStyleKitShadowProperties::blur() const
1277{
1278 return styleProperty<qreal>(QQSK::Property::Blur, 10.0);
1279}
1280
1281void QQStyleKitShadowProperties::setBlur(qreal blur)
1282{
1283 if (setStyleProperty(QQSK::Property::Blur, blur))
1284 handleStylePropertyChanged(&QQStyleKitShadowProperties::blurChanged);
1285}
1286
1287bool QQStyleKitShadowProperties::visible() const
1288{
1289 return styleProperty<bool>(QQSK::Property::Visible, true);
1290}
1291
1292void QQStyleKitShadowProperties::setVisible(bool visible)
1293{
1294 if (setStyleProperty(QQSK::Property::Visible, visible))
1295 handleStylePropertyChanged(&QQStyleKitShadowProperties::visibleChanged);
1296}
1297
1298QQmlComponent *QQStyleKitShadowProperties::delegate() const
1299{
1300 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1301}
1302
1303void QQStyleKitShadowProperties::setDelegate(QQmlComponent *delegate)
1304{
1305 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1306 handleStylePropertyChanged(&QQStyleKitShadowProperties::delegateChanged);
1307}
1308
1309// ************* QQStyleKitDelegateProperties ****************
1310
1311QQStyleKitDelegateProperties::QQStyleKitDelegateProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1312 : QQStyleKitPropertyGroup(group, parent)
1313{
1314}
1315
1316template <typename... CHANGED_SIGNALS>
1317void QQStyleKitDelegateProperties::emitGlobally(
1318 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1319{
1320 // Go through all instances of QQStyleKitDelegateProperties
1321 const QQStyleKitControlProperties *cp = controlProperties();
1325 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground());
1326}
1327
1328qreal QQStyleKitDelegateProperties::radius() const
1329{
1330 return styleProperty<qreal>(QQSK::Property::Radius);
1331}
1332
1333void QQStyleKitDelegateProperties::setRadius(qreal radius)
1334{
1335 if (setStyleProperty(QQSK::Property::Radius, radius))
1336 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1337 &QQStyleKitDelegateProperties::radiusChanged,
1338 &QQStyleKitDelegateProperties::topLeftRadiusChanged,
1339 &QQStyleKitDelegateProperties::topRightRadiusChanged,
1340 &QQStyleKitDelegateProperties::bottomLeftRadiusChanged,
1341 &QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1342}
1343
1344qreal QQStyleKitDelegateProperties::topLeftRadius() const
1345{
1346 return styleProperty<qreal>(QQSK::Property::TopLeftRadius, QQSK::Property::Radius);
1347}
1348
1349void QQStyleKitDelegateProperties::setTopLeftRadius(qreal radius)
1350{
1351 if (setStyleProperty(QQSK::Property::TopLeftRadius, radius))
1352 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topLeftRadiusChanged);
1353}
1354
1355qreal QQStyleKitDelegateProperties::topRightRadius() const
1356{
1357 return styleProperty<qreal>(QQSK::Property::TopRightRadius, QQSK::Property::Radius);
1358}
1359
1360void QQStyleKitDelegateProperties::setTopRightRadius(qreal radius)
1361{
1362 if (setStyleProperty(QQSK::Property::TopRightRadius, radius))
1363 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topRightRadiusChanged);
1364}
1365
1366qreal QQStyleKitDelegateProperties::bottomLeftRadius() const
1367{
1368 return styleProperty<qreal>(QQSK::Property::BottomLeftRadius, QQSK::Property::Radius);
1369}
1370
1371void QQStyleKitDelegateProperties::setBottomLeftRadius(qreal radius)
1372{
1373 if (setStyleProperty(QQSK::Property::BottomLeftRadius, radius))
1374 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomLeftRadiusChanged);
1375}
1376
1377qreal QQStyleKitDelegateProperties::bottomRightRadius() const
1378{
1379 return styleProperty<qreal>(QQSK::Property::BottomRightRadius, QQSK::Property::Radius);
1380}
1381
1382void QQStyleKitDelegateProperties::setBottomRightRadius(qreal radius)
1383{
1384 if (setStyleProperty(QQSK::Property::BottomRightRadius, radius))
1385 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1386}
1387
1388qreal QQStyleKitDelegateProperties::scale() const
1389{
1390 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1391}
1392
1393void QQStyleKitDelegateProperties::setScale(qreal scale)
1394{
1395 if (setStyleProperty(QQSK::Property::Scale, scale))
1396 handleStylePropertyChanged(&QQStyleKitDelegateProperties::scaleChanged);
1397}
1398
1399qreal QQStyleKitDelegateProperties::rotation() const
1400{
1401 return styleProperty<qreal>(QQSK::Property::Rotation);
1402}
1403
1404void QQStyleKitDelegateProperties::setRotation(qreal rotation)
1405{
1406 if (setStyleProperty(QQSK::Property::Rotation, rotation))
1407 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rotationChanged);
1408}
1409
1410qreal QQStyleKitDelegateProperties::implicitWidth() const
1411{
1412 return styleProperty<qreal>(QQSK::Property::ImplicitWidth);
1413}
1414
1415void QQStyleKitDelegateProperties::setImplicitWidth(qreal width)
1416{
1417 if (setStyleProperty(QQSK::Property::ImplicitWidth, width))
1418 handleStylePropertyChanged(&QQStyleKitDelegateProperties::implicitWidthChanged);
1419}
1420
1421qreal QQStyleKitDelegateProperties::implicitHeight() const
1422{
1423 return styleProperty<qreal>(QQSK::Property::ImplicitHeight);
1424}
1425
1426void QQStyleKitDelegateProperties::setImplicitHeight(qreal height)
1427{
1428 if (setStyleProperty(QQSK::Property::ImplicitHeight, height))
1429 handleStylePropertyChanged(&QQStyleKitDelegateProperties::implicitHeightChanged);
1430}
1431
1432qreal QQStyleKitDelegateProperties::minimumWidth() const
1433{
1434 return styleProperty<qreal>(QQSK::Property::MinimumWidth);
1435}
1436
1437void QQStyleKitDelegateProperties::setMinimumWidth(qreal width)
1438{
1439 if (setStyleProperty(QQSK::Property::MinimumWidth, width))
1440 handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumWidthChanged);
1441}
1442
1443qreal QQStyleKitDelegateProperties::margins() const
1444{
1445 return styleProperty<qreal>(QQSK::Property::Margins);
1446}
1447
1448void QQStyleKitDelegateProperties::setMargins(qreal margins)
1449{
1450 if (setStyleProperty(QQSK::Property::Margins, margins))
1451 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1452 &QQStyleKitDelegateProperties::marginsChanged,
1453 &QQStyleKitDelegateProperties::leftMarginChanged,
1454 &QQStyleKitDelegateProperties::rightMarginChanged,
1455 &QQStyleKitDelegateProperties::topMarginChanged,
1456 &QQStyleKitDelegateProperties::bottomMarginChanged);
1457}
1458
1459qreal QQStyleKitDelegateProperties::leftMargin() const
1460{
1461 return styleProperty<qreal>(QQSK::Property::LeftMargin, QQSK::Property::Margins);
1462}
1463
1464void QQStyleKitDelegateProperties::setLeftMargin(qreal margin)
1465{
1466 if (setStyleProperty(QQSK::Property::LeftMargin, margin))
1467 handleStylePropertyChanged(&QQStyleKitDelegateProperties::leftMarginChanged);
1468}
1469
1470qreal QQStyleKitDelegateProperties::rightMargin() const
1471{
1472 return styleProperty<qreal>(QQSK::Property::RightMargin, QQSK::Property::Margins);
1473}
1474
1475void QQStyleKitDelegateProperties::setRightMargin(qreal margin)
1476{
1477 if (setStyleProperty(QQSK::Property::RightMargin, margin))
1478 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rightMarginChanged);
1479}
1480
1481qreal QQStyleKitDelegateProperties::topMargin() const
1482{
1483 return styleProperty<qreal>(QQSK::Property::TopMargin, QQSK::Property::Margins);
1484}
1485
1486void QQStyleKitDelegateProperties::setTopMargin(qreal margin)
1487{
1488 if (setStyleProperty(QQSK::Property::TopMargin, margin))
1489 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topMarginChanged);
1490}
1491
1492qreal QQStyleKitDelegateProperties::bottomMargin() const
1493{
1494 return styleProperty<qreal>(QQSK::Property::BottomMargin, QQSK::Property::Margins);
1495}
1496
1497void QQStyleKitDelegateProperties::setBottomMargin(qreal margin)
1498{
1499 if (setStyleProperty(QQSK::Property::BottomMargin, margin))
1500 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomMarginChanged);
1501}
1502
1503Qt::Alignment QQStyleKitDelegateProperties::alignment() const
1504{
1505 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment, Qt::AlignLeft | Qt::AlignVCenter);
1506}
1507
1508void QQStyleKitDelegateProperties::setAlignment(Qt::Alignment alignment)
1509{
1510 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1511 handleStylePropertyChanged(&QQStyleKitDelegateProperties::alignmentChanged);
1512}
1513
1514qreal QQStyleKitDelegateProperties::opacity() const
1515{
1516 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1517}
1518
1519void QQStyleKitDelegateProperties::setOpacity(qreal opacity)
1520{
1521 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1522 handleStylePropertyChanged(&QQStyleKitDelegateProperties::opacityChanged);
1523}
1524
1525QColor QQStyleKitDelegateProperties::color() const
1526{
1527 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1528}
1529
1530void QQStyleKitDelegateProperties::setColor(const QColor &color)
1531{
1532 if (setStyleProperty(QQSK::Property::Color, color))
1533 handleStylePropertyChanged(&QQStyleKitDelegateProperties::colorChanged);
1534}
1535
1536bool QQStyleKitDelegateProperties::visible() const
1537{
1538 return styleProperty<bool>(QQSK::Property::Visible, true);
1539}
1540
1541void QQStyleKitDelegateProperties::setVisible(bool visible)
1542{
1543 if (setStyleProperty(QQSK::Property::Visible, visible))
1544 handleStylePropertyChanged(&QQStyleKitDelegateProperties::visibleChanged);
1545}
1546
1547bool QQStyleKitDelegateProperties::clip() const
1548{
1549 return styleProperty<bool>(QQSK::Property::Clip, false);
1550}
1551
1552void QQStyleKitDelegateProperties::setClip(bool clip)
1553{
1554 if (setStyleProperty(QQSK::Property::Clip, clip))
1555 handleStylePropertyChanged(&QQStyleKitDelegateProperties::clipChanged);
1556}
1557
1558QQuickGradient *QQStyleKitDelegateProperties::gradient() const
1559{
1560 return styleProperty<QQuickGradient *>(QQSK::Property::Gradient);
1561}
1562
1563void QQStyleKitDelegateProperties::setGradient(QQuickGradient *gradient)
1564{
1565 if (setStyleProperty(QQSK::Property::Gradient, gradient))
1566 handleStylePropertyChanged(&QQStyleKitDelegateProperties::gradientChanged);
1567}
1568
1569QObject *QQStyleKitDelegateProperties::data() const
1570{
1571 return styleProperty<QObject *>(QQSK::Property::Data);
1572}
1573
1574void QQStyleKitDelegateProperties::setData(QObject *data)
1575{
1576 if (setStyleProperty(QQSK::Property::Data, data))
1577 handleStylePropertyChanged(&QQStyleKitDelegateProperties::dataChanged);
1578}
1579
1580QQmlComponent *QQStyleKitDelegateProperties::delegate() const
1581{
1582 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1583}
1584
1585void QQStyleKitDelegateProperties::setDelegate(QQmlComponent *delegate)
1586{
1587 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1588 handleStylePropertyChanged(&QQStyleKitDelegateProperties::delegateChanged);
1589}
1590
1591QQStyleKitBorderProperties *QQStyleKitDelegateProperties::border() const
1592{
1593 return lazyCreateGroup(m_border, QQSK::PropertyGroup::Border);
1594}
1595
1596QQStyleKitShadowProperties *QQStyleKitDelegateProperties::shadow() const
1597{
1598 return lazyCreateGroup(m_shadow, QQSK::PropertyGroup::Shadow);
1599}
1600
1601QQStyleKitImageProperties *QQStyleKitDelegateProperties::image() const
1602{
1603 return lazyCreateGroup(m_image, QQSK::PropertyGroup::Image);
1604}
1605
1606// ************* QQStyleKitHandleProperties ****************
1607
1608QQStyleKitHandleProperties::QQStyleKitHandleProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1609 : QQStyleKitDelegateProperties(group, parent)
1610{
1611}
1612
1613QQStyleKitDelegateProperties *QQStyleKitHandleProperties::first() const
1614{
1615 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1616}
1617
1618QQStyleKitDelegateProperties *QQStyleKitHandleProperties::second() const
1619{
1620 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
1621}
1622
1623// ************* QQStyleKitIndicatorProperties ****************
1624
1625QQStyleKitIndicatorProperties::QQStyleKitIndicatorProperties(
1626 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1627 : QQStyleKitDelegateProperties(group, parent)
1628{
1629}
1630
1631template <typename... CHANGED_SIGNALS>
1633 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1634{
1635 // Go through all instances of QQStyleKitIndicatorProperties
1636 const QQStyleKitControlProperties *cp = controlProperties();
1637 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->up());
1638 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->down());
1639}
1640
1641QQStyleKitDelegateProperties *QQStyleKitIndicatorProperties::foreground() const
1642{
1643 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1644}
1645
1646// ************* QQStyleKitIndicatorWithSubTypes ****************
1647
1648QQStyleKitIndicatorWithSubTypes::QQStyleKitIndicatorWithSubTypes(
1649 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1650 : QQStyleKitDelegateProperties(group, parent)
1651{
1652}
1653
1654template <typename... CHANGED_SIGNALS>
1656 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1657{
1658 // Go through all instances of QQStyleKitIndicatorWithSubTypes
1659 const QQStyleKitControlProperties *cp = controlProperties();
1661}
1662
1663QQStyleKitDelegateProperties *QQStyleKitIndicatorWithSubTypes::foreground() const
1664{
1665 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1666}
1667
1669{
1670 return lazyCreateGroup(m_up, QQSK::PropertyGroup::DelegateSubtype1);
1671}
1672
1674{
1675 return lazyCreateGroup(m_down, QQSK::PropertyGroup::DelegateSubtype2);
1676}
1677
1678// ************* QQStyleKitTextProperties ****************
1679QQStyleKitTextProperties::QQStyleKitTextProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1680 : QQStyleKitPropertyGroup(group, parent)
1681{
1682}
1683
1684template <typename... CHANGED_SIGNALS>
1686 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1687{
1688 const QQStyleKitControlProperties *cp = controlProperties();
1690}
1691
1693{
1694 return styleProperty<QColor>(QQSK::Property::Color);
1695}
1696
1697void QQStyleKitTextProperties::setColor(const QColor &color)
1698{
1699 if (setStyleProperty(QQSK::Property::Color, color))
1700 handleStylePropertyChanged(&QQStyleKitTextProperties::colorChanged);
1701}
1702
1704{
1705 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment);
1706}
1707
1708void QQStyleKitTextProperties::setAlignment(Qt::Alignment alignment)
1709{
1710 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1711 handleStylePropertyChanged(&QQStyleKitTextProperties::alignmentChanged);
1712}
1713
1715{
1716 return styleProperty<bool>(QQSK::Property::Bold, false);
1717}
1718
1720{
1721 if (setStyleProperty(QQSK::Property::Bold, bold))
1722 handleStylePropertyChanged(&QQStyleKitTextProperties::boldChanged);
1723}
1724
1726{
1727 return styleProperty<bool>(QQSK::Property::Italic, false);
1728}
1729
1731{
1732 if (setStyleProperty(QQSK::Property::Italic, italic))
1733 handleStylePropertyChanged(&QQStyleKitTextProperties::italicChanged);
1734}
1735
1737{
1738 return styleProperty<qreal>(QQSK::Property::PointSize);
1739}
1740
1742{
1743 if (setStyleProperty(QQSK::Property::PointSize, pointSize))
1744 handleStylePropertyChanged(&QQStyleKitTextProperties::pointSizeChanged);
1745}
1746
1748{
1749 return styleProperty<qreal>(QQSK::Property::Padding);
1750}
1751
1762
1764{
1765 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
1766}
1767
1769{
1770 if (setStyleProperty(QQSK::Property::LeftPadding, padding))
1771 handleStylePropertyChanged(&QQStyleKitTextProperties::leftPaddingChanged);
1772}
1773
1775{
1776 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
1777}
1778
1780{
1781 if (setStyleProperty(QQSK::Property::RightPadding, padding))
1782 handleStylePropertyChanged(&QQStyleKitTextProperties::rightPaddingChanged);
1783}
1784
1786{
1787 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
1788}
1789
1791{
1792 if (setStyleProperty(QQSK::Property::TopPadding, padding))
1793 handleStylePropertyChanged(&QQStyleKitTextProperties::topPaddingChanged);
1794}
1795
1797{
1798 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
1799}
1800
1802{
1803 if (setStyleProperty(QQSK::Property::BottomPadding, padding))
1804 handleStylePropertyChanged(&QQStyleKitTextProperties::bottomPaddingChanged);
1805}
1806
1807// ************* QQStyleKitControlProperties ****************
1808
1809QQStyleKitControlProperties::QQStyleKitControlProperties(QQSK::PropertyGroup group, QObject *parent)
1810 : QQStyleKitPropertyGroup(group, parent)
1811{
1812 /* Calculate the free space storage ID space that can accommodate all unique style
1813 * properties that may be applied to a control. Since we'll prepend different states
1814 * and subtypes during the property propagation lookup phase later, we need to reserve
1815 * ID space for them both already now. More docs about the property space is written in
1816 * the implementation of PropertyPathId. */
1817 m_groupSpace.size = nestedGroupsStartSize;
1818 m_groupSpace.start = 0;
1819
1820 if (group == QQSK::PropertyGroup::GlobalFlag) {
1821 /* A property path may include pseudo-groups that offers a convenient API for
1822 * reading properties with specific options applied. The 'global' group is one such
1823 * pseudo-group. When it is prefixed to a property path, it indicates that the property
1824 * should be read directly from the style, bypassing any active transitions that might
1825 * otherwise affect its value.
1826 * Note: The global group should be ignored when computing a PropertyPathId_t, as it
1827 * only affect _where_ the property should be read from, not its ID. */
1828 m_pathFlags.setFlag(QQSK::PropertyPathFlag::Global);
1829 }
1830}
1831
1832QQStyleKitStyle *QQStyleKitControlProperties::style() const
1833{
1834 if (subclass() == QQSK::Subclass::QQStyleKitState) {
1835 /* A QQStyleKitControlState (and its subclasses) should always be a (grand)child of a
1836 * QQStyleKitStyle. And it belongs to that style, even it that style is not the
1837 * currently active application style. This is opposed to a QQStyleKitReader,
1838 * that normally belongs / communicates with the currently active style.
1839 * NOTE: a style can also be a fallback style for another style (which can be recursive,
1840 * meaning that a fallback style can also have its own fallback style, and so on). But
1841 * this function will return the nearest style, and not the root style */
1842 QObject *obj = parent();
1843 while (obj && !obj->metaObject()->inherits(&QQStyleKitStyle::staticMetaObject))
1844 obj = obj->parent();
1845 return obj ? static_cast<QQStyleKitStyle *>(obj) : nullptr;
1846 }
1847
1848 if (subclass() == QQSK::Subclass::QQStyleKitReader) {
1849 const auto *reader = static_cast<const QQStyleKitReader *>(this);
1850 if (reader->m_explicitStyle)
1851 return reader->m_explicitStyle;
1852 }
1853
1854 // For a QQStyleKitReader without an explicit style, we return the currently active style for now
1855 return QQStyleKitStyle::current();
1856}
1857
1858QQSK::Subclass QQStyleKitControlProperties::subclass() const
1859{
1860 /* QQStyleKitControlProperties is subclassed by several different classes in this
1861 * framework. As such, it's basically just an interface because it only declares the
1862 * different properties that can be read or written to in a QQStyleKitStyle, such as
1863 * hovered.background.color or pressed.indicator.foreground.color. It says nothing
1864 * about how those properties are stored, instead that is up to each individual
1865 * subclass to decide */
1866 if (metaObject()->inherits(&QQStyleKitReader::staticMetaObject))
1867 return QQSK::Subclass::QQStyleKitReader;
1868 if (metaObject()->inherits(&QQStyleKitControlState::staticMetaObject))
1869 return QQSK::Subclass::QQStyleKitState;
1870 Q_UNREACHABLE();
1871}
1872
1873QQStyleKitReader *QQStyleKitControlProperties::asQQStyleKitReader() const
1874{
1875 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitReader);
1876 return static_cast<QQStyleKitReader *>(const_cast<QQStyleKitControlProperties *>(this));
1877}
1878
1879QQStyleKitControlState *QQStyleKitControlProperties::asQQStyleKitState() const
1880{
1881 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitState);
1882 Q_ASSERT(metaObject()->inherits(&QQStyleKitControlState::staticMetaObject));
1883 return static_cast<QQStyleKitControlState *>(const_cast<QQStyleKitControlProperties *>(this));
1884}
1885
1886void QQStyleKitControlProperties::forEachUsedDelegate(
1887 std::function<void (QQStyleKitDelegateProperties *, QQSK::Delegate, const QString &)> f)
1888{
1889 // If adding more delegates here, remember to keep StyleAnimation.qml in sync
1890 if (m_background)
1891 f(m_background, QQSK::Delegate::Background, "background"_L1);
1892
1893 if (m_indicator) {
1894 f(m_indicator, QQSK::Delegate::Indicator, "indicator"_L1);
1895 if (m_indicator->m_foreground)
1896 f(m_indicator->m_foreground, QQSK::Delegate::IndicatorForeground, "indicator.foreground"_L1);
1897 if (m_indicator->m_up) {
1898 f(m_indicator->m_up, QQSK::Delegate::IndicatorUp, "indicator.up"_L1);
1899 if (m_indicator->m_up->m_foreground)
1900 f(m_indicator->m_up->m_foreground, QQSK::Delegate::IndicatorUpForeground, "indicator.up.foreground"_L1);
1901 }
1902 if (m_indicator->m_down) {
1903 f(m_indicator->m_down, QQSK::Delegate::IndicatorDown, "indicator.down"_L1);
1904 if (m_indicator->m_down->m_foreground)
1905 f(m_indicator->m_down->m_foreground, QQSK::Delegate::IndicatorDownForeground, "indicator.down.foreground"_L1);
1906 }
1907 }
1908
1909 if (m_handle) {
1910 f(m_handle, QQSK::Delegate::Handle, "handle"_L1);
1911 if (m_handle->m_first)
1912 f(m_handle->m_first, QQSK::Delegate::HandleFirst, "handle.first"_L1);
1913 if (m_handle->m_second)
1914 f(m_handle->m_second, QQSK::Delegate::HandleSecond, "handle.second"_L1);
1915 }
1916}
1917
1918void QQStyleKitControlProperties::emitChangedForAllStyleProperties(EmitFlags emitFlags)
1919{
1920 /* This brute-force function will emit update signals for _all_ style properties
1921 * in the QQStyleKitStyle API. Doing so is typically needed after a style-, or theme
1922 * change, as we don't know which properties are affected by such a big change. */
1923 if (emitFlags.testFlag(EmitFlag::AllProperties)) {
1924 emit leftPaddingChanged();
1925 emit rightPaddingChanged();
1926 emit topPaddingChanged();
1927 emit bottomPaddingChanged();
1928 emit spacingChanged();
1929 emit transitionChanged();
1930 emit textChanged();
1931 }
1932
1933 forEachUsedDelegate([=](QQStyleKitDelegateProperties *delegate, QQSK::Delegate, const QString &){
1934 delegate->emitChangedForAllStylePropertiesRecursive(emitFlags);
1935 });
1936}
1937
1938template <typename... CHANGED_SIGNALS>
1939void QQStyleKitControlProperties::emitGlobally(
1940 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1941{
1942 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
1943 if (reader->controlType() != controlType)
1944 continue;
1945 ((reader->*changedSignals)(), ...);
1946 }
1947}
1948
1949qreal QQStyleKitControlProperties::spacing() const
1950{
1951 return styleProperty<qreal>(QQSK::Property::Spacing);
1952}
1953
1954void QQStyleKitControlProperties::setSpacing(qreal spacing)
1955{
1956 if (setStyleProperty(QQSK::Property::Spacing, spacing))
1957 handleStylePropertyChanged(&QQStyleKitControlProperties::spacingChanged);
1958}
1959
1960qreal QQStyleKitControlProperties::padding() const
1961{
1962 return styleProperty<qreal>(QQSK::Property::Padding);
1963}
1964
1965void QQStyleKitControlProperties::setPadding(qreal padding)
1966{
1967 if (setStyleProperty(QQSK::Property::Padding, padding))
1968 handleStylePropertiesChanged<QQStyleKitControlProperties>(
1969 &QQStyleKitControlProperties::paddingChanged,
1970 &QQStyleKitControlProperties::leftPaddingChanged,
1971 &QQStyleKitControlProperties::rightPaddingChanged,
1972 &QQStyleKitControlProperties::topPaddingChanged,
1973 &QQStyleKitControlProperties::bottomPaddingChanged);
1974}
1975
1976qreal QQStyleKitControlProperties::leftPadding() const
1977{
1978 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
1979}
1980
1981void QQStyleKitControlProperties::setLeftPadding(qreal leftPadding)
1982{
1983 if (setStyleProperty(QQSK::Property::LeftPadding, leftPadding))
1984 handleStylePropertyChanged(&QQStyleKitControlProperties::leftPaddingChanged);
1985}
1986
1987qreal QQStyleKitControlProperties::rightPadding() const
1988{
1989 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
1990}
1991
1992void QQStyleKitControlProperties::setRightPadding(qreal rightPadding)
1993{
1994 if (setStyleProperty(QQSK::Property::RightPadding, rightPadding))
1995 handleStylePropertyChanged(&QQStyleKitControlProperties::rightPaddingChanged);
1996}
1997
1998qreal QQStyleKitControlProperties::topPadding() const
1999{
2000 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
2001}
2002
2003void QQStyleKitControlProperties::setTopPadding(qreal topPadding)
2004{
2005 if (setStyleProperty(QQSK::Property::TopPadding, topPadding))
2006 handleStylePropertyChanged(&QQStyleKitControlProperties::topPaddingChanged);
2007}
2008
2009qreal QQStyleKitControlProperties::bottomPadding() const
2010{
2011 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
2012}
2013
2014void QQStyleKitControlProperties::setBottomPadding(qreal bottomPadding)
2015{
2016 if (setStyleProperty(QQSK::Property::BottomPadding, bottomPadding))
2017 handleStylePropertyChanged(&QQStyleKitControlProperties::bottomPaddingChanged);
2018}
2019
2020QQuickTransition *QQStyleKitControlProperties::transition() const
2021{
2022 return styleProperty<QQuickTransition *>(QQSK::Property::Transition);
2023}
2024
2025void QQStyleKitControlProperties::setTransition(QQuickTransition *transition)
2026{
2027 if (setStyleProperty(QQSK::Property::Transition, transition))
2028 handleStylePropertyChanged(&QQStyleKitControlProperties::transitionChanged);
2029}
2030
2031QQStyleKitTextProperties *QQStyleKitControlProperties::text() const
2032{
2033 return lazyCreateGroup(m_text, QQSK::PropertyGroup::Text);
2034}
2035
2036QQStyleKitDelegateProperties *QQStyleKitControlProperties::background() const
2037{
2038 return lazyCreateGroup(m_background, QQSK::PropertyGroup::Background);
2039}
2040
2041QQStyleKitHandleProperties *QQStyleKitControlProperties::handle() const
2042{
2043 return lazyCreateGroup(m_handle, QQSK::PropertyGroup::Handle);
2044}
2045
2046QQStyleKitIndicatorWithSubTypes *QQStyleKitControlProperties::indicator() const
2047{
2048 return lazyCreateGroup(m_indicator, QQSK::PropertyGroup::Indicator);
2049}
2050
2051QT_END_NAMESPACE
2052
2053#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
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
Combined button and popup list for selecting options.
#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH)