5#include <QQmlListProperty>
6#include <QQmlParserStatus>
7#include <qqmlregistration.h>
9#include "qml_material/core/state_bindings.hpp"
10#include "qml_material/export.hpp"
11#include "qml_material/token/token.hpp"
13#include "qml_material/util/corner.hpp"
15Q_MOC_INCLUDE(
"QQuickItem")
16Q_MOC_INCLUDE("qml_material/token/color.hpp")
17Q_MOC_INCLUDE("qml_material/token/token.hpp")
18Q_MOC_INCLUDE("qml_material/style/theme.hpp")
27 Q_GADGET_EXPORT(QML_MATERIAL_API)
28 QML_VALUE_TYPE(state_values)
29 Q_PROPERTY(QString state MEMBER state CONSTANT FINAL)
30 Q_PROPERTY(QColor textColor MEMBER textColor CONSTANT FINAL)
31 Q_PROPERTY(QColor backgroundColor MEMBER backgroundColor CONSTANT FINAL)
32 Q_PROPERTY(QColor stateLayerColor MEMBER stateLayerColor CONSTANT FINAL)
33 Q_PROPERTY(QColor outlineColor MEMBER outlineColor CONSTANT FINAL)
34 Q_PROPERTY(QColor supportTextColor MEMBER supportTextColor CONSTANT FINAL)
35 Q_PROPERTY(qreal contentOpacity MEMBER contentOpacity CONSTANT FINAL)
36 Q_PROPERTY(qreal backgroundOpacity MEMBER backgroundOpacity CONSTANT FINAL)
37 Q_PROPERTY(qreal stateLayerOpacity MEMBER stateLayerOpacity CONSTANT FINAL)
38 Q_PROPERTY(qreal elevation MEMBER elevation CONSTANT FINAL)
39 Q_PROPERTY(qreal corner MEMBER corner CONSTANT FINAL)
42 QColor textColor { Qt::transparent }, backgroundColor { Qt::transparent };
43 QColor outlineColor { Qt::transparent }, supportTextColor { Qt::transparent };
44 QColor stateLayerColor { Qt::transparent };
45 qreal contentOpacity = 1, backgroundOpacity = 1, stateLayerOpacity = 0;
46 qreal elevation = 0, corner = 0;
47 bool operator==(
const StateValues&)
const =
default;
50class QML_MATERIAL_API CommonState :
public QObject,
public QQmlParserStatus {
52 QML_NAMED_ELEMENT(CommonState)
53 QML_UNCREATABLE(
"Base class for native control states")
54 Q_INTERFACES(QQmlParserStatus)
55 Q_CLASSINFO("DefaultProperty", "datas")
56 Q_PROPERTY(QQmlListProperty<QObject> datas READ datas FINAL)
57 Q_PROPERTY(qml_material::MdColorMgr* colors READ colors WRITE setColors NOTIFY colorsChanged
58 RESET resetColors BINDABLE bindableColors FINAL)
59 Q_PROPERTY(qml_material::token::State stateTokens READ stateTokens WRITE setStateTokens NOTIFY
60 stateTokensChanged BINDABLE bindableStateTokens FINAL)
62 qml_material::token::Elevation elevationTokens READ elevationTokens WRITE setElevationTokens
63 NOTIFY elevationTokensChanged BINDABLE bindableElevationTokens FINAL)
64 Q_PROPERTY(qml_material::StateValues values READ values NOTIFY valuesChanged BINDABLE
66 Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor RESET resetTextColor NOTIFY
67 textColorChanged BINDABLE bindableTextColor)
69 QColor backgroundColor READ backgroundColor WRITE setBackgroundColor RESET
70 resetBackgroundColor NOTIFY backgroundColorChanged BINDABLE bindableBackgroundColor)
72 QColor stateLayerColor READ stateLayerColor WRITE setStateLayerColor RESET
73 resetStateLayerColor NOTIFY stateLayerColorChanged BINDABLE bindableStateLayerColor)
74 Q_PROPERTY(QColor outlineColor READ outlineColor WRITE setOutlineColor RESET resetOutlineColor
75 NOTIFY outlineColorChanged BINDABLE bindableOutlineColor)
77 QColor supportTextColor READ supportTextColor WRITE setSupportTextColor RESET
78 resetSupportTextColor NOTIFY supportTextColorChanged BINDABLE bindableSupportTextColor)
79 Q_PROPERTY(qreal elevation READ elevation WRITE setElevation RESET resetElevation NOTIFY
80 elevationChanged BINDABLE bindableElevation)
81 Q_PROPERTY(qreal corner READ corner WRITE setCorner RESET resetCorner NOTIFY cornerChanged
82 BINDABLE bindableCorner)
83 Q_PROPERTY(qml_material::CornersGroup corners READ corners WRITE setCorners RESET resetCorners
84 NOTIFY cornersChanged BINDABLE bindableCorners)
85 Q_PROPERTY(qreal contentOpacity READ contentOpacity WRITE setContentOpacity RESET
86 resetContentOpacity NOTIFY contentOpacityChanged BINDABLE bindableContentOpacity)
87 Q_PROPERTY(qreal backgroundOpacity READ backgroundOpacity WRITE setBackgroundOpacity RESET
88 resetBackgroundOpacity NOTIFY backgroundOpacityChanged BINDABLE
89 bindableBackgroundOpacity)
90 Q_PROPERTY(qreal stateLayerOpacity READ stateLayerOpacity WRITE setStateLayerOpacity RESET
91 resetStateLayerOpacity NOTIFY stateLayerOpacityChanged BINDABLE
92 bindableStateLayerOpacity)
94 qml_material::Theme* ctx READ ctx WRITE setCtx RESET resetCtx NOTIFY ctxChanged FINAL)
95 Q_PROPERTY(QObject* target READ target NOTIFY targetChanged)
96 Q_PROPERTY(QString state READ state NOTIFY stateChanged FINAL)
99 ~CommonState() override;
100 QObject* target() const;
101 MdColorMgr* colors() const;
102 void setColors(MdColorMgr*);
103 QBindable<MdColorMgr*> bindableColors();
104 StateValues values() const;
105 QBindable<StateValues> bindableValues() const;
106 QQmlListProperty<QObject> datas();
107 void classBegin() override;
108 void componentComplete() override;
109 token::State stateTokens() const;
110 void setStateTokens(const token::State&);
111 QBindable<token::State> bindableStateTokens();
112 token::Elevation elevationTokens() const;
113 void setElevationTokens(const token::Elevation&);
114 QBindable<token::Elevation> bindableElevationTokens();
116 QColor textColor() const;
117 void setTextColor(const QColor&);
118 Q_INVOKABLE
void resetTextColor();
119 QBindable<QColor> bindableTextColor();
120 Q_SIGNAL
void textColorChanged();
121 QColor backgroundColor() const;
122 void setBackgroundColor(const QColor&);
123 Q_INVOKABLE
void resetBackgroundColor();
124 QBindable<QColor> bindableBackgroundColor();
125 Q_SIGNAL
void backgroundColorChanged();
126 QColor stateLayerColor() const;
127 void setStateLayerColor(const QColor&);
128 Q_INVOKABLE
void resetStateLayerColor();
129 QBindable<QColor> bindableStateLayerColor();
130 Q_SIGNAL
void stateLayerColorChanged();
131 QColor outlineColor() const;
132 void setOutlineColor(const QColor&);
133 Q_INVOKABLE
void resetOutlineColor();
134 QBindable<QColor> bindableOutlineColor();
135 Q_SIGNAL
void outlineColorChanged();
136 QColor supportTextColor() const;
137 void setSupportTextColor(const QColor&);
138 Q_INVOKABLE
void resetSupportTextColor();
139 QBindable<QColor> bindableSupportTextColor();
140 Q_SIGNAL
void supportTextColorChanged();
141 qreal elevation() const;
142 void setElevation(const qreal&);
143 Q_INVOKABLE
void resetElevation();
144 QBindable<qreal> bindableElevation();
145 Q_SIGNAL
void elevationChanged();
146 qreal corner() const;
147 void setCorner(const qreal&);
148 Q_INVOKABLE
void resetCorner();
149 QBindable<qreal> bindableCorner();
150 Q_SIGNAL
void cornerChanged();
151 CornersGroup corners() const;
152 void setCorners(const CornersGroup&);
153 Q_INVOKABLE
void resetCorners();
154 QBindable<CornersGroup> bindableCorners();
155 Q_SIGNAL
void cornersChanged();
156 qreal contentOpacity() const;
157 void setContentOpacity(const qreal&);
158 Q_INVOKABLE
void resetContentOpacity();
159 QBindable<qreal> bindableContentOpacity();
160 Q_SIGNAL
void contentOpacityChanged();
161 qreal backgroundOpacity() const;
162 void setBackgroundOpacity(const qreal&);
163 Q_INVOKABLE
void resetBackgroundOpacity();
164 QBindable<qreal> bindableBackgroundOpacity();
165 Q_SIGNAL
void backgroundOpacityChanged();
166 qreal stateLayerOpacity() const;
167 void setStateLayerOpacity(const qreal&);
168 Q_INVOKABLE
void resetStateLayerOpacity();
169 QBindable<qreal> bindableStateLayerOpacity();
170 Q_SIGNAL
void stateLayerOpacityChanged();
173 Q_INVOKABLE
void resetCtx();
174 Q_INVOKABLE
void resetColors();
175 QString state() const;
176 Q_SIGNAL
void ctxChanged();
178 Q_SIGNAL
void colorsChanged();
179 Q_SIGNAL
void targetChanged();
180 Q_SIGNAL
void stateTokensChanged();
181 Q_SIGNAL
void elevationTokensChanged();
182 Q_SIGNAL
void valuesChanged();
183 Q_SIGNAL
void stateChanged();
186 explicit CommonState(QObject* parent =
nullptr);
187 void setTarget(QObject*);
188 void publishState(const QString&, std::function<
void()> apply);
189 bool isStateActive() const;
191 void updateStateInput(QProperty<T>& property, const std::type_identity_t<T>& value) {
195 property.setValueBypassingBindings(value);
197 quint64 targetGeneration()
const {
return m_targetGeneration.value(); }
198 template<
typename Domain>
199 void initializeAppearance(StateBindingSet<Domain>& bindings) {
200 bindings.setOwnerAliveCheck([owner = QPointer<CommonState>(
this)] {
201 return owner && owner->isStateActive();
203#define REGISTER(Name, Upper) \
204 m_appearance.Name = bindings.template property<&CommonState::bindable##Upper>(this); \
205 m_appearance.Name.reset();
206 REGISTER(textColor, TextColor)
207 REGISTER(backgroundColor, BackgroundColor)
208 REGISTER(stateLayerColor, StateLayerColor)
209 REGISTER(outlineColor, OutlineColor)
210 REGISTER(supportTextColor, SupportTextColor)
211 REGISTER(elevation, Elevation)
212 REGISTER(corner, Corner)
213 REGISTER(corners, Corners)
214 REGISTER(contentOpacity, ContentOpacity)
215 REGISTER(backgroundOpacity, BackgroundOpacity)
216 REGISTER(stateLayerOpacity, StateLayerOpacity)
218 m_applyState = [&bindings] {
219 bindings.select(Domain {});
222 template<
typename Role>
223 QColor color(Role role)
const {
224 const auto* palette = colors();
225 return palette ? std::invoke(role, palette) : QColor(Qt::transparent);
227 template<
typename Role>
228 auto colorBinding(Role role)
const {
229 return [
this, role] {
234 struct AppearanceKeys {
235 PropertyKey<QColor> textColor, backgroundColor, stateLayerColor, outlineColor,
237 PropertyKey<qreal> elevation, corner, contentOpacity, backgroundOpacity, stateLayerOpacity;
238 PropertyKey<CornersGroup> corners;
242 void updateContext(Theme*);
244 QProperty<QString> m_state;
245 std::function<void()> m_applyState;
246 bool m_canApply =
true;
248 QPointer<QObject> m_target;
249 QMetaObject::Connection m_targetDestroyed;
250 QProperty<Theme*> m_context {
nullptr };
251 Q_OBJECT_BINDABLE_PROPERTY(CommonState, MdColorMgr*, m_colors, &CommonState::colorsChange)
252 bool m_explicitContext =
false;
253 QList<QMetaObject::Connection> m_contextConnections, m_colorConnections;
254 QList<QObject*> m_datas;
255 Q_OBJECT_BINDABLE_PROPERTY(CommonState, token::State, m_stateTokens,
256 &CommonState::stateTokensChanged)
257 Q_OBJECT_BINDABLE_PROPERTY(CommonState, token::Elevation, m_elevationTokens,
258 &CommonState::elevationTokensChanged)
259 QProperty<quint64> m_targetGeneration { 0 };
260 Q_OBJECT_BINDABLE_PROPERTY(CommonState, StateValues, m_values, &CommonState::valuesChanged)
262 Q_OBJECT_BINDABLE_PROPERTY(CommonState, QColor, m_textColorValue,
263 &CommonState::textColorChanged)
264 Q_OBJECT_BINDABLE_PROPERTY(CommonState, QColor, m_backgroundColorValue,
265 &CommonState::backgroundColorChanged)
266 Q_OBJECT_BINDABLE_PROPERTY(CommonState, QColor, m_stateLayerColorValue,
267 &CommonState::stateLayerColorChanged)
268 Q_OBJECT_BINDABLE_PROPERTY(CommonState, QColor, m_outlineColorValue,
269 &CommonState::outlineColorChanged)
270 Q_OBJECT_BINDABLE_PROPERTY(CommonState, QColor, m_supportTextColorValue,
271 &CommonState::supportTextColorChanged)
272 Q_OBJECT_BINDABLE_PROPERTY(CommonState, qreal, m_elevationValue, &CommonState::elevationChanged)
273 Q_OBJECT_BINDABLE_PROPERTY(CommonState, qreal, m_cornerValue, &CommonState::cornerChanged)
274 Q_OBJECT_BINDABLE_PROPERTY(CommonState, CornersGroup, m_cornersValue,
275 &CommonState::cornersChanged)
276 Q_OBJECT_BINDABLE_PROPERTY(CommonState, qreal, m_contentOpacityValue,
277 &CommonState::contentOpacityChanged)
278 Q_OBJECT_BINDABLE_PROPERTY(CommonState, qreal, m_backgroundOpacityValue,
279 &CommonState::backgroundOpacityChanged)
280 Q_OBJECT_BINDABLE_PROPERTY(CommonState, qreal, m_stateLayerOpacityValue,
281 &CommonState::stateLayerOpacityChanged)