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
47QT_BEGIN_NAMESPACE
48
49using namespace Qt3DCore;
50
51namespace Qt3DInput {
52/*! \internal */
53QMouseHandlerPrivate::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
67QMouseHandlerPrivate::~QMouseHandlerPrivate()
68{
69}
70
71void QMouseHandlerPrivate::init(QObject *parent)
72{
73 m_pressAndHoldTimer->setParent(parent);
74}
75
76void 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 */
264QMouseHandler::QMouseHandler(QNode *parent)
265 : QComponent(*new QMouseHandlerPrivate, parent)
266{
267 Q_D(QMouseHandler);
268 d->init(parent: this);
269}
270
271QMouseHandler::~QMouseHandler()
272{
273}
274
275/*!
276 * Sets the mouse device of the QMouseHandler instance to \a mouseDevice.
277 */
278void 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
303void 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 */
312QMouseDevice *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 */
327bool QMouseHandler::containsMouse() const
328{
329 Q_D(const QMouseHandler);
330 return d->m_containsMouse;
331}
332
333/*! \internal */
334void 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
343Qt3DCore::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
356QT_END_NAMESPACE
357

source code of qt3d/src/input/frontend/qmousehandler.cpp