Revision control

Copy as Markdown

// 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"