on xenial help sign in
DragHandle: Never restart hinting animation while still pressed Fixes: 1269022
commite9862c770fcafd9249a502c23e97188f0b25253c authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateTue 28 Jan 2014, 15:57 (13 years ago) parentdbafc16b968169
2 files changed+72−17
qml/Components/DragHandle.qml+7−7 tests/qmltests/Components/tst_DragHandle.cpp+65−10
qml/Components/DragHandle.qml+7−7
@@ -97,7 +97,7 @@ EdgeDragArea {
9797 // Private stuff
9898 QtObject {
9999 id: d
100− property var previousStatus: undefined
100+ property var previousStatus: DirectionalDragArea.WaitingForTouch
101101 property real startValue
102102 property real minValue: Direction.isPositive(direction) ? startValue
103103 : startValue - maxTotalDragDistance
@@ -193,14 +193,14 @@ EdgeDragArea {
193193 d.rollbackDrag();
194194 }
195195 } else /* Undecided || Recognized */ {
196− if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
197− d.previousStatus === undefined) {
196+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch) {
198197 dragEvaluator.reset();
199198 d.startValue = parent[d.targetProp];
200− }
201− if (hintDisplacement > 0) {
202− hintingAnimation.targetValue = d.startValue;
203− hintingAnimation.start();
199+
200+ if (hintDisplacement > 0) {
201+ hintingAnimation.targetValue = d.startValue;
202+ hintingAnimation.start();
203+ }
204204 }
205205 }
206206
tests/qmltests/Components/tst_DragHandle.cpp+65−10
@@ -62,9 +62,13 @@ private Q_SLOTS:
6262 void stretch_horizontal();
6363 void stretch_vertical();
6464 void hintingAnimation();
65+ void hintingAnimation_dontRestartAfterFinishedAndStillPressed();
66+
6567
6668private:
6769 void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
70+ void drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
71+ int numSteps, qint64 timeMs = 500);
6872 DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
6973 qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
7074 void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
@@ -161,25 +165,29 @@ void tst_DragHandle::flickAndHold(DirectionalDragArea *dragHandle,
161165 QPointF initialTouchPos = dragHandle->mapToScene(
162166 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
163167 QPointF touchPoint = initialTouchPos;
164− int numSteps = 10;
165− qint64 flickTimeMs = 500;
166− qint64 timeStep = flickTimeMs / numSteps;
167168
169+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
170+
171+ int numSteps = 10;
168172 QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
169− QPointF touchMovement = dragDirectionVector * (distance / (qreal)numSteps);
173+ drag(touchPoint, dragDirectionVector, distance, numSteps);
170174
171− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
175+ // Wait for quite a bit before finally releasing to make a very low flick/release
176+ // speed.
177+ m_fakeTimeSource->m_msecsSinceReference += 5000;
178+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
179+}
172180
181+void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
182+ int numSteps, qint64 timeMs)
183+{
184+ qint64 timeStep = timeMs / numSteps;
185+ QPointF touchMovement = direction * (distance / (qreal)numSteps);
173186 for (int i = 0; i < numSteps; ++i) {
174187 touchPoint += touchMovement;
175188 m_fakeTimeSource->m_msecsSinceReference += timeStep;
176189 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
177190 }
178−
179− // Wait for quite a bit before finally releasing to make a very low flick/release
180− // speed.
181− m_fakeTimeSource->m_msecsSinceReference += 5000;
182− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
183191}
184192
185193DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
@@ -389,6 +397,53 @@ void tst_DragHandle::hintingAnimation()
389397 QCOMPARE(parentItem->property("shown").toBool(), false);
390398}
391399
400+/*
401+ Regression test for LP#1269022: https://bugs.launchpad.net/unity8/+bug/1269022
402+
403+ 1) Click on handle.
404+ 2) wait for hint portion to appear
405+ 3) slowly drag handle, only a few pixels
406+
407+ Expected outcome:
408+ Nothing happens
409+
410+ Actual outcome:
411+ Handle will momentarily move back to zero position, then back down to the
412+ hint displacement location.
413+ */
414+void tst_DragHandle::hintingAnimation_dontRestartAfterFinishedAndStillPressed()
415+{
416+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
417+ QQuickItem *parentItem = dragHandle->parentItem();
418+ qreal hintDisplacement = 100.0;
419+
420+ // enable hinting animations
421+ m_view->rootObject()->setProperty("hintDisplacement", QVariant(hintDisplacement));
422+ m_view->rootObject()->setProperty("stretch", QVariant(true));
423+
424+ QCOMPARE(parentItem->height(), 0.0);
425+
426+ QPointF initialTouchPos = dragHandle->mapToScene(
427+ QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
428+ QPointF touchPoint = initialTouchPos;
429+
430+ // Pressing causes the Showable to be stretched by hintDisplacement pixels
431+ const int touchId = 0;
432+ QTest::touchEvent(m_view, m_device).press(touchId, touchPoint.toPoint());
433+ tryCompare([&](){ return parentItem->height(); }, hintDisplacement);
434+
435+
436+ QSignalSpy parentHeightChangedSpy(parentItem, SIGNAL(heightChanged()));
437+
438+ drag(touchPoint, QPointF(0.0, -1.0) /*dragDirectionVector*/, 15 /*distance*/, 3 /*numSteps*/);
439+
440+ // Give some time for animations to run, if any
441+ QTest::qWait(300);
442+
443+ // parentItem height shouldn't have changed at all
444+ QVERIFY(parentHeightChangedSpy.isEmpty());
445+}
446+
392447QTEST_MAIN(tst_DragHandle)
393448
394449#include "tst_DragHandle.moc"