Loading...
Searching...
No Matches
AxisVelocityCalculator.h
/*
* Copyright (C) 2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License, as
* published by the Free Software Foundation; either version 2.1 or 3.0
* of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the applicable version of the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of both the GNU Lesser General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>
*
* Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
*/
#ifndef VELOCITY_CALCULATOR_H
#define VELOCITY_CALCULATOR_H
#include "LomiriGesturesQmlGlobal.h"
#include <stdint.h>
#include <QtCore/QObject>
#include <LomiriGestures/private/timesource_p.h>
/*
Estimates the current velocity of a finger based on recent movement along an axis
Taking an estimate from a reasonable number of samples, instead of only
from its last movement, removes wild variations in velocity caused
by the jitter normally present in input from a touchscreen.
Usage example:
AxisVelocityCalculator {
id: velocityCalculator
trackedPosition: myMouseArea.mouseX
}
MouseArea {
id: myMouseArea
onReleased: {
console.log("Drag velocity along the X axis before release was: "
+ velocityCalculator.calculate())
}
}
*/
class LOMIRIGESTURESQML_EXPORT AxisVelocityCalculator : public QObject
{
Q_OBJECT
/*
Position whose movement will be tracked to calculate its velocity
*/
Q_PROPERTY(qreal trackedPosition READ trackedPosition WRITE setTrackedPosition
NOTIFY trackedPositionChanged)
public:
/*
Regular, simple, constructor
*/
AxisVelocityCalculator(QObject *parent = 0);
/*
Constructor that takes a TimeSource
*/
AxisVelocityCalculator(const UG_PREPEND_NAMESPACE(SharedTimeSource) &timeSource, QObject *parent = 0);
virtual ~AxisVelocityCalculator();
qreal trackedPosition() const;
void setTrackedPosition(qreal value);
/*
Calculates the finger velocity, in axis units/millisecond
*/
Q_INVOKABLE qreal calculate();
/*
Removes all stored movements from previous calls to setTrackedPosition()
*/
Q_INVOKABLE void reset();
int numSamples() const;
/*
Replaces the TimeSource with the given one. Useful for testing purposes.
*/
void setTimeSource(const UG_PREPEND_NAMESPACE(SharedTimeSource) &timeSource);
/*
The minimum amount of samples needed for a velocity calculation.
*/
static const int MIN_SAMPLES_NEEDED = 2;
/*
Maximum number of movement samples stored
*/
static const int MAX_SAMPLES = 50;
/*
Age of the oldest sample considered in the velocity calculations, in
milliseconds, compared to the most recent one.
*/
static const int AGE_OLDEST_SAMPLE = 100;
Q_SIGNALS:
void trackedPositionChanged(qreal value);
private:
/*
Inform that trackedPosition remained motionless since the time it was
last changed.
It's the same as calling setTrackedPosition(trackedPosition())
*/
void updateIdleTime();
/*
How much the finger has moved since processMovement() was last called.
*/
void processMovement(qreal movement);
class Sample
{
public:
qreal mov; /* movement distance since last sample */
qint64 time; /* time, in milliseconds */
};
/* a circular buffer of samples */
Sample m_samples[MAX_SAMPLES];
int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
int m_samplesWrite; /* index where the next sample will be written */
UG_PREPEND_NAMESPACE(SharedTimeSource) m_timeSource;
qreal m_trackedPosition;
};
#endif // VELOCITY_CALCULATOR_H