1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtLocation module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#ifndef QQUICKGEOMAPGESTUREAREA_P_H
38#define QQUICKGEOMAPGESTUREAREA_P_H
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists purely as an
45// implementation detail. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49//
50
51#include <QtLocation/private/qlocationglobal_p.h>
52
53#include <QtCore/QPointer>
54#include <QtQuick/QQuickItem>
55#include <QTouchEvent>
56#include <QDebug>
57#include <QElapsedTimer>
58#include <QtPositioning/qgeocoordinate.h>
59#include <QtGui/QVector2D>
60
61QT_BEGIN_NAMESPACE
62
63class QGraphicsSceneMouseEvent;
64class QQuickGeoCoordinateAnimation;
65class QDeclarativeGeoMap;
66class QTouchEvent;
67class QWheelEvent;
68class QGeoMap;
69
70class Q_LOCATION_PRIVATE_EXPORT QGeoMapPinchEvent : public QObject
71{
72 Q_OBJECT
73
74 Q_PROPERTY(QPointF center READ center)
75 Q_PROPERTY(qreal angle READ angle)
76 Q_PROPERTY(QPointF point1 READ point1)
77 Q_PROPERTY(QPointF point2 READ point2)
78 Q_PROPERTY(int pointCount READ pointCount)
79 Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
80
81public:
82 QGeoMapPinchEvent(const QPointF &center, qreal angle,
83 const QPointF &point1, const QPointF &point2,
84 int pointCount = 0, bool accepted = true)
85 : QObject(), m_center(center), m_angle(angle),
86 m_point1(point1), m_point2(point2),
87 m_pointCount(pointCount), m_accepted(accepted) {}
88 QGeoMapPinchEvent()
89 : QObject(),
90 m_angle(0.0),
91 m_pointCount(0),
92 m_accepted(true) {}
93
94 QPointF center() const { return m_center; }
95 void setCenter(const QPointF &center) { m_center = center; }
96 qreal angle() const { return m_angle; }
97 void setAngle(qreal angle) { m_angle = angle; }
98 QPointF point1() const { return m_point1; }
99 void setPoint1(const QPointF &p) { m_point1 = p; }
100 QPointF point2() const { return m_point2; }
101 void setPoint2(const QPointF &p) { m_point2 = p; }
102 int pointCount() const { return m_pointCount; }
103 void setPointCount(int count) { m_pointCount = count; }
104 bool accepted() const { return m_accepted; }
105 void setAccepted(bool a) { m_accepted = a; }
106
107private:
108 QPointF m_center;
109 qreal m_angle;
110 QPointF m_point1;
111 QPointF m_point2;
112 int m_pointCount;
113 bool m_accepted;
114};
115
116class Q_LOCATION_PRIVATE_EXPORT QQuickGeoMapGestureArea: public QQuickItem
117{
118 Q_OBJECT
119 Q_ENUMS(GeoMapGesture)
120 Q_FLAGS(AcceptedGestures)
121
122 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
123 Q_PROPERTY(bool pinchActive READ isPinchActive NOTIFY pinchActiveChanged)
124 Q_PROPERTY(bool panActive READ isPanActive NOTIFY panActiveChanged)
125 Q_PROPERTY(bool rotationActive READ isRotationActive NOTIFY rotationActiveChanged)
126 Q_PROPERTY(bool tiltActive READ isTiltActive NOTIFY tiltActiveChanged)
127 Q_PROPERTY(AcceptedGestures acceptedGestures READ acceptedGestures WRITE setAcceptedGestures NOTIFY acceptedGesturesChanged)
128 Q_PROPERTY(qreal maximumZoomLevelChange READ maximumZoomLevelChange WRITE setMaximumZoomLevelChange NOTIFY maximumZoomLevelChangeChanged)
129 Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
130 Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged REVISION 1)
131
132public:
133 QQuickGeoMapGestureArea(QDeclarativeGeoMap *map);
134 ~QQuickGeoMapGestureArea();
135
136 enum GeoMapGesture {
137 NoGesture = 0x0000,
138 PinchGesture = 0x0001,
139 PanGesture = 0x0002,
140 FlickGesture = 0x0004,
141 RotationGesture = 0x0008,
142 TiltGesture = 0x0010
143 };
144
145 Q_DECLARE_FLAGS(AcceptedGestures, GeoMapGesture)
146
147 AcceptedGestures acceptedGestures() const;
148 void setAcceptedGestures(AcceptedGestures acceptedGestures);
149
150 bool isPinchActive() const;
151 bool isRotationActive() const;
152 bool isTiltActive() const;
153 bool isPanActive() const;
154 bool isActive() const;
155
156 bool enabled() const;
157 void setEnabled(bool enabled);
158
159 qreal maximumZoomLevelChange() const;
160 void setMaximumZoomLevelChange(qreal maxChange);
161
162 qreal flickDeceleration() const;
163 void setFlickDeceleration(qreal deceleration);
164
165 void handleTouchEvent(QTouchEvent *event);
166#if QT_CONFIG(wheelevent)
167 void handleWheelEvent(QWheelEvent *event);
168#endif
169 void handleMousePressEvent(QMouseEvent *event);
170 void handleMouseMoveEvent(QMouseEvent *event);
171 void handleMouseReleaseEvent(QMouseEvent *event);
172 void handleMouseUngrabEvent();
173 void handleTouchUngrabEvent();
174
175 void setMinimumZoomLevel(qreal min);
176 qreal minimumZoomLevel() const;
177
178 void setMaximumZoomLevel(qreal max);
179 qreal maximumZoomLevel() const;
180
181 void setMap(QGeoMap* map);
182
183 bool preventStealing() const;
184 void setPreventStealing(bool prevent);
185
186Q_SIGNALS:
187 void panActiveChanged();
188 void pinchActiveChanged();
189 void rotationActiveChanged();
190 void tiltActiveChanged();
191 void enabledChanged();
192 void maximumZoomLevelChangeChanged();
193 void acceptedGesturesChanged();
194 void flickDecelerationChanged();
195 void pinchStarted(QGeoMapPinchEvent *pinch);
196 void pinchUpdated(QGeoMapPinchEvent *pinch);
197 void pinchFinished(QGeoMapPinchEvent *pinch);
198 void panStarted();
199 void panFinished();
200 void flickStarted();
201 void flickFinished();
202 void rotationStarted(QGeoMapPinchEvent *pinch);
203 void rotationUpdated(QGeoMapPinchEvent *pinch);
204 void rotationFinished(QGeoMapPinchEvent *pinch);
205 void tiltStarted(QGeoMapPinchEvent *pinch);
206 void tiltUpdated(QGeoMapPinchEvent *pinch);
207 void tiltFinished(QGeoMapPinchEvent *pinch);
208 void preventStealingChanged();
209private:
210 void update();
211
212 // Create general data relating to the touch points
213 void touchPointStateMachine();
214 void startOneTouchPoint();
215 void updateOneTouchPoint();
216 void startTwoTouchPoints();
217 void updateTwoTouchPoints();
218
219 // All two fingers vertical parallel panning related code, which encompasses tilting
220 void tiltStateMachine();
221 bool canStartTilt();
222 void startTilt();
223 void updateTilt();
224 void endTilt();
225
226 // All two fingers rotation related code, which encompasses rotation
227 void rotationStateMachine();
228 bool canStartRotation();
229 void startRotation();
230 void updateRotation();
231 void endRotation();
232
233 // All pinch related code, which encompasses zoom
234 void pinchStateMachine();
235 bool canStartPinch();
236 void startPinch();
237 void updatePinch();
238 void endPinch();
239
240 // Pan related code (regardles of number of touch points),
241 // includes the flick based panning after letting go
242 void panStateMachine();
243 bool canStartPan();
244 void updatePan();
245 bool tryStartFlick();
246 void startFlick(int dx, int dy, int timeMs = 0);
247 void stopFlick();
248
249 bool pinchEnabled() const;
250 void setPinchEnabled(bool enabled);
251 bool rotationEnabled() const;
252 void setRotationEnabled(bool enabled);
253 bool tiltEnabled() const;
254 void setTiltEnabled(bool enabled);
255 bool panEnabled() const;
256 void setPanEnabled(bool enabled);
257 bool flickEnabled() const;
258 void setFlickEnabled(bool enabled);
259
260private Q_SLOTS:
261 void handleFlickAnimationStopped();
262
263
264private:
265 void stopPan();
266 void clearTouchData();
267 void updateFlickParameters(const QPointF &pos);
268
269private:
270 QGeoMap* m_map;
271 QDeclarativeGeoMap *m_declarativeMap;
272 bool m_enabled;
273
274 // This should be intended as a "two fingers gesture" struct
275 struct Pinch
276 {
277 Pinch() : m_pinchEnabled(true), m_rotationEnabled(true), m_tiltEnabled(true),
278 m_startDist(0), m_lastAngle(0.0) {}
279
280 QGeoMapPinchEvent m_event;
281 bool m_pinchEnabled;
282 bool m_rotationEnabled;
283 bool m_tiltEnabled;
284 struct Zoom
285 {
286 Zoom() : m_minimum(0.0), m_maximum(30.0), m_start(0.0), m_previous(0.0),
287 maximumChange(4.0) {}
288 qreal m_minimum;
289 qreal m_maximum;
290 qreal m_start;
291 qreal m_previous;
292 qreal maximumChange;
293 } m_zoom;
294
295 struct Rotation
296 {
297 Rotation() : m_startBearing(0.0), m_previousTouchAngle(0.0), m_totalAngle(0.0) {}
298 qreal m_startBearing;
299 qreal m_previousTouchAngle; // needed for detecting crossing +- 180 in a safer way
300 qreal m_totalAngle;
301 } m_rotation;
302
303 struct Tilt
304 {
305 Tilt() {}
306 QPointF m_startTouchCentroid;
307 qreal m_startTilt;
308 } m_tilt;
309
310 QPointF m_lastPoint1;
311 QPointF m_lastPoint2;
312 qreal m_startDist;
313 qreal m_lastAngle;
314 } m_pinch;
315
316 AcceptedGestures m_acceptedGestures;
317
318 struct Pan
319 {
320 Pan() : m_maxVelocity(2500), m_deceleration(2500), m_animation(0), m_flickEnabled(true), m_panEnabled(true) {}
321
322 qreal m_maxVelocity;
323 qreal m_deceleration;
324 QQuickGeoCoordinateAnimation *m_animation;
325 bool m_flickEnabled;
326 bool m_panEnabled;
327 } m_flick;
328
329
330 // these are calculated regardless of gesture or number of touch points
331 QVector2D m_flickVector;
332 QElapsedTimer m_lastPosTime;
333 QPointF m_lastPos;
334 QVector<QTouchEvent::TouchPoint> m_allPoints;
335 QVector<QTouchEvent::TouchPoint> m_touchPoints;
336 QScopedPointer<QTouchEvent::TouchPoint> m_mousePoint;
337 QPointF m_sceneStartPoint1;
338
339 // only set when two points in contact
340 QPointF m_sceneStartPoint2;
341 QGeoCoordinate m_startCoord;
342 QGeoCoordinate m_touchCenterCoord;
343 qreal m_twoTouchAngle;
344 qreal m_twoTouchAngleStart;
345 qreal m_distanceBetweenTouchPoints;
346 qreal m_distanceBetweenTouchPointsStart;
347 QPointF m_twoTouchPointsCentroidStart;
348 QPointF m_touchPointsCentroid;
349 bool m_preventStealing;
350 bool m_panEnabled;
351
352private:
353 // prototype state machine...
354 enum TouchPointState
355 {
356 touchPoints0,
357 touchPoints1,
358 touchPoints2
359 } m_touchPointState;
360
361 enum PinchState
362 {
363 pinchInactive,
364 pinchInactiveTwoPoints,
365 pinchActive
366 } m_pinchState;
367
368 enum RotationState
369 {
370 rotationInactive,
371 rotationInactiveTwoPoints,
372 rotationActive
373 } m_rotationState;
374
375 enum TiltState
376 {
377 tiltInactive,
378 tiltInactiveTwoPoints,
379 tiltActive
380 } m_tiltState;
381
382 enum FlickState
383 {
384 flickInactive,
385 panActive,
386 flickActive
387 } m_flickState;
388
389 inline void setTouchPointState(const TouchPointState state);
390 inline void setFlickState(const FlickState state);
391 inline void setTiltState(const TiltState state);
392 inline void setRotationState(const RotationState state);
393 inline void setPinchState(const PinchState state);
394};
395
396QT_END_NAMESPACE
397QML_DECLARE_TYPE(QQuickGeoMapGestureArea)
398
399#endif // QQUICKGEOMAPGESTUREAREA_P_H
400

source code of qtlocation/src/location/declarativemaps/qquickgeomapgesturearea_p.h