Unity 8
AxisVelocityCalculator.h
1 /*
2  * Copyright (C) 2013 - Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License, as
6  * published by the Free Software Foundation; either version 2.1 or 3.0
7  * of the License.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranties of
11  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12  * PURPOSE. See the applicable version of the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of both the GNU Lesser General Public
16  * License along with this program. If not, see <http://www.gnu.org/licenses/>
17  *
18  * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
19  */
20 
21 #ifndef VELOCITY_CALCULATOR_H
22 #define VELOCITY_CALCULATOR_H
23 
24 #include "UbuntuGesturesQmlGlobal.h"
25 #include <stdint.h>
26 #include <QtCore/QObject>
27 #include "TimeSource.h"
28 
29 /*
30  Estimates the current velocity of a finger based on recent movement along an axis
31 
32  Taking an estimate from a reasonable number of samples, instead of only
33  from its last movement, removes wild variations in velocity caused
34  by the jitter normally present in input from a touchscreen.
35 
36  Usage example:
37 
38  AxisVelocityCalculator {
39  id: velocityCalculator
40  trackedPosition: myMouseArea.mouseX
41  }
42 
43  MouseArea {
44  id: myMouseArea
45 
46  onReleased: {
47  console.log("Drag velocity along the X axis before release was: "
48  + velocityCalculator.calculate())
49  }
50  }
51  */
52 class UBUNTUGESTURESQML_EXPORT AxisVelocityCalculator : public QObject
53 {
54  Q_OBJECT
55 
56  /*
57  Position whose movement will be tracked to calculate its velocity
58  */
59  Q_PROPERTY(qreal trackedPosition READ trackedPosition WRITE setTrackedPosition
60  NOTIFY trackedPositionChanged)
61 public:
62 
63  /*
64  Regular, simple, constructor
65  */
66  AxisVelocityCalculator(QObject *parent = 0);
67 
68  /*
69  Constructor that takes a TimeSource
70  */
71  AxisVelocityCalculator(const UbuntuGestures::SharedTimeSource &timeSource, QObject *parent = 0);
72 
73  virtual ~AxisVelocityCalculator();
74 
75  qreal trackedPosition() const;
76  void setTrackedPosition(qreal value);
77 
78  /*
79  Calculates the finger velocity, in axis units/millisecond
80  */
81  Q_INVOKABLE qreal calculate();
82 
83  /*
84  Removes all stored movements from previous calls to setTrackedPosition()
85  */
86  Q_INVOKABLE void reset();
87 
88  int numSamples() const;
89 
90  /*
91  Replaces the TimeSource with the given one. Useful for testing purposes.
92  */
93  void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
94 
95  /*
96  The minimum amount of samples needed for a velocity calculation.
97  */
98  static const int MIN_SAMPLES_NEEDED = 2;
99 
100  /*
101  Maximum number of movement samples stored
102  */
103  static const int MAX_SAMPLES = 50;
104 
105  /*
106  Age of the oldest sample considered in the velocity calculations, in
107  milliseconds, compared to the most recent one.
108  */
109  static const int AGE_OLDEST_SAMPLE = 100;
110 
111 Q_SIGNALS:
112  void trackedPositionChanged(qreal value);
113 
114 private:
115 
116  /*
117  Inform that trackedPosition remained motionless since the time it was
118  last changed.
119 
120  It's the same as calling setTrackedPosition(trackedPosition())
121  */
122  void updateIdleTime();
123 
124  /*
125  How much the finger has moved since processMovement() was last called.
126  */
127  void processMovement(qreal movement);
128 
129  class Sample
130  {
131  public:
132  qreal mov; /* movement distance since last sample */
133  qint64 time; /* time, in milliseconds */
134  };
135 
136  /* a circular buffer of samples */
137  Sample m_samples[MAX_SAMPLES];
138  int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
139  int m_samplesWrite; /* index where the next sample will be written */
140 
141  UbuntuGestures::SharedTimeSource m_timeSource;
142 
143  qreal m_trackedPosition;
144 };
145 
146 #endif // VELOCITY_CALCULATOR_H