@@ -83,6 +83,9 @@ private Q_SLOTS:
8383 void twoFingerTap();
8484 void movingDDA();
8585 void ignoreOldFinger();
86+ void rotated();
87+ void sceneDistance();
88+ void sceneDistance_data();
8689
8790private:
8891 void passTime(qint64 timeSpan);
@@ -131,18 +134,10 @@ void tst_DirectionalDragArea::passTime(qint64 timeSpan)
131134}
132135
133136namespace {
134−QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea, QQuickView *view)
137+QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea)
135138{
136− switch (edgeDragArea->direction()) {
137− case Direction::Upwards:
138− return QPointF(view->width()/2.0f, view->height() - (edgeDragArea->height()/2.0f));
139− case Direction::Downwards:
140− return QPointF(view->width()/2.0f, edgeDragArea->height()/2.0f);
141− case Direction::Leftwards:
142− return QPointF(view->width() - (edgeDragArea->width()/2.0f), view->height()/2.0f);
143− default: // Direction::Rightwards:
144− return QPointF(edgeDragArea->width()/2.0f, view->height()/2.0f);
145− }
139+ QPointF localCenter(edgeDragArea->width() / 2., edgeDragArea->height() / 2.);
140+ return edgeDragArea->mapToScene(localCenter);
146141}
147142
148143QPointF calculateDirectionVector(DirectionalDragArea *edgeDragArea,
@@ -193,7 +188,7 @@ void tst_DirectionalDragArea::edgeDrag()
193188
194189 QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
195190
196− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
191+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
197192 QPointF touchPoint = initialTouchPos;
198193
199194 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor;
@@ -300,7 +295,7 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
300295 edgeDragArea->setRecognitionTimer(fakeTimer);
301296 edgeDragArea->setTimeSource(fakeTimeSource);
302297
303− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
298+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
304299 QPointF touchPoint = initialTouchPos;
305300
306301 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0;
@@ -360,7 +355,7 @@ void tst_DirectionalDragArea::minSpeed()
360355
361356 edgeDragArea->setMinSpeed(minSpeed);
362357
363− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
358+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
364359 QPointF touchPoint = initialTouchPos;
365360
366361 QPointF dragDirectionVector(1.0, 0.0);
@@ -408,7 +403,7 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
408403
409404 int timeStepMs = 5; // some arbitrary small value.
410405
411− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
406+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
412407 QPointF touchPoint = initialTouchPos;
413408
414409 QPointF dragDirectionVector(1.0, 0.0);
@@ -452,7 +447,7 @@ void tst_DirectionalDragArea::maxSilenceTime()
452447 // Make sure this property is not disabled
453448 edgeDragArea->setMaxSilenceTime(100);
454449
455− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
450+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
456451 QPointF touchPoint = initialTouchPos;
457452
458453 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
@@ -620,7 +615,7 @@ void tst_DirectionalDragArea::movingDDA()
620615 edgeDragArea->setRecognitionTimer(fakeTimer);
621616 edgeDragArea->setTimeSource(fakeTimeSource);
622617
623− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
618+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
624619 QPointF touchPoint = initialTouchPos;
625620
626621 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
@@ -704,6 +699,102 @@ void tst_DirectionalDragArea::ignoreOldFinger()
704699 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
705700}
706701
702+/*
703+ A Rightwards DDA that is rotated 90 degrees clockwise should recognize gestures
704+ that are done downwards in scene coordinates. I.e. the gesture recognition direction
705+ should be in local coordinates, not scene coordinates.
706+ */
707+void tst_DirectionalDragArea::rotated()
708+{
709+ QQuickItem *baseItem = m_view->rootObject()->findChild<QQuickItem*>("baseItem");
710+ baseItem->setRotation(90.);
711+
712+ QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
713+ Q_ASSERT(rightwardsLauncher != 0);
714+
715+ DirectionalDragArea *edgeDragArea =
716+ rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
717+ Q_ASSERT(edgeDragArea != 0);
718+ edgeDragArea->setRecognitionTimer(fakeTimer);
719+ edgeDragArea->setTimeSource(fakeTimeSource);
720+
721+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
722+ QPointF touchPoint = initialTouchPos;
723+
724+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
725+ QPointF dragDirectionVector(0.0f, 1.0f);
726+
727+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
728+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
729+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
730+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
731+
732+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
733+
734+ for (int i = 0; i < totalMovementSteps; ++i) {
735+ touchPoint += touchMovement;
736+ passTime(movementTimeStepMs);
737+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
738+ }
739+
740+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
741+
742+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
743+}
744+
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+
707798QTEST_MAIN(tst_DirectionalDragArea)
708799
709800#include "tst_DirectionalDragArea.moc"