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

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