Revision control

++ // Copyright (C) 2025 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ #include "qqstylekitcontrol_p.h"
++ #include "qqstylekitstyle_p.h"
++ #include "qqstylekittheme_p.h"
++ #include "qqstylekitcontrolproperties_p.h"
++ #include "qqstylekitpropertyresolver_p.h"
++
++ QT_BEGIN_NAMESPACE
++
++ // ************* ControlStyleProperties ****************
++
++ /*!
++ \qmltype ControlStyleProperties
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the stylable properties for a control.
++
++ ControlStyleProperties defines the stylable properties for a
++ control: the visual building blocks \l background, \l indicator, \l handle,
++ and \l text, as well as layout properties like \l padding, \l spacing,
++ and \l transition.
++
++ The style properties are accessed through inherited types such as
++ \l ControlStyle and \l StyleReader.
++
++ \labs
++
++ \sa ControlStyle, StyleReader, ControlStateStyle, DelegateStyle
++ */
++
++ /*!
++ \qmlproperty DelegateStyle ControlStyleProperties::background
++
++ Grouped property for styling the background of a control.
++
++ The background delegate is typically the main visual rectangle behind
++ the control. Use it to set \l {DelegateStyle::color}{colors},
++ \l {DelegateStyle::border}{borders},
++ \l {DelegateStyle::radius}{radii},
++ \l {DelegateStyle::shadow}{shadows},
++ \l {DelegateStyle::gradient}{gradients},
++ and \l {DelegateStyle::image}{images}.
++
++ \note The default \l {Style.fallbackStyle}{fallback style} sets \c {background.visible}
++ to \c false for controls that typically should not draw a background,
++ such as \l [QtQuickControls]{CheckBox}, \l [QtQuickControls]{RadioButton},
++ and \l [QtQuickControls]{Slider}. To show their background, set
++ \c {background.visible} to \c true explicitly.
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::bottomPadding
++
++ The \l [QtQuickControls]{Control Layout}{bottom padding}
++ of the control. If not set, falls back to \l padding.
++
++ \sa padding, topPadding, leftPadding, rightPadding
++ */
++
++ /*!
++ \qmlproperty HandleStyle ControlStyleProperties::handle
++
++ Grouped property for styling the handle of a control.
++
++ The handle is used by controls such as \l [QtQuickControls]{Switch},
++ \l [QtQuickControls]{Slider}, and \l [QtQuickControls]{RangeSlider}.
++ For a RangeSlider, the two handles can be styled individually through
++ \l {HandleStyle.first}{handle.first} and \l {HandleStyle.second}{handle.second}.
++
++ \sa HandleStyle, DelegateStyle
++ */
++
++ /*!
++ \qmlproperty IndicatorStyle ControlStyleProperties::indicator
++
++ Grouped property for styling the indicator of a control. For a
++ \l {StylableControls::}{checkBox}, the indicator is the
++ frame, and its \l {IndicatorStyle::}{foreground} is the check mark.
++ For a \l {StylableControls::}{slider}, the indicator is
++ the groove, and the foreground is the fill.
++
++ \sa DelegateStyle
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::leftPadding
++
++ The \l [QtQuickControls]{Control Layout}{left padding} of the control. If not set, falls back to
++ \l padding.
++
++ \sa padding, rightPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::padding
++
++ The uniform spacing between the
++ \l [QtQuickControls]{Control Layout}{control's content area and the
++ bounds of the control}. Setting this provides a default value for
++ \l leftPadding, \l rightPadding, \l topPadding, and \l bottomPadding.
++ Each side can be overridden individually.
++
++ \sa leftPadding, rightPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::rightPadding
++
++ The \l [QtQuickControls]{Control Layout}{right padding} of the control.
++ If not set, falls back to \l padding.
++
++ \sa padding, leftPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::spacing
++
++ The spacing between visual elements inside the control, for example
++ between an indicator and a label.
++ */
++
++ /*!
++ \qmlproperty TextStyle ControlStyleProperties::text
++
++ Grouped property for styling the text label of a control.
++ */
++
++ /*!
++ \qmlproperty real ControlStyleProperties::topPadding
++
++ The \l [QtQuickControls]{Control Layout}{top padding}
++ of the control. If not set, falls back to \l padding.
++
++ \sa padding, bottomPadding, leftPadding, rightPadding
++ */
++
++ /*!
++ \qmlproperty Transition ControlStyleProperties::transition
++
++ A \l [QtQuick]{Transition} used to animate style properties when the
++ control enters a new state, such as \l {ControlStateStyle::}{hovered}
++ or \l {ControlStateStyle::}{pressed}. If set
++ to \c null (the default), property changes are applied immediately
++ without animation.
++
++ \snippet DelegateStyle_transitions.qml custom transition
++
++ To avoid repeating the same target properties for each delegate,
++ StyleKit provides \l StyleAnimation for convenience, which can be
++ used instead of, or in combination with, the
++ \l {Animation and Transitions in Qt Quick}{standard animations:}
++
++ \snippet DelegateStyle_transitions.qml transition
++
++ \note For color properties that participate in a transition, prefer
++ \l {Qt.alpha} over \c "transparent"
++ (e.g. \c {menuBarItem.background.color: Qt.alpha(palette.accent, 0)}).
++ \c "transparent" is \c {Qt.rgba(0, 0, 0, 0)}, which can pull interpolated
++ colors toward black during the transition.
++ */
++
++ // ************* DelegateStyle ****************
++
++ /*!
++ \qmltype DelegateStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the visual appearance of an element within a control.
++
++ DelegateStyle describes the visual appearance of a visual element
++ within a \l ControlStyle, such as its \l {ControlStyleProperties::}{background},
++ \l {ControlStyleProperties::}{indicator}, or a sub-element like
++ \l {IndicatorStyle::foreground}{indicator.foreground}.
++ It provides properties for controlling
++ \l {DelegateStyle::width}{size},
++ \l {DelegateStyle::}{color}, \l {DelegateStyle::}{border},
++ \l {DelegateStyle::}{radius}, \l {DelegateStyle::}{shadow},
++ \l {DelegateStyle::}{image}, \l {DelegateStyle::}{opacity}, and more.
++
++ \labs
++
++ \sa ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty Qt::Alignment DelegateStyle::alignment
++
++ The alignment of the delegate within its parent. The default
++ value is \c {Qt.AlignLeft | Qt.AlignVCenter}.
++ */
++
++ /*!
++ \qmlproperty BorderStyle DelegateStyle::border
++
++ Grouped property for styling the border of this delegate.
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::bottomLeftRadius
++
++ The bottom-left corner radius. If not set, falls back to \l radius.
++
++ \sa radius, topLeftRadius, topRightRadius, bottomRightRadius
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::bottomMargin
++
++ The bottom margin of this delegate. If not set, falls back to
++ \l margins.
++
++ \sa margins, topMargin, leftMargin, rightMargin
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::bottomRightRadius
++
++ The bottom-right corner radius. If not set, falls back to \l radius.
++
++ \sa radius, topLeftRadius, topRightRadius, bottomLeftRadius
++ */
++
++ /*!
++ \qmlproperty bool DelegateStyle::clip
++
++ Whether the delegate clips its contents. The default value is \c false.
++ */
++
++ /*!
++ \qmlproperty color DelegateStyle::color
++
++ The fill color of this delegate. The default value is \c transparent.
++
++ Unlike a Quick \l [QtQuick]{Rectangle}, where a gradient replaces
++ the color, StyleKit draws the \l gradient on top of the color. This
++ means you can use a semi-transparent gradient as an overlay (for
++ example, a subtle shading effect) while the color shows through
++ underneath.
++
++ \snippet ControlStateStyle_properties.qml color and gradient
++
++ \sa gradient, opacity
++ */
++
++ /*!
++ \qmlproperty QObject DelegateStyle::data
++
++ An arbitrary object that can be used for passing
++ custom data from the style to a custom \l delegate component.
++
++ This allows you to define custom style properties beyond what the
++ StyleKit API provides. The data object can vary between states and
++ themes, making it possible to style elements in a custom \l delegate
++ that are not covered by the built-in properties.
++
++ The following snippet uses a custom delegate that draws an overlay
++ \l Text whose color varies depending on the control's state. The delegate
++ inherits \l StyledItem, which is optional but ensures the rest of
++ the button background is rendered normally.
++
++ \snippet DelegateStyle_delegates.qml data
++
++ \note The \c data object is propagated as a whole. Unlike regular style
++ properties, individual properties \e inside the data object do not
++ propagate separately.
++
++ \sa delegate
++ */
++
++ /*!
++ \qmlproperty Component DelegateStyle::delegate
++
++ The delegate used to render the DelegateStyle in a
++ \l {Qt Quick Controls}{Qt Quick Control}.
++
++ The default value is \c null, in which case \l StyledItem is used
++ for rendering instead. If you want to hide the delegate altogether
++ (and prevent if from being created), set \l visible to \c false.
++
++ The delegate needs to define the following required properties:
++ \qml
++ required property DelegateStyle delegateStyle
++ required property QtObject control
++ \endqml
++
++ \c delegateStyle points to the DelegateStyle that describes how the
++ delegate should be styled. \c control points to the
++ \l {Qt Quick Controls}{Qt Quick Control} that owns the delegate. The latter
++ can be used to resolve additional information about the control not
++ available from the style.
++
++ If you know the specific type of the owning control, you can use it
++ instead of \l QtObject for the \c control property. For example, since
++ a handle delegate in the snippet below is always used inside a Slider, the
++ type can be set to \l {Qt Quick Templates 2 QML Types}{T.Slider}:
++
++ \snippet DelegateStyle_delegates.qml delegate
++
++ \note If a DelegateStyle has a \l {shadow}{drop shadow} defined, it will be
++ drawn separately by a \l {ShadowStyle::delegate}{shadow delegate.}
++
++ \sa data, visible, StyledItem
++ */
++
++ /*!
++ \qmlproperty Gradient DelegateStyle::gradient
++
++ The gradient of this delegate. The default value is \c null (no gradient).
++
++ Unlike a Quick \l [QtQuick]{Rectangle}, where a gradient replaces
++ the color, StyleKit draws the \l gradient on top of the color. This
++ means you can use a semi-transparent gradient as an overlay (for
++ example, a subtle shading effect) while the color shows through
++ underneath.
++
++ \snippet ControlStateStyle_properties.qml color and gradient
++
++ \sa color
++ */
++
++ /*!
++ \qmlproperty ImageStyle DelegateStyle::image
++
++ Grouped property for placing an image inside this delegate.
++
++ \sa ImageStyle
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::width
++
++ The width of this delegate.
++
++ \note This property will only set the delegate width when \l fillWidth is \c false. This also
++ applies when \l fillWidth is set higher up in the style hierarchy, for example
++ in the \l {Style::fallbackStyle}{fallback style}.
++
++ If this delegate is at the root of the control — for example the
++ \l {ControlStyleProperties::background}{background} or the
++ \l {ControlStyleProperties::indicator}{indicator} — it will also be included when
++ calculating the \l [QtQuick]{Item::implicitWidth}{implicit width} of the control, even when \l fillWidth is \c true.
++
++ \sa height, fillWidth, minimumWidth, {StyleKit Property Resolution}
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::height
++
++ The height of this delegate.
++
++ \note This property will only set the delegate height when \l fillHeight is \c false. This also
++ applies when \l fillHeight is set higher up in the style hierarchy, for example
++ in the \l {Style::fallbackStyle}{fallback style}.
++
++ If this delegate is at the root of the control — for example the
++ \l {ControlStyleProperties::background}{background} or the
++ \l {ControlStyleProperties::indicator}{indicator} — it will also be included when
++ calculating the \l [QtQuick]{Item::implicitHeight}{implicit height} of the control, even when \l fillHeight is \c true.
++
++ \sa width, fillHeight, minimumHeight, {StyleKit Property Resolution}
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::leftMargin
++
++ The left margin of this delegate. If not set, falls back to
++ \l margins.
++
++ \sa margins, rightMargin, topMargin, bottomMargin
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::margins
++
++ The uniform margin around this delegate. Setting this provides a
++ default value for \l leftMargin, \l rightMargin, \l topMargin,
++ and \l bottomMargin. Each side can be overridden individually.
++
++ \sa leftMargin, rightMargin, topMargin, bottomMargin
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::minimumWidth
++
++ The minimum width of this delegate. The delegate will not be sized
++ smaller than this value.
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::minimumHeight
++
++ The minimum height of this delegate. The delegate will not be sized
++ smaller than this value.
++ */
++
++ /*!
++ \qmlproperty bool DelegateStyle::fillWidth
++
++ Whether the delegate should fill the available width of the parent item.
++
++ Some delegates, such as the groove of a \l [QtQuickControls]{Slider}, are
++ often expected to fill the available width of the control, rather than
++ having a fixed implicit width. This can be achieved by setting
++ \c fillWidth to \c true. To add some space between the delegate and the
++ edges of its parent, use the \l margins properties.
++
++ If \c fillWidth is \c false, the delegate's width is determined by its \l width.
++
++ \sa fillHeight, width
++ */
++
++ /*!
++ \qmlproperty bool DelegateStyle::fillHeight
++
++ Whether the delegate should fill the available height of the parent item.
++
++ Some delegates, such as the foreground of a checkbox indicator, are often expected
++ to fill the available height (and width) of the indicator, rather than
++ having a fixed height. This can be achieved by setting
++ \c fillHeight to \c true. To add some space between the delegate and the
++ edges of its parent, use the \l margins properties.
++
++ If \c fillHeight is \c false, the delegate's height is determined by its \l height.
++
++ \sa fillWidth, height
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::opacity
++
++ The opacity of this delegate, from \c 0.0 (fully transparent) to
++ \c 1.0 (fully opaque). The default value is \c 1.0.
++
++ \sa visible, color
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::radius
++
++ The corner radius applied to all four corners of this delegate.
++ Individual corners can be overridden with \l topLeftRadius,
++ \l topRightRadius, \l bottomLeftRadius, and \l bottomRightRadius.
++
++ \sa topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::rightMargin
++
++ The right margin of this delegate. If not set, falls back to
++ \l margins.
++
++ \sa margins, leftMargin, topMargin, bottomMargin
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::rotation
++
++ The rotation of this delegate, in degrees.
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::scale
++
++ The scale factor of this delegate. The default value is \c 1.0.
++ */
++
++ /*!
++ \qmlproperty ShadowStyle DelegateStyle::shadow
++
++ Grouped property for styling a drop shadow behind this delegate.
++
++ \sa ShadowStyle
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::topLeftRadius
++
++ The top-left corner radius. If not set, falls back to \l radius.
++
++ \sa radius, topRightRadius, bottomLeftRadius, bottomRightRadius
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::topMargin
++
++ The top margin of this delegate. If not set, falls back to
++ \l margins.
++
++ \sa margins, bottomMargin, leftMargin, rightMargin
++ */
++
++ /*!
++ \qmlproperty real DelegateStyle::topRightRadius
++
++ The top-right corner radius. If not set, falls back to \l radius.
++
++ \sa radius, topLeftRadius, bottomLeftRadius, bottomRightRadius
++ */
++
++ /*!
++ \qmlproperty bool DelegateStyle::visible
++
++ Whether this delegate is visible. The default value is \c true.
++
++ \note Although the default value is \c true, the
++ \l {Style::fallbackStyle}{fallback style} (which overrides many of the default
++ values) sets \c {background.visible} to \c false for controls that typically
++ should not draw a background, such as \l [QtQuickControls]{CheckBox},
++ \l [QtQuickControls]{RadioButton}, and \l [QtQuickControls]{Slider}.
++
++ When \c visible is \c false, the \l delegate will not be created. If you need
++ a hidden delegate to be created, consider setting \l opacity to \c 0 instead.
++
++ \sa opacity
++ */
++
++ // ************* ImageStyle ****************
++
++ /*!
++ \qmltype ImageStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the image style for a delegate.
++
++ ImageStyle provides properties for placing an image inside a
++ \l DelegateStyle. It is available as the
++ \l {DelegateStyle::image}{image} grouped property on any delegate.
++
++ \labs
++
++ \sa DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty color ImageStyle::color
++
++ A color overlay applied to the image. This is typically used to tint
++ monochrome icons to match the style's color scheme.
++ */
++
++ /*!
++ \qmlproperty enumeration ImageStyle::fillMode
++
++ How the image should be scaled or tiled within the delegate. The
++ value is one of the \l [QtQuick]{Image::fillMode}{Image.fillMode}
++ enum values.
++ */
++
++ /*!
++ \qmlproperty url ImageStyle::source
++
++ The URL of the image to display inside the delegate.
++ */
++
++ // ************* BorderStyle ****************
++
++ /*!
++ \qmltype BorderStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the border style for a delegate.
++
++ BorderStyle provides properties for the border drawn around a
++ \l DelegateStyle. It is available as the
++ \l {DelegateStyle::border}{border} grouped property on any delegate.
++
++ \labs
++
++ \sa DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty color BorderStyle::color
++
++ The color of the border. The default value is \c transparent.
++ */
++
++ /*!
++ \qmlproperty real BorderStyle::width
++
++ The width of the border in pixels.
++ */
++
++ // ************* ShadowStyle ****************
++
++ /*!
++ \qmltype ShadowStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the drop shadow style for a delegate.
++
++ ShadowStyle provides properties for rendering a drop shadow behind
++ a \l DelegateStyle. It is available as the
++ \l {DelegateStyle::shadow}{shadow} grouped property on any delegate.
++
++ \snippet DelegateStyle_shadow.qml drop shadow
++
++ By adjusting scale and color, shadows can also be used to create
++ glow effects. The following snippet adds a diffuse white glow to
++ the handle of a \l [QtQuickControls]{Switch} that intensifies
++ when checked:
++
++ \snippet DelegateStyle_shadow.qml glow
++
++ \labs
++
++ \sa DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty real ShadowStyle::blur
++
++ The blur of the shadow. A value of \c 0.0 produces a sharp shadow, while
++ larger values produce a softer, more diffuse shadow.
++ The default value is \c 10.0.
++ */
++
++ /*!
++ \qmlproperty color ShadowStyle::color
++
++ The color of the shadow. The default value is \c transparent, which
++ means that no shadow will be drawn by default.
++
++ \sa visible, opacity
++ */
++
++ /*!
++ \qmlproperty Component ShadowStyle::delegate
++
++ A custom QML \l [QML]{Component} that replaces the default shadow
++ rendering. When set, StyleKit instantiates this component instead
++ of drawing the default shadow.
++ */
++
++ /*!
++ \qmlproperty real ShadowStyle::horizontalOffset
++
++ The horizontal offset of the shadow from the delegate, in pixels.
++ */
++
++ /*!
++ \qmlproperty real ShadowStyle::opacity
++
++ The opacity of the shadow, from \c 0.0 (fully transparent) to
++ \c 1.0 (fully opaque). The default value is \c 1.0.
++
++ \sa visible, color
++ */
++
++ /*!
++ \qmlproperty real ShadowStyle::scale
++
++ The scale factor of the shadow relative to the delegate.
++ The default value is \c 1.0.
++ */
++
++ /*!
++ \qmlproperty real ShadowStyle::verticalOffset
++
++ The vertical offset of the shadow from the delegate, in pixels.
++ */
++
++ /*!
++ \qmlproperty bool ShadowStyle::visible
++
++ Whether the shadow is visible. The default value is \c true.
++
++ However, since the default shadow \l color is \c transparent,
++ the shadow will not be visible unless a different color is set.
++
++ \sa opacity
++ */
++
++ // ************* HandleStyle ****************
++
++ /*!
++ \qmltype HandleStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \inherits DelegateStyle
++ \brief Defines the handle style for controls such as \l [QtQuickControls]{Switch},
++ \l [QtQuickControls]{Slider} and \l [QtQuickControls]{RangeSlider}.
++
++ HandleStyle extends \l DelegateStyle with properties that are specific to
++ styling a handle.
++
++ Some controls have more than one handle. For example,
++ \l [QtQuickControls]{RangeSlider} has both a \l [QtQuickControls]{RangeSlider::}{first} and a \l [QtQuickControls]{RangeSlider::}{second} handle.
++ These can be styled independently using the \l first and \l second
++ sub-handles, \c {slider.handle.first} and \c {slider.handle.second}.
++ Properties not set on a sub-handle fall back to the handle itself.
++
++ \labs
++
++ \sa DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty DelegateStyle HandleStyle::first
++
++ Grouped property for styling the first handle of for example a
++ \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
++ the HandleStyle itself.
++ */
++
++ /*!
++ \qmlproperty DelegateStyle HandleStyle::second
++
++ Grouped property for styling the second handle of for example a
++ \l [QtQuickControls]{RangeSlider}. Unset properties fall back to
++ the HandleStyle itself.
++ */
++
++ // ************* SubIndicatorStyle ****************
++
++ /*!
++ \qmltype SubIndicatorStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \inherits DelegateStyle
++ \brief Defines the style for a sub-indicator delegate.
++
++ SubIndicatorStyle extends \l DelegateStyle with a \l foreground
++ property. It is used for styling sub-indicator delegates such as
++ \l {IndicatorStyle::first}{indicator.first} and
++ \l {IndicatorStyle::second}{indicator.second} in controls
++ with multiple indicators, like \l [QtQuickControls]{SpinBox}.
++ For SpinBox, \c {indicator.first} styles the increment button, and
++ \c {indicator.second} styles the decrement button.
++ It is equivalent to \l IndicatorStyle, but does not itself
++ contain sub-indicators.
++
++ \labs
++
++ \sa IndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty DelegateStyle SubIndicatorStyle::foreground
++
++ Grouped property for styling the foreground element of this
++ indicator. The foreground typically represents a checkmark, icon
++ or arrow rendered inside the indicator.
++ */
++
++ // ************* IndicatorStyle ****************
++
++ /*!
++ \qmltype IndicatorStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \inherits DelegateStyle
++ \brief Defines the style for a control's indicator.
++
++ IndicatorStyle extends \l DelegateStyle with properties that are specific to
++ styling an indicator.
++
++ The IndicatorStyle itself describes the indicator background, while the
++ \l foreground describes the content drawn inside it. For example,
++ \c {checkBox.indicator} styles the check box frame and
++ \c {checkBox.indicator.foreground} styles the check mark. For
++ \l {StylableControls::}{switchControl},
++ \l {StylableControls::}{slider} and
++ \l {StylableControls::}{progressBar}, the indicator styles
++ the groove and the foreground styles the fill.
++
++ \snippet DelegateStyle_indicator.qml checkBox
++
++ Some controls have more than one indicator. For example,
++ \l [QtQuickControls]{SpinBox} has both an increment and a decrement
++ button. These can be styled independently using the \l first and \l second
++ sub-indicators, \c {spinBox.indicator.first} and
++ \c {spinBox.indicator.second}. For SpinBox, \c {indicator.first} styles
++ the increment button, and \c {indicator.second} styles the decrement
++ button. Properties not set on a sub-indicator fall back to the indicator
++ itself.
++
++ \note The \c up and \c down properties are kept as aliases for
++ \c first and \c second for backward compatibility. New code
++ should use \c first and \c second, as these names are generic and can be
++ used by controls with sub-indicators that do not represent up/down actions.
++ The compatibility aliases may be removed in a future version.
++
++ \snippet DelegateStyle_indicator.qml up and down indicator
++
++ \labs
++
++ \sa SubIndicatorStyle, DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty DelegateStyle IndicatorStyle::foreground
++
++ Grouped property for styling the foreground element of this
++ indicator. For example, \c {checkBox.indicator} describes
++ the check box frame, while \c {checkBox.indicator.foreground} is the check mark.
++
++ For controls like \l {StylableControls::}{slider},
++ \l {StylableControls::}{progressBar}, and
++ \l {StylableControls::}{switchControl}, the \c {indicator.foreground}
++ represents the progress track or fill within the groove, while the \c indicator
++ itself represents the groove.
++ */
++
++ /*!
++ \qmlproperty SubIndicatorStyle IndicatorStyle::first
++
++ Grouped property for styling the first sub-indicator of controls that
++ expose multiple indicators. For \l [QtQuickControls]{SpinBox}, this
++ styles the increment button.
++ Unset properties fall back to the indicator itself.
++
++ \note The \c up property is kept as an alias for \c first for backward
++ compatibility. New code should use \c first, as this name is generic
++ and can be used by controls with sub-indicators that do not represent
++ up actions. The compatibility alias may be removed in a future version.
++
++ \sa second
++ */
++
++ /*!
++ \qmlproperty SubIndicatorStyle IndicatorStyle::second
++
++ Grouped property for styling the second sub-indicator of for example a
++ \l [QtQuickControls]{SpinBox}.
++ Unset properties fall back to the indicator itself.
++
++ \note The \c down property is kept as an alias for \c second for backward
++ compatibility. New code should use \c second, as this name is generic
++ and can be used by controls with sub-indicators that do not represent
++ down actions. The compatibility alias may be removed in a future version.
++
++ \sa first
++ */
++
++ // ************* TextStyle ****************
++
++ /*!
++ \qmltype TextStyle
++ \inqmlmodule Qt.labs.StyleKit
++ \brief Defines the text style for a control's label.
++
++ TextStyle provides properties for controlling the appearance of
++ text labels within a control, such as
++ \l color, \l alignment and \l padding,
++ and certain font-related properties such as
++ \l {TextStyle::}{bold},
++ \l {TextStyle::}{italic}, and
++ \l {TextStyle::pointSize}{font size}.
++
++ It is available as the \l {ControlStyleProperties::text}{text}
++ grouped property on every \l ControlStateStyle.
++
++ \labs
++
++ \sa DelegateStyle, ControlStyle, ControlStateStyle,
++ {qtlabsstylekit-fallbackstyle.html}{FallbackStyle Reference}
++ */
++
++ /*!
++ \qmlproperty Qt::Alignment TextStyle::alignment
++
++ The alignment of the text within its available area.
++ */
++
++ /*!
++ \qmlproperty bool TextStyle::bold
++
++ Whether the text should be rendered in bold. The default value
++ is \c false.
++
++ \sa italic
++ */
++
++ /*!
++ \qmlproperty real TextStyle::bottomPadding
++
++ The bottom padding around the text. If not set, falls back to
++ \l padding.
++
++ \sa padding, topPadding, leftPadding, rightPadding
++ */
++
++ /*!
++ \qmlproperty color TextStyle::color
++
++ The color of the text.
++ */
++
++ /*!
++ \qmlproperty bool TextStyle::italic
++
++ Whether the text should be rendered in italic. The default value
++ is \c false.
++
++ \sa bold
++ */
++
++ /*!
++ \qmlproperty real TextStyle::leftPadding
++
++ The left padding around the text. If not set, falls back to
++ \l padding.
++
++ \sa padding, rightPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real TextStyle::padding
++
++ The uniform padding around the text. Setting this provides a
++ default value for \l leftPadding, \l rightPadding, \l topPadding,
++ and \l bottomPadding. Each side can be overridden individually.
++
++ \sa leftPadding, rightPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real TextStyle::pointSize
++
++ The point size of the text font.
++ */
++
++ /*!
++ \qmlproperty real TextStyle::rightPadding
++
++ The right padding around the text. If not set, falls back to
++ \l padding.
++
++ \sa padding, leftPadding, topPadding, bottomPadding
++ */
++
++ /*!
++ \qmlproperty real TextStyle::topPadding
++
++ The top padding around the text. If not set, falls back to
++ \l padding.
++
++ \sa padding, bottomPadding, leftPadding, rightPadding
++ */
++
++ /*!
++ \qmlproperty TextStyle TextStyle::first
++
++ Grouped property for styling the first text element in controls that
++ expose two separate text labels. Unset properties fall back to
++ \l {ControlStyleProperties::text}{text} itself.
++
++ \sa second
++ */
++
++ /*!
++ \qmlproperty TextStyle TextStyle::second
++
++ Grouped property for styling the second text element in controls that
++ expose two separate text labels. Unset properties fall back to
++ \l {ControlStyleProperties::text}{text} itself.
++
++ \sa first
++ */
++
++ // ************* QQStyleKitPropertyGroup ****************
++
++ QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent)
++ : QObject(parent)
++ {
++ }
++
++ QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const
++ {
++ if (isControlProperties()) {
++ Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(this));
++ auto *self = const_cast<QQStyleKitPropertyGroup *>(this);
++ return static_cast<QQStyleKitControlProperties *>(self);
++ }
++ Q_ASSERT(qobject_cast<const QQStyleKitControlProperties *>(parent()));
++ return static_cast<QQStyleKitControlProperties *>(parent());
++ }
++
++ template<typename T>
++ T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup group) const
++ {
++ T *nestedGroup = QQSK::lazyCreate(ptr, controlProperties(), group);
++
++ // Nested groups inherit path flags from their parents
++ nestedGroup->m_pathFlags = m_pathFlags;
++
++ if (group == QQSK::PropertyGroup::DelegateSubtype1) {
++ /* The subtype is stripped from a group's core path, and stored as a flag. This is because
++ * during style property look-up, we want to check many different alternative paths where
++ * the core group path can occur, some with, and some without, the subtype included.
++ * Whether or not to include a subtype is therefore decided as late as possible, when
++ * creating a QQStyleKitPropertyPath, and then depending on the usage. */
++ nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype1);
++ nestedGroup->m_groupSpace = m_groupSpace;
++ } else if (group == QQSK::PropertyGroup::DelegateSubtype2) {
++ nestedGroup->m_pathFlags.setFlag(QQSK::PropertyPathFlag::DelegateSubtype2);
++ nestedGroup->m_groupSpace = m_groupSpace;
++ } else {
++ /* Calculate the available property ID space for the nested group. This is done by
++ * dividing the available space inside _this_ group on the number of potential groups
++ * that _this_ group can potentially contain. */
++ const PropertyPathId nestedGroupIndex = PropertyPathId(group);
++ const PropertyPathId nestedGroupSize = m_groupSpace.size / nestedGroupCount;
++ nestedGroup->m_groupSpace.size = nestedGroupSize;
++ nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize);
++ /* Ensure that we haven’t exhausted the available PropertyPathId space. There must be
++ * enough room remaining to assign IDs for all properties defined in QQSK::Property.
++ * If this assertion triggers, consider switching to a wider PropertyPathId type or
++ * optimizing how the space is allocated. For example, certain nested paths (such as
++ * control.handle.indicator) can never occur, yet we currently reserve INNER_GROUP_COUNT
++ * for every nesting level, which is wasteful. */
++ Q_ASSERT(nestedGroupSize >= PropertyPathId(QQSK::Property::COUNT));
++ }
++ return nestedGroup;
++ }
++
++ /* This macro will check if the caller has the same group path as \a GROUP_PATH.
++ * This is needed since a QQSK::Property (e.g Color) can sometimes be a
++ * property in several different subclasses of QQStyleKitPropertyGroup.
++ * For example, both control.background.color and control.indicator.color has a
++ * color property. But the group path differs, so they are in reality two completely
++ * different properties. And in that case, when the former changes value, we want to
++ * emit changes globally only to that property, and not the latter.
++ * The caller of this macro will therefore need to go through all the usages of its
++ * subclass in the API, to figure out which group itself is an instance of. For the
++ * one that is a match, the macro will go through all readers and emit the same
++ * signal for them. */
++ #define CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(CONTROL_PROPERTIES, GROUP_PATH) \
++ if (this == CONTROL_PROPERTIES -> GROUP_PATH ) { \
++ for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) { \
++ const auto baseTypes = QQStyleKitPropertyResolver::baseTypesForType(reader->controlType()); \
++ if (reader->controlType() != controlType && !baseTypes.contains(controlType)) \
++ continue; \
++ reader->clearLocalStorage(); \
++ ((reader-> GROUP_PATH ->*changedSignals)(), ...); \
++ } \
++ return; \
++ }
++
++ template<typename SUBCLASS>
++ void QQStyleKitPropertyGroup::handleStylePropertyChanged(void (SUBCLASS::*changedSignal)()) {
++ handleStylePropertiesChanged<SUBCLASS>(changedSignal);
++ }
++
++ template <typename SUBCLASS, typename... CHANGED_SIGNALS>
++ void QQStyleKitPropertyGroup::handleStylePropertiesChanged(CHANGED_SIGNALS... changedSignals)
++ {
++ /* This function will check which subclass of QQStyleKitProperties this
++ * group is (nested) inside. Based on that, it will decide if the signals
++ * should be emitted locally or not, and if the changed properties affects
++ * all existing QQStyleKitReaders, and therefore will need to be
++ * emitted 'globally'. Note that it only makes sense to call this function
++ * for changed properties that are available from a QQStyleKitReader.
++ * Properities only available from e.g QQStyleKitControl (such as
++ * variations), are anyway not readable from a QQStyleKitReader. */
++ static_assert(std::is_base_of<QQStyleKitPropertyGroup, SUBCLASS>::value,
++ "SUBCLASS must inherit QQStyleKitPropertyGroup");
++
++ auto *group = static_cast<SUBCLASS *>(this);
++ const QQSK::Subclass objectWrittenTo = controlProperties()->subclass();
++
++ if (objectWrittenTo == QQSK::Subclass::QQStyleKitState) {
++ ((group->*changedSignals)(), ...);
++
++ if (shouldEmitGlobally()) {
++ const QQStyleKitControl *control = controlProperties()->asQQStyleKitState()->control();
++ const QQStyleKitExtendableControlType type = control->controlType();
++ group->emitGlobally(type, changedSignals...);
++ }
++ return;
++ }
++
++ if (objectWrittenTo == QQSK::Subclass::QQStyleKitReader) {
++ /* Unless the StyleReader has told us not to emit any signals (because it's only
++ * syncing it's own local storage with old values before starting a transition), we
++ * emit the signal like normal. This will cause the control to repaint (perhaps
++ * using a transition). */
++ if (shouldEmitLocally()) {
++ QQStyleKitReader *reader = controlProperties()->asQQStyleKitReader();
++ /* Readers notify their consumer in two different ways depending on who is
++ * consuming them. A QML control binds to the reader's change signals, so we
++ * emit those directly. A widget consumer (m_target set) doesn't listen on
++ * signals; it repaints in response to a QEvent::StyleAnimationUpdate posted
++ * to the widget, and only while a transition is actually running. */
++ if (!reader->m_target)
++ ((group->*changedSignals)(), ...);
++ else
++ QCoreApplication::postEvent(reader->m_target, new QEvent(QEvent::StyleAnimationUpdate));
++ }
++ return;
++ }
++
++ Q_UNREACHABLE();
++ }
++
++ void QQStyleKitPropertyGroup::emitChangedForAllStylePropertiesRecursive(EmitFlags emitFlags)
++ {
++ /* This function will emit changed signals for all style properties in the
++ * StyleKit API (for a single QQStyleKitReader), which is needed after
++ * doing a style-, or theme change. */
++ const QMetaObject *meta = metaObject();
++ if (meta->inherits(&QQStyleKitControlProperties::staticMetaObject)) {
++ /* Subclasses of QQStyleKitControlProperties, such as QQStyleKitReader, add
++ * properties that describe the state of the control (hovered, checked, etc.)
++ * rather than its style. Those should not be emitted from here. */
++ meta = &QQStyleKitControlProperties::staticMetaObject;
++ }
++
++ const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
++ for (int i = startIndex; i < meta->propertyCount(); ++i) {
++ const QMetaProperty prop = meta->property(i);
++ const QMetaObject* propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
++ if (propMetaObject && propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject)) {
++ /* Nested groups are handled by forEachExistingNestedGroup() below. Reading them
++ * through their property getters from here would lazily create them. */
++ continue;
++ }
++
++ if (!emitFlags.testFlag(EmitFlag::AllProperties)) {
++ // Only emit for color properties when the Colors flag is set
++ if (emitFlags.testFlag(EmitFlag::Colors)) {
++ if (prop.metaType() != QMetaType::fromType<QColor>())
++ continue;
++ }
++ }
++
++ /* Emit the changed signal for the property.
++ * Note: even if we call invoke() for every style property, only the signals that
++ * are connected to something (e.g. a binding) end up doing any real work. If
++ * isSignalConnected() is false, the emit will exit early. */
++ Q_ASSERT(prop.hasNotifySignal());
++ QMetaMethod notify = prop.notifySignal();
++ notify.invoke(this, Qt::DirectConnection);
++ }
++
++ /* Recurse into the nested groups, but only the ones that have been created. Since
++ * nested groups are lazily created when first read, a group that doesn't exist has
++ * never been read, so there are no bindings to it that would need to be notified. */
++ forEachExistingNestedGroup([emitFlags](QQStyleKitPropertyGroup *group) {
++ group->emitChangedForAllStylePropertiesRecursive(emitFlags);
++ });
++ }
++
++ void QQStyleKitPropertyGroup::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ /* Subclasses with nested groups should override this function and call f for
++ * each nested group that has been created, mirroring the groups that the subclass
++ * creates with lazyCreateGroup(). Nested groups are lazily created when read, so a
++ * group that hasn't been created has never been read either. Using the member
++ * pointers directly (as opposed to the property getters) avoids creating them by
++ * accident. Overrides should not call this base implementation. */
++ Q_UNUSED(f);
++
++ #ifdef QT_DEBUG
++ /* Verify that this group has no nested groups, since it would otherwise need to
++ * override this function. */
++ const QMetaObject *meta = metaObject();
++ const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
++ for (int i = startIndex; i < meta->propertyCount(); ++i) {
++ const QMetaProperty prop = meta->property(i);
++ const QMetaObject *propMetaObject = QMetaType::fromName(prop.typeName()).metaObject();
++ Q_ASSERT_X(!propMetaObject || !propMetaObject->inherits(&QQStyleKitPropertyGroup::staticMetaObject),
++ meta->className(), "Classes with nested property groups must override forEachExistingNestedGroup()");
++ }
++ #endif
++ }
++
++ bool QQStyleKitPropertyGroup::shouldEmitLocally()
++ {
++ return !controlProperties()->asQQStyleKitReader()->dontEmitChangedSignals();
++ }
++
++ bool QQStyleKitPropertyGroup::shouldEmitGlobally()
++ {
++ QQStyleKitStyle *parentStyle = controlProperties()->style();
++ if (!parentStyle)
++ return false;
++
++ if (parentStyle->loaded() && !parentStyle->m_isUpdatingPalette) {
++ /* When a property has changed in the 'global' QQStyleKitStyle itself, it can
++ * potentially affect all control instances. We therefore need to go through all
++ * QQStyleKitReaders and inform that their own local property that matches the
++ * 'global' property needs to be re-read. We emit the signals directly, omitting any
++ * applied transitions in the QQStyleKitReaders, to optimize for speed. The exception
++ * is if we're just updating the palette in the Style to match the palette in the current
++ * control / QQStyleKitReader. Such a change will only affect a single control. */
++ return parentStyle == QQStyleKitStyle::current();
++ }
++ return false;
++ }
++
++ // ************* QQStyleKitImageProperties ****************
++
++ QQStyleKitImageProperties::QQStyleKitImageProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitImageProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitImageProperties
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->image());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->image());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->image());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->image());
++ }
++
++ QUrl QQStyleKitImageProperties::source() const
++ {
++ return styleProperty<QUrl>(QQSK::Property::Source);
++ }
++
++ void QQStyleKitImageProperties::setSource(const QUrl &source)
++ {
++ if (setStyleProperty(QQSK::Property::Source, source))
++ handleStylePropertyChanged(&QQStyleKitImageProperties::sourceChanged);
++ }
++
++ QColor QQStyleKitImageProperties::color() const
++ {
++ return styleProperty<QColor>(QQSK::Property::Color);
++ }
++
++ void QQStyleKitImageProperties::setColor(const QColor &color)
++ {
++ if (setStyleProperty(QQSK::Property::Color, color))
++ handleStylePropertyChanged(&QQStyleKitImageProperties::colorChanged);
++ }
++
++ QQuickImage::FillMode QQStyleKitImageProperties::fillMode() const
++ {
++ return styleProperty<QQuickImage::FillMode>(QQSK::Property::FillMode);
++ }
++
++ void QQStyleKitImageProperties::setFillMode(QQuickImage::FillMode fillMode)
++ {
++ if (setStyleProperty(QQSK::Property::FillMode, fillMode))
++ handleStylePropertyChanged(&QQStyleKitImageProperties::fillModeChanged);
++ }
++
++ // ************* QQStyleKitBorderProperties ****************
++
++ QQStyleKitBorderProperties::QQStyleKitBorderProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitBorderProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitBorderProperties
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->border());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->border());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->border());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->border());
++ }
++
++ qreal QQStyleKitBorderProperties::width() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Width);
++ }
++
++ void QQStyleKitBorderProperties::setWidth(qreal width)
++ {
++ if (setStyleProperty(QQSK::Property::Width, width))
++ handleStylePropertyChanged(&QQStyleKitBorderProperties::widthChanged);
++ }
++
++ QColor QQStyleKitBorderProperties::color() const
++ {
++ return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
++ }
++
++ void QQStyleKitBorderProperties::setColor(const QColor &color)
++ {
++ if (setStyleProperty(QQSK::Property::Color, color))
++ handleStylePropertyChanged(&QQStyleKitBorderProperties::colorChanged);
++ }
++
++ // ************* QQStyleKitShadowProperties ****************
++
++ QQStyleKitShadowProperties::QQStyleKitShadowProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitShadowProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitShadowProperties
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background()->shadow());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle()->shadow());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->shadow());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground()->shadow());
++ }
++
++ QColor QQStyleKitShadowProperties::color() const
++ {
++ return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
++ }
++
++ void QQStyleKitShadowProperties::setColor(QColor color)
++ {
++ if (setStyleProperty(QQSK::Property::Color, color))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::colorChanged);
++ }
++
++ qreal QQStyleKitShadowProperties::opacity() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
++ }
++
++ void QQStyleKitShadowProperties::setOpacity(qreal opacity)
++ {
++ if (setStyleProperty(QQSK::Property::Opacity, opacity))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::opacityChanged);
++ }
++
++ qreal QQStyleKitShadowProperties::scale() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
++ }
++
++ void QQStyleKitShadowProperties::setScale(qreal scale)
++ {
++ if (setStyleProperty(QQSK::Property::Scale, scale))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::scaleChanged);
++ }
++
++ qreal QQStyleKitShadowProperties::verticalOffset() const
++ {
++ return styleProperty<qreal>(QQSK::Property::VOffset);
++ }
++
++ void QQStyleKitShadowProperties::setVerticalOffset(qreal verticalOffset)
++ {
++ if (setStyleProperty(QQSK::Property::VOffset, verticalOffset))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::verticalOffsetChanged);
++ }
++
++ qreal QQStyleKitShadowProperties::horizontalOffset() const
++ {
++ return styleProperty<qreal>(QQSK::Property::HOffset);
++ }
++
++ void QQStyleKitShadowProperties::setHorizontalOffset(qreal horizontalOffset)
++ {
++ if (setStyleProperty(QQSK::Property::HOffset, horizontalOffset))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::horizontalOffsetChanged);
++ }
++
++ qreal QQStyleKitShadowProperties::blur() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Blur, 10.0);
++ }
++
++ void QQStyleKitShadowProperties::setBlur(qreal blur)
++ {
++ if (setStyleProperty(QQSK::Property::Blur, blur))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::blurChanged);
++ }
++
++ bool QQStyleKitShadowProperties::visible() const
++ {
++ return styleProperty<bool>(QQSK::Property::Visible, true);
++ }
++
++ void QQStyleKitShadowProperties::setVisible(bool visible)
++ {
++ if (setStyleProperty(QQSK::Property::Visible, visible))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::visibleChanged);
++ }
++
++ QQmlComponent *QQStyleKitShadowProperties::delegate() const
++ {
++ return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
++ }
++
++ void QQStyleKitShadowProperties::setDelegate(QQmlComponent *delegate)
++ {
++ if (setStyleProperty(QQSK::Property::Delegate, delegate))
++ handleStylePropertyChanged(&QQStyleKitShadowProperties::delegateChanged);
++ }
++
++ // ************* QQStyleKitDelegateProperties ****************
++
++ QQStyleKitDelegateProperties::QQStyleKitDelegateProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitDelegateProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitDelegateProperties
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, background());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, handle());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->foreground());
++ }
++
++ void QQStyleKitDelegateProperties::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ if (m_image)
++ f(m_image);
++ if (m_border)
++ f(m_border);
++ if (m_shadow)
++ f(m_shadow);
++ }
++
++ qreal QQStyleKitDelegateProperties::radius() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Radius);
++ }
++
++ void QQStyleKitDelegateProperties::setRadius(qreal radius)
++ {
++ if (setStyleProperty(QQSK::Property::Radius, radius))
++ handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
++ &QQStyleKitDelegateProperties::radiusChanged,
++ &QQStyleKitDelegateProperties::topLeftRadiusChanged,
++ &QQStyleKitDelegateProperties::topRightRadiusChanged,
++ &QQStyleKitDelegateProperties::bottomLeftRadiusChanged,
++ &QQStyleKitDelegateProperties::bottomRightRadiusChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::topLeftRadius() const
++ {
++ return styleProperty<qreal>(QQSK::Property::TopLeftRadius, QQSK::Property::Radius);
++ }
++
++ void QQStyleKitDelegateProperties::setTopLeftRadius(qreal radius)
++ {
++ if (setStyleProperty(QQSK::Property::TopLeftRadius, radius))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::topLeftRadiusChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::topRightRadius() const
++ {
++ return styleProperty<qreal>(QQSK::Property::TopRightRadius, QQSK::Property::Radius);
++ }
++
++ void QQStyleKitDelegateProperties::setTopRightRadius(qreal radius)
++ {
++ if (setStyleProperty(QQSK::Property::TopRightRadius, radius))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::topRightRadiusChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::bottomLeftRadius() const
++ {
++ return styleProperty<qreal>(QQSK::Property::BottomLeftRadius, QQSK::Property::Radius);
++ }
++
++ void QQStyleKitDelegateProperties::setBottomLeftRadius(qreal radius)
++ {
++ if (setStyleProperty(QQSK::Property::BottomLeftRadius, radius))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomLeftRadiusChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::bottomRightRadius() const
++ {
++ return styleProperty<qreal>(QQSK::Property::BottomRightRadius, QQSK::Property::Radius);
++ }
++
++ void QQStyleKitDelegateProperties::setBottomRightRadius(qreal radius)
++ {
++ if (setStyleProperty(QQSK::Property::BottomRightRadius, radius))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomRightRadiusChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::scale() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Scale, 1.0);
++ }
++
++ void QQStyleKitDelegateProperties::setScale(qreal scale)
++ {
++ if (setStyleProperty(QQSK::Property::Scale, scale))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::scaleChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::rotation() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Rotation);
++ }
++
++ void QQStyleKitDelegateProperties::setRotation(qreal rotation)
++ {
++ if (setStyleProperty(QQSK::Property::Rotation, rotation))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::rotationChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::width() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Width);
++ }
++
++ void QQStyleKitDelegateProperties::setWidth(qreal width)
++ {
++ if (setStyleProperty(QQSK::Property::Width, width))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::widthChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::height() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Height);
++ }
++
++ void QQStyleKitDelegateProperties::setHeight(qreal height)
++ {
++ if (setStyleProperty(QQSK::Property::Height, height))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::heightChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::minimumWidth() const
++ {
++ return styleProperty<qreal>(QQSK::Property::MinimumWidth);
++ }
++
++ void QQStyleKitDelegateProperties::setMinimumWidth(qreal width)
++ {
++ if (setStyleProperty(QQSK::Property::MinimumWidth, width))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumWidthChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::minimumHeight() const
++ {
++ return styleProperty<qreal>(QQSK::Property::MinimumHeight);
++ }
++
++ void QQStyleKitDelegateProperties::setMinimumHeight(qreal height)
++ {
++ if (setStyleProperty(QQSK::Property::MinimumHeight, height))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::minimumHeightChanged);
++ }
++
++ bool QQStyleKitDelegateProperties::fillWidth() const
++ {
++ return styleProperty<bool>(QQSK::Property::FillWidth);
++ }
++
++ void QQStyleKitDelegateProperties::setFillWidth(bool fill)
++ {
++ if (setStyleProperty(QQSK::Property::FillWidth, fill))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillWidthChanged);
++ }
++
++ bool QQStyleKitDelegateProperties::fillHeight() const
++ {
++ return styleProperty<bool>(QQSK::Property::FillHeight);
++ }
++
++ void QQStyleKitDelegateProperties::setFillHeight(bool fill)
++ {
++ if (setStyleProperty(QQSK::Property::FillHeight, fill))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::fillHeightChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::margins() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Margins);
++ }
++
++ void QQStyleKitDelegateProperties::setMargins(qreal margins)
++ {
++ if (setStyleProperty(QQSK::Property::Margins, margins))
++ handleStylePropertiesChanged<QQStyleKitDelegateProperties>(
++ &QQStyleKitDelegateProperties::marginsChanged,
++ &QQStyleKitDelegateProperties::leftMarginChanged,
++ &QQStyleKitDelegateProperties::rightMarginChanged,
++ &QQStyleKitDelegateProperties::topMarginChanged,
++ &QQStyleKitDelegateProperties::bottomMarginChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::leftMargin() const
++ {
++ return styleProperty<qreal>(QQSK::Property::LeftMargin, QQSK::Property::Margins);
++ }
++
++ void QQStyleKitDelegateProperties::setLeftMargin(qreal margin)
++ {
++ if (setStyleProperty(QQSK::Property::LeftMargin, margin))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::leftMarginChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::rightMargin() const
++ {
++ return styleProperty<qreal>(QQSK::Property::RightMargin, QQSK::Property::Margins);
++ }
++
++ void QQStyleKitDelegateProperties::setRightMargin(qreal margin)
++ {
++ if (setStyleProperty(QQSK::Property::RightMargin, margin))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::rightMarginChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::topMargin() const
++ {
++ return styleProperty<qreal>(QQSK::Property::TopMargin, QQSK::Property::Margins);
++ }
++
++ void QQStyleKitDelegateProperties::setTopMargin(qreal margin)
++ {
++ if (setStyleProperty(QQSK::Property::TopMargin, margin))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::topMarginChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::bottomMargin() const
++ {
++ return styleProperty<qreal>(QQSK::Property::BottomMargin, QQSK::Property::Margins);
++ }
++
++ void QQStyleKitDelegateProperties::setBottomMargin(qreal margin)
++ {
++ if (setStyleProperty(QQSK::Property::BottomMargin, margin))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::bottomMarginChanged);
++ }
++
++ Qt::Alignment QQStyleKitDelegateProperties::alignment() const
++ {
++ return styleProperty<Qt::Alignment>(QQSK::Property::Alignment, Qt::AlignLeft | Qt::AlignVCenter);
++ }
++
++ void QQStyleKitDelegateProperties::setAlignment(Qt::Alignment alignment)
++ {
++ if (setStyleProperty(QQSK::Property::Alignment, alignment))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::alignmentChanged);
++ }
++
++ qreal QQStyleKitDelegateProperties::opacity() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Opacity, 1.0);
++ }
++
++ void QQStyleKitDelegateProperties::setOpacity(qreal opacity)
++ {
++ if (setStyleProperty(QQSK::Property::Opacity, opacity))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::opacityChanged);
++ }
++
++ QColor QQStyleKitDelegateProperties::color() const
++ {
++ return styleProperty<QColor>(QQSK::Property::Color, Qt::transparent);
++ }
++
++ void QQStyleKitDelegateProperties::setColor(const QColor &color)
++ {
++ if (setStyleProperty(QQSK::Property::Color, color))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::colorChanged);
++ }
++
++ bool QQStyleKitDelegateProperties::visible() const
++ {
++ return styleProperty<bool>(QQSK::Property::Visible, true);
++ }
++
++ void QQStyleKitDelegateProperties::setVisible(bool visible)
++ {
++ if (setStyleProperty(QQSK::Property::Visible, visible))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::visibleChanged);
++ }
++
++ bool QQStyleKitDelegateProperties::clip() const
++ {
++ return styleProperty<bool>(QQSK::Property::Clip, false);
++ }
++
++ void QQStyleKitDelegateProperties::setClip(bool clip)
++ {
++ if (setStyleProperty(QQSK::Property::Clip, clip))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::clipChanged);
++ }
++
++ QQuickGradient *QQStyleKitDelegateProperties::gradient() const
++ {
++ return styleProperty<QQuickGradient *>(QQSK::Property::Gradient);
++ }
++
++ void QQStyleKitDelegateProperties::setGradient(QQuickGradient *gradient)
++ {
++ if (setStyleProperty(QQSK::Property::Gradient, gradient))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::gradientChanged);
++ }
++
++ QObject *QQStyleKitDelegateProperties::data() const
++ {
++ return styleProperty<QObject *>(QQSK::Property::Data);
++ }
++
++ void QQStyleKitDelegateProperties::setData(QObject *data)
++ {
++ if (setStyleProperty(QQSK::Property::Data, data))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::dataChanged);
++ }
++
++ QQmlComponent *QQStyleKitDelegateProperties::delegate() const
++ {
++ return styleProperty<QQmlComponent *>(QQSK::Property::Delegate);
++ }
++
++ void QQStyleKitDelegateProperties::setDelegate(QQmlComponent *delegate)
++ {
++ if (setStyleProperty(QQSK::Property::Delegate, delegate))
++ handleStylePropertyChanged(&QQStyleKitDelegateProperties::delegateChanged);
++ }
++
++ QQStyleKitBorderProperties *QQStyleKitDelegateProperties::border() const
++ {
++ return lazyCreateGroup(m_border, QQSK::PropertyGroup::Border);
++ }
++
++ QQStyleKitShadowProperties *QQStyleKitDelegateProperties::shadow() const
++ {
++ return lazyCreateGroup(m_shadow, QQSK::PropertyGroup::Shadow);
++ }
++
++ QQStyleKitImageProperties *QQStyleKitDelegateProperties::image() const
++ {
++ return lazyCreateGroup(m_image, QQSK::PropertyGroup::Image);
++ }
++
++ // ************* QQStyleKitHandleProperties ****************
++
++ QQStyleKitHandleProperties::QQStyleKitHandleProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitDelegateProperties(group, parent)
++ {
++ }
++
++ void QQStyleKitHandleProperties::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
++ if (m_first)
++ f(m_first);
++ if (m_second)
++ f(m_second);
++ }
++
++ QQStyleKitDelegateProperties *QQStyleKitHandleProperties::first() const
++ {
++ return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
++ }
++
++ QQStyleKitDelegateProperties *QQStyleKitHandleProperties::second() const
++ {
++ return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
++ }
++
++ // ************* QQStyleKitIndicatorProperties ****************
++
++ QQStyleKitIndicatorProperties::QQStyleKitIndicatorProperties(
++ QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitDelegateProperties(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitIndicatorProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitIndicatorProperties
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->first());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator()->second());
++ }
++
++ void QQStyleKitIndicatorProperties::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
++ if (m_foreground)
++ f(m_foreground);
++ }
++
++ QQStyleKitDelegateProperties *QQStyleKitIndicatorProperties::foreground() const
++ {
++ return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
++ }
++
++ // ************* QQStyleKitIndicatorWithSubTypes ****************
++
++ QQStyleKitIndicatorWithSubTypes::QQStyleKitIndicatorWithSubTypes(
++ QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitDelegateProperties(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitIndicatorWithSubTypes::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ // Go through all instances of QQStyleKitIndicatorWithSubTypes
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, indicator());
++ }
++
++ void QQStyleKitIndicatorWithSubTypes::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ QQStyleKitDelegateProperties::forEachExistingNestedGroup(f);
++ if (m_foreground)
++ f(m_foreground);
++ if (m_first)
++ f(m_first);
++ if (m_second)
++ f(m_second);
++ }
++
++ QQStyleKitDelegateProperties *QQStyleKitIndicatorWithSubTypes::foreground() const
++ {
++ return lazyCreateGroup(m_foreground, QQSK::PropertyGroup::Foreground);
++ }
++
++ QQStyleKitIndicatorProperties *QQStyleKitIndicatorWithSubTypes::up() const
++ {
++ return first();
++ }
++
++ QQStyleKitIndicatorProperties *QQStyleKitIndicatorWithSubTypes::down() const
++ {
++ return second();
++ }
++
++ QQStyleKitIndicatorProperties *QQStyleKitIndicatorWithSubTypes::first() const
++ {
++ return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
++ }
++
++ QQStyleKitIndicatorProperties *QQStyleKitIndicatorWithSubTypes::second() const
++ {
++ return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
++ }
++
++ // ************* QQStyleKitTextProperties ****************
++ QQStyleKitTextProperties::QQStyleKitTextProperties(QQSK::PropertyGroup group, QQStyleKitControlProperties *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitTextProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ const QQStyleKitControlProperties *cp = controlProperties();
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->first());
++ CONDITIONALLY_EMIT_SIGNALS_GLOBALLY_FOR(cp, text()->second());
++ }
++
++ void QQStyleKitTextProperties::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ if (m_first)
++ f(m_first);
++ if (m_second)
++ f(m_second);
++ }
++
++ QColor QQStyleKitTextProperties::color() const
++ {
++ return styleProperty<QColor>(QQSK::Property::Color);
++ }
++
++ void QQStyleKitTextProperties::setColor(const QColor &color)
++ {
++ if (setStyleProperty(QQSK::Property::Color, color))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::colorChanged);
++ }
++
++ Qt::Alignment QQStyleKitTextProperties::alignment() const
++ {
++ return styleProperty<Qt::Alignment>(QQSK::Property::Alignment);
++ }
++
++ void QQStyleKitTextProperties::setAlignment(Qt::Alignment alignment)
++ {
++ if (setStyleProperty(QQSK::Property::Alignment, alignment))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::alignmentChanged);
++ }
++
++ bool QQStyleKitTextProperties::bold() const
++ {
++ return styleProperty<bool>(QQSK::Property::Bold, false);
++ }
++
++ void QQStyleKitTextProperties::setBold(bool bold)
++ {
++ if (setStyleProperty(QQSK::Property::Bold, bold))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::boldChanged);
++ }
++
++ bool QQStyleKitTextProperties::italic() const
++ {
++ return styleProperty<bool>(QQSK::Property::Italic, false);
++ }
++
++ void QQStyleKitTextProperties::setItalic(bool italic)
++ {
++ if (setStyleProperty(QQSK::Property::Italic, italic))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::italicChanged);
++ }
++
++ qreal QQStyleKitTextProperties::pointSize() const
++ {
++ return styleProperty<qreal>(QQSK::Property::PointSize, QFont().pointSize());
++ }
++
++ void QQStyleKitTextProperties::setPointSize(qreal pointSize)
++ {
++ if (setStyleProperty(QQSK::Property::PointSize, pointSize))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::pointSizeChanged);
++ }
++
++ qreal QQStyleKitTextProperties::padding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Padding);
++ }
++
++ void QQStyleKitTextProperties::setPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::Padding, padding))
++ handleStylePropertiesChanged<QQStyleKitTextProperties>(
++ &QQStyleKitTextProperties::paddingChanged,
++ &QQStyleKitTextProperties::leftPaddingChanged,
++ &QQStyleKitTextProperties::rightPaddingChanged,
++ &QQStyleKitTextProperties::topPaddingChanged,
++ &QQStyleKitTextProperties::bottomPaddingChanged);
++ }
++
++ qreal QQStyleKitTextProperties::leftPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitTextProperties::setLeftPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::LeftPadding, padding))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::leftPaddingChanged);
++ }
++
++ qreal QQStyleKitTextProperties::rightPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitTextProperties::setRightPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::RightPadding, padding))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::rightPaddingChanged);
++ }
++
++ qreal QQStyleKitTextProperties::topPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitTextProperties::setTopPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::TopPadding, padding))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::topPaddingChanged);
++ }
++
++ qreal QQStyleKitTextProperties::bottomPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitTextProperties::setBottomPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::BottomPadding, padding))
++ handleStylePropertyChanged(&QQStyleKitTextProperties::bottomPaddingChanged);
++ }
++
++ QQStyleKitTextProperties *QQStyleKitTextProperties::first() const
++ {
++ return lazyCreateGroup(m_first, QQSK::PropertyGroup::DelegateSubtype1);
++ }
++
++ QQStyleKitTextProperties *QQStyleKitTextProperties::second() const
++ {
++ return lazyCreateGroup(m_second, QQSK::PropertyGroup::DelegateSubtype2);
++ }
++
++ // ************* QQStyleKitControlProperties ****************
++
++ QQStyleKitControlProperties::QQStyleKitControlProperties(QQSK::PropertyGroup group, QObject *parent)
++ : QQStyleKitPropertyGroup(group, parent)
++ {
++ /* Calculate the free space storage ID space that can accommodate all unique style
++ * properties that may be applied to a control. Since we'll prepend different states
++ * and subtypes during the property propagation lookup phase later, we need to reserve
++ * ID space for them both already now. More docs about the property space is written in
++ * the implementation of QQStyleKitPropertyPath. */
++ m_groupSpace.size = nestedGroupsStartSize;
++ m_groupSpace.start = 0;
++
++ if (group == QQSK::PropertyGroup::GlobalFlag) {
++ /* A property path may include pseudo-groups that offers a convenient API for
++ * reading properties with specific options applied. The 'global' group is one such
++ * pseudo-group. When it is prefixed to a property path, it indicates that the property
++ * should be read directly from the style, bypassing any active transitions that might
++ * otherwise affect its value.
++ * Note: The global group should be ignored when computing a PropertyPathId, as it
++ * only affect _where_ the property should be read from, not its ID. */
++ m_pathFlags.setFlag(QQSK::PropertyPathFlag::Global);
++ }
++ }
++
++ QQStyleKitStyle *QQStyleKitControlProperties::style() const
++ {
++ if (subclass() == QQSK::Subclass::QQStyleKitState) {
++ /* A QQStyleKitControlState (and its subclasses) should always be a (grand)child of a
++ * QQStyleKitStyle. And it belongs to that style, even it that style is not the
++ * currently active application style. This is opposed to a QQStyleKitReader,
++ * that normally belongs / communicates with the currently active style.
++ * NOTE: a style can also be a fallback style for another style (which can be recursive,
++ * meaning that a fallback style can also have its own fallback style, and so on). But
++ * this function will return the nearest style, and not the root style */
++ QObject *obj = parent();
++ while (obj && !obj->metaObject()->inherits(&QQStyleKitStyle::staticMetaObject))
++ obj = obj->parent();
++ return obj ? static_cast<QQStyleKitStyle *>(obj) : nullptr;
++ }
++
++ if (subclass() == QQSK::Subclass::QQStyleKitReader) {
++ const auto *reader = static_cast<const QQStyleKitReader *>(this);
++ if (reader->m_explicitStyle)
++ return reader->m_explicitStyle;
++ }
++
++ // For a QQStyleKitReader without an explicit style, we return the currently active style for now
++ return QQStyleKitStyle::current();
++ }
++
++ QQSK::Subclass QQStyleKitControlProperties::subclass() const
++ {
++ /* QQStyleKitControlProperties is subclassed by several different classes in this
++ * framework. As such, it's basically just an interface because it only declares the
++ * different properties that can be read or written to in a QQStyleKitStyle, such as
++ * hovered.background.color or pressed.indicator.foreground.color. It says nothing
++ * about how those properties are stored, instead that is up to each individual
++ * subclass to decide */
++ if (metaObject()->inherits(&QQStyleKitReader::staticMetaObject))
++ return QQSK::Subclass::QQStyleKitReader;
++ if (metaObject()->inherits(&QQStyleKitControlState::staticMetaObject))
++ return QQSK::Subclass::QQStyleKitState;
++ Q_UNREACHABLE();
++ }
++
++ QQStyleKitReader *QQStyleKitControlProperties::asQQStyleKitReader() const
++ {
++ Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitReader);
++ return static_cast<QQStyleKitReader *>(const_cast<QQStyleKitControlProperties *>(this));
++ }
++
++ QQStyleKitControlState *QQStyleKitControlProperties::asQQStyleKitState() const
++ {
++ Q_ASSERT(subclass() == QQSK::Subclass::QQStyleKitState);
++ Q_ASSERT(metaObject()->inherits(&QQStyleKitControlState::staticMetaObject));
++ return static_cast<QQStyleKitControlState *>(const_cast<QQStyleKitControlProperties *>(this));
++ }
++
++ void QQStyleKitControlProperties::forEachUsedDelegate(
++ std::function<void (QQStyleKitDelegateProperties *, QQSK::Delegate, const QString &)> f)
++ {
++ // If adding more delegates here, remember to keep StyleAnimation.qml in sync
++ if (m_background)
++ f(m_background, QQSK::Delegate::Background, "background"_L1);
++
++ if (m_indicator) {
++ f(m_indicator, QQSK::Delegate::Indicator, "indicator"_L1);
++ if (m_indicator->m_foreground)
++ f(m_indicator->m_foreground, QQSK::Delegate::IndicatorForeground, "indicator.foreground"_L1);
++ if (m_indicator->m_first) {
++ f(m_indicator->m_first, QQSK::Delegate::IndicatorFirst, "indicator.first"_L1);
++ if (m_indicator->m_first->m_foreground)
++ f(m_indicator->m_first->m_foreground, QQSK::Delegate::IndicatorFirstForeground, "indicator.first.foreground"_L1);
++ }
++ if (m_indicator->m_second) {
++ f(m_indicator->m_second, QQSK::Delegate::IndicatorSecond, "indicator.second"_L1);
++ if (m_indicator->m_second->m_foreground)
++ f(m_indicator->m_second->m_foreground, QQSK::Delegate::IndicatorSecondForeground, "indicator.second.foreground"_L1);
++ }
++ }
++
++ if (m_handle) {
++ f(m_handle, QQSK::Delegate::Handle, "handle"_L1);
++ if (m_handle->m_first)
++ f(m_handle->m_first, QQSK::Delegate::HandleFirst, "handle.first"_L1);
++ if (m_handle->m_second)
++ f(m_handle->m_second, QQSK::Delegate::HandleSecond, "handle.second"_L1);
++ }
++ }
++
++ void QQStyleKitControlProperties::emitChangedForAllStyleProperties(EmitFlags emitFlags)
++ {
++ /* This brute-force function will emit update signals for _all_ style properties
++ * in the QQStyleKitStyle API. Doing so is typically needed after a style-, or theme
++ * change, as we don't know which properties are affected by such a big change. */
++ emitChangedForAllStylePropertiesRecursive(emitFlags);
++ }
++
++ template <typename... CHANGED_SIGNALS>
++ void QQStyleKitControlProperties::emitGlobally(
++ QQStyleKitExtendableControlType controlType, CHANGED_SIGNALS... changedSignals) const
++ {
++ for (QQStyleKitReader *reader : QQStyleKitReader::s_allReaders) {
++ if (reader->controlType() != controlType)
++ continue;
++ ((reader->*changedSignals)(), ...);
++ }
++ }
++
++ void QQStyleKitControlProperties::forEachExistingNestedGroup(
++ const std::function<void (QQStyleKitPropertyGroup *)> &f) const
++ {
++ // Keep in sync with the nested groups this class creates with lazyCreateGroup()
++ if (m_background)
++ f(m_background);
++ if (m_handle)
++ f(m_handle);
++ if (m_indicator)
++ f(m_indicator);
++ if (m_text)
++ f(m_text);
++ }
++
++ qreal QQStyleKitControlProperties::spacing() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Spacing);
++ }
++
++ void QQStyleKitControlProperties::setSpacing(qreal spacing)
++ {
++ if (setStyleProperty(QQSK::Property::Spacing, spacing))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::spacingChanged);
++ }
++
++ qreal QQStyleKitControlProperties::padding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::Padding);
++ }
++
++ void QQStyleKitControlProperties::setPadding(qreal padding)
++ {
++ if (setStyleProperty(QQSK::Property::Padding, padding))
++ handleStylePropertiesChanged<QQStyleKitControlProperties>(
++ &QQStyleKitControlProperties::paddingChanged,
++ &QQStyleKitControlProperties::leftPaddingChanged,
++ &QQStyleKitControlProperties::rightPaddingChanged,
++ &QQStyleKitControlProperties::topPaddingChanged,
++ &QQStyleKitControlProperties::bottomPaddingChanged);
++ }
++
++ qreal QQStyleKitControlProperties::leftPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::LeftPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitControlProperties::setLeftPadding(qreal leftPadding)
++ {
++ if (setStyleProperty(QQSK::Property::LeftPadding, leftPadding))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::leftPaddingChanged);
++ }
++
++ qreal QQStyleKitControlProperties::rightPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::RightPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitControlProperties::setRightPadding(qreal rightPadding)
++ {
++ if (setStyleProperty(QQSK::Property::RightPadding, rightPadding))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::rightPaddingChanged);
++ }
++
++ qreal QQStyleKitControlProperties::topPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::TopPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitControlProperties::setTopPadding(qreal topPadding)
++ {
++ if (setStyleProperty(QQSK::Property::TopPadding, topPadding))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::topPaddingChanged);
++ }
++
++ qreal QQStyleKitControlProperties::bottomPadding() const
++ {
++ return styleProperty<qreal>(QQSK::Property::BottomPadding, QQSK::Property::Padding);
++ }
++
++ void QQStyleKitControlProperties::setBottomPadding(qreal bottomPadding)
++ {
++ if (setStyleProperty(QQSK::Property::BottomPadding, bottomPadding))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::bottomPaddingChanged);
++ }
++
++ QQuickTransition *QQStyleKitControlProperties::transition() const
++ {
++ return styleProperty<QQuickTransition *>(QQSK::Property::Transition);
++ }
++
++ void QQStyleKitControlProperties::setTransition(QQuickTransition *transition)
++ {
++ if (setStyleProperty(QQSK::Property::Transition, transition))
++ handleStylePropertyChanged(&QQStyleKitControlProperties::transitionChanged);
++ }
++
++ QQStyleKitTextProperties *QQStyleKitControlProperties::text() const
++ {
++ return lazyCreateGroup(m_text, QQSK::PropertyGroup::Text);
++ }
++
++ QQStyleKitDelegateProperties *QQStyleKitControlProperties::background() const
++ {
++ return lazyCreateGroup(m_background, QQSK::PropertyGroup::Background);
++ }
++
++ QQStyleKitHandleProperties *QQStyleKitControlProperties::handle() const
++ {
++ return lazyCreateGroup(m_handle, QQSK::PropertyGroup::Handle);
++ }
++
++ QQStyleKitIndicatorWithSubTypes *QQStyleKitControlProperties::indicator() const
++ {
++ return lazyCreateGroup(m_indicator, QQSK::PropertyGroup::Indicator);
++ }
++
++ QT_END_NAMESPACE
++
++ #include "moc_qqstylekitcontrolproperties_p.cpp"