1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQUICKSTATE_P_H
41#define QQUICKSTATE_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "qquickstate_p.h"
55
56#include "qquicktransitionmanager_p_p.h"
57
58#include <private/qqmlproperty_p.h>
59#include <private/qqmlguard_p.h>
60
61#include <private/qqmlbinding_p.h>
62
63#include <private/qobject_p.h>
64
65QT_BEGIN_NAMESPACE
66
67class QQuickSimpleAction
68{
69public:
70 enum State { StartState, EndState };
71 QQuickSimpleAction(const QQuickStateAction &a, State state = StartState)
72 {
73 m_property = a.property;
74 m_specifiedObject = a.specifiedObject;
75 m_specifiedProperty = a.specifiedProperty;
76 m_event = a.event;
77 if (state == StartState) {
78 m_value = a.fromValue;
79 if (QQmlPropertyPrivate::binding(m_property)) {
80 m_binding = QQmlPropertyPrivate::binding(m_property);
81 }
82 m_reverseEvent = true;
83 } else {
84 m_value = a.toValue;
85 m_binding = a.toBinding;
86 m_reverseEvent = false;
87 }
88 }
89
90 ~QQuickSimpleAction()
91 {
92 }
93
94 QQuickSimpleAction(const QQuickSimpleAction &other)
95 : m_property(other.m_property),
96 m_value(other.m_value),
97 m_binding(other.binding()),
98 m_specifiedObject(other.m_specifiedObject),
99 m_specifiedProperty(other.m_specifiedProperty),
100 m_event(other.m_event),
101 m_reverseEvent(other.m_reverseEvent)
102 {
103 }
104
105 QQuickSimpleAction &operator =(const QQuickSimpleAction &other)
106 {
107 m_property = other.m_property;
108 m_value = other.m_value;
109 m_binding = other.binding();
110 m_specifiedObject = other.m_specifiedObject;
111 m_specifiedProperty = other.m_specifiedProperty;
112 m_event = other.m_event;
113 m_reverseEvent = other.m_reverseEvent;
114
115 return *this;
116 }
117
118 void setProperty(const QQmlProperty &property)
119 {
120 m_property = property;
121 }
122
123 const QQmlProperty &property() const
124 {
125 return m_property;
126 }
127
128 void setValue(const QVariant &value)
129 {
130 m_value = value;
131 }
132
133 const QVariant &value() const
134 {
135 return m_value;
136 }
137
138 void setBinding(QQmlAbstractBinding *binding)
139 {
140 m_binding = binding;
141 }
142
143 QQmlAbstractBinding *binding() const
144 {
145 return m_binding.data();
146 }
147
148 QObject *specifiedObject() const
149 {
150 return m_specifiedObject;
151 }
152
153 const QString &specifiedProperty() const
154 {
155 return m_specifiedProperty;
156 }
157
158 QQuickStateActionEvent *event() const
159 {
160 return m_event;
161 }
162
163 bool reverseEvent() const
164 {
165 return m_reverseEvent;
166 }
167
168private:
169 QQmlProperty m_property;
170 QVariant m_value;
171 QQmlAbstractBinding::Ptr m_binding;
172 QObject *m_specifiedObject;
173 QString m_specifiedProperty;
174 QQuickStateActionEvent *m_event;
175 bool m_reverseEvent;
176};
177
178class QQuickRevertAction
179{
180public:
181 QQuickRevertAction() : event(nullptr) {}
182 QQuickRevertAction(const QQmlProperty &prop) : property(prop), event(nullptr) {}
183 QQuickRevertAction(QQuickStateActionEvent *e) : event(e) {}
184 QQmlProperty property;
185 QQuickStateActionEvent *event;
186};
187
188class QQuickStateOperationPrivate : public QObjectPrivate
189{
190 Q_DECLARE_PUBLIC(QQuickStateOperation)
191
192public:
193
194 QQuickStateOperationPrivate()
195 : m_state(nullptr) {}
196
197 QQuickState *m_state;
198};
199
200class QQuickStatePrivate : public QObjectPrivate
201{
202 Q_DECLARE_PUBLIC(QQuickState)
203
204public:
205 QQuickStatePrivate()
206 : when(false), whenKnown(false), named(false), inState(false), group(nullptr) {}
207
208 typedef QList<QQuickSimpleAction> SimpleActionList;
209
210 QString name;
211 bool when;
212 bool whenKnown;
213 bool named;
214
215 struct OperationGuard : public QQmlGuard<QQuickStateOperation>
216 {
217 OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) {
218 setObject(static_cast<QQuickStateOperation *>(obj));
219 }
220 QList<OperationGuard> *list;
221 void objectDestroyed(QQuickStateOperation *) override {
222 // we assume priv will always be destroyed after objectDestroyed calls
223 list->removeOne(*this);
224 }
225 };
226 QList<OperationGuard> operations;
227
228 static void operations_append(QQmlListProperty<QQuickStateOperation> *prop, QQuickStateOperation *op) {
229 QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
230 op->setState(qobject_cast<QQuickState*>(prop->object));
231 list->append(OperationGuard(op, list));
232 }
233 static void operations_clear(QQmlListProperty<QQuickStateOperation> *prop) {
234 QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
235 for (auto &e : *list)
236 e->setState(nullptr);
237 list->clear();
238 }
239 static int operations_count(QQmlListProperty<QQuickStateOperation> *prop) {
240 QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
241 return list->count();
242 }
243 static QQuickStateOperation *operations_at(QQmlListProperty<QQuickStateOperation> *prop, int index) {
244 QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
245 return list->at(index);
246 }
247
248 QQuickTransitionManager transitionManager;
249
250 SimpleActionList revertList;
251 QList<QQuickRevertAction> reverting;
252 QString extends;
253 mutable bool inState;
254 QQuickStateGroup *group;
255
256 QQuickStateOperation::ActionList generateActionList() const;
257 void complete();
258};
259
260QT_END_NAMESPACE
261
262#endif // QQUICKSTATE_P_H
263