Unity 8
DirectionalDragArea.h
1 /*
2  * Copyright (C) 2013,2014 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef DIRECTIONAL_DRAG_AREA_H
18 #define DIRECTIONAL_DRAG_AREA_H
19 
20 #include <QtQuick/QQuickItem>
21 #include "UbuntuGesturesQmlGlobal.h"
22 #include "Damper.h"
23 #include "Direction.h"
24 
25 // lib UbuntuGestures
26 #include <Pool.h>
27 #include <Timer.h>
28 
29 class TouchOwnershipEvent;
30 class UnownedTouchEvent;
31 class DirectionalDragAreaPrivate;
32 
33 /*
34  An area that detects axis-aligned single-finger drag gestures
35 
36  If a drag deviates too much from the components' direction recognition will
37  fail. It will also fail if the drag or flick is too short. E.g. a noisy or
38  fidgety click
39 
40  See doc/DirectionalDragArea.svg
41  */
42 class UBUNTUGESTURESQML_EXPORT DirectionalDragArea : public QQuickItem {
43  Q_OBJECT
44 
45  // The direction in which the gesture should move in order to be recognized.
46  Q_PROPERTY(Direction::Type direction READ direction WRITE setDirection NOTIFY directionChanged)
47 
48  // The distance travelled by the finger along the axis specified by
49  // DirectionalDragArea's direction.
50  Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged)
51 
52  // The distance travelled by the finger along the axis specified by
53  // DirectionalDragArea's direction in scene coordinates
54  Q_PROPERTY(qreal sceneDistance READ sceneDistance NOTIFY sceneDistanceChanged)
55 
56  // Position of the touch point performing the drag relative to this item.
57  Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged)
58  Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged)
59 
60  // Position of the touch point performing the drag, in scene's coordinate system
61  Q_PROPERTY(qreal touchSceneX READ touchSceneX NOTIFY touchSceneXChanged)
62  Q_PROPERTY(qreal touchSceneY READ touchSceneY NOTIFY touchSceneYChanged)
63 
64  // Whether a drag gesture is taking place
65  Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
66 
67  // Whether the drag area is pressed.
68  Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
69 
70  // Whether a gesture should be Recognized as soon a touch lands on the area.
71  // With this property enabled it will work pretty much like a MultiPointTouchArea,
72  // just with a different API.
73  //
74  // It's false by default. In most cases you will not want that enabled.
75  Q_PROPERTY(bool immediateRecognition
76  READ immediateRecognition
77  WRITE setImmediateRecognition
78  NOTIFY immediateRecognitionChanged)
79 
80  // Whether we are merely monitoring touch events (in which case, we don't
81  // claim ownership of the touch).
82  Q_PROPERTY(bool monitorOnly READ monitorOnly WRITE setMonitorOnly NOTIFY monitorOnlyChanged)
83 
84  Q_ENUMS(Direction)
85 public:
86  DirectionalDragArea(QQuickItem *parent = 0);
87 
88  Direction::Type direction() const;
89  void setDirection(Direction::Type);
90 
91  qreal distance() const;
92  qreal sceneDistance() const;
93 
94  qreal touchX() const;
95  qreal touchY() const;
96 
97  qreal touchSceneX() const;
98  qreal touchSceneY() const;
99 
100  bool dragging() const;
101 
102  bool pressed() const;
103 
104  bool immediateRecognition() const;
105  void setImmediateRecognition(bool enabled);
106 
107  bool monitorOnly() const;
108  void setMonitorOnly(bool monitorOnly);
109 
110  bool event(QEvent *e) override;
111 
112  /*
113  In qmltests, sequences of touch events are sent all at once, unlike in "real life".
114  Also qmltests might run really slowly, e.g. when run from inside virtual machines.
115  Thus to remove a variable that qmltests cannot really control, namely time, this
116  function removes all constraints that are sensible to elapsed time.
117 
118  This effectively makes the DirectionalDragArea easier to fool.
119  */
120  Q_INVOKABLE void removeTimeConstraints();
121 
122 Q_SIGNALS:
123  void directionChanged(Direction::Type direction);
124  void draggingChanged(bool value);
125  void pressedChanged(bool value);
126  void distanceChanged(qreal value);
127  void sceneDistanceChanged(qreal value);
128  void touchXChanged(qreal value);
129  void touchYChanged(qreal value);
130  void touchSceneXChanged(qreal value);
131  void touchSceneYChanged(qreal value);
132  void immediateRecognitionChanged(bool value);
133  void monitorOnlyChanged(bool value);
134 
135 protected:
136  void touchEvent(QTouchEvent *event) override;
137  void itemChange(ItemChange change, const ItemChangeData &value) override;
138 
139 public: // so tests can access it
140  DirectionalDragAreaPrivate *d;
141 };
142 
143 #endif // DIRECTIONAL_DRAG_AREA_H