1/*
2 SPDX-FileCopyrightText: 2011 Marco Martin <notmart@gmail.com>
3 SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef MOUSEEVENTLISTENER_H
9#define MOUSEEVENTLISTENER_H
10
11#include <QQuickItem>
12
13/*!
14 * \qmltype KDeclarativeMouseEvent
15 * \inqmlmodule org.kde.kquickcontrols.addons
16 *
17 * \brief This item spies on mouse events from all child objects
18 * including child MouseAreas regardless
19 * of whether the child MouseArea propagates events.
20 * It does not accept the event.
21 *
22 * In addition unlike MouseArea events include the mouse position
23 * in global coordinates and provides
24 * the screen the mouse is in.
25 */
26class KDeclarativeMouseEvent : public QObject
27{
28 Q_OBJECT
29 QML_ANONYMOUS
30 /*! \qmlproperty bool KDeclarativeMouseEvent::x */
31 Q_PROPERTY(int x READ x)
32 /*! \qmlproperty bool KDeclarativeMouseEvent::y */
33 Q_PROPERTY(int y READ y)
34 /*! \qmlproperty bool KDeclarativeMouseEvent::screenX */
35 Q_PROPERTY(int screenX READ screenX)
36 /*! \qmlproperty bool KDeclarativeMouseEvent::screenY */
37 Q_PROPERTY(int screenY READ screenY)
38 /*! \qmlproperty bool KDeclarativeMouseEvent::button */
39 Q_PROPERTY(int button READ button)
40 /*! \qmlproperty Qt::MouseButtons KDeclarativeMouseEvent::buttons */
41 Q_PROPERTY(Qt::MouseButtons buttons READ buttons)
42 /*! \qmlproperty Qt::KeyboardModifiers KDeclarativeMouseEvent::modifiers */
43 Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers)
44 /*! \qmlproperty QScreen KDeclarativeMouseEvent::screen */
45 Q_PROPERTY(QScreen *screen READ screen CONSTANT)
46 /*! \qmlproperty bool KDeclarativeMouseEvent::accepted */
47 Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted NOTIFY acceptedChanged)
48 /*! \qmlproperty int KDeclarativeMouseEvent::source */
49 Q_PROPERTY(int source READ source)
50
51public:
52 KDeclarativeMouseEvent(int x,
53 int y,
54 int screenX,
55 int screenY,
56 Qt::MouseButton button,
57 Qt::MouseButtons buttons,
58 Qt::KeyboardModifiers modifiers,
59 QScreen *screen,
60 Qt::MouseEventSource source)
61 : m_x(x)
62 , m_y(y)
63 , m_screenX(screenX)
64 , m_screenY(screenY)
65 , m_button(button)
66 , m_buttons(buttons)
67 , m_modifiers(modifiers)
68 , m_screen(screen)
69 , m_source(source)
70 {
71 }
72
73 int x() const
74 {
75 return m_x;
76 }
77 int y() const
78 {
79 return m_y;
80 }
81 int screenX() const
82 {
83 return m_screenX;
84 }
85 int screenY() const
86 {
87 return m_screenY;
88 }
89 int button() const
90 {
91 return m_button;
92 }
93 Qt::MouseButtons buttons() const
94 {
95 return m_buttons;
96 }
97 Qt::KeyboardModifiers modifiers() const
98 {
99 return m_modifiers;
100 }
101 QScreen *screen() const
102 {
103 return m_screen;
104 }
105 int source() const
106 {
107 return m_source;
108 }
109
110 bool isAccepted() const
111 {
112 return m_accepted;
113 }
114 void setAccepted(bool accepted)
115 {
116 if (m_accepted != accepted) {
117 m_accepted = accepted;
118 Q_EMIT acceptedChanged();
119 }
120 }
121
122 // only for internal usage
123 void setX(int x)
124 {
125 m_x = x;
126 }
127 void setY(int y)
128 {
129 m_y = y;
130 }
131
132Q_SIGNALS:
133 /*! \qmlsignal KDeclarativeMouseEvent::acceptedChanged() */
134 void acceptedChanged();
135
136private:
137 int m_x;
138 int m_y;
139 int m_screenX;
140 int m_screenY;
141 Qt::MouseButton m_button;
142 Qt::MouseButtons m_buttons;
143 Qt::KeyboardModifiers m_modifiers;
144 QScreen *m_screen;
145 bool m_accepted = false;
146 int m_source;
147};
148
149/*!
150 * \qmltype KDeclarativeWheelEvent
151 * \inqmlmodule org.kde.kquickcontrols.addons
152 */
153class KDeclarativeWheelEvent : public QObject
154{
155 Q_OBJECT
156 QML_ANONYMOUS
157 /*! \qmlproperty int KDeclarativeWheelEvent::x */
158 Q_PROPERTY(int x READ x CONSTANT)
159 /*! \qmlproperty int KDeclarativeWheelEvent::y */
160 Q_PROPERTY(int y READ y CONSTANT)
161 /*! \qmlproperty int KDeclarativeWheelEvent::screenX */
162 Q_PROPERTY(int screenX READ screenX CONSTANT)
163 /*! \qmlproperty int KDeclarativeWheelEvent::screenY */
164 Q_PROPERTY(int screenY READ screenY CONSTANT)
165 /*! \qmlproperty int KDeclarativeWheelEvent::deltaX */
166 Q_PROPERTY(int deltaX READ deltaX CONSTANT)
167 /*! \qmlproperty int KDeclarativeWheelEvent::deltaY */
168 Q_PROPERTY(int deltaY READ deltaY CONSTANT)
169 /*! \qmlproperty int KDeclarativeWheelEvent::delta
170 * \deprecated Use deltaY instead.
171 */
172 Q_PROPERTY(int delta READ deltaY CONSTANT)
173 /*! \qmlproperty Qt::MouseButtons KDeclarativeWheelEvent::buttons */
174 Q_PROPERTY(Qt::MouseButtons buttons READ buttons CONSTANT)
175 /*! \qmlproperty Qt::KeyboardModifiers KDeclarativeWheelEvent::modifiers */
176 Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers CONSTANT)
177 /*! \qmlproperty Qt::Orientation KDeclarativeWheelEvent::orientation
178 * \deprecated
179 */
180 Q_PROPERTY(Qt::Orientation orientation READ orientation CONSTANT)
181
182public:
183 KDeclarativeWheelEvent(QPointF pos,
184 QPoint screenPos,
185 QPoint angleDelta,
186 Qt::MouseButtons buttons,
187 Qt::KeyboardModifiers modifiers,
188 Qt::Orientation orientation)
189 : m_x(pos.x())
190 , m_y(pos.y())
191 , m_screenX(screenPos.x())
192 , m_screenY(screenPos.y())
193 , m_angleDelta(angleDelta)
194 , m_buttons(buttons)
195 , m_modifiers(modifiers)
196 , m_orientation(orientation)
197 {
198 }
199
200 int x() const
201 {
202 return m_x;
203 }
204 int y() const
205 {
206 return m_y;
207 }
208 int screenX() const
209 {
210 return m_screenX;
211 }
212 int screenY() const
213 {
214 return m_screenY;
215 }
216 int deltaX() const
217 {
218 return m_angleDelta.x();
219 }
220 int deltaY() const
221 {
222 return m_angleDelta.y();
223 }
224 Qt::MouseButtons buttons() const
225 {
226 return m_buttons;
227 }
228 Qt::KeyboardModifiers modifiers() const
229 {
230 return m_modifiers;
231 }
232 Qt::Orientation orientation()
233 {
234 return m_orientation;
235 } // TODO KF6: remove
236
237 // only for internal usage
238 void setX(int x)
239 {
240 m_x = x;
241 }
242 void setY(int y)
243 {
244 m_y = y;
245 }
246
247private:
248 int m_x;
249 int m_y;
250 int m_screenX;
251 int m_screenY;
252 QPoint m_angleDelta;
253 Qt::MouseButtons m_buttons;
254 Qt::KeyboardModifiers m_modifiers;
255 Qt::Orientation m_orientation;
256};
257
258/*!
259 * \qmltype MouseEventListener
260 * \inqmlmodule org.kde.kquickcontrols.addons
261 */
262class MouseEventListener : public QQuickItem
263{
264 Q_OBJECT
265 QML_ELEMENT
266 /*!
267 * \qmlproperty bool MouseEventListener::hoverEnabled
268 * This property holds whether hover events are handled.
269 * By default hover events are disabled
270 */
271 Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
272
273 /*!
274 * \qmlproperty bool MouseEventListener::containsMouse
275 * True if this MouseEventListener or any of its children contains the mouse cursor:
276 * this property will change only when the mouse button is pressed if hoverEnabled is false.
277 */
278 Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
279
280 /*! \qmlproperty Qt::MouseButtons MouseEventListener::acceptedButtons */
281 Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
282
283 /*!
284 * \qmlproperty Qt::CursorShape MouseEventListener::cursorShape
285 * This property holds the cursor shape for this mouse area.
286 * Note that on platforms that do not display a mouse cursor this may have no effect.
287 */
288 Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged)
289
290 /*!
291 * \qmlproperty bool MouseEventListener::pressed
292 * True if the mouse is pressed in the item or any of its children
293 */
294 Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged)
295
296public:
297 MouseEventListener(QQuickItem *parent = nullptr);
298 ~MouseEventListener() override;
299
300 bool containsMouse() const;
301 void setHoverEnabled(bool enable);
302 bool hoverEnabled() const;
303 bool isPressed() const;
304
305 Qt::MouseButtons acceptedButtons() const;
306 void setAcceptedButtons(Qt::MouseButtons buttons);
307
308 Qt::CursorShape cursorShape() const;
309 void setCursorShape(Qt::CursorShape shape);
310
311protected:
312 void hoverEnterEvent(QHoverEvent *event) override;
313 void hoverLeaveEvent(QHoverEvent *event) override;
314 void hoverMoveEvent(QHoverEvent *event) override;
315 void mousePressEvent(QMouseEvent *event) override;
316 void mouseMoveEvent(QMouseEvent *event) override;
317 void mouseReleaseEvent(QMouseEvent *event) override;
318 void wheelEvent(QWheelEvent *event) override;
319 bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
320 void mouseUngrabEvent() override;
321 void touchUngrabEvent() override;
322
323Q_SIGNALS:
324 /*! \qmlsignal MouseEventListener::pressed(KDeclarativeMouseEventmouse) */
325 void pressed(KDeclarativeMouseEvent *mouse);
326 /*! \qmlsignal MouseEventListener::positionChanged(KDeclarativeMouseEvent mouse) */
327 void positionChanged(KDeclarativeMouseEvent *mouse);
328 /*! \qmlsignal MouseEventListener::released(KDeclarativeMouseEvent mouse) */
329 void released(KDeclarativeMouseEvent *mouse);
330 /*! \qmlsignal MouseEventListener::clicked(KDeclarativeMouseEvent mouse) */
331 void clicked(KDeclarativeMouseEvent *mouse);
332 /*! \qmlsignal MouseEventListener::pressAndHold(KDeclarativeMouseEvent *mouse) */
333 void pressAndHold(KDeclarativeMouseEvent *mouse);
334 /*! \qmlsignal MouseEventListener::wheelMoved(KDeclarativeWheelEvent wheel) */
335 void wheelMoved(KDeclarativeWheelEvent *wheel);
336 /*! \qmlsignal MouseEventListener::containsMouseChanged(bool containsMouseChanged) */
337 void containsMouseChanged(bool containsMouseChanged);
338 /*! \qmlsignal MouseEventListener::hoverEnabledChanged(bool hoverEnabled) */
339 void hoverEnabledChanged(bool hoverEnabled);
340 /*! \qmlsignal MouseEventListener::acceptedButtonsChanged() */
341 void acceptedButtonsChanged();
342 /*! \qmlsignal MouseEventListener::cursorShapeChanged() */
343 void cursorShapeChanged();
344 /*! \qmlsignal MouseEventListener::pressedChanged() */
345 void pressedChanged();
346 /*! \qmlsignal MouseEventListener::canceled() */
347 void canceled();
348
349private Q_SLOTS:
350 void handlePressAndHold();
351 void handleUngrab();
352
353private:
354 static QScreen *screenForGlobalPos(const QPointF &globalPos);
355
356 bool m_pressed;
357 KDeclarativeMouseEvent *m_pressAndHoldEvent;
358 QPointF m_buttonDownPos;
359 // Important: used only for comparison. If you will ever need to access this pointer, make it a QWeakPointer
360 QEvent *m_lastEvent;
361 QTimer *m_pressAndHoldTimer;
362 bool m_containsMouse = false;
363 bool m_childContainsMouse = false;
364 Qt::MouseButtons m_acceptedButtons;
365};
366
367#endif
368

source code of kdeclarative/src/qmlcontrols/kquickcontrolsaddons/mouseeventlistener.h