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