-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTransitions.h
235 lines (206 loc) · 9.89 KB
/
Transitions.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
// Transitions.h
// Useful functions for Qt Transitions
// (c) Eric Lecolinet - Telecom ParisTech - 2016/2018
// www.telecom-paristech.fr/~elc
//
#ifndef QTRANSITION_H
#define QTRANSITION_H
#include <QWidget>
#include <QMouseEvent>
#include <QState>
#include <QStateMachine>
#include <QSignalTransition>
#include <QKeyEventTransition>
#include <QMouseEventTransition>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Returns the position of the mouse cursor in widget coordinates.
inline QPoint cursorPos(QWidget* w) {
return w->mapFromGlobal(QCursor::pos());
}
/// Returns the position of the mouse cursor in widget coordinates.
inline QPoint cursorPos(QWidget& w) {
return w.mapFromGlobal(QCursor::pos());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Adds a Signal transition between _from_ and _to_.
inline QSignalTransition* addTrans(QState* from, QState* to,
QObject* sender, const char* signal) {
return from->addTransition(sender, signal, to);
}
/// Adds a Signal transition between _from_ and _to_ and connects a slot to this transition.
inline QSignalTransition* addTrans(QState* from, QState* to,
QObject* sender, const char* signal,
QObject* receiver, const char* slot) {
QSignalTransition* trans = from->addTransition(sender, signal, to);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Signal transition with a guard.
template <typename Guard>
class GuardedSignalTransition : public QSignalTransition {
public:
GuardedSignalTransition(Guard& guard, QObject* sender, const char* signal, QState* from)
: QSignalTransition(sender, signal, from), guard(guard) {}
protected:
Guard& guard;
bool eventTest(QEvent* e) {return guard && QSignalTransition::eventTest(e);}
};
/// Adds a guarded Signal transition between _from_ and _to_.
/** The transition cannot be triggered when _guard_ is false.
* _guard_ can be a bool or any object that can be compared to a bool.
* _guard_ should exist as long as the transition exists (e.g. _guard_ should not be a local variable).
*/
template <typename Guard>
inline GuardedSignalTransition<Guard>* addTrans(Guard& guard, QState* from, QState* to,
QObject* sender, const char* signal) {
GuardedSignalTransition<Guard>* trans = new GuardedSignalTransition<Guard>(guard, sender, signal, from);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Adds a guarded Signal transition between _from_ and _to_ and connects a slot to this transition.
/** The transition cannot be triggered when _guard_ is false.
* _guard_ can be a bool or any object that can be compared to a bool.
* _guard_ should exist as long as the transition exists (e.g. _guard_ should not be a local variable).
*/
template <typename Guard>
inline GuardedSignalTransition<Guard>* addTrans(Guard& guard, QState* from, QState* to,
QObject* sender, const char* signal,
QObject* receiver, const char* slot) {
GuardedSignalTransition<Guard>* trans = addTrans(guard, from, to, sender, signal);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Adds an Event transition between _from_ and _to_.
/** @note Not compatible with User Events: use addUserTrans() instead.
*/
inline QEventTransition* addEventTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type) {
QEventTransition* trans = new QEventTransition(sender, type);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Adds an Event transition between _from_ and _to_ and connects a slot to this transition.
/** @note Not compatible with User Events: use addUserTrans() instead.
*/
inline QEventTransition* addEventTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type,
QObject* receiver, const char* slot) {
QEventTransition* trans = addEventTrans(from, to, sender, type);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
/// Adds a transition for Key Events between _from_ and _to_.
inline QKeyEventTransition* addKeyTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, int key) {
QKeyEventTransition* trans = new QKeyEventTransition(sender, type, key);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Adds a transition for Key Events between _from_ and _to_ and connects a slot to this transition.
inline QKeyEventTransition* addKeyTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, int key,
QObject* receiver, const char* slot) {
QKeyEventTransition* trans = addKeyTrans(from, to, sender, type, key);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
/// Adds a transition for Mouse Events between _from_ and _to_.
inline QMouseEventTransition* addMouseTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, Qt::MouseButton btn) {
QMouseEventTransition* trans = new QMouseEventTransition(sender, type, btn);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Add a transition for Mouse Events between _from_ and _to_ and connects a slot to this transition.
inline QMouseEventTransition* addMouseTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, Qt::MouseButton btn,
QObject* receiver, const char* slot) {
QMouseEventTransition* trans = addMouseTrans(from, to, sender, type, btn);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
/// Transition for Mouse Events that updates the mouse position.
class MouseEventTransition : public QMouseEventTransition {
QPoint& pos;
public:
MouseEventTransition(QObject* sender, QEvent::Type type, Qt::MouseButton button, QPoint& pos)
: QMouseEventTransition(sender, type, button), pos(pos) {}
virtual void onTransition(QEvent *e) {
QEvent* realEvent = static_cast<QStateMachine::WrappedEvent*>(e)->event();
switch (realEvent->type()) {
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
pos = (static_cast<QMouseEvent*>(realEvent))->pos();
default: break;
}
}
};
/// Adds a transition for Mouse Events that updates the mouse position.
/** _pos_ is a QPoint which value is updated when the transition is fired.
* _pos_ should exist as long as the transition exists (e.g. _pos_ should not be a local variable).
*/
inline MouseEventTransition* addMouseTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, Qt::MouseButton btn,
QPoint& pos) {
MouseEventTransition* trans = new MouseEventTransition(sender, type, btn, pos);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Adds a transition for Mouse Events that updates the mouse position, and connects a slot to this transition.
/** _pos_ is a QPoint which value is updated when the transition is fired.
* _pos_ should exist as long as the transition exists (e.g. _pos_ should not be a local variable).
*/
inline MouseEventTransition* addMouseTrans(QState* from, QState* to,
QObject* sender, QEvent::Type type, Qt::MouseButton btn,
QPoint& pos,
QObject* receiver, const char* slot) {
MouseEventTransition* trans = addMouseTrans(from, to, sender, type, btn, pos);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Transition for User Events.
class UserEventTransition : public QAbstractTransition {
public:
/// constructor (_eventType_ must be between QEvent::User and QEvent::MaxUser).
UserEventTransition(int eventType) : type(eventType) {}
int eventType() const {return type;}
void setEventType(int eventType) {type = eventType;}
protected:
int type;
virtual bool eventTest(QEvent* e) {return type == e->type();}
virtual void onTransition(QEvent*) {}
};
/// Adds a transition between _from_ and _to_ that can be fired by a User Event.
/** The transition is fired by posting a QEvent with the same _eventType_:
* state_machine->postEvent(new QEvent(_eventType_));
* @note _eventType_ must be between QEvent::User and QEvent::MaxUser.
*/
inline UserEventTransition* addUserTrans(QState* from, QState* to, int eventType) {
UserEventTransition* trans = new UserEventTransition(eventType);
trans->setTargetState(to);
from->addTransition(trans);
return trans;
}
/// Adds a transition between _from_ and _to_ that can be fired by a user event and connects a slot to this transition.
/** The transition is fired by posting a QEvent with the same _eventType_:
* state_machine->postEvent(new QEvent(_eventType_));
* @note _eventType_ must be between QEvent::User and QEvent::MaxUser.
*/
inline UserEventTransition* addUserTrans(QState* from, QState* to, int eventType,
QObject* receiver, const char* slot) {
UserEventTransition* trans = addUserTrans(from, to, eventType);
QObject::connect(trans, SIGNAL(triggered()), receiver, slot);
return trans;
}
#endif // TRANSITION_H