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 d->eventType.removeBindingUnlessInWrapper();
153 if (d->eventType.valueBypassingBindings() == type)
154 return;
155 d->unregister();
156 d->eventType.setValueBypassingBindings(type);
157 d->maybeRegister();
158 d->eventType.notify();
159}
160
161QBindable<QEvent::Type> QEventTransition::bindableEventType()
162{
163 Q_D(QEventTransition);
164 return &d->eventType;
165}
166
167/*!
168 Returns the event source associated with this event transition.
169*/
170QObject *QEventTransition::eventSource() const
171{
172 Q_D(const QEventTransition);
173 return d->object;
174}
175
176/*!
177 Sets the event source associated with this event transition to be the given
178 \a object.
179*/
180void QEventTransition::setEventSource(QObject *object)
181{
182 Q_D(QEventTransition);
183 d->object.removeBindingUnlessInWrapper();
184 if (d->object.valueBypassingBindings() == object)
185 return;
186 d->unregister();
187 d->object.setValueBypassingBindings(object);
188 d->maybeRegister();
189 d->object.notify();
190}
191
192QBindable<QObject*> QEventTransition::bindableEventSource()
193{
194 Q_D(QEventTransition);
195 return &d->object;
196}
197
198/*!
199 \reimp
200*/
201bool QEventTransition::eventTest(QEvent *event)
202{
203 Q_D(const QEventTransition);
204 if (event->type() == QEvent::StateMachineWrapped) {
205 QStateMachine::WrappedEvent *we = static_cast<QStateMachine::WrappedEvent*>(event);
206 return (we->object() == d->object)
207 && (we->event()->type() == d->eventType.value());
208 }
209 return false;
210}
211
212/*!
213 \reimp
214*/
215void QEventTransition::onTransition(QEvent *event)
216{
217 Q_UNUSED(event);
218}
219
220/*!
221 \reimp
222*/
223bool QEventTransition::event(QEvent *e)
224{
225 return QAbstractTransition::event(e);
226}
227
228QT_END_NAMESPACE
229
230#include "moc_qeventtransition.cpp"
231

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