Lomiri
Loading...
Searching...
No Matches
EdgeDragEvaluator.qml
1/*
2 * Copyright (C) 2013 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
17import QtQuick 2.12
18import Lomiri.Components 1.3
19import Lomiri.Gestures 0.1
20
21/*
22 Evaluates end velocity (velocity at the moment the gesture ends) and travelled
23 distance (delta between finger down and finger up positions) to determine
24 whether the drag should continue by itself towards completion (auto-complete)
25 after the finger has left the touchscreen.
26 */
27AxisVelocityCalculator {
28
29 // How far the drag can go, or should go to achieve completion.
30 property real maxDragDistance
31
32 // Ending a drag at any point before this threshold will need some positive velocity
33 // (i.e., towards the set direction) to get auto-completion (e.g. to get show()
34 // called for a hidden Showable) and ending a drag at any point after this
35 // threshold will need some negative velocity to avoid auto-completion.
36 property real dragThreshold: maxDragDistance / 2
37
38 property real minDragDistance: maxDragDistance * 0.1
39
40 // Speed needed to get auto-completion for an hypothetical flick of length zero.
41 //
42 // This requirement is gradually reduced as flicks gets longer until it reaches
43 // a value of zero for flicks of dragThreshold lenght.
44 //
45 // in pixels per second
46 property real speedThreshold: units.gu(70)
47
48 property int direction
49
50 property real velocity
51 property real minVelocity
52
53 // Returns whether the drag should continue by itself until completed.
54 function shouldAutoComplete() {
55 var deltaPos = trackedPosition - __startPosition;
56
57 if (Math.abs(deltaPos) < minDragDistance) {
58 velocity = 0;
59 minVelocity = 0;
60 return false;
61 }
62
63 velocity = calculate();
64 minVelocity = __calculateMinimumVelocityForAutoCompletion();
65
66 if (_dragDirectionIsPositive()) {
67 return velocity >= minVelocity;
68 } else {
69 return velocity <= minVelocity;
70 }
71 }
72
73 property real __startPosition
74
75 // speedThreshold in pixels per millisecond
76 property real __speedThresholdMs: speedThreshold / 1000.0
77
78 function _dragDirectionIsPositive() {
79 if (direction === Direction.Horizontal) {
80 return (trackedPosition - __startPosition) > 0;
81 } else {
82 return Direction.isPositive(direction);
83 }
84 }
85
86 function __calculateMinimumVelocityForAutoCompletion() {
87 // Minimum velocity when a drag total distance is zero
88 var v0 = _dragDirectionIsPositive() ? __speedThresholdMs : - __speedThresholdMs;
89 var deltaPos = trackedPosition - __startPosition;
90
91 return v0 - ((__speedThresholdMs / dragThreshold) * deltaPos);
92 }
93
94 function reset() {
95 __startPosition = trackedPosition;
96 }
97}