17 #ifndef DIRECTIONAL_DRAG_AREA_H
18 #define DIRECTIONAL_DRAG_AREA_H
20 #include <QtQuick/QQuickItem>
21 #include "AxisVelocityCalculator.h"
22 #include "UbuntuGesturesQmlGlobal.h"
24 #include "Direction.h"
30 class TouchOwnershipEvent;
31 class UnownedTouchEvent;
42 class UBUNTUGESTURESQML_EXPORT DirectionalDragArea :
public QQuickItem {
46 Q_PROPERTY(Direction::Type direction READ direction WRITE setDirection NOTIFY directionChanged)
50 Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged)
54 Q_PROPERTY(qreal sceneDistance READ sceneDistance NOTIFY sceneDistanceChanged)
57 Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged)
58 Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged)
61 Q_PROPERTY(qreal touchSceneX READ touchSceneX NOTIFY touchSceneXChanged)
62 Q_PROPERTY(qreal touchSceneY READ touchSceneY NOTIFY touchSceneYChanged)
65 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
70 Q_PROPERTY(
bool dragging READ dragging NOTIFY draggingChanged)
80 Q_PROPERTY(qreal maxDeviation READ maxDeviation WRITE setMaxDeviation NOTIFY maxDeviationChanged)
86 Q_PROPERTY(qreal wideningAngle READ wideningAngle WRITE setWideningAngle
87 NOTIFY wideningAngleChanged)
91 Q_PROPERTY(qreal distanceThreshold READ distanceThreshold WRITE setDistanceThreshold
92 NOTIFY distanceThresholdChanged)
97 Q_PROPERTY(qreal minSpeed READ minSpeed WRITE setMinSpeed NOTIFY minSpeedChanged)
106 Q_PROPERTY(
int maxSilenceTime READ maxSilenceTime
107 WRITE setMaxSilenceTime
108 NOTIFY maxSilenceTimeChanged)
116 Q_PROPERTY(
int compositionTime READ compositionTime
117 WRITE setCompositionTime
118 NOTIFY compositionTimeChanged)
123 DirectionalDragArea(QQuickItem *parent = 0);
125 Direction::Type direction() const;
126 void setDirection(Direction::Type);
148 Status status()
const {
return m_status; }
150 qreal distance()
const;
151 qreal sceneDistance()
const;
152 void updateSceneDistance();
154 qreal touchX()
const;
155 qreal touchY()
const;
157 qreal touchSceneX()
const;
158 qreal touchSceneY()
const;
160 bool dragging()
const {
return (m_status == Undecided) || (m_status == Recognized); }
162 qreal maxDeviation()
const {
return m_dampedScenePos.maxDelta(); }
163 void setMaxDeviation(qreal value);
165 qreal wideningAngle()
const;
166 void setWideningAngle(qreal value);
168 qreal distanceThreshold()
const {
return m_distanceThreshold; }
169 void setDistanceThreshold(qreal value);
171 qreal minSpeed()
const {
return m_minSpeed; }
172 void setMinSpeed(qreal value);
174 int maxSilenceTime()
const {
return m_maxSilenceTime; }
175 void setMaxSilenceTime(
int value);
177 int compositionTime()
const {
return m_compositionTime; }
178 void setCompositionTime(
int value);
183 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
186 void setTimeSource(
const UbuntuGestures::SharedTimeSource &timeSource);
188 bool event(QEvent *e)
override;
192 int maxTapDuration()
const {
return 300; }
195 void directionChanged(Direction::Type direction);
196 void statusChanged(Status value);
197 void draggingChanged(
bool value);
198 void distanceChanged(qreal value);
199 void sceneDistanceChanged(qreal value);
200 void maxDeviationChanged(qreal value);
201 void wideningAngleChanged(qreal value);
202 void distanceThresholdChanged(qreal value);
203 void minSpeedChanged(qreal value);
204 void maxSilenceTimeChanged(
int value);
205 void compositionTimeChanged(
int value);
206 void touchXChanged(qreal value);
207 void touchYChanged(qreal value);
208 void touchSceneXChanged(qreal value);
209 void touchSceneYChanged(qreal value);
217 virtual void touchEvent(QTouchEvent *event);
221 void giveUpIfDisabledOrInvisible();
224 void touchEvent_absent(QTouchEvent *event);
225 void touchEvent_undecided(QTouchEvent *event);
226 void touchEvent_recognized(QTouchEvent *event);
227 bool pointInsideAllowedArea()
const;
228 bool movingInRightDirection()
const;
229 bool movedFarEnough(
const QPointF &point)
const;
230 const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event);
231 void setStatus(Status newStatus);
232 void setPreviousPos(
const QPointF &point);
233 void setPreviousScenePos(
const QPointF &point);
234 void updateVelocityCalculator(
const QPointF &point);
235 bool isWithinTouchCompositionWindow();
236 void updateSceneDirectionVector();
239 qreal projectOntoDirectionVector(
const QPointF &sceneVector)
const;
240 void touchOwnershipEvent(TouchOwnershipEvent *event);
241 void unownedTouchEvent(UnownedTouchEvent *event);
242 void unownedTouchEvent_undecided(UnownedTouchEvent *unownedTouchEvent);
243 void watchPressedTouchPoints(
const QList<QTouchEvent::TouchPoint> &touchPoints);
244 bool recognitionIsDisabled()
const;
245 void emitSignalIfTapped();
250 QPointF m_startScenePos;
251 QPointF m_previousPos;
252 QPointF m_previousScenePos;
253 qreal m_sceneDistance;
258 DampedPointF m_dampedScenePos;
259 QPointF m_previousDampedScenePos;
262 QPointF m_sceneDirectionVector;
264 Direction::Type m_direction;
265 qreal m_wideningAngle;
266 qreal m_wideningFactor;
267 qreal m_distanceThreshold;
268 qreal m_distanceThresholdSquared;
270 int m_maxSilenceTime;
272 int m_compositionTime;
273 int m_numSamplesOnLastSpeedCheck;
274 UbuntuGestures::AbstractTimer *m_recognitionTimer;
275 AxisVelocityCalculator *m_velocityCalculator;
277 UbuntuGestures::SharedTimeSource m_timeSource;
280 struct ActiveTouchInfo {
281 ActiveTouchInfo() : id(-1), startTime(-1) {}
282 bool isValid()
const {
return id != -1; }
283 void reset() {
id = -1; }
287 class ActiveTouchesInfo {
289 ActiveTouchesInfo(
const UbuntuGestures::SharedTimeSource &timeSource);
290 void update(QTouchEvent *event);
291 qint64 touchStartTime(
int id);
292 bool isEmpty()
const {
return m_touchInfoPool.isEmpty(); }
293 qint64 mostRecentStartTime();
294 UbuntuGestures::SharedTimeSource m_timeSource;
296 void addTouchPoint(
int touchId);
297 void removeTouchPoint(
int touchId);
298 #if ACTIVETOUCHESINFO_DEBUG
302 Pool<ActiveTouchInfo> m_touchInfoPool;
305 friend class tst_DirectionalDragArea;
308 #endif // DIRECTIONAL_DRAG_AREA_H