on xenial help sign in
Final rotation fixes for DragHandle and DirectionalDragArea
commit61b6ac4a76f6fc5db6e820f13e75b9a5ed53f922 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateWed 12 Feb 2014, 16:53 (13 years ago) parent586efb4cf12ebe
6 files changed+146−107
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+16−9 plugins/Ubuntu/Gestures/DirectionalDragArea.h+2 qml/Components/DragHandle.qml+2−1 tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+55 tests/qmltests/Components/tst_DragHandle.qml+71−56 tests/qmltests/Components/tst_DragHandle/TestButton.qml−41
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+16−9
@@ -246,13 +246,15 @@ qreal DirectionalDragArea::distance() const
246246 }
247247}
248248
249+void DirectionalDragArea::updateSceneDistance()
250+{
251+ QPointF totalMovement = m_previousScenePos - m_startScenePos;
252+ m_sceneDistance = projectOntoDirectionVector(totalMovement);
253+}
254+
249255qreal DirectionalDragArea::sceneDistance() const
250256{
251− if (Direction::isHorizontal(m_direction)) {
252− return m_previousScenePos.x() - m_startScenePos.x();
253− } else {
254− return m_previousScenePos.y() - m_startScenePos.y();
255− }
257+ return m_sceneDistance;
256258}
257259
258260qreal DirectionalDragArea::touchX() const
@@ -587,18 +589,23 @@ void DirectionalDragArea::setPreviousScenePos(const QPointF &point)
587589 bool xChanged = m_previousScenePos.x() != point.x();
588590 bool yChanged = m_previousScenePos.y() != point.y();
589591
592+ if (!xChanged && !yChanged)
593+ return;
594+
595+ qreal oldSceneDistance = sceneDistance();
590596 m_previousScenePos = point;
597+ updateSceneDistance();
598+
599+ if (oldSceneDistance != sceneDistance()) {
600+ Q_EMIT sceneDistanceChanged(sceneDistance());
601+ }
591602
592603 if (xChanged) {
593604 Q_EMIT touchSceneXChanged(point.x());
594− if (Direction::isHorizontal(m_direction))
595− Q_EMIT sceneDistanceChanged(sceneDistance());
596605 }
597606
598607 if (yChanged) {
599608 Q_EMIT touchSceneYChanged(point.y());
600− if (Direction::isVertical(m_direction))
601− Q_EMIT sceneDistanceChanged(sceneDistance());
602609 }
603610}
604611
plugins/Ubuntu/Gestures/DirectionalDragArea.h+2
@@ -160,6 +160,7 @@ public:
160160
161161 qreal distance() const;
162162 qreal sceneDistance() const;
163+ void updateSceneDistance();
163164
164165 qreal touchX() const;
165166 qreal touchY() const;
@@ -242,6 +243,7 @@ private:
242243 QPointF m_startScenePos;
243244 QPointF m_previousPos;
244245 QPointF m_previousScenePos;
246+ qreal m_sceneDistance;
245247 int m_touchId;
246248
247249 // A movement damper is used in some of the gesture recognition calculations
qml/Components/DragHandle.qml+2−1
@@ -167,7 +167,8 @@ EdgeDragArea {
167167 EdgeDragEvaluator {
168168 objectName: "edgeDragEvaluator"
169169 id: dragEvaluator
170− trackedPosition: sceneDistance
170+ // Effectively convert distance into the drag position projected onto the gesture direction axis
171+ trackedPosition: Direction.isPositive(dragArea.direction) ? sceneDistance : -sceneDistance
171172 maxDragDistance: maxTotalDragDistance
172173 direction: dragArea.direction
173174 }
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+55
@@ -84,6 +84,8 @@ private Q_SLOTS:
8484 void movingDDA();
8585 void ignoreOldFinger();
8686 void rotated();
87+ void sceneDistance();
88+ void sceneDistance_data();
8789
8890private:
8991 void passTime(qint64 timeSpan);
@@ -740,6 +742,59 @@ void tst_DirectionalDragArea::rotated()
740742 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
741743}
742744
745+void tst_DirectionalDragArea::sceneDistance()
746+{
747+ QQuickItem *baseItem = m_view->rootObject()->findChild<QQuickItem*>("baseItem");
748+ QFETCH(qreal, rotation);
749+ QFETCH(QPointF, dragDirectionVector);
750+ baseItem->setRotation(rotation);
751+
752+ QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
753+ Q_ASSERT(rightwardsLauncher != 0);
754+
755+ DirectionalDragArea *edgeDragArea =
756+ rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
757+ Q_ASSERT(edgeDragArea != 0);
758+ edgeDragArea->setRecognitionTimer(fakeTimer);
759+ edgeDragArea->setTimeSource(fakeTimeSource);
760+
761+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
762+ QPointF touchPoint = initialTouchPos;
763+
764+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
765+
766+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
767+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
768+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
769+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
770+
771+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
772+
773+ for (int i = 0; i < totalMovementSteps; ++i) {
774+ touchPoint += touchMovement;
775+ passTime(movementTimeStepMs);
776+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
777+ }
778+
779+ qreal actualDragDistance = ((qreal)totalMovementSteps) * movementStepDistance;
780+
781+ // DirectionalDragArea::sceneDistance() must match the actual drag distance as the
782+ // drag was aligned with the gesture direction
783+ // NB: qFuzzyCompare(), used internally by QCOMPARE(), is broken.
784+ QVERIFY(qAbs(edgeDragArea->sceneDistance() - actualDragDistance) < 0.001);
785+
786+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
787+}
788+
789+void tst_DirectionalDragArea::sceneDistance_data()
790+{
791+ QTest::addColumn<qreal>("rotation");
792+ QTest::addColumn<QPointF>("dragDirectionVector");
793+
794+ QTest::newRow("not rotated") << 0. << QPointF(1., 0.);
795+ QTest::newRow("rotated by 90 degrees") << 90. << QPointF(0., 1.);
796+}
797+
743798QTEST_MAIN(tst_DirectionalDragArea)
744799
745800#include "tst_DirectionalDragArea.moc"
tests/qmltests/Components/tst_DragHandle.qml+71−56
@@ -29,62 +29,67 @@ import Ubuntu.Gestures 0.1
2929 */
3030Item {
3131 id: root
32− width: 700
33− height: 500
32+ width: units.gu(70)
33+ height: units.gu(70)
3434
3535 property var dragHandle
3636
3737 property bool stretch: false
3838 property real hintDisplacement: 0
3939
40− VerticalShowable {
41− onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
42− stretch: root.stretch
43− hintDisplacement: root.hintDisplacement
44− }
45−
46− HorizontalShowable {
47− onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
48− stretch: root.stretch
49− hintDisplacement: root.hintDisplacement
50− }
40+ Item {
41+ id: baseItem
42+ anchors.fill: parent
5143
52− // Visually mark drag threshold
53− Rectangle {
54− color: "black"
55− width: 2
56− height: parent.height
44+ VerticalShowable {
45+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
46+ stretch: root.stretch
47+ hintDisplacement: root.hintDisplacement
48+ }
5749
58− visible: dragHandle !== undefined && Direction.isHorizontal(dragHandle.direction)
50+ HorizontalShowable {
51+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
52+ stretch: root.stretch
53+ hintDisplacement: root.hintDisplacement
54+ }
5955
60− x: {
61− if (dragHandle) {
62− if (dragHandle.direction === Direction.Rightwards) {
63− dragHandle.edgeDragEvaluator.dragThreshold;
56+ // Visually mark drag threshold
57+ Rectangle {
58+ color: "black"
59+ width: 2
60+ height: parent.height
61+
62+ visible: dragHandle !== undefined && Direction.isHorizontal(dragHandle.direction)
63+
64+ x: {
65+ if (dragHandle) {
66+ if (dragHandle.direction === Direction.Rightwards) {
67+ dragHandle.edgeDragEvaluator.dragThreshold;
68+ } else {
69+ parent.width - dragHandle.edgeDragEvaluator.dragThreshold;
70+ }
6471 } else {
65− parent.width - dragHandle.edgeDragEvaluator.dragThreshold;
72+ 0
6673 }
67− } else {
68− 0
6974 }
7075 }
71− }
72− Rectangle {
73− color: "black";
74− height: 2
75− width: parent.width
76−
77− visible: dragHandle !== undefined && Direction.isVertical(dragHandle.direction)
78−
79− y: {
80− if (dragHandle) {
81− if (dragHandle.direction === Direction.Downwards) {
82− dragHandle.edgeDragEvaluator.dragThreshold;
76+ Rectangle {
77+ color: "black";
78+ height: 2
79+ width: parent.width
80+
81+ visible: dragHandle !== undefined && Direction.isVertical(dragHandle.direction)
82+
83+ y: {
84+ if (dragHandle) {
85+ if (dragHandle.direction === Direction.Downwards) {
86+ dragHandle.edgeDragEvaluator.dragThreshold;
87+ } else {
88+ parent.height - dragHandle.edgeDragEvaluator.dragThreshold;
89+ }
8390 } else {
84− parent.height - dragHandle.edgeDragEvaluator.dragThreshold;
91+ 0
8592 }
86− } else {
87− 0
8893 }
8994 }
9095 }
@@ -119,27 +124,37 @@ Item {
119124 }
120125 }
121126
122− TestButton {
123− id: stretchButton
127+ Row {
124128 anchors.bottom: parent.bottom
125129 anchors.left: parent.left
126130 anchors.margins: units.gu(1)
131+ spacing: units.gu(1)
127132
128− text: root.stretch ? "stretch" : "move"
129− onClicked: { root.stretch = !root.stretch; }
130− }
133+ Button {
134+ id: stretchButton
135+ text: root.stretch ? "stretch" : "move"
136+ onClicked: { root.stretch = !root.stretch; }
137+ }
131138
132− TestButton {
133− anchors.bottom: parent.bottom
134− anchors.left: stretchButton.right
135− anchors.margins: units.gu(1)
139+ Button {
140+ text: root.hintDisplacement > 0 ? "hint" : "no hint"
141+ onClicked: {
142+ if (root.hintDisplacement > 0) {
143+ root.hintDisplacement = 0;
144+ } else {
145+ root.hintDisplacement = units.gu(6);
146+ }
147+ }
148+ }
136149
137− text: root.hintDisplacement > 0 ? "hint" : "no hint"
138− onClicked: {
139− if (root.hintDisplacement > 0) {
140− root.hintDisplacement = 0;
141− } else {
142− root.hintDisplacement = units.gu(6);
150+ Button {
151+ text: "rotation: " + baseItem.rotation
152+ onClicked: {
153+ if (baseItem.rotation === 0.0) {
154+ baseItem.rotation = 90.0
155+ } else {
156+ baseItem.rotation = 0.0
157+ }
143158 }
144159 }
145160 }
tests/qmltests/Components/tst_DragHandle/TestButton.qmldeleted−41
@@ -1,41 +0,0 @@
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−
20−Rectangle {
21− id: rect
22− width: childrenRect.width
23− height: childrenRect.height
24−
25− property alias text: textComponent.text
26−
27− signal clicked
28−
29− color: "yellow"
30− Text {
31− id: textComponent
32− font.pixelSize: units.gu(2)
33− text: root.stretch ? "stretch" : "move"
34− MouseArea {
35− anchors.fill: parent
36− onClicked: {
37− rect.clicked()
38− }
39− }
40− }
41−}