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