~macslow/unity8/fix-1475678

« back to all changes in this revision

Viewing changes to Components/DraggingArea.qml

  • Committer: Michał Sawicz
  • Date: 2013-06-05 22:03:08 UTC
  • Revision ID: michal.sawicz@canonical.com-20130605220308-yny8fv3futtr04fg
Inital unity8 commit.

Previous history can be found at https://code.launchpad.net/~unity-team/unity/phablet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
17
import QtQuick 2.0
 
18
import Ubuntu.Components 0.1
 
19
import "Math.js" as MathLocal
 
20
 
 
21
MouseArea {
 
22
    id: draggingArea
 
23
 
 
24
    property int orientation: Qt.Vertical
 
25
    property bool dragging
 
26
    property real dragVelocity: 0
 
27
    property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
 
28
                                                            : (mouseX - __pressedPosition.x))
 
29
    property real lateralPosition: orientation == Qt.Horizontal ? MathLocal.clamp(mouseY, 0, height) : MathLocal.clamp(mouseX, 0, width)
 
30
    property point __pressedPosition: Qt.point(0, 0)
 
31
    property var __dragEvents: []
 
32
    property bool clickValidated: true
 
33
    property bool zeroVelocityCounts: false
 
34
 
 
35
    // Can be replaced with a fake implementation during tests
 
36
    // property var __getCurrentTimeMs: function () { return new Date().getTime() }
 
37
    property var __dateTime: new function() {
 
38
        this.getCurrentTimeMs = function() {return new Date().getTime()}
 
39
    }
 
40
 
 
41
 
 
42
    signal dragStart
 
43
    signal dragEnd
 
44
 
 
45
    onDragValueChanged: {
 
46
        if (dragValue != 0 && pressed) {
 
47
            dragging = true
 
48
        }
 
49
    }
 
50
 
 
51
    onDraggingChanged: {
 
52
        if (dragging) {
 
53
            dragStart()
 
54
        }
 
55
        else {
 
56
            dragEnd()
 
57
        }
 
58
    }
 
59
 
 
60
    function updateSpeed() {
 
61
        var totalSpeed = 0
 
62
        for (var i=0; i<__dragEvents.length; i++) {
 
63
            totalSpeed += __dragEvents[i][3]
 
64
        }
 
65
 
 
66
        if (zeroVelocityCounts || Math.abs(totalSpeed) > 0.001) {
 
67
            dragVelocity = totalSpeed / __dragEvents.length * 1000
 
68
        }
 
69
    }
 
70
 
 
71
    function cullOldDragEvents(currentTime) {
 
72
        // cull events older than 50 ms but always keep the latest 2 events
 
73
        for (var numberOfCulledEvents=0; numberOfCulledEvents<__dragEvents.length-2; numberOfCulledEvents++) {
 
74
            // __dragEvents[numberOfCulledEvents][0] is the dragTime
 
75
            if (currentTime - __dragEvents[numberOfCulledEvents][0] <= 50) break
 
76
        }
 
77
 
 
78
        __dragEvents.splice(0, numberOfCulledEvents)
 
79
    }
 
80
 
 
81
    function getEventSpeed(currentTime, event) {
 
82
        if (__dragEvents.length != 0) {
 
83
            var lastDrag = __dragEvents[__dragEvents.length-1]
 
84
            var duration = Math.max(1, currentTime - lastDrag[0])
 
85
            if (orientation == Qt.Vertical) {
 
86
                return (event.y - lastDrag[2]) / duration
 
87
            } else {
 
88
                return (event.x - lastDrag[1]) / duration
 
89
            }
 
90
        } else {
 
91
            return 0
 
92
        }
 
93
    }
 
94
 
 
95
    function pushDragEvent(event) {
 
96
        var currentTime = __dateTime.getCurrentTimeMs()
 
97
        __dragEvents.push([currentTime, event.x, event.y, getEventSpeed(currentTime, event)])
 
98
        cullOldDragEvents(currentTime)
 
99
        updateSpeed()
 
100
    }
 
101
 
 
102
    onPositionChanged: {
 
103
        if (dragging) {
 
104
            pushDragEvent(mouse)
 
105
        }
 
106
        if (!draggingArea.containsMouse)
 
107
            clickValidated = false
 
108
    }
 
109
 
 
110
    onPressed: {
 
111
        __pressedPosition = Qt.point(mouse.x, mouse.y)
 
112
        __dragEvents = []
 
113
        pushDragEvent(mouse)
 
114
        clickValidated = true
 
115
    }
 
116
 
 
117
    onReleased: {
 
118
        dragging = false
 
119
        __pressedPosition = Qt.point(mouse.x, mouse.y)
 
120
    }
 
121
}