1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qeventtransition.h"
5#include "qeventtransition_p.h"
6#include "qstate.h"
7#include "qstate_p.h"
8#include "qstatemachine.h"
9#include "qstatemachine_p.h"
10#include <qdebug.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QEventTransition
16 \inmodule QtStateMachine
17
18 \brief The QEventTransition class provides a QObject-specific transition for Qt events.
19
20 \since 4.6
21 \ingroup statemachine
22
23 A QEventTransition object binds an event to a particular QObject.
24 QEventTransition is part of \l{Qt State Machine Overview}{Qt State Machine Framework}.
25
26 Example:
27
28 \code
29 QPushButton *button = ...;
30 QState *s1 = ...;
31 QState *s2 = ...;
32 // If in s1 and the button receives an Enter event, transition to s2
33 QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter);
34 enterTransition->setTargetState(s2);
35 s1->addTransition(enterTransition);
36 // If in s2 and the button receives an Exit event, transition back to s1
37 QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave);
38 leaveTransition->setTargetState(s1);
39 s2->addTransition(leaveTransition);
40 \endcode
41
42 \section1 Subclassing
43
44 When reimplementing the eventTest() function, you should first call the base
45 implementation to verify that the event is a QStateMachine::WrappedEvent for
46 the proper object and event type. You may then cast the event to a
47 QStateMachine::WrappedEvent and get the original event by calling
48 QStateMachine::WrappedEvent::event(), and perform additional checks on that
49 object.
50
51 \sa QState::addTransition()
52*/
53
54/*!
55 \property QEventTransition::eventSource
56
57 \brief the event source that this event transition is associated with
58*/
59
60/*!
61 \property QEventTransition::eventType
62
63 \brief the type of event that this event transition is associated with
64*/
65
66QEventTransitionPrivate::~QEventTransitionPrivate()
67{
68}
69
70void QEventTransitionPrivate::unregister()
71{
72 Q_Q(QEventTransition);
73 if (!registered || !machine())
74 return;
75 QStateMachinePrivate::get(q: machine())->unregisterEventTransition(transition: q);
76}
77
78void QEventTransitionPrivate::maybeRegister()
79{
80 Q_Q(QEventTransition);
81 if (QStateMachine *mach = machine())
82 QStateMachinePrivate::get(q: mach)->maybeRegisterEventTransition(transition: q);
83}
84
85/*!
86 Constructs a new QEventTransition object with the given \a sourceState.
87*/
88QEventTransition::QEventTransition(QState *sourceState)
89 : QAbstractTransition(*new QEventTransitionPrivate, sourceState)
90{
91}
92
93/*!
94 Constructs a new QEventTransition object associated with events of the given
95 \a type for the given \a object, and with the given \a sourceState.
96*/
97QEventTransition::QEventTransition(QObject *object, QEvent::Type type,
98 QState *sourceState)
99 : QAbstractTransition(*new QEventTransitionPrivate, sourceState)
100{
101 Q_D(QEventTransition);
102 d->registered = false;
103 d->object.setValueBypassingBindings(object);
104 d->eventType.setValueBypassingBindings(type);
105 d->maybeRegister();
106}
107
108/*!
109 \internal
110*/
111QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent)
112 : QAbstractTransition(dd, parent)
113{
114}
115
116/*!
117 \internal
118*/
119QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object,
120 QEvent::Type type, QState *parent)
121 : QAbstractTransition(dd, parent)
122{
123 Q_D(QEventTransition);
124 d->registered = false;
125 d->object.setValueBypassingBindings(object);
126 d->eventType.setValueBypassingBindings(type);
127 d->maybeRegister();
128}
129
130/*!
131 Destroys this QObject event transition.
132*/
133QEventTransition::~QEventTransition()
134{
135}
136
137/*!
138 Returns the event type that this event transition is associated with.
139*/
140QEvent::Type QEventTransition::eventType() const
141{
142 Q_D(const QEventTransition);
143 return d->eventType;
144}
145
146/*!
147 Sets the event \a type that this event transition is associated with.
148*/
149void QEventTransition::setEventType(QEvent::Type type)
150{
151 Q_D(QEventTransition);
152 if (d->eventType.value() == type) {
153 d->eventType.removeBindingUnlessInWrapper();
154 return;
155 }
156 d->unregister();
157 d->eventType = type;
158 d->maybeRegister();
159 d->eventType.notify();
160}
161
162QBindable<QEvent::Type> QEventTransition::bindableEventType()
163{
164 Q_D(QEventTransition);
165 return &d->eventType;
166}
167
168/*!
169 Returns the event source associated with this event transition.
170*/
171QObject *QEventTransition::eventSource() const
172{
173 Q_D(const QEventTransition);
174 return d->object;
175}
176
177/*!
178 Sets the event source associated with this event transition to be the given
179 \a object.
180*/
181void QEventTransition::setEventSource(QObject *object)
182{
183 Q_D(QEventTransition);
184 if (d->object.value() == object) {
185 d->object.removeBindingUnlessInWrapper();
186 return;
187 }
188 d->unregister();
189 d->object = object;
190 d->maybeRegister();
191 d->object.notify();
192}
193
194QBindable<QObject*> QEventTransition::bindableEventSource()
195{
196 Q_D(QEventTransition);
197 return &d->object;
198}
199
200/*!
201 \reimp
202*/
203bool QEventTransition::eventTest(QEvent *event)
204{
205 Q_D(const QEventTransition);
206 if (event->type() == QEvent::StateMachineWrapped) {
207 QStateMachine::WrappedEvent *we = static_cast<QStateMachine::WrappedEvent*>(event);
208 return (we->object() == d->object)
209 && (we->event()->type() == d->eventType.value());
210 }
211 return false;
212}
213
214/*!
215 \reimp
216*/
217void QEventTransition::onTransition(QEvent *event)
218{
219 Q_UNUSED(event);
220}
221
222/*!
223 \reimp
224*/
225bool QEventTransition::event(QEvent *e)
226{
227 return QAbstractTransition::event(e);
228}
229
230QT_END_NAMESPACE
231
232#include "moc_qeventtransition.cpp"
233

source code of qtscxml/src/statemachine/qeventtransition.cpp