@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20+import "Math.js" as MathLocal
22 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
23 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
@@ -45,19 +46,122 @@ import Ubuntu.Gestures 0.1
46EdgeDragArea {
47EdgeDragArea {
47 id: dragArea
48 id: dragArea
49+ objectName: "dragHandle"
51+ property bool stretch: false
53+ property alias autoCompleteDragThreshold: dragEvaluator.dragThreshold
49 // How far you can drag
55 // How far you can drag
56+ property real maxTotalDragDistance: {
58+ 0; // not enough context information to set a sensible default
50− property real maxTotalDragDistance: Direction.isHorizontal(direction) ? parent.width : parent.height
60+ Direction.isHorizontal(direction) ? parent.width : parent.height;
64+ property real hintDisplacement: 0
67+ target: hintingAnimation
68+ property: "targetValue"
71+ to: Direction.isPositive(direction) ? d.startValue + hintDisplacement
72+ : d.startValue - hintDisplacement
73+ property real targetValue
74+ onTargetValueChanged: {
79+ if (Direction.isPositive(direction)) {
80+ if (parent[d.targetProp] < targetValue) {
81+ parent[d.targetProp] = targetValue;
84+ if (parent[d.targetProp] > targetValue) {
85+ parent[d.targetProp] = targetValue;
94+ property var previousStatus: undefined
95+ property real startValue
96+ property real minValue: Direction.isPositive(direction) ? startValue
97+ : startValue - maxTotalDragDistance
98+ property real maxValue: Direction.isPositive(direction) ? startValue + maxTotalDragDistance
101+ property var dragParent: dragArea.parent
103+ // The property of DragHandle's parent that will be modified
104+ property string targetProp: {
106+ Direction.isHorizontal(direction) ? "width" : "height";
108+ Direction.isHorizontal(direction) ? "x" : "y";
112+ function limitMovement(step) {
113+ var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
114+ var step = targetValue - dragParent[targetProp];
116+ if (hintDisplacement == 0) {
120+ // we should not go behind hintingAnimation's current value
121+ if (Direction.isPositive(direction)) {
122+ if (dragParent[targetProp] + step < hintingAnimation.targetValue) {
123+ step = hintingAnimation.targetValue - dragParent[targetProp];
126+ if (dragParent[targetProp] + step > hintingAnimation.targetValue) {
127+ step = hintingAnimation.targetValue - dragParent[targetProp];
134+ function onFinishedRecognizedGesture() {
135+ if (dragEvaluator.shouldAutoComplete()) {
52− property var __previousStatus
142+ function completeDrag() {
53− property real __totalDragDistance: 0
143+ if (dragParent.shown) {
150+ function rollbackDrag() {
151+ if (dragParent.shown) {
55 property alias edgeDragEvaluator: dragEvaluator
159 property alias edgeDragEvaluator: dragEvaluator
57 EdgeDragEvaluator {
161 EdgeDragEvaluator {
58 objectName: "edgeDragEvaluator"
162 objectName: "edgeDragEvaluator"
59 id: dragEvaluator
163 id: dragEvaluator
60− trackedPosition: Direction.isHorizontal(direction) ? parent.x + touchX : parent.y + touchY
164+ trackedPosition: sceneDistance
61 maxDragDistance: maxTotalDragDistance
165 maxDragDistance: maxTotalDragDistance
62 direction: dragArea.direction
166 direction: dragArea.direction
@@ -67,75 +171,38 @@ EdgeDragArea {
67 // don't go the whole distance in order to smooth out the movement
171 // don't go the whole distance in order to smooth out the movement
68 var step = distance * 0.3;
172 var step = distance * 0.3;
70− step = __limitMovement(step);
174+ step = d.limitMovement(step);
72− __totalDragDistance += step;
176+ parent[d.targetProp] += step;
74− if (Direction.isHorizontal(direction)) {
82−
180+ onDraggingChanged: {
83− function __limitMovement(step) {
181+ if (dragging) {
84− if (Direction.isPositive(direction)) {
182+ if (hintDisplacement > 0) {
85− if (__totalDragDistance + step > maxTotalDragDistance) {
183+ hintingAnimation.targetValue = d.startValue;
86− step = maxTotalDragDistance - __totalDragDistance;
184+ hintingAnimation.start();
87− } else if (__totalDragDistance + step < 0) {
88− step = 0 - __totalDragDistance;
91− if (__totalDragDistance + step < -maxTotalDragDistance) {
187+ hintingAnimation.stop();
92− step = -maxTotalDragDistance - __totalDragDistance;
93− } else if (__totalDragDistance + step > 0) {
94− step = 0 - __totalDragDistance;
101 onStatusChanged: {
191 onStatusChanged: {
102 if (status === DirectionalDragArea.WaitingForTouch) {
192 if (status === DirectionalDragArea.WaitingForTouch) {
103− if (__previousStatus === DirectionalDragArea.Recognized) {
193+ if (d.previousStatus === DirectionalDragArea.Recognized) {
104− __onFinishedRecognizedGesture();
194+ d.onFinishedRecognizedGesture();
106− __totalDragDistance = 0;
196+ d.startValue = parent[d.targetProp];
108− else if (status === DirectionalDragArea.Undecided) {
199+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
200+ d.previousStatus === undefined) {
109 dragEvaluator.reset();
201 dragEvaluator.reset();
202+ d.startValue = parent[d.targetProp];
111− else if (status === DirectionalDragArea.Recognized) {
112− if (__previousStatus === DirectionalDragArea.WaitingForTouch)
113− dragEvaluator.reset();
115− __previousStatus = status;
118− function __onFinishedRecognizedGesture() {
205+ d.previousStatus = status;
119− if (dragEvaluator.shouldAutoComplete()) {
126− function __completeDrag() {
134− function __rollbackDrag() {