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 {StylableControls::}{checkBox}, the indicator is the
78 frame, and its \l {IndicatorStyle::}{foreground} is the check mark.
79 For a \l {StylableControls::}{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} 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 {StylableControls::}{switchControl},
763 \l {StylableControls::}{slider} and
764 \l {StylableControls::}{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 {StylableControls::}{slider},
800 \l {StylableControls::}{progressBar}, and
801 \l {StylableControls::}{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
965QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent)
966 : QObject(parent)
967{
968}
969
970QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const
971{
973 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(this));
974 auto *self = const_cast<QQStyleKitPropertyGroup *>(this);
975 return static_cast<QQStyleKitControlProperties *>(self);
976 }
977 Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(parent()));
978 return static_cast<QQStyleKitControlProperties *>(parent());
979}
980
981template<typename T>
982T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup group) const
983{
984 T *nestedGroup = QQSK::lazyCreate(ptr, controlProperties(), group);
985
986 // Nested groups inherit path flags from their parents
987 nestedGroup->m_pathFlags = m_pathFlags;
988
989 if (group == QQSK::PropertyGroup::DelegateSubtype1) {
990 /* The subtype is stripped from a group's core path, and stored as a flag. This is because
991 * during style property look-up, we want to check many different alternative paths where
992 * the core group path can occur, some with, and some without, the subtype included.
993 * Whether or not to include a subtype is therefore decided as late as possible, when
994 * creating a QQStyleKitPropertyPath, and then depending on the usage. */
995 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype1);
996 nestedGroup->m_groupSpace = m_groupSpace;
997 } else if (group == QQSK::PropertyGroup::DelegateSubtype2) {
998 nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype2);
999 nestedGroup->m_groupSpace = m_groupSpace;
1000 } else {
1001 /* Calculate the available property ID space for the nested group. This is done by
1002 * dividing the available space inside _this_ group on the number of potential groups
1003 * that _this_ group can potentially contain. */
1004 const PropertyPathId nestedGroupIndex = PropertyPathId(group);
1005 const PropertyPathId nestedGroupSize = m_groupSpace.size / nestedGroupCount;
1006 nestedGroup->m_groupSpace.size = nestedGroupSize;
1007 nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize);
1008 /* Ensure that we haven’t exhausted the available PropertyPathId space. There must be
1009 * enough room remaining to assign IDs for all properties defined in QQSK::Property.
1010 * If this assertion triggers, consider switching to a wider PropertyPathId type or
1011 * optimizing how the space is allocated. For example, certain nested paths (such as
1012 * control.handle.indicator) can never occur, yet we currently reserve INNER_GROUP_COUNT
1013 * for every nesting level, which is wasteful. */
1014 Q_ASSERT(nestedGroupSize >= PropertyPathId(QQSK::Property::COUNT));
1015 }
1016 return nestedGroup;
1017}
1018
1019/* This macro will check if the caller has the same group path as \a GROUP_PATH.
1020 * This is needed since a QQSK::Property (e.g Color) can sometimes be a
1021 * property in several different subclasses of QQStyleKitPropertyGroup.
1022 * For example, both control.background.color and control.indicator.color has a
1023 * color property. But the group path differs, so they are in reality two completely
1024 * different properties. And in that case, when the former changes value, we want to
1025 * emit changes globally only to that property, and not the latter.
1026 * The caller of this macro will therefore need to go through all the usages of its
1027 * subclass in the API, to figure out which group itself is an instance of. For the
1028 * one that is a match, the macro will go through all readers and emit the same
1029 * signal for them. */
1030#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH) if
1031 (this == CONTROL_PROPERTIES -> GROUP_PATH ) {
1032 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
1033 const auto baseTypes = QQStyleKitPropertyResolver::baseTypesForType(reader->controlType());
1034 if (reader->controlType() != controlType && !baseTypes.contains(controlType))
1035 continue;
1036 reader->clearLocalStorage();
1037 ((reader-> GROUP_PATH ->*changedSignals)(), ...);
1038 }
1039 return; \
1040}
1041
1042template<typename SUBCLASS>
1043void QQStyleKitPropertyGroup::handleStylePropertyChanged(void (SUBCLASS::*changedSignal)()) {
1044 handleStylePropertiesChanged<SUBCLASS>(changedSignal);
1045}
1046
1047template <typename SUBCLASS, typename... CHANGED_SIGNALS>
1048void QQStyleKitPropertyGroup::handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
1049{
1050 /* This function will check which subclass of QQStyleKitProperties this
1051 * group is (nested) inside. Based on that, it will decide if the signals
1052 * should be emitted locally or not, and if the changed properties affects
1053 * all existing QQStyleKitReaders, and therefore will need to be
1054 * emitted 'globally'. Note that it only makes sense to call this function
1055 * for changed properties that are available from a QQStyleKitReader.
1056 * Properities only available from e.g QQStyleKitControl (such as
1057 * variations), are anyway not readable from a QQStyleKitReader. */
1058 static_assert(std::is_base_of<QQStyleKitPropertyGroup, SUBCLASS>::value,
1059 "SUBCLASS must inherit QQStyleKitPropertyGroup");
1060
1061 auto *group = static_cast<SUBCLASS *>(this);
1062 const QQSK::Subclass objectWrittenTo = controlProperties()->subclass();
1063
1064 if (objectWrittenTo == QQSK::Subclass::QQStyleKitState) {
1065 ((group->*changedSignals)(), ...);
1066
1067 if (shouldEmitGlobally()) {
1068 const QQStyleKitControl *control = controlProperties()->asQQStyleKitState()->control();
1069 const QQStyleKitExtendableControlType type = control->controlType();
1070 group->emitGlobally(type, changedSignals...);
1071 }
1072 return;
1073 }
1074
1075 if (objectWrittenTo == QQSK::Subclass::QQStyleKitReader) {
1076 /* Unless the StyleReader has told us not to emit any signals (because it's only
1077 * syncing it's own local storage with old values before starting a transition), we
1078 * emit the signal like normal. This will cause the control to repaint (perhaps
1079 * using a transition). */
1080 if (shouldEmitLocally()) {
1081 QQStyleKitReader *reader = controlProperties()->asQQStyleKitReader();
1082 /* Readers notify their consumer in two different ways depending on who is
1083 * consuming them. A QML control binds to the reader's change signals, so we
1084 * emit those directly. A widget consumer (m_target set) doesn't listen on
1085 * signals; it repaints in response to a QEvent::StyleAnimationUpdate posted
1086 * to the widget, and only while a transition is actually running. */
1087 if (!reader->m_target)
1088 ((group->*changedSignals)(), ...);
1089 else
1090 QCoreApplication::postEvent(reader->m_target, new QEvent(QEvent::StyleAnimationUpdate));
1091 }
1092 return;
1093 }
1094
1095 Q_UNREACHABLE();
1096}
1097
1099{
1100 /* This function will emit changed signals for all style properties in the
1101 * StyleKit API (for a single QQStyleKitReader), which is needed after
1102 * doing a style-, or theme change. */
1103 const QMetaObject *meta = metaObject();
1104 if (meta->inherits(&QQStyleKitControlProperties::staticMetaObject)) {
1105 /* Subclasses of QQStyleKitControlProperties, such as QQStyleKitReader, add
1106 * properties that describe the state of the control (hovered, checked, etc.)
1107 * rather than its style. Those should not be emitted from here. */
1108 meta = &QQStyleKitControlProperties::staticMetaObject;
1109 }
1110
1111 const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
1112 for (int i = startIndex; i < meta->propertyCount(); ++i) {
1113 const QMetaProperty prop = meta->property(i);
1114 const QMetaObject* propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
1115 if (propMetaObject && propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject)) {
1116 /* Nested groups are handled by forEachExistingNestedGroup() below. Reading them
1117 * through their property getters from here would lazily create them. */
1118 continue;
1119 }
1120
1121 if (!emitFlags.testFlag(EmitFlag::AllProperties)) {
1122 // Only emit for color properties when the Colors flag is set
1123 if (emitFlags.testFlag(EmitFlag::Colors)) {
1124 if (prop.metaType() != QMetaType::fromType<QColor>())
1125 continue;
1126 }
1127 }
1128
1129 /* Emit the changed signal for the property.
1130 * Note: even if we call invoke() for every style property, only the signals that
1131 * are connected to something (e.g. a binding) end up doing any real work. If
1132 * isSignalConnected() is false, the emit will exit early. */
1133 Q_ASSERT(prop.hasNotifySignal());
1134 QMetaMethod notify = prop.notifySignal();
1135 notify.invoke(this, Qt::DirectConnection);
1136 }
1137
1138 /* Recurse into the nested groups, but only the ones that have been created. Since
1139 * nested groups are lazily created when first read, a group that doesn't exist has
1140 * never been read, so there are no bindings to it that would need to be notified. */
1141 forEachExistingNestedGroup([emitFlags](QQStyleKitPropertyGroup *group) {
1142 group->emitChangedForAllStylePropertiesRecursive(emitFlags);
1143 });
1144}
1145
1147 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1148{
1149 /* Subclasses with nested groups should override this function and call f for
1150 * each nested group that has been created, mirroring the groups that the subclass
1151 * creates with lazyCreateGroup(). Nested groups are lazily created when read, so a
1152 * group that hasn't been created has never been read either. Using the member
1153 * pointers directly (as opposed to the property getters) avoids creating them by
1154 * accident. Overrides should not call this base implementation. */
1155 Q_UNUSED(f);
1156
1157#ifdef QT_DEBUG
1158 /* Verify that this group has no nested groups, since it would otherwise need to
1159 * override this function. */
1160 const QMetaObject *meta = metaObject();
1161 const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
1162 for (int i = startIndex; i < meta->propertyCount(); ++i) {
1163 const QMetaProperty prop = meta->property(i);
1164 const QMetaObject *propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
1165 Q_ASSERT_X(!propMetaObject || !propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject),
1166 meta->className(), "Classes with nested property groups must override forEachExistingNestedGroup()");
1167 }
1168#endif
1169}
1170
1171bool QQStyleKitPropertyGroup::shouldEmitLocally()
1172{
1173 return !controlProperties()->asQQStyleKitReader()->dontEmitChangedSignals();
1174}
1175
1176bool QQStyleKitPropertyGroup::shouldEmitGlobally()
1177{
1178 QQStyleKitStyle *parentStyle = controlProperties()->style();
1179 if (!parentStyle)
1180 return false;
1181
1182 if (parentStyle->loaded() && !parentStyle->m_isUpdatingPalette) {
1183 /* When a property has changed in the 'global' QQStyleKitStyle itself, it can
1184 * potentially affect all control instances. We therefore need to go through all
1185 * QQStyleKitReaders and inform that their own local property that matches the
1186 * 'global' property needs to be re-read. We emit the signals directly, omitting any
1187 * applied transitions in the QQStyleKitReaders, to optimize for speed. The exception
1188 * is if we're just updating the palette in the Style to match the palette in the current
1189 * control / QQStyleKitReader. Such a change will only affect a single control. */
1190 return parentStyle == QQStyleKitStyle::current();
1191 }
1192 return false;
1193}
1194
1195// ************* QQStyleKitImageProperties ****************
1196
1197QQStyleKitImageProperties::QQStyleKitImageProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1198 : QQStyleKitPropertyGroup(group, parent)
1199{
1200}
1201
1202template <typename... CHANGED_SIGNALS>
1203void QQStyleKitImageProperties::emitGlobally(
1204 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1205{
1206 // Go through all instances of QQStyleKitImageProperties
1207 const QQStyleKitControlProperties *cp = controlProperties();
1208 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->image());
1209 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->image());
1210 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->image());
1211 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->image());
1212}
1213
1214QUrl QQStyleKitImageProperties::source() const
1215{
1216 return styleProperty<QUrl>(QQSK::Property::Source);
1217}
1218
1219void QQStyleKitImageProperties::setSource(const QUrl &source)
1220{
1221 if (setStyleProperty(QQSK::Property::Source, source))
1222 handleStylePropertyChanged(&QQStyleKitImageProperties::sourceChanged);
1223}
1224
1225QColor QQStyleKitImageProperties::color() const
1226{
1227 return styleProperty<QColor>(QQSK::Property::Color);
1228}
1229
1230void QQStyleKitImageProperties::setColor(const QColor &color)
1231{
1232 if (setStyleProperty(QQSK::Property::Color, color))
1233 handleStylePropertyChanged(&QQStyleKitImageProperties::colorChanged);
1234}
1235
1236QQuickImage::FillMode QQStyleKitImageProperties::fillMode() const
1237{
1238 return styleProperty<QQuickImage::FillMode>(QQSK::Property::FillMode);
1239}
1240
1241void QQStyleKitImageProperties::setFillMode(QQuickImage::FillMode fillMode)
1242{
1243 if (setStyleProperty(QQSK::Property::FillMode, fillMode))
1244 handleStylePropertyChanged(&QQStyleKitImageProperties::fillModeChanged);
1245}
1246
1247// ************* QQStyleKitBorderProperties ****************
1248
1249QQStyleKitBorderProperties::QQStyleKitBorderProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1250 : QQStyleKitPropertyGroup(group, parent)
1251{
1252}
1253
1254template <typename... CHANGED_SIGNALS>
1255void QQStyleKitBorderProperties::emitGlobally(
1256 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1257{
1258 // Go through all instances of QQStyleKitBorderProperties
1259 const QQStyleKitControlProperties *cp = controlProperties();
1260 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->border());
1261 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->border());
1262 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->border());
1263 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->border());
1264}
1265
1266qreal QQStyleKitBorderProperties::width() const
1267{
1268 return styleProperty<qreal>(QQSK::Property::Width);
1269}
1270
1271void QQStyleKitBorderProperties::setWidth(qreal width)
1272{
1273 if (setStyleProperty(QQSK::Property::Width, width))
1274 handleStylePropertyChanged(&QQStyleKitBorderProperties::widthChanged);
1275}
1276
1277QColor QQStyleKitBorderProperties::color() const
1278{
1279 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1280}
1281
1282void QQStyleKitBorderProperties::setColor(const QColor &color)
1283{
1284 if (setStyleProperty(QQSK::Property::Color, color))
1285 handleStylePropertyChanged(&QQStyleKitBorderProperties::colorChanged);
1286}
1287
1288// ************* QQStyleKitShadowProperties ****************
1289
1290QQStyleKitShadowProperties::QQStyleKitShadowProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1291 : QQStyleKitPropertyGroup(group, parent)
1292{
1293}
1294
1295template <typename... CHANGED_SIGNALS>
1296void QQStyleKitShadowProperties::emitGlobally(
1297 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1298{
1299 // Go through all instances of QQStyleKitShadowProperties
1300 const QQStyleKitControlProperties *cp = controlProperties();
1301 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->shadow());
1302 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->shadow());
1303 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->shadow());
1304 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->shadow());
1305}
1306
1307QColor QQStyleKitShadowProperties::color() const
1308{
1309 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1310}
1311
1312void QQStyleKitShadowProperties::setColor(QColor color)
1313{
1314 if (setStyleProperty(QQSK::Property::Color, color))
1315 handleStylePropertyChanged(&QQStyleKitShadowProperties::colorChanged);
1316}
1317
1318qreal QQStyleKitShadowProperties::opacity() const
1319{
1320 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1321}
1322
1323void QQStyleKitShadowProperties::setOpacity(qreal opacity)
1324{
1325 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1326 handleStylePropertyChanged(&QQStyleKitShadowProperties::opacityChanged);
1327}
1328
1329qreal QQStyleKitShadowProperties::scale() const
1330{
1331 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1332}
1333
1334void QQStyleKitShadowProperties::setScale(qreal scale)
1335{
1336 if (setStyleProperty(QQSK::Property::Scale, scale))
1337 handleStylePropertyChanged(&QQStyleKitShadowProperties::scaleChanged);
1338}
1339
1340qreal QQStyleKitShadowProperties::verticalOffset() const
1341{
1342 return styleProperty<qreal>(QQSK::Property::VOffset);
1343}
1344
1345void QQStyleKitShadowProperties::setVerticalOffset(qreal verticalOffset)
1346{
1347 if (setStyleProperty(QQSK::Property::VOffset, verticalOffset))
1348 handleStylePropertyChanged(&QQStyleKitShadowProperties::verticalOffsetChanged);
1349}
1350
1351qreal QQStyleKitShadowProperties::horizontalOffset() const
1352{
1353 return styleProperty<qreal>(QQSK::Property::HOffset);
1354}
1355
1356void QQStyleKitShadowProperties::setHorizontalOffset(qreal horizontalOffset)
1357{
1358 if (setStyleProperty(QQSK::Property::HOffset, horizontalOffset))
1359 handleStylePropertyChanged(&QQStyleKitShadowProperties::horizontalOffsetChanged);
1360}
1361
1362qreal QQStyleKitShadowProperties::blur() const
1363{
1364 return styleProperty<qreal>(QQSK::Property::Blur, 10.0);
1365}
1366
1367void QQStyleKitShadowProperties::setBlur(qreal blur)
1368{
1369 if (setStyleProperty(QQSK::Property::Blur, blur))
1370 handleStylePropertyChanged(&QQStyleKitShadowProperties::blurChanged);
1371}
1372
1373bool QQStyleKitShadowProperties::visible() const
1374{
1375 return styleProperty<bool>(QQSK::Property::Visible, true);
1376}
1377
1378void QQStyleKitShadowProperties::setVisible(bool visible)
1379{
1380 if (setStyleProperty(QQSK::Property::Visible, visible))
1381 handleStylePropertyChanged(&QQStyleKitShadowProperties::visibleChanged);
1382}
1383
1384QQmlComponent *QQStyleKitShadowProperties::delegate() const
1385{
1386 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1387}
1388
1389void QQStyleKitShadowProperties::setDelegate(QQmlComponent *delegate)
1390{
1391 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1392 handleStylePropertyChanged(&QQStyleKitShadowProperties::delegateChanged);
1393}
1394
1395// ************* QQStyleKitDelegateProperties ****************
1396
1397QQStyleKitDelegateProperties::QQStyleKitDelegateProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1398 : QQStyleKitPropertyGroup(group, parent)
1399{
1400}
1401
1402template <typename... CHANGED_SIGNALS>
1403void QQStyleKitDelegateProperties::emitGlobally(
1404 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1405{
1406 // Go through all instances of QQStyleKitDelegateProperties
1407 const QQStyleKitControlProperties *cp = controlProperties();
1411 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground());
1412}
1413
1414void QQStyleKitDelegateProperties::forEachExistingNestedGroup(
1415 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1416{
1417 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1418 if (m_image)
1419 f(m_image);
1420 if (m_border)
1421 f(m_border);
1422 if (m_shadow)
1423 f(m_shadow);
1424}
1425
1426qreal QQStyleKitDelegateProperties::radius() const
1427{
1428 return styleProperty<qreal>(QQSK::Property::Radius);
1429}
1430
1431void QQStyleKitDelegateProperties::setRadius(qreal radius)
1432{
1433 if (setStyleProperty(QQSK::Property::Radius, radius))
1434 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1435 &QQStyleKitDelegateProperties::radiusChanged,
1436 &QQStyleKitDelegateProperties::topLeftRadiusChanged,
1437 &QQStyleKitDelegateProperties::topRightRadiusChanged,
1438 &QQStyleKitDelegateProperties::bottomLeftRadiusChanged,
1439 &QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1440}
1441
1442qreal QQStyleKitDelegateProperties::topLeftRadius() const
1443{
1444 return styleProperty<qreal>(QQSK::Property::TopLeftRadius, QQSK::Property::Radius);
1445}
1446
1447void QQStyleKitDelegateProperties::setTopLeftRadius(qreal radius)
1448{
1449 if (setStyleProperty(QQSK::Property::TopLeftRadius, radius))
1450 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topLeftRadiusChanged);
1451}
1452
1453qreal QQStyleKitDelegateProperties::topRightRadius() const
1454{
1455 return styleProperty<qreal>(QQSK::Property::TopRightRadius, QQSK::Property::Radius);
1456}
1457
1458void QQStyleKitDelegateProperties::setTopRightRadius(qreal radius)
1459{
1460 if (setStyleProperty(QQSK::Property::TopRightRadius, radius))
1461 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topRightRadiusChanged);
1462}
1463
1464qreal QQStyleKitDelegateProperties::bottomLeftRadius() const
1465{
1466 return styleProperty<qreal>(QQSK::Property::BottomLeftRadius, QQSK::Property::Radius);
1467}
1468
1469void QQStyleKitDelegateProperties::setBottomLeftRadius(qreal radius)
1470{
1471 if (setStyleProperty(QQSK::Property::BottomLeftRadius, radius))
1472 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomLeftRadiusChanged);
1473}
1474
1475qreal QQStyleKitDelegateProperties::bottomRightRadius() const
1476{
1477 return styleProperty<qreal>(QQSK::Property::BottomRightRadius, QQSK::Property::Radius);
1478}
1479
1480void QQStyleKitDelegateProperties::setBottomRightRadius(qreal radius)
1481{
1482 if (setStyleProperty(QQSK::Property::BottomRightRadius, radius))
1483 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomRightRadiusChanged);
1484}
1485
1486qreal QQStyleKitDelegateProperties::scale() const
1487{
1488 return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
1489}
1490
1491void QQStyleKitDelegateProperties::setScale(qreal scale)
1492{
1493 if (setStyleProperty(QQSK::Property::Scale, scale))
1494 handleStylePropertyChanged(&QQStyleKitDelegateProperties::scaleChanged);
1495}
1496
1497qreal QQStyleKitDelegateProperties::rotation() const
1498{
1499 return styleProperty<qreal>(QQSK::Property::Rotation);
1500}
1501
1502void QQStyleKitDelegateProperties::setRotation(qreal rotation)
1503{
1504 if (setStyleProperty(QQSK::Property::Rotation, rotation))
1505 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rotationChanged);
1506}
1507
1508qreal QQStyleKitDelegateProperties::width() const
1509{
1510 return styleProperty<qreal>(QQSK::Property::Width);
1511}
1512
1513void QQStyleKitDelegateProperties::setWidth(qreal width)
1514{
1515 if (setStyleProperty(QQSK::Property::Width, width))
1516 handleStylePropertyChanged(&QQStyleKitDelegateProperties::widthChanged);
1517}
1518
1519qreal QQStyleKitDelegateProperties::height() const
1520{
1521 return styleProperty<qreal>(QQSK::Property::Height);
1522}
1523
1524void QQStyleKitDelegateProperties::setHeight(qreal height)
1525{
1526 if (setStyleProperty(QQSK::Property::Height, height))
1527 handleStylePropertyChanged(&QQStyleKitDelegateProperties::heightChanged);
1528}
1529
1530qreal QQStyleKitDelegateProperties::minimumWidth() const
1531{
1532 return styleProperty<qreal>(QQSK::Property::MinimumWidth);
1533}
1534
1535void QQStyleKitDelegateProperties::setMinimumWidth(qreal width)
1536{
1537 if (setStyleProperty(QQSK::Property::MinimumWidth, width))
1538 handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumWidthChanged);
1539}
1540
1541qreal QQStyleKitDelegateProperties::minimumHeight() const
1542{
1543 return styleProperty<qreal>(QQSK::Property::MinimumHeight);
1544}
1545
1546void QQStyleKitDelegateProperties::setMinimumHeight(qreal height)
1547{
1548 if (setStyleProperty(QQSK::Property::MinimumHeight, height))
1549 handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumHeightChanged);
1550}
1551
1552bool QQStyleKitDelegateProperties::fillWidth() const
1553{
1554 return styleProperty<bool>(QQSK::Property::FillWidth);
1555}
1556
1557void QQStyleKitDelegateProperties::setFillWidth(bool fill)
1558{
1559 if (setStyleProperty(QQSK::Property::FillWidth, fill))
1560 handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillWidthChanged);
1561}
1562
1563bool QQStyleKitDelegateProperties::fillHeight() const
1564{
1565 return styleProperty<bool>(QQSK::Property::FillHeight);
1566}
1567
1568void QQStyleKitDelegateProperties::setFillHeight(bool fill)
1569{
1570 if (setStyleProperty(QQSK::Property::FillHeight, fill))
1571 handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillHeightChanged);
1572}
1573
1574qreal QQStyleKitDelegateProperties::margins() const
1575{
1576 return styleProperty<qreal>(QQSK::Property::Margins);
1577}
1578
1579void QQStyleKitDelegateProperties::setMargins(qreal margins)
1580{
1581 if (setStyleProperty(QQSK::Property::Margins, margins))
1582 handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
1583 &QQStyleKitDelegateProperties::marginsChanged,
1584 &QQStyleKitDelegateProperties::leftMarginChanged,
1585 &QQStyleKitDelegateProperties::rightMarginChanged,
1586 &QQStyleKitDelegateProperties::topMarginChanged,
1587 &QQStyleKitDelegateProperties::bottomMarginChanged);
1588}
1589
1590qreal QQStyleKitDelegateProperties::leftMargin() const
1591{
1592 return styleProperty<qreal>(QQSK::Property::LeftMargin, QQSK::Property::Margins);
1593}
1594
1595void QQStyleKitDelegateProperties::setLeftMargin(qreal margin)
1596{
1597 if (setStyleProperty(QQSK::Property::LeftMargin, margin))
1598 handleStylePropertyChanged(&QQStyleKitDelegateProperties::leftMarginChanged);
1599}
1600
1601qreal QQStyleKitDelegateProperties::rightMargin() const
1602{
1603 return styleProperty<qreal>(QQSK::Property::RightMargin, QQSK::Property::Margins);
1604}
1605
1606void QQStyleKitDelegateProperties::setRightMargin(qreal margin)
1607{
1608 if (setStyleProperty(QQSK::Property::RightMargin, margin))
1609 handleStylePropertyChanged(&QQStyleKitDelegateProperties::rightMarginChanged);
1610}
1611
1612qreal QQStyleKitDelegateProperties::topMargin() const
1613{
1614 return styleProperty<qreal>(QQSK::Property::TopMargin, QQSK::Property::Margins);
1615}
1616
1617void QQStyleKitDelegateProperties::setTopMargin(qreal margin)
1618{
1619 if (setStyleProperty(QQSK::Property::TopMargin, margin))
1620 handleStylePropertyChanged(&QQStyleKitDelegateProperties::topMarginChanged);
1621}
1622
1623qreal QQStyleKitDelegateProperties::bottomMargin() const
1624{
1625 return styleProperty<qreal>(QQSK::Property::BottomMargin, QQSK::Property::Margins);
1626}
1627
1628void QQStyleKitDelegateProperties::setBottomMargin(qreal margin)
1629{
1630 if (setStyleProperty(QQSK::Property::BottomMargin, margin))
1631 handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomMarginChanged);
1632}
1633
1634Qt::Alignment QQStyleKitDelegateProperties::alignment() const
1635{
1636 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment, Qt::AlignLeft | Qt::AlignVCenter);
1637}
1638
1639void QQStyleKitDelegateProperties::setAlignment(Qt::Alignment alignment)
1640{
1641 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1642 handleStylePropertyChanged(&QQStyleKitDelegateProperties::alignmentChanged);
1643}
1644
1645qreal QQStyleKitDelegateProperties::opacity() const
1646{
1647 return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
1648}
1649
1650void QQStyleKitDelegateProperties::setOpacity(qreal opacity)
1651{
1652 if (setStyleProperty(QQSK::Property::Opacity, opacity))
1653 handleStylePropertyChanged(&QQStyleKitDelegateProperties::opacityChanged);
1654}
1655
1656QColor QQStyleKitDelegateProperties::color() const
1657{
1658 return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
1659}
1660
1661void QQStyleKitDelegateProperties::setColor(const QColor &color)
1662{
1663 if (setStyleProperty(QQSK::Property::Color, color))
1664 handleStylePropertyChanged(&QQStyleKitDelegateProperties::colorChanged);
1665}
1666
1667bool QQStyleKitDelegateProperties::visible() const
1668{
1669 return styleProperty<bool>(QQSK::Property::Visible, true);
1670}
1671
1672void QQStyleKitDelegateProperties::setVisible(bool visible)
1673{
1674 if (setStyleProperty(QQSK::Property::Visible, visible))
1675 handleStylePropertyChanged(&QQStyleKitDelegateProperties::visibleChanged);
1676}
1677
1678bool QQStyleKitDelegateProperties::clip() const
1679{
1680 return styleProperty<bool>(QQSK::Property::Clip, false);
1681}
1682
1683void QQStyleKitDelegateProperties::setClip(bool clip)
1684{
1685 if (setStyleProperty(QQSK::Property::Clip, clip))
1686 handleStylePropertyChanged(&QQStyleKitDelegateProperties::clipChanged);
1687}
1688
1689QQuickGradient *QQStyleKitDelegateProperties::gradient() const
1690{
1691 return styleProperty<QQuickGradient *>(QQSK::Property::Gradient);
1692}
1693
1694void QQStyleKitDelegateProperties::setGradient(QQuickGradient *gradient)
1695{
1696 if (setStyleProperty(QQSK::Property::Gradient, gradient))
1697 handleStylePropertyChanged(&QQStyleKitDelegateProperties::gradientChanged);
1698}
1699
1700QObject *QQStyleKitDelegateProperties::data() const
1701{
1702 return styleProperty<QObject *>(QQSK::Property::Data);
1703}
1704
1705void QQStyleKitDelegateProperties::setData(QObject *data)
1706{
1707 if (setStyleProperty(QQSK::Property::Data, data))
1708 handleStylePropertyChanged(&QQStyleKitDelegateProperties::dataChanged);
1709}
1710
1711QQmlComponent *QQStyleKitDelegateProperties::delegate() const
1712{
1713 return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
1714}
1715
1716void QQStyleKitDelegateProperties::setDelegate(QQmlComponent *delegate)
1717{
1718 if (setStyleProperty(QQSK::Property::Delegate, delegate))
1719 handleStylePropertyChanged(&QQStyleKitDelegateProperties::delegateChanged);
1720}
1721
1722QQStyleKitBorderProperties *QQStyleKitDelegateProperties::border() const
1723{
1724 return lazyCreateGroup(m_border, QQSK::PropertyGroup::Border);
1725}
1726
1727QQStyleKitShadowProperties *QQStyleKitDelegateProperties::shadow() const
1728{
1729 return lazyCreateGroup(m_shadow, QQSK::PropertyGroup::Shadow);
1730}
1731
1732QQStyleKitImageProperties *QQStyleKitDelegateProperties::image() const
1733{
1734 return lazyCreateGroup(m_image, QQSK::PropertyGroup::Image);
1735}
1736
1737// ************* QQStyleKitHandleProperties ****************
1738
1739QQStyleKitHandleProperties::QQStyleKitHandleProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1740 : QQStyleKitDelegateProperties(group, parent)
1741{
1742}
1743
1745 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1746{
1747 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1748 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1749 if (m_first)
1750 f(m_first);
1751 if (m_second)
1752 f(m_second);
1753}
1754
1755QQStyleKitDelegateProperties *QQStyleKitHandleProperties::first() const
1756{
1757 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1758}
1759
1760QQStyleKitDelegateProperties *QQStyleKitHandleProperties::second() const
1761{
1762 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
1763}
1764
1765// ************* QQStyleKitIndicatorProperties ****************
1766
1767QQStyleKitIndicatorProperties::QQStyleKitIndicatorProperties(
1768 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1769 : QQStyleKitDelegateProperties(group, parent)
1770{
1771}
1772
1773template <typename... CHANGED_SIGNALS>
1775 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1776{
1777 // Go through all instances of QQStyleKitIndicatorProperties
1778 const QQStyleKitControlProperties *cp = controlProperties();
1779 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->first());
1780 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->second());
1781}
1782
1784 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1785{
1786 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1787 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1788 if (m_foreground)
1789 f(m_foreground);
1790}
1791
1792QQStyleKitDelegateProperties *QQStyleKitIndicatorProperties::foreground() const
1793{
1794 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1795}
1796
1797// ************* QQStyleKitIndicatorWithSubTypes ****************
1798
1799QQStyleKitIndicatorWithSubTypes::QQStyleKitIndicatorWithSubTypes(
1800 QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1801 : QQStyleKitDelegateProperties(group, parent)
1802{
1803}
1804
1805template <typename... CHANGED_SIGNALS>
1807 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1808{
1809 // Go through all instances of QQStyleKitIndicatorWithSubTypes
1810 const QQStyleKitControlProperties *cp = controlProperties();
1812}
1813
1815 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1816{
1817 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1818 QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
1819 if (m_foreground)
1820 f(m_foreground);
1821 if (m_first)
1822 f(m_first);
1823 if (m_second)
1824 f(m_second);
1825}
1826
1827QQStyleKitDelegateProperties *QQStyleKitIndicatorWithSubTypes::foreground() const
1828{
1829 return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
1830}
1831
1836
1841
1843{
1844 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1845}
1846
1848{
1849 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
1850}
1851
1852// ************* QQStyleKitTextProperties ****************
1853QQStyleKitTextProperties::QQStyleKitTextProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
1854 : QQStyleKitPropertyGroup(group, parent)
1855{
1856}
1857
1858template <typename... CHANGED_SIGNALS>
1860 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
1861{
1862 const QQStyleKitControlProperties *cp = controlProperties();
1864 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->first());
1865 CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->second());
1866}
1867
1869 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
1870{
1871 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
1872 if (m_first)
1873 f(m_first);
1874 if (m_second)
1875 f(m_second);
1876}
1877
1879{
1880 return styleProperty<QColor>(QQSK::Property::Color);
1881}
1882
1883void QQStyleKitTextProperties::setColor(const QColor &color)
1884{
1885 if (setStyleProperty(QQSK::Property::Color, color))
1886 handleStylePropertyChanged(&QQStyleKitTextProperties::colorChanged);
1887}
1888
1890{
1891 return styleProperty<Qt::Alignment>(QQSK::Property::Alignment);
1892}
1893
1894void QQStyleKitTextProperties::setAlignment(Qt::Alignment alignment)
1895{
1896 if (setStyleProperty(QQSK::Property::Alignment, alignment))
1897 handleStylePropertyChanged(&QQStyleKitTextProperties::alignmentChanged);
1898}
1899
1901{
1902 return styleProperty<bool>(QQSK::Property::Bold, false);
1903}
1904
1906{
1907 if (setStyleProperty(QQSK::Property::Bold, bold))
1908 handleStylePropertyChanged(&QQStyleKitTextProperties::boldChanged);
1909}
1910
1912{
1913 return styleProperty<bool>(QQSK::Property::Italic, false);
1914}
1915
1917{
1918 if (setStyleProperty(QQSK::Property::Italic, italic))
1919 handleStylePropertyChanged(&QQStyleKitTextProperties::italicChanged);
1920}
1921
1923{
1924 return styleProperty<qreal>(QQSK::Property::PointSize, QFont().pointSize());
1925}
1926
1928{
1929 if (setStyleProperty(QQSK::Property::PointSize, pointSize))
1930 handleStylePropertyChanged(&QQStyleKitTextProperties::pointSizeChanged);
1931}
1932
1934{
1935 return styleProperty<qreal>(QQSK::Property::Padding);
1936}
1937
1948
1950{
1951 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
1952}
1953
1955{
1956 if (setStyleProperty(QQSK::Property::LeftPadding, padding))
1957 handleStylePropertyChanged(&QQStyleKitTextProperties::leftPaddingChanged);
1958}
1959
1961{
1962 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
1963}
1964
1966{
1967 if (setStyleProperty(QQSK::Property::RightPadding, padding))
1968 handleStylePropertyChanged(&QQStyleKitTextProperties::rightPaddingChanged);
1969}
1970
1972{
1973 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
1974}
1975
1977{
1978 if (setStyleProperty(QQSK::Property::TopPadding, padding))
1979 handleStylePropertyChanged(&QQStyleKitTextProperties::topPaddingChanged);
1980}
1981
1983{
1984 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
1985}
1986
1988{
1989 if (setStyleProperty(QQSK::Property::BottomPadding, padding))
1990 handleStylePropertyChanged(&QQStyleKitTextProperties::bottomPaddingChanged);
1991}
1992
1994{
1995 return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
1996}
1997
1999{
2000 return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
2001}
2002
2003// ************* QQStyleKitControlProperties ****************
2004
2005QQStyleKitControlProperties::QQStyleKitControlProperties(QQSK::PropertyGroup group, QObject *parent)
2006 : QQStyleKitPropertyGroup(group, parent)
2007{
2008 /* Calculate the free space storage ID space that can accommodate all unique style
2009 * properties that may be applied to a control. Since we'll prepend different states
2010 * and subtypes during the property propagation lookup phase later, we need to reserve
2011 * ID space for them both already now. More docs about the property space is written in
2012 * the implementation of QQStyleKitPropertyPath. */
2013 m_groupSpace.size = nestedGroupsStartSize;
2014 m_groupSpace.start = 0;
2015
2016 if (group == QQSK::PropertyGroup::GlobalFlag) {
2017 /* A property path may include pseudo-groups that offers a convenient API for
2018 * reading properties with specific options applied. The 'global' group is one such
2019 * pseudo-group. When it is prefixed to a property path, it indicates that the property
2020 * should be read directly from the style, bypassing any active transitions that might
2021 * otherwise affect its value.
2022 * Note: The global group should be ignored when computing a PropertyPathId, as it
2023 * only affect _where_ the property should be read from, not its ID. */
2024 m_pathFlags.setFlag(QQSK::PropertyPathFlag::Global);
2025 }
2026}
2027
2028QQStyleKitStyle *QQStyleKitControlProperties::style() const
2029{
2030 if (subclass() == QQSK::Subclass::QQStyleKitState) {
2031 /* A QQStyleKitControlState (and its subclasses) should always be a (grand)child of a
2032 * QQStyleKitStyle. And it belongs to that style, even it that style is not the
2033 * currently active application style. This is opposed to a QQStyleKitReader,
2034 * that normally belongs / communicates with the currently active style.
2035 * NOTE: a style can also be a fallback style for another style (which can be recursive,
2036 * meaning that a fallback style can also have its own fallback style, and so on). But
2037 * this function will return the nearest style, and not the root style */
2038 QObject *obj = parent();
2039 while (obj && !obj->metaObject()->inherits(&QQStyleKitStyle::staticMetaObject))
2040 obj = obj->parent();
2041 return obj ? static_cast<QQStyleKitStyle *>(obj) : nullptr;
2042 }
2043
2044 if (subclass() == QQSK::Subclass::QQStyleKitReader) {
2045 const auto *reader = static_cast<const QQStyleKitReader *>(this);
2046 if (reader->m_explicitStyle)
2047 return reader->m_explicitStyle;
2048 }
2049
2050 // For a QQStyleKitReader without an explicit style, we return the currently active style for now
2051 return QQStyleKitStyle::current();
2052}
2053
2054QQSK::Subclass QQStyleKitControlProperties::subclass() const
2055{
2056 /* QQStyleKitControlProperties is subclassed by several different classes in this
2057 * framework. As such, it's basically just an interface because it only declares the
2058 * different properties that can be read or written to in a QQStyleKitStyle, such as
2059 * hovered.background.color or pressed.indicator.foreground.color. It says nothing
2060 * about how those properties are stored, instead that is up to each individual
2061 * subclass to decide */
2062 if (metaObject()->inherits(&QQStyleKitReader::staticMetaObject))
2063 return QQSK::Subclass::QQStyleKitReader;
2064 if (metaObject()->inherits(&QQStyleKitControlState::staticMetaObject))
2065 return QQSK::Subclass::QQStyleKitState;
2066 Q_UNREACHABLE();
2067}
2068
2069QQStyleKitReader *QQStyleKitControlProperties::asQQStyleKitReader() const
2070{
2071 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitReader);
2072 return static_cast<QQStyleKitReader *>(const_cast<QQStyleKitControlProperties *>(this));
2073}
2074
2075QQStyleKitControlState *QQStyleKitControlProperties::asQQStyleKitState() const
2076{
2077 Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitState);
2078 Q_ASSERT(metaObject()->inherits(&QQStyleKitControlState::staticMetaObject));
2079 return static_cast<QQStyleKitControlState *>(const_cast<QQStyleKitControlProperties *>(this));
2080}
2081
2082void QQStyleKitControlProperties::forEachUsedDelegate(
2083 std::function<void (QQStyleKitDelegateProperties *, QQSK::Delegate, const QString &)> f)
2084{
2085 // If adding more delegates here, remember to keep StyleAnimation.qml in sync
2086 if (m_background)
2087 f(m_background, QQSK::Delegate::Background, "background"_L1);
2088
2089 if (m_indicator) {
2090 f(m_indicator, QQSK::Delegate::Indicator, "indicator"_L1);
2091 if (m_indicator->m_foreground)
2092 f(m_indicator->m_foreground, QQSK::Delegate::IndicatorForeground, "indicator.foreground"_L1);
2093 if (m_indicator->m_first) {
2094 f(m_indicator->m_first, QQSK::Delegate::IndicatorFirst, "indicator.first"_L1);
2095 if (m_indicator->m_first->m_foreground)
2096 f(m_indicator->m_first->m_foreground, QQSK::Delegate::IndicatorFirstForeground, "indicator.first.foreground"_L1);
2097 }
2098 if (m_indicator->m_second) {
2099 f(m_indicator->m_second, QQSK::Delegate::IndicatorSecond, "indicator.second"_L1);
2100 if (m_indicator->m_second->m_foreground)
2101 f(m_indicator->m_second->m_foreground, QQSK::Delegate::IndicatorSecondForeground, "indicator.second.foreground"_L1);
2102 }
2103 }
2104
2105 if (m_handle) {
2106 f(m_handle, QQSK::Delegate::Handle, "handle"_L1);
2107 if (m_handle->m_first)
2108 f(m_handle->m_first, QQSK::Delegate::HandleFirst, "handle.first"_L1);
2109 if (m_handle->m_second)
2110 f(m_handle->m_second, QQSK::Delegate::HandleSecond, "handle.second"_L1);
2111 }
2112}
2113
2114void QQStyleKitControlProperties::emitChangedForAllStyleProperties(EmitFlags emitFlags)
2115{
2116 /* This brute-force function will emit update signals for _all_ style properties
2117 * in the QQStyleKitStyle API. Doing so is typically needed after a style-, or theme
2118 * change, as we don't know which properties are affected by such a big change. */
2119 emitChangedForAllStylePropertiesRecursive(emitFlags);
2120}
2121
2122template <typename... CHANGED_SIGNALS>
2123void QQStyleKitControlProperties::emitGlobally(
2124 QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
2125{
2126 for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
2127 if (reader->controlType() != controlType)
2128 continue;
2129 ((reader->*changedSignals)(), ...);
2130 }
2131}
2132
2133void QQStyleKitControlProperties::forEachExistingNestedGroup(
2134 const std::function<void (QQStyleKitPropertyGroup *)> &f) const
2135{
2136 // Keep in sync with the nested groups this class creates with lazyCreateGroup()
2137 if (m_background)
2138 f(m_background);
2139 if (m_handle)
2140 f(m_handle);
2141 if (m_indicator)
2142 f(m_indicator);
2143 if (m_text)
2144 f(m_text);
2145}
2146
2147qreal QQStyleKitControlProperties::spacing() const
2148{
2149 return styleProperty<qreal>(QQSK::Property::Spacing);
2150}
2151
2152void QQStyleKitControlProperties::setSpacing(qreal spacing)
2153{
2154 if (setStyleProperty(QQSK::Property::Spacing, spacing))
2155 handleStylePropertyChanged(&QQStyleKitControlProperties::spacingChanged);
2156}
2157
2158qreal QQStyleKitControlProperties::padding() const
2159{
2160 return styleProperty<qreal>(QQSK::Property::Padding);
2161}
2162
2163void QQStyleKitControlProperties::setPadding(qreal padding)
2164{
2165 if (setStyleProperty(QQSK::Property::Padding, padding))
2166 handleStylePropertiesChanged<QQStyleKitControlProperties>(
2167 &QQStyleKitControlProperties::paddingChanged,
2168 &QQStyleKitControlProperties::leftPaddingChanged,
2169 &QQStyleKitControlProperties::rightPaddingChanged,
2170 &QQStyleKitControlProperties::topPaddingChanged,
2171 &QQStyleKitControlProperties::bottomPaddingChanged);
2172}
2173
2174qreal QQStyleKitControlProperties::leftPadding() const
2175{
2176 return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
2177}
2178
2179void QQStyleKitControlProperties::setLeftPadding(qreal leftPadding)
2180{
2181 if (setStyleProperty(QQSK::Property::LeftPadding, leftPadding))
2182 handleStylePropertyChanged(&QQStyleKitControlProperties::leftPaddingChanged);
2183}
2184
2185qreal QQStyleKitControlProperties::rightPadding() const
2186{
2187 return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
2188}
2189
2190void QQStyleKitControlProperties::setRightPadding(qreal rightPadding)
2191{
2192 if (setStyleProperty(QQSK::Property::RightPadding, rightPadding))
2193 handleStylePropertyChanged(&QQStyleKitControlProperties::rightPaddingChanged);
2194}
2195
2196qreal QQStyleKitControlProperties::topPadding() const
2197{
2198 return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
2199}
2200
2201void QQStyleKitControlProperties::setTopPadding(qreal topPadding)
2202{
2203 if (setStyleProperty(QQSK::Property::TopPadding, topPadding))
2204 handleStylePropertyChanged(&QQStyleKitControlProperties::topPaddingChanged);
2205}
2206
2207qreal QQStyleKitControlProperties::bottomPadding() const
2208{
2209 return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
2210}
2211
2212void QQStyleKitControlProperties::setBottomPadding(qreal bottomPadding)
2213{
2214 if (setStyleProperty(QQSK::Property::BottomPadding, bottomPadding))
2215 handleStylePropertyChanged(&QQStyleKitControlProperties::bottomPaddingChanged);
2216}
2217
2218QQuickTransition *QQStyleKitControlProperties::transition() const
2219{
2220 return styleProperty<QQuickTransition *>(QQSK::Property::Transition);
2221}
2222
2223void QQStyleKitControlProperties::setTransition(QQuickTransition *transition)
2224{
2225 if (setStyleProperty(QQSK::Property::Transition, transition))
2226 handleStylePropertyChanged(&QQStyleKitControlProperties::transitionChanged);
2227}
2228
2229QQStyleKitTextProperties *QQStyleKitControlProperties::text() const
2230{
2231 return lazyCreateGroup(m_text, QQSK::PropertyGroup::Text);
2232}
2233
2234QQStyleKitDelegateProperties *QQStyleKitControlProperties::background() const
2235{
2236 return lazyCreateGroup(m_background, QQSK::PropertyGroup::Background);
2237}
2238
2239QQStyleKitHandleProperties *QQStyleKitControlProperties::handle() const
2240{
2241 return lazyCreateGroup(m_handle, QQSK::PropertyGroup::Handle);
2242}
2243
2244QQStyleKitIndicatorWithSubTypes *QQStyleKitControlProperties::indicator() const
2245{
2246 return lazyCreateGroup(m_indicator, QQSK::PropertyGroup::Indicator);
2247}
2248
2249QT_END_NAMESPACE
2250
2251#include "moc_qqstylekitcontrolproperties_p.cpp"
QObject * parent
Definition qobject.h:74
QQStyleKitDelegateProperties * first() const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
QQStyleKitDelegateProperties * second() const
QQStyleKitDelegateProperties * foreground() const
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
QQStyleKitDelegateProperties * foreground() const
QQStyleKitIndicatorProperties * down() const
QQStyleKitIndicatorProperties * up() const
QQStyleKitIndicatorProperties * second() const
QQStyleKitIndicatorProperties * first() const
void emitChangedForAllStylePropertiesRecursive(EmitFlags emitFlags)
T * lazyCreateGroup(T *const &ptr, QQSK::PropertyGroup group) const
void handleStylePropertyChanged(void(SUBCLASS::*changedSignal)())
virtual void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const
void handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
QQStyleKitControlProperties * controlProperties() const
void setBottomPadding(qreal bottomPadding)
void forEachExistingNestedGroup(const std::function< void(QQStyleKitPropertyGroup *)> &f) const override
void emitGlobally(QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
QQStyleKitTextProperties * first() const
QQStyleKitTextProperties * second() const
Combined button and popup list for selecting options.
#define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH)