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