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 
65 QT_BEGIN_NAMESPACE
66 
67 class QQuickSimpleAction
68 {
69 public:
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 
~QQuickSimpleAction()90     ~QQuickSimpleAction()
91     {
92     }
93 
QQuickSimpleAction(const QQuickSimpleAction & other)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 
setProperty(const QQmlProperty & property)118     void setProperty(const QQmlProperty &property)
119     {
120         m_property = property;
121     }
122 
property()123     const QQmlProperty &property() const
124     {
125         return m_property;
126     }
127 
setValue(const QVariant & value)128     void setValue(const QVariant &value)
129     {
130         m_value = value;
131     }
132 
value()133     const QVariant &value() const
134     {
135         return m_value;
136     }
137 
setBinding(QQmlAbstractBinding * binding)138     void setBinding(QQmlAbstractBinding *binding)
139     {
140         m_binding = binding;
141     }
142 
binding()143     QQmlAbstractBinding *binding() const
144     {
145         return m_binding.data();
146     }
147 
specifiedObject()148     QObject *specifiedObject() const
149     {
150         return m_specifiedObject;
151     }
152 
specifiedProperty()153     const QString &specifiedProperty() const
154     {
155         return m_specifiedProperty;
156     }
157 
event()158     QQuickStateActionEvent *event() const
159     {
160         return m_event;
161     }
162 
reverseEvent()163     bool reverseEvent() const
164     {
165         return m_reverseEvent;
166     }
167 
168 private:
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 
178 class QQuickRevertAction
179 {
180 public:
QQuickRevertAction()181     QQuickRevertAction() : event(nullptr) {}
QQuickRevertAction(const QQmlProperty & prop)182     QQuickRevertAction(const QQmlProperty &prop) : property(prop), event(nullptr) {}
QQuickRevertAction(QQuickStateActionEvent * e)183     QQuickRevertAction(QQuickStateActionEvent *e) : event(e) {}
184     QQmlProperty property;
185     QQuickStateActionEvent *event;
186 };
187 
188 class QQuickStateOperationPrivate : public QObjectPrivate
189 {
Q_DECLARE_PUBLIC(QQuickStateOperation)190     Q_DECLARE_PUBLIC(QQuickStateOperation)
191 
192 public:
193 
194     QQuickStateOperationPrivate()
195     : m_state(nullptr) {}
196 
197     QQuickState *m_state;
198 };
199 
200 class QQuickStatePrivate : public QObjectPrivate
201 {
Q_DECLARE_PUBLIC(QQuickState)202     Q_DECLARE_PUBLIC(QQuickState)
203 
204 public:
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     {
OperationGuardOperationGuard217         OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) {
218             setObject(static_cast<QQuickStateOperation *>(obj));
219         }
220         QList<OperationGuard> *list;
objectDestroyedOperationGuard221         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 
operations_append(QQmlListProperty<QQuickStateOperation> * prop,QQuickStateOperation * op)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     }
operations_clear(QQmlListProperty<QQuickStateOperation> * prop)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     }
operations_count(QQmlListProperty<QQuickStateOperation> * prop)239     static int operations_count(QQmlListProperty<QQuickStateOperation> *prop) {
240         QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
241         return list->count();
242     }
operations_at(QQmlListProperty<QQuickStateOperation> * prop,int index)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     }
operations_replace(QQmlListProperty<QQuickStateOperation> * prop,int index,QQuickStateOperation * op)247     static void operations_replace(QQmlListProperty<QQuickStateOperation> *prop, int index,
248                                    QQuickStateOperation *op) {
249         QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
250         auto &guard = list->at(index);
251         if (guard.object() == op) {
252             op->setState(qobject_cast<QQuickState*>(prop->object));
253         } else {
254             list->at(index)->setState(nullptr);
255             op->setState(qobject_cast<QQuickState*>(prop->object));
256             list->replace(index, OperationGuard(op, list));
257         }
258     }
operations_removeLast(QQmlListProperty<QQuickStateOperation> * prop)259     static void operations_removeLast(QQmlListProperty<QQuickStateOperation> *prop) {
260         QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
261         list->last()->setState(nullptr);
262         list->removeLast();
263     }
264 
265     QQuickTransitionManager transitionManager;
266 
267     SimpleActionList revertList;
268     QList<QQuickRevertAction> reverting;
269     QString extends;
270     mutable bool inState;
271     QQuickStateGroup *group;
272 
273     QQuickStateOperation::ActionList generateActionList() const;
274     void complete();
275 };
276 
277 QT_END_NAMESPACE
278 
279 #endif // QQUICKSTATE_P_H
280