1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQUICKMULTIPOINTTOUCHAREA_H
5#define QQUICKMULTIPOINTTOUCHAREA_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qtquickglobal_p.h>
19
20#include <QtQuick/qquickitem.h>
21
22#include <QtGui/qevent.h>
23#include <QtGui/qguiapplication.h>
24#include <QtGui/qstylehints.h>
25
26#include <QtCore/qlist.h>
27#include <QtCore/qmap.h>
28#include <QtCore/qpointer.h>
29
30QT_BEGIN_NAMESPACE
31
32class QQuickMultiPointTouchArea;
33class Q_QUICK_PRIVATE_EXPORT QQuickTouchPoint : public QObject
34{
35 Q_OBJECT
36 Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged FINAL)
37 Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION(2, 9) FINAL)
38 Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged FINAL)
39 Q_PROPERTY(qreal x READ x NOTIFY xChanged FINAL)
40 Q_PROPERTY(qreal y READ y NOTIFY yChanged FINAL)
41 Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION(2, 9) FINAL)
42 Q_PROPERTY(qreal pressure READ pressure NOTIFY pressureChanged FINAL)
43 Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION(2, 9) FINAL)
44 Q_PROPERTY(QVector2D velocity READ velocity NOTIFY velocityChanged FINAL)
45 Q_PROPERTY(QRectF area READ area NOTIFY areaChanged FINAL)
46
47 Q_PROPERTY(qreal startX READ startX NOTIFY startXChanged FINAL)
48 Q_PROPERTY(qreal startY READ startY NOTIFY startYChanged FINAL)
49 Q_PROPERTY(qreal previousX READ previousX NOTIFY previousXChanged FINAL)
50 Q_PROPERTY(qreal previousY READ previousY NOTIFY previousYChanged FINAL)
51 Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged FINAL)
52 Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged FINAL)
53 QML_NAMED_ELEMENT(TouchPoint)
54 QML_ADDED_IN_VERSION(2, 0)
55
56public:
57 QQuickTouchPoint(bool qmlDefined = true)
58 : _qmlDefined(qmlDefined)
59 {}
60
61 int pointId() const { return _id; }
62 void setPointId(int id);
63
64 QPointingDeviceUniqueId uniqueId() const { return _uniqueId; }
65 void setUniqueId(const QPointingDeviceUniqueId &id);
66
67 qreal x() const { return _x; }
68 qreal y() const { return _y; }
69 void setPosition(QPointF pos);
70
71 QSizeF ellipseDiameters() const { return _ellipseDiameters; }
72 void setEllipseDiameters(const QSizeF &d);
73
74 qreal pressure() const { return _pressure; }
75 void setPressure(qreal pressure);
76
77 qreal rotation() const { return _rotation; }
78 void setRotation(qreal r);
79
80 QVector2D velocity() const { return _velocity; }
81 void setVelocity(const QVector2D &velocity);
82
83 QRectF area() const { return _area; }
84 void setArea(const QRectF &area);
85
86 bool isQmlDefined() const { return _qmlDefined; }
87
88 bool inUse() const { return _inUse; }
89 void setInUse(bool inUse) { _inUse = inUse; }
90
91 bool pressed() const { return _pressed; }
92 void setPressed(bool pressed);
93
94 qreal startX() const { return _startX; }
95 void setStartX(qreal startX);
96
97 qreal startY() const { return _startY; }
98 void setStartY(qreal startY);
99
100 qreal previousX() const { return _previousX; }
101 void setPreviousX(qreal previousX);
102
103 qreal previousY() const { return _previousY; }
104 void setPreviousY(qreal previousY);
105
106 qreal sceneX() const { return _sceneX; }
107 void setSceneX(qreal sceneX);
108
109 qreal sceneY() const { return _sceneY; }
110 void setSceneY(qreal sceneY);
111
112Q_SIGNALS:
113 void pressedChanged();
114 void pointIdChanged();
115 Q_REVISION(2, 9) void uniqueIdChanged();
116 void xChanged();
117 void yChanged();
118 Q_REVISION(2, 9) void ellipseDiametersChanged();
119 void pressureChanged();
120 Q_REVISION(2, 9) void rotationChanged();
121 void velocityChanged();
122 void areaChanged();
123 void startXChanged();
124 void startYChanged();
125 void previousXChanged();
126 void previousYChanged();
127 void sceneXChanged();
128 void sceneYChanged();
129
130private:
131 friend class QQuickMultiPointTouchArea;
132 int _id = 0;
133 qreal _x = 0.0;
134 qreal _y = 0.0;
135 qreal _pressure = 0.0;
136 qreal _rotation = 0;
137 QSizeF _ellipseDiameters;
138 QVector2D _velocity;
139 QRectF _area;
140 bool _qmlDefined;
141 bool _inUse = false; //whether the point is currently in use (only valid when _qmlDefined == true)
142 bool _pressed = false;
143 qreal _startX = 0.0;
144 qreal _startY = 0.0;
145 qreal _previousX = 0.0;
146 qreal _previousY = 0.0;
147 qreal _sceneX = 0.0;
148 qreal _sceneY = 0.0;
149 QPointingDeviceUniqueId _uniqueId;
150};
151
152class QQuickGrabGestureEvent : public QObject
153{
154 Q_OBJECT
155 Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints CONSTANT FINAL)
156 Q_PROPERTY(qreal dragThreshold READ dragThreshold CONSTANT FINAL)
157 QML_NAMED_ELEMENT(GestureEvent)
158 QML_ADDED_IN_VERSION(2, 0)
159 QML_UNCREATABLE("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea.")
160
161public:
162 QQuickGrabGestureEvent() : _dragThreshold(QGuiApplication::styleHints()->startDragDistance()) {}
163
164 Q_INVOKABLE void grab() { _grab = true; }
165 bool wantsGrab() const { return _grab; }
166
167 QQmlListProperty<QObject> touchPoints() {
168 return QQmlListProperty<QObject>(this, &_touchPoints);
169 }
170 qreal dragThreshold() const { return _dragThreshold; }
171
172private:
173 friend class QQuickMultiPointTouchArea;
174 bool _grab = false;
175 qreal _dragThreshold;
176 QList<QObject*> _touchPoints;
177};
178
179class Q_QUICK_PRIVATE_EXPORT QQuickMultiPointTouchArea : public QQuickItem
180{
181 Q_OBJECT
182 Q_DISABLE_COPY_MOVE(QQuickMultiPointTouchArea)
183
184 Q_PROPERTY(QQmlListProperty<QQuickTouchPoint> touchPoints READ touchPoints CONSTANT FINAL)
185 Q_PROPERTY(int minimumTouchPoints READ minimumTouchPoints WRITE setMinimumTouchPoints NOTIFY minimumTouchPointsChanged FINAL)
186 Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged FINAL)
187 Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged FINAL)
188 QML_NAMED_ELEMENT(MultiPointTouchArea)
189 QML_ADDED_IN_VERSION(2, 0)
190
191public:
192 QQuickMultiPointTouchArea(QQuickItem *parent=nullptr);
193 ~QQuickMultiPointTouchArea();
194
195 int minimumTouchPoints() const;
196 void setMinimumTouchPoints(int num);
197 int maximumTouchPoints() const;
198 void setMaximumTouchPoints(int num);
199 bool mouseEnabled() const { return _mouseEnabled; }
200 void setMouseEnabled(bool arg);
201
202 QQmlListProperty<QQuickTouchPoint> touchPoints() {
203 return QQmlListProperty<QQuickTouchPoint>(this, nullptr, QQuickMultiPointTouchArea::touchPoint_append, QQuickMultiPointTouchArea::touchPoint_count, QQuickMultiPointTouchArea::touchPoint_at, nullptr);
204 }
205
206 static void touchPoint_append(QQmlListProperty<QQuickTouchPoint> *list, QQuickTouchPoint* touch) {
207 QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
208 q->addTouchPrototype(prototype: touch);
209 }
210
211 static qsizetype touchPoint_count(QQmlListProperty<QQuickTouchPoint> *list) {
212 QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
213 return q->_touchPrototypes.size();
214 }
215
216 static QQuickTouchPoint* touchPoint_at(QQmlListProperty<QQuickTouchPoint> *list, qsizetype index) {
217 QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
218 return q->_touchPrototypes.value(key: index);
219 }
220
221Q_SIGNALS:
222#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
223 void pressed(const QList<QObject*> &touchPoints);
224 void updated(const QList<QObject*> &touchPoints);
225 void released(const QList<QObject*> &touchPoints);
226 void canceled(const QList<QObject*> &touchPoints);
227#else
228 void pressed(const QList<QObject*> &points);
229 void updated(const QList<QObject*> &points);
230 void released(const QList<QObject*> &points);
231 void canceled(const QList<QObject*> &points);
232#endif
233 void gestureStarted(QQuickGrabGestureEvent *gesture);
234#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
235 void touchUpdated(const QList<QObject*> &touchPoints);
236#else
237 void touchUpdated(const QList<QObject*> &points);
238#endif
239 void minimumTouchPointsChanged();
240 void maximumTouchPointsChanged();
241 void mouseEnabledChanged();
242
243protected:
244 void touchEvent(QTouchEvent *) override;
245 bool childMouseEventFilter(QQuickItem *receiver, QEvent *event) override;
246 void mousePressEvent(QMouseEvent *event) override;
247 void mouseReleaseEvent(QMouseEvent *event) override;
248 void mouseMoveEvent(QMouseEvent *event) override;
249 void mouseUngrabEvent() override;
250 void touchUngrabEvent() override;
251
252 void addTouchPrototype(QQuickTouchPoint* prototype);
253 void addTouchPoint(const QEventPoint *p);
254 void addTouchPoint(const QMouseEvent *e);
255 void clearTouchLists();
256
257 void updateTouchPoint(QQuickTouchPoint*, const QEventPoint*);
258 void updateTouchPoint(QQuickTouchPoint *dtp, const QMouseEvent *e);
259 enum class RemapEventPoints { No, ToLocal };
260 void updateTouchData(QEvent*, RemapEventPoints remap = RemapEventPoints::No);
261
262 bool sendMouseEvent(QMouseEvent *event);
263 bool shouldFilter(QEvent *event);
264 void grabGesture(QPointingDevice *dev);
265 QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
266#ifdef Q_OS_MACOS
267 void hoverEnterEvent(QHoverEvent *event) override;
268 void hoverLeaveEvent(QHoverEvent *event) override;
269 void setTouchEventsEnabled(bool enable);
270 void itemChange(ItemChange change, const ItemChangeData &data) override;
271#endif
272
273private:
274 void ungrab(bool normalRelease = false);
275 QMap<int,QQuickTouchPoint*> _touchPrototypes; //TouchPoints defined in QML
276 QMap<int,QObject*> _touchPoints; //All current touch points
277 QList<QObject*> _releasedTouchPoints;
278 QList<QObject*> _pressedTouchPoints;
279 QList<QObject*> _movedTouchPoints;
280 int _minimumTouchPoints;
281 int _maximumTouchPoints;
282 QVector<int> _lastFilterableTouchPointIds;
283 QPointer<QQuickTouchPoint> _mouseTouchPoint; // exists when mouse button is down and _mouseEnabled is true; null otherwise
284 QEventPoint _mouseQpaTouchPoint; // synthetic QPA touch point to hold state and position of the mouse
285 const QPointingDevice *_touchMouseDevice;
286 QPointF _mousePos;
287 bool _stealMouse;
288 bool _mouseEnabled;
289};
290
291QT_END_NAMESPACE
292
293QML_DECLARE_TYPE(QQuickTouchPoint)
294QML_DECLARE_TYPE(QQuickGrabGestureEvent)
295QML_DECLARE_TYPE(QQuickMultiPointTouchArea)
296
297#endif // QQUICKMULTIPOINTTOUCHAREA_H
298

source code of qtdeclarative/src/quick/items/qquickmultipointtoucharea_p.h