1 | // Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). |
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 "qmousehandler.h" |
5 | #include "qmousehandler_p.h" |
6 | |
7 | #include <Qt3DInput/qmousedevice.h> |
8 | #include <Qt3DInput/qmouseevent.h> |
9 | #include <QtCore/QTimer> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | namespace Qt3DInput { |
14 | |
15 | using namespace Qt3DCore; |
16 | using namespace std::chrono_literals; |
17 | |
18 | /*! \internal */ |
19 | QMouseHandlerPrivate::QMouseHandlerPrivate() |
20 | : QComponentPrivate() |
21 | , m_mouseDevice(nullptr) |
22 | , m_containsMouse(false) |
23 | { |
24 | m_shareable = false; |
25 | } |
26 | |
27 | QMouseHandlerPrivate::~QMouseHandlerPrivate() |
28 | { |
29 | } |
30 | |
31 | void QMouseHandlerPrivate::init() |
32 | { |
33 | Q_Q(QMouseHandler); |
34 | |
35 | m_pressAndHoldTimer = new QTimer(q); |
36 | m_pressAndHoldTimer->setSingleShot(true); |
37 | m_pressAndHoldTimer->setInterval(800ms); |
38 | QObject::connect(sender: m_pressAndHoldTimer, signal: &QTimer::timeout, context: q, slot: [this, q] { |
39 | emit q->pressAndHold(mouse: m_lastPressedEvent.data()); |
40 | }); |
41 | } |
42 | |
43 | void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event) |
44 | { |
45 | Q_Q(QMouseHandler); |
46 | switch (event->type()) { |
47 | case QEvent::MouseButtonPress: |
48 | m_lastPressedEvent = event; |
49 | m_pressAndHoldTimer->start(); |
50 | emit q->pressed(mouse: event.data()); |
51 | break; |
52 | case QEvent::MouseButtonRelease: |
53 | m_pressAndHoldTimer->stop(); |
54 | emit q->released(mouse: event.data()); |
55 | emit q->clicked(mouse: event.data()); |
56 | break; |
57 | #if QT_CONFIG(gestures) |
58 | case QEvent::Gesture: |
59 | emit q->clicked(mouse: event.data()); |
60 | break; |
61 | #endif |
62 | case QEvent::MouseButtonDblClick: |
63 | emit q->doubleClicked(mouse: event.data()); |
64 | break; |
65 | case QEvent::MouseMove: |
66 | m_pressAndHoldTimer->stop(); |
67 | emit q->positionChanged(mouse: event.data()); |
68 | break; |
69 | default: |
70 | break; |
71 | } |
72 | } |
73 | |
74 | /*! |
75 | * \qmltype MouseHandler |
76 | * \nativetype Qt3DInput::QMouseHandler |
77 | * \inqmlmodule Qt3D.Input |
78 | * \since 5.5 |
79 | * \brief Provides mouse event notification. |
80 | * |
81 | * \TODO |
82 | * \sa MouseDevice, MouseEvent |
83 | */ |
84 | |
85 | /*! |
86 | * \class Qt3DInput::QMouseHandler |
87 | * \inheaderfile Qt3DInput/QMouseHandler |
88 | * \inmodule Qt3DInput |
89 | * |
90 | * \brief Provides a means of being notified about mouse events when attached to |
91 | * a QMouseDevice instance. |
92 | * |
93 | * \since 5.5 |
94 | * |
95 | * \note QMouseHandler components shouldn't be shared, not respecting that |
96 | * condition will most likely result in undefined behaviors. |
97 | * |
98 | * \sa QMouseDevice, QMouseEvent |
99 | */ |
100 | |
101 | /*! |
102 | \qmlproperty MouseDevice Qt3D.Input::MouseHandler::sourceDevice |
103 | |
104 | Holds the current mouse source device of the MouseHandler instance. |
105 | */ |
106 | |
107 | /*! |
108 | \qmlproperty bool Qt3D.Input::MouseHandler::containsMouse |
109 | \readonly |
110 | |
111 | Holds \c true if the QMouseHandler currently contains the mouse. |
112 | */ |
113 | |
114 | /*! |
115 | \qmlsignal Qt3D.Input::MouseHandler::clicked(MouseEvent mouse) |
116 | |
117 | This signal is emitted when a mouse button is clicked with the event details |
118 | being contained within \a mouse |
119 | */ |
120 | |
121 | /*! |
122 | \qmlsignal Qt3D.Input::MouseHandler::doubleClicked(MouseEvent mouse) |
123 | |
124 | This signal is emitted when a mouse button is double clicked with the event |
125 | details being contained within \a mouse |
126 | */ |
127 | |
128 | /*! |
129 | \qmlsignal Qt3D.Input::MouseHandler::entered() |
130 | */ |
131 | |
132 | /*! |
133 | \qmlsignal Qt3D.Input::MouseHandler::exited() |
134 | */ |
135 | |
136 | /*! |
137 | \qmlsignal Qt3D.Input::MouseHandler::pressed(MouseEvent mouse) |
138 | |
139 | This signal is emitted when a mouse button is pressed with the event details |
140 | being contained within \a mouse |
141 | */ |
142 | |
143 | /*! |
144 | \qmlsignal Qt3D.Input::MouseHandler::released(MouseEvent mouse) |
145 | |
146 | This signal is emitted when a mouse button is released with the event |
147 | details being contained within \a mouse |
148 | */ |
149 | |
150 | /*! |
151 | \qmlsignal Qt3D.Input::MouseHandler::pressAndHold(MouseEvent mouse) |
152 | |
153 | This signal is emitted when a mouse button is pressed and held down with the |
154 | event details being contained within \a mouse |
155 | */ |
156 | |
157 | /*! |
158 | \qmlsignal Qt3D.Input::MouseHandler::positionChanged(MouseEvent mouse) |
159 | |
160 | This signal is emitted when the mouse position changes with the event |
161 | details being contained within \a mouse |
162 | */ |
163 | |
164 | /*! |
165 | \qmlsignal Qt3D.Input::MouseHandler::wheel(MouseEvent mouse) |
166 | |
167 | This signal is emitted when the mouse wheel is used with the event details |
168 | being contained within \a mouse. |
169 | */ |
170 | |
171 | /*! |
172 | \fn Qt3DInput::QMouseHandler::clicked(Qt3DInput::QMouseEvent *mouse) |
173 | |
174 | This signal is emitted when a mouse button is clicked with the event details |
175 | being contained within \a mouse. |
176 | */ |
177 | |
178 | /*! |
179 | \fn Qt3DInput::QMouseHandler::doubleClicked(Qt3DInput::QMouseEvent *mouse) |
180 | |
181 | This signal is emitted when a mouse button is double clicked with the event |
182 | details being contained within \a mouse. |
183 | */ |
184 | |
185 | /*! |
186 | \fn Qt3DInput::QMouseHandler::entered() |
187 | */ |
188 | |
189 | /*! |
190 | \fn Qt3DInput::QMouseHandler::exited() |
191 | */ |
192 | |
193 | /*! |
194 | \fn Qt3DInput::QMouseHandler::pressed(Qt3DInput::QMouseEvent *mouse) |
195 | |
196 | This signal is emitted when a mouse button is pressed with the event details |
197 | being contained within \a mouse |
198 | */ |
199 | |
200 | /*! |
201 | \fn Qt3DInput::QMouseHandler::released(Qt3DInput::QMouseEvent *mouse) |
202 | |
203 | This signal is emitted when a mouse button is released with the event |
204 | details being contained within \a mouse |
205 | */ |
206 | |
207 | /*! |
208 | \fn Qt3DInput::QMouseHandler::pressAndHold(Qt3DInput::QMouseEvent *mouse) |
209 | |
210 | This signal is emitted when a mouse button is pressed and held down with the |
211 | event details being contained within \a mouse |
212 | */ |
213 | |
214 | /*! |
215 | \fn Qt3DInput::QMouseHandler::positionChanged(Qt3DInput::QMouseEvent *mouse) |
216 | |
217 | This signal is emitted when the mouse position changes with the event |
218 | details being contained within \a mouse |
219 | */ |
220 | |
221 | /*! |
222 | \fn Qt3DInput::QMouseHandler::wheel(Qt3DInput::QWheelEvent *wheel) |
223 | |
224 | This signal is emitted when the mouse wheel is used with the event details |
225 | being contained within \a wheel |
226 | */ |
227 | |
228 | /*! |
229 | * Constructs a new QMouseHandler instance with parent \a parent. |
230 | */ |
231 | QMouseHandler::QMouseHandler(QNode *parent) |
232 | : QComponent(*new QMouseHandlerPrivate, parent) |
233 | { |
234 | Q_D(QMouseHandler); |
235 | d->init(); |
236 | } |
237 | |
238 | QMouseHandler::~QMouseHandler() |
239 | { |
240 | } |
241 | |
242 | /*! |
243 | * Sets the mouse device of the QMouseHandler instance to \a mouseDevice. |
244 | */ |
245 | void QMouseHandler::setSourceDevice(QMouseDevice *mouseDevice) |
246 | { |
247 | Q_D(QMouseHandler); |
248 | if (d->m_mouseDevice != mouseDevice) { |
249 | |
250 | if (d->m_mouseDevice) |
251 | d->unregisterDestructionHelper(node: d->m_mouseDevice); |
252 | |
253 | // We need to add it as a child of the current node if it has been declared inline |
254 | // Or not previously added as a child of the current node so that |
255 | // 1) The backend gets notified about it's creation |
256 | // 2) When the current node is destroyed, it gets destroyed as well |
257 | if (mouseDevice && !mouseDevice->parent()) |
258 | mouseDevice->setParent(this); |
259 | d->m_mouseDevice = mouseDevice; |
260 | |
261 | // Ensures proper bookkeeping |
262 | if (d->m_mouseDevice) |
263 | d->registerDestructionHelper(node: d->m_mouseDevice, func: &QMouseHandler::setSourceDevice, d->m_mouseDevice); |
264 | |
265 | emit sourceDeviceChanged(mouseDevice); |
266 | } |
267 | } |
268 | |
269 | |
270 | /*! |
271 | * \property Qt3DInput::QMouseHandler::sourceDevice |
272 | * |
273 | * Holds the current mouse source device of the QMouseHandler instance. |
274 | */ |
275 | QMouseDevice *QMouseHandler::sourceDevice() const |
276 | { |
277 | Q_D(const QMouseHandler); |
278 | return d->m_mouseDevice; |
279 | } |
280 | |
281 | /*! |
282 | * \property Qt3DInput::QMouseHandler::containsMouse |
283 | * |
284 | * Holds \c true if the QMouseHandler currently contains the mouse. |
285 | * |
286 | * \note In this context, contains mean that the ray originating from the |
287 | * mouse is intersecting with the Qt3DCore::QEntity that aggregates the current |
288 | * QMouseHandler instance component. |
289 | */ |
290 | bool QMouseHandler::containsMouse() const |
291 | { |
292 | Q_D(const QMouseHandler); |
293 | return d->m_containsMouse; |
294 | } |
295 | |
296 | /*! \internal */ |
297 | void QMouseHandler::setContainsMouse(bool contains) |
298 | { |
299 | Q_D(QMouseHandler); |
300 | if (contains != d->m_containsMouse) { |
301 | d->m_containsMouse = contains; |
302 | emit containsMouseChanged(containsMouse: contains); |
303 | } |
304 | } |
305 | |
306 | } // namespace Qt3DInput |
307 | |
308 | QT_END_NAMESPACE |
309 | |
310 | #include "moc_qmousehandler.cpp" |
311 | |