on xenial help sign in
Fix DragHandle so it works in all directions

And therefore we can remove the hack in SideStage Approved by: Michael Terry

commitbfcf8baf9613f0ae0393ba80b31f2301904bdc1a authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateFri 27 May 2016, 13:49 (10 years ago) parenteacc6bebe06a7a
8 files changed+281−28
qml/Components/DragHandle.qml+28−8 qml/Stages/SideStage.qml+1−2 tests/qmltests/Components/tst_DragHandle.cpp+7−7 tests/qmltests/Components/tst_DragHandle.qml+22−4 tests/qmltests/Components/tst_DragHandle/BottomEdgeShowable.qml+108 tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qml → tests/qmltests/Components/tst_DragHandle/LeftEdgeShowable.qml tests/qmltests/Components/tst_DragHandle/RightEdgeShowable.qml+108 tests/qmltests/Components/tst_DragHandle/VerticalShowable.qml → tests/qmltests/Components/tst_DragHandle/TopEdgeShowable.qml+7−7
qml/Components/DragHandle.qml+28−8
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -70,15 +70,16 @@ SwipeArea {
7070 property: "targetValue"
7171 duration: 150
7272 velocity: -1
73− to: Direction.isPositive(direction) ? d.startValue + hintDisplacement
74− : d.startValue - hintDisplacement
73+
74+ to: d.incrementTargetProp ? d.startValue + hintDisplacement
75+ : d.startValue - hintDisplacement
7576 property real targetValue
7677 onTargetValueChanged: {
7778 if (!running) {
7879 return;
7980 }
8081
81− if (Direction.isPositive(direction)) {
82+ if (d.incrementTargetProp) {
8283 if (parent[d.targetProp] < targetValue) {
8384 parent[d.targetProp] = targetValue;
8485 }
@@ -93,19 +94,24 @@ SwipeArea {
9394 // Private stuff
9495 QtObject {
9596 id: d
97+
98+ // Whether movement along the designated direction will increment the value of the target property
99+ readonly property bool incrementTargetProp: (Direction.isPositive(direction) && !dragArea.stretch)
100+ || (dragArea.stretch && !d.dragParent.shown)
101+
96102 property real startValue
97103 property real minValue: {
98104 if (direction == Direction.Horizontal) {
99105 return startValue - maxTotalDragDistance;
100− } else if (Direction.isPositive(direction)) {
106+ } else if (incrementTargetProp) {
101107 return startValue;
102108 } else {
103109 return startValue - maxTotalDragDistance;
104110 }
105111 }
106112
107− property real maxValue: Direction.isPositive(direction) ? startValue + maxTotalDragDistance
108− : startValue
113+ property real maxValue: incrementTargetProp ? startValue + maxTotalDragDistance
114+ : startValue;
109115
110116 property var dragParent: dragArea.parent
111117
@@ -127,7 +133,7 @@ SwipeArea {
127133 }
128134
129135 // we should not go behind hintingAnimation's current value
130− if (Direction.isPositive(direction)) {
136+ if (d.incrementTargetProp) {
131137 if (d.startValue + diff < hintingAnimation.targetValue) {
132138 diff = hintingAnimation.targetValue - d.startValue;
133139 }
@@ -180,6 +186,20 @@ SwipeArea {
180186 if (dragging) {
181187 if (!Direction.isPositive(direction))
182188 distance = -distance;
189+
190+ if (dragArea.stretch &&
191+ ((!Direction.isPositive(direction) && !d.dragParent.shown)
192+ ||
193+ (Direction.isPositive(direction) && d.dragParent.shown))
194+ )
195+ {
196+ // This happens when you have a stretching showable being shown from the right or
197+ // top edge (and consequently being hidden when dragged towards the right/top edge)
198+ // In those situations, dimension expansion/retraction happens in the opposite
199+ // sign of the axis direction
200+ distance = -distance;
201+ }
202+
183203 var toAdd = d.limitMovement(distance);
184204 parent[d.targetProp] = d.startValue + toAdd;
185205 }
qml/Stages/SideStage.qml+1−2
@@ -98,8 +98,7 @@ Showable {
9898 id: hideSideStageDragArea
9999 objectName: "hideSideStageDragArea"
100100
101− direction: Direction.Leftwards
102− rotation: 180
101+ direction: Direction.Rightwards
103102 enabled: root.shown
104103 anchors.right: root.left
105104 width: sideStageDragHandle.width
tests/qmltests/Components/tst_DragHandle.cpp+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2014 Canonical, Ltd.
2+ * Copyright (C) 2013-2014,2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -290,7 +290,7 @@ void tst_DragHandle::dragThreshold_vertical()
290290 QQuickItem *baseItem = m_view->rootObject()->findChild<QQuickItem*>("baseItem");
291291 baseItem->setRotation(rotation);
292292
293− QQuickItem *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
293+ QQuickItem *dragHandle = fetchAndSetupDragHandle("topEdgeShowDragHandle");
294294
295295 qreal dragThreshold = fetchDragThreshold(dragHandle);
296296
@@ -309,7 +309,7 @@ void tst_DragHandle::dragThreshold_vertical()
309309 tryCompare([&](){ return parentItem->y(); }, 0);
310310 QCOMPARE(parentItem->property("shown").toBool(), true);
311311
312− dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
312+ dragHandle = fetchAndSetupDragHandle("topEdgeHideDragHandle");
313313
314314 dragThreshold = fetchDragThreshold(dragHandle);
315315
@@ -372,7 +372,7 @@ void tst_DragHandle::stretch_horizontal()
372372
373373void tst_DragHandle::stretch_vertical()
374374{
375− QQuickItem *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
375+ QQuickItem *dragHandle = fetchAndSetupDragHandle("topEdgeShowDragHandle");
376376 qreal totalDragDistance = dragHandle->property("maxTotalDragDistance").toReal();
377377 QQuickItem *parentItem = dragHandle->parentItem();
378378
@@ -389,7 +389,7 @@ void tst_DragHandle::stretch_vertical()
389389 tryCompare([&](){ return parentItem->height(); }, totalDragDistance);
390390 QCOMPARE(parentItem->property("shown").toBool(), true);
391391
392− dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
392+ dragHandle = fetchAndSetupDragHandle("topEdgeHideDragHandle");
393393
394394 // flick all the way
395395 flickAndHold(dragHandle, totalDragDistance);
@@ -408,7 +408,7 @@ void tst_DragHandle::stretch_vertical()
408408 */
409409void tst_DragHandle::hintingAnimation()
410410{
411− QQuickItem *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
411+ QQuickItem *dragHandle = fetchAndSetupDragHandle("topEdgeShowDragHandle");
412412 QQuickItem *parentItem = dragHandle->parentItem();
413413 qreal hintDisplacement = 100.0;
414414
@@ -449,7 +449,7 @@ void tst_DragHandle::hintingAnimation()
449449 */
450450void tst_DragHandle::hintingAnimation_dontRestartAfterFinishedAndStillPressed()
451451{
452− QQuickItem *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
452+ QQuickItem *dragHandle = fetchAndSetupDragHandle("topEdgeShowDragHandle");
453453 QQuickItem *parentItem = dragHandle->parentItem();
454454 qreal hintDisplacement = 100.0;
455455
tests/qmltests/Components/tst_DragHandle.qml+22−4
@@ -64,15 +64,33 @@ Rectangle {
6464 onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
6565 }
6666
67− VerticalShowable {
68− visible: !root.bidirectional
67+ TopEdgeShowable {
68+ id: topEdgeShowable
69+ visible: !root.bidirectional && !bottomEdgeShowable.shown
6970 onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
7071 stretch: root.stretch
7172 hintDisplacement: root.hintDisplacement
7273 }
7374
74− HorizontalShowable {
75− visible: !root.bidirectional
75+ BottomEdgeShowable {
76+ id: bottomEdgeShowable
77+ visible: !root.bidirectional && !topEdgeShowable.shown
78+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
79+ stretch: root.stretch
80+ hintDisplacement: root.hintDisplacement
81+ }
82+
83+ LeftEdgeShowable {
84+ id: leftEdgeShowable
85+ visible: !root.bidirectional && !rightEdgeShowable.shown
86+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
87+ stretch: root.stretch
88+ hintDisplacement: root.hintDisplacement
89+ }
90+
91+ RightEdgeShowable {
92+ id: rightEdgeShowable
93+ visible: !root.bidirectional && !leftEdgeShowable.shown
7694 onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
7795 stretch: root.stretch
7896 hintDisplacement: root.hintDisplacement
tests/qmltests/Components/tst_DragHandle/BottomEdgeShowable.qmlnew file+108
@@ -0,0 +1,108 @@
1+/*
2+ * Copyright (C) 2016 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.4
18+import "../../../../qml/Components"
19+import Ubuntu.Components 1.3
20+import Ubuntu.Gestures 0.1
21+
22+Showable {
23+ id: root
24+ y: height
25+ width: parent.width
26+ height: parent.height
27+
28+ property bool stretch
29+ property real hintDisplacement
30+
31+ Binding {
32+ when: stretch
33+ target: root
34+ property: "y"
35+ value: root.parent.height - root.height
36+ }
37+
38+ onStretchChanged: {
39+ // reset
40+ shown = false;
41+ if (stretch) {
42+ height = 0;
43+ } else {
44+ y = parent.height;
45+ height = parent.height;
46+ }
47+ }
48+
49+ shown: false
50+
51+ signal dragHandleRecognizedGesture(var dragHandle)
52+
53+ property string animatedProp: stretch ? "height" : "y"
54+ property real propValueWhenShown: stretch ? parent.height : 0
55+ property real propValueWhenHidden: stretch ? 0 : height
56+
57+ showAnimation: StandardAnimation { property: animatedProp; to: propValueWhenShown }
58+ hideAnimation: StandardAnimation { property: animatedProp; to: propValueWhenHidden }
59+
60+ Image { source: "../../UnityLogo.png"; anchors.fill: parent }
61+
62+ DragHandle {
63+ objectName: "topEdgeHideDragHandle"
64+ id: hideDragHandle
65+ anchors.left: parent.left
66+ anchors.right: parent.right
67+ anchors.top: parent.top
68+
69+ height: units.gu(2)
70+
71+ direction: Direction.Downwards
72+ stretch: root.stretch
73+ maxTotalDragDistance: root.parent.height
74+ hintDisplacement: root.hintDisplacement
75+
76+ onDraggingChanged: {
77+ if (dragging) {
78+ dragHandleRecognizedGesture(hideDragHandle);
79+ }
80+ }
81+
82+ Rectangle { color: "red"; anchors.fill: parent }
83+ }
84+
85+ DragHandle {
86+ objectName: "topEdgeShowDragHandle"
87+ id: showDragHandle
88+ anchors.left: parent.left
89+ anchors.right: parent.right
90+ anchors.bottom: parent.top
91+
92+ height: units.gu(2)
93+
94+ direction: Direction.Upwards
95+ stretch: root.stretch
96+ maxTotalDragDistance: root.parent.height
97+ hintDisplacement: root.hintDisplacement
98+
99+ onDraggingChanged: {
100+ if (dragging) {
101+ dragHandleRecognizedGesture(showDragHandle);
102+ }
103+ }
104+
105+ Rectangle { color: "green"; anchors.fill: parent }
106+ }
107+
108+}
tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qml → tests/qmltests/Components/tst_DragHandle/LeftEdgeShowable.qmlrenamed

The content is the same.

tests/qmltests/Components/tst_DragHandle/RightEdgeShowable.qmlnew file+108
@@ -0,0 +1,108 @@
1+/*
2+ * Copyright (C) 2016 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.4
18+import "../../../../qml/Components"
19+import Ubuntu.Components 1.3
20+import Ubuntu.Gestures 0.1
21+
22+Showable {
23+ id: root
24+ x: parent.width
25+ width: parent.width
26+ height: parent.height
27+
28+ property bool stretch
29+ property real hintDisplacement
30+
31+ Binding {
32+ when: stretch
33+ target: root
34+ property: "x"
35+ value: root.parent.width - root.width
36+ }
37+
38+ onStretchChanged: {
39+ // reset
40+ shown = false;
41+ if (stretch) {
42+ width = 0;
43+ } else {
44+ x = parent.width;
45+ width = parent.width;
46+ }
47+ }
48+
49+ shown: false
50+
51+ signal dragHandleRecognizedGesture(var dragHandle)
52+
53+ property string animatedProp: stretch ? "width" : "x"
54+ property real propValueWhenShown: stretch ? parent.width : 0
55+ property real propValueWhenHidden: stretch ? 0 : parent.width
56+
57+ showAnimation: StandardAnimation { property: animatedProp; to: propValueWhenShown }
58+ hideAnimation: StandardAnimation { property: animatedProp; to: propValueWhenHidden }
59+
60+ Image { source: "../../UnityLogo.png"; anchors.fill: parent }
61+
62+ DragHandle {
63+ objectName: "rightEdgeHideDragHandle"
64+ id: hideDragHandle
65+ anchors.top: parent.top
66+ anchors.bottom: parent.bottom
67+ anchors.left: parent.left
68+
69+ width: units.gu(2)
70+
71+ direction: Direction.Rightwards
72+ stretch: root.stretch
73+ maxTotalDragDistance: root.parent.width
74+ hintDisplacement: root.hintDisplacement
75+
76+ onDraggingChanged: {
77+ if (dragging) {
78+ dragHandleRecognizedGesture(hideDragHandle);
79+ }
80+ }
81+
82+ Rectangle { color: "red"; anchors.fill: parent }
83+ }
84+
85+ DragHandle {
86+ objectName: "rightEdgeShowDragHandle"
87+ id: showDragHandle
88+ anchors.top: parent.top
89+ anchors.bottom: parent.bottom
90+ anchors.right: parent.left
91+
92+ width: units.gu(2)
93+
94+ direction: Direction.Leftwards
95+ stretch: root.stretch
96+ maxTotalDragDistance: root.parent.width
97+ hintDisplacement: root.hintDisplacement
98+
99+ onDraggingChanged: {
100+ if (dragging) {
101+ dragHandleRecognizedGesture(showDragHandle);
102+ }
103+ }
104+
105+ Rectangle { color: "green"; anchors.fill: parent }
106+ }
107+
108+}
tests/qmltests/Components/tst_DragHandle/VerticalShowable.qml → tests/qmltests/Components/tst_DragHandle/TopEdgeShowable.qmlrenamed+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -52,8 +52,8 @@ Showable {
5252 Image { source: "../../UnityLogo.png"; anchors.fill: parent }
5353
5454 DragHandle {
55− objectName: "upwardsDragHandle"
56− id: upwardsDragHandle
55+ objectName: "topEdgeHideDragHandle"
56+ id: hideDragHandle
5757 anchors.left: parent.left
5858 anchors.right: parent.right
5959 anchors.bottom: parent.bottom
@@ -67,7 +67,7 @@ Showable {
6767
6868 onDraggingChanged: {
6969 if (dragging) {
70− dragHandleRecognizedGesture(upwardsDragHandle);
70+ dragHandleRecognizedGesture(hideDragHandle);
7171 }
7272 }
7373
@@ -75,8 +75,8 @@ Showable {
7575 }
7676
7777 DragHandle {
78− objectName: "downwardsDragHandle"
79− id: downwardsDragHandle
78+ objectName: "topEdgeShowDragHandle"
79+ id: showDragHandle
8080 anchors.left: parent.left
8181 anchors.right: parent.right
8282 anchors.top: parent.bottom
@@ -90,7 +90,7 @@ Showable {
9090
9191 onDraggingChanged: {
9292 if (dragging) {
93− dragHandleRecognizedGesture(downwardsDragHandle);
93+ dragHandleRecognizedGesture(showDragHandle);
9494 }
9595 }
9696