@@ -0,0 +1,262 @@
2+import Ubuntu.Components 1.3
3+import Ubuntu.Gestures 0.1
4+import "../../Components"
9+ property bool closeable: true
10+ readonly property real minSpeedToClose: units.gu(40)
11+ property bool zeroVelocityCounts: false
13+ readonly property alias containsMouse: mouseArea.containsMouse
14+ readonly property alias distance: d.distance
21+ property real distance: 0
22+ property bool moving: false
23+ property var dragEvents: []
24+ property real dragVelocity: 0
26+ // Can be replaced with a fake implementation during tests
27+ // property var __getCurrentTimeMs: function () { return new Date().getTime() }
28+ property var __dateTime: new function() {
29+ this.getCurrentTimeMs = function() {return new Date().getTime()}
32+ function pushDragEvent(event) {
33+ var currentTime = __dateTime.getCurrentTimeMs()
34+ dragEvents.push([currentTime, event.x, event.y, getEventSpeed(currentTime, event)])
35+ cullOldDragEvents(currentTime)
39+ function cullOldDragEvents(currentTime) {
40+ // cull events older than 50 ms but always keep the latest 2 events
41+ for (var numberOfCulledEvents = 0; numberOfCulledEvents < dragEvents.length-2; numberOfCulledEvents++) {
42+ // dragEvents[numberOfCulledEvents][0] is the dragTime
43+ if (currentTime - dragEvents[numberOfCulledEvents][0] <= 50) break
46+ dragEvents.splice(0, numberOfCulledEvents)
49+ function updateSpeed() {
51+ for (var i = 0; i < dragEvents.length; i++) {
52+ totalSpeed += dragEvents[i][3]
54+ print("total speed", totalSpeed)
56+ if (zeroVelocityCounts || Math.abs(totalSpeed) > 0.001) {
57+ dragVelocity = totalSpeed / dragEvents.length * 1000
61+ function getEventSpeed(currentTime, event) {
62+ if (dragEvents.length != 0) {
63+ var lastDrag = dragEvents[dragEvents.length-1]
64+ var duration = Math.max(1, currentTime - lastDrag[0])
65+ return (event.y - lastDrag[2]) / duration
76+ onClicked: root.clicked()
79+ MultiPointTouchArea {
82+ maximumTouchPoints: 1
94+ animation.animate("center");
98+ if (touchPoints.length == 0 || !d.moving) {
102+ var touchPoint = touchPoints[0];
103+ d.distance = touchPoint.y - touchPoint.startY
104+ d.pushDragEvent(touchPoint);
105+ print("pushed event", touchPoint.y, "velocity is now", d.dragVelocity)
109+ print("released", d.moving)
114+ if (!root.closeable) {
115+ animation.animate("center")
119+ var touchPoint = touchPoints[0];
121+ print("released velocity is", d.dragVelocity, "min velocity", root.minSpeedToClose)
122+ if ((d.dragVelocity < -root.minSpeedToClose && d.distance < -units.gu(8)) || d.distance < -root.height / 2) {
123+ animation.animate("up")
124+ } else if ((d.dragVelocity > root.minSpeedToClose && d.distance > units.gu(8)) || d.distance > root.height / 2) {
125+ animation.animate("down")
127+ animation.animate("center")
132+ UbuntuNumberAnimation {
134+ objectName: "closeAnimation"
136+ property: "distance"
137+ property bool requestClose: false
139+ function animate(direction) {
140+ animation.from = dragArea.distance;
141+ switch (direction) {
143+ animation.to = -root.height * 1.5;
144+ requestClose = true;
147+ animation.to = root.height * 1.5;
148+ requestClose = true;
171+// onPressed: mouse.accepted = true;
172+// hoverEnabled: true
175+// property bool closeable: true
177+// property bool moving: false
178+// property real distance: 0
179+// readonly property int threshold: units.gu(2)
180+// property int offset: 0
182+// readonly property real minSpeedToClose: units.gu(40)
186+// onMouseYChanged: {
192+// onDragValueChanged: {
196+// moving = moving || Math.abs(dragValue) > threshold;
198+// distance = dragValue + offset;
202+// onMovingChanged: {
204+// offset = (dragValue > 0 ? -threshold: threshold)
211+// if (!root.closeable) {
212+// animation.animate("center")
216+// // velocity and distance values specified by design prototype
217+// if ((dragVelocity < -minSpeedToClose && distance < -units.gu(8)) || distance < -root.height / 2) {
218+// animation.animate("up")
219+// } else if ((dragVelocity > minSpeedToClose && distance > units.gu(8)) || distance > root.height / 2) {
220+// animation.animate("down")
222+// animation.animate("center")
226+// UbuntuNumberAnimation {
228+// objectName: "closeAnimation"
230+// property: "distance"
231+// property bool requestClose: false
233+// function animate(direction) {
234+// animation.from = dragArea.distance;
235+// switch (direction) {
237+// animation.to = -root.height * 1.5;
238+// requestClose = true;
241+// animation.to = root.height * 1.5;
242+// requestClose = true;
247+// animation.start();
250+// onRunningChanged: {
252+// dragArea.moving = false;
253+// if (requestClose) {
256+// dragArea.distance = 0;