@@ -1,1306 +0,0 @@
2− * Copyright (C) 2013-2015 Canonical, Ltd.
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.
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.
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/>.
17−#include <QtTest/QtTest>
18−#include <QtCore/QObject>
19−#include <QtQuick/QQuickView>
20−#include <QtQml/QQmlEngine>
22−#include <private/qquickmousearea_p.h>
23−#include <private/qquickwindow_p.h>
26−#include <DirectionalDragArea.h>
27−#include <DirectionalDragArea_p.h>
28−#include <TouchRegistry.h>
30−#include "GestureTest.h"
32−using namespace UbuntuGestures;
34−// Because QSignalSpy(directionalDragArea, SIGNAL(DirectionalDragArea::Status)) simply
36−class StatusSpy : public QObject {
39− StatusSpy(DirectionalDragArea *edgeDragArea) {
40− m_recognized = false;
41− connect(edgeDragArea->d, &DirectionalDragAreaPrivate::statusChanged,
42− this, &StatusSpy::onStatusChanged);
49− void onStatusChanged(DirectionalDragAreaPrivate::Status status) {
50− m_recognized |= status == DirectionalDragAreaPrivate::Recognized;
58− QQuickMouseArea::canceled() signal is not registered in the meta object system.
59− So using a QSignalSpy to track it won't work. Thus the only way to connect to it
60− is using its method address directly.
62−class MouseAreaSpy : public QObject
66− MouseAreaSpy(QQuickMouseArea *mouseArea)
69− connect(mouseArea, &QQuickMouseArea::canceled,
70− this, &MouseAreaSpy::onMouseAreaCanceled);
76− void onMouseAreaCanceled() {
81−class tst_DirectionalDragArea: public GestureTest
85− tst_DirectionalDragArea();
87− void init() override; // called right before each and every test function is executed
89− void dragWithShortDirectionChange();
90− void recognitionTimerUsage();
95− void ignoreOldFinger();
97− void sceneDistance();
98− void sceneDistance_data();
99− void disabledWhileDragging();
100− void oneFingerDownFollowedByLateSecondFingerDown();
101− void givesUpWhenLosesTouch();
102− void threeFingerDrag();
103− void immediateRecognitionWhenConstraintsDisabled();
104− void withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition();
105− void withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition_data();
106− void gettingTouchOwnershipMakesMouseAreaBehindGetCanceled();
107− void interleavedTouches();
108− void makoRightEdgeDrag();
109− void makoRightEdgeDrag_verticalDownwards();
110− void makoLeftEdgeDrag_slowStart();
111− void makoLeftEdgeDrag_movesSlightlyBackwardsOnStart();
114− // QTest::touchEvent takes QPoint instead of QPointF and I don't want to
115− // lose precision due to rounding.
116− // Besides, those helper functions lead to more compact code.
117− void sendTouchPress(qint64 timestamp, int id, QPointF pos);
118− void sendTouchUpdate(qint64 timestamp, int id, QPointF pos);
119− void sendTouchRelease(qint64 timestamp, int id, QPointF pos);
120− void sendTouch(qint64 timestamp, int id, QPointF pos,
121− Qt::TouchPointState pointState, QEvent::Type eventType);
123− void passTime(qint64 timeSpanMs);
126−tst_DirectionalDragArea::tst_DirectionalDragArea()
127− : GestureTest(QStringLiteral("tst_DirectionalDragArea.qml"))
131−void tst_DirectionalDragArea::init()
133− GestureTest::init();
135− // We shouldn't need the three lines below, but a compiz/unity7
136− // regression means we don't pass the test without them because
137− // the window doesn't have the proper size. Can be removed in the
138− // future if the regression is fixed and tests pass again
139− m_view->resize(m_view->rootObject()->width(), m_view->rootObject()->height());
140− QTRY_COMPARE(m_view->width(), (int)m_view->rootObject()->width());
141− QTRY_COMPARE(m_view->height(), (int)m_view->rootObject()->height());
144−void tst_DirectionalDragArea::sendTouchPress(qint64 timestamp, int id, QPointF pos)
146− sendTouch(timestamp, id, pos, Qt::TouchPointPressed, QEvent::TouchBegin);
149−void tst_DirectionalDragArea::sendTouchUpdate(qint64 timestamp, int id, QPointF pos)
151− sendTouch(timestamp, id, pos, Qt::TouchPointMoved, QEvent::TouchUpdate);
154−void tst_DirectionalDragArea::sendTouchRelease(qint64 timestamp, int id, QPointF pos)
156− sendTouch(timestamp, id, pos, Qt::TouchPointReleased, QEvent::TouchEnd);
159−void tst_DirectionalDragArea::sendTouch(qint64 timestamp, int id, QPointF pos,
160− Qt::TouchPointState pointState, QEvent::Type eventType)
162− m_fakeTimerFactory->updateTime(timestamp);
164− QTouchEvent::TouchPoint point;
166− point.setState(pointState);
168− point.setScenePos(pos);
171− QList<QTouchEvent::TouchPoint> points;
174− QTouchEvent touchEvent(eventType, m_device, Qt::NoModifier, Qt::TouchPointPressed, points);
175− QCoreApplication::sendEvent(m_view, &touchEvent);
177− QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
178− windowPrivate->flushDelayedTouchEvent();
181−void tst_DirectionalDragArea::passTime(qint64 timeSpanMs)
183− qint64 finalTime = m_fakeTimerFactory->timeSource()->msecsSinceReference() + timeSpanMs;
184− m_fakeTimerFactory->updateTime(finalTime);
188−QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea)
190− QPointF localCenter(edgeDragArea->width() / 2., edgeDragArea->height() / 2.);
191− return edgeDragArea->mapToScene(localCenter);
196− A directional drag should still be recognized if there is a momentaneous, small,
197− change in the direction of a drag. That should be accounted as input noise and
200−void tst_DirectionalDragArea::dragWithShortDirectionChange()
202− DirectionalDragArea *edgeDragArea =
203− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
204− QVERIFY(edgeDragArea != 0);
205− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
206− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
208− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
209− QPointF touchPoint = initialTouchPos;
211− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0;
212− QPointF dragDirectionVector(1.0, 0.0);
213− qreal touchStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
214− // make sure we are above maximum time
215− int touchStepTimeMs = edgeDragArea->d->maxTime / 20. ;
216− QPointF touchMovement = dragDirectionVector * touchStepDistance;
218− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
220− // Move a bit in the proper direction
221− for (int i=0; i < 3; ++i) {
222− touchPoint += touchMovement;
223− passTime(touchStepTimeMs);
224− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
227− // Then a sudden and small movement to the opposite direction
228− touchPoint -= touchMovement*0.2;
229− passTime(touchStepTimeMs*0.2);
230− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
232− // And then resume movment in the correct direction until it crosses the distance and time
235− touchPoint += touchMovement;
236− passTime(touchStepTimeMs);
237− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
238− } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance
239− || m_fakeTimerFactory->timeSource()->msecsSinceReference() < (edgeDragArea->d->compositionTime * 1.5f));
241− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
243− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
247− Checks that the recognition timer is started and stopped appropriately.
248− I.e., check that it's running only while gesture recognition is taking place
249− (status == Undecided)
251−void tst_DirectionalDragArea::recognitionTimerUsage()
253− DirectionalDragArea *edgeDragArea =
254− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
255− QVERIFY(edgeDragArea != 0);
256− AbstractTimer *fakeTimer = m_fakeTimerFactory->createTimer();
257− edgeDragArea->d->setRecognitionTimer(fakeTimer);
258− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
260− int timeStepMs = 5; // some arbitrary small value.
262− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
263− QPointF touchPoint = initialTouchPos;
265− QPointF dragDirectionVector(1.0, 0.0);
266− QPointF touchMovement = dragDirectionVector * (edgeDragArea->d->distanceThreshold * 0.2f);
268− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
269− QVERIFY(!fakeTimer->isRunning());
271− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
273− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
274− QVERIFY(fakeTimer->isRunning());
276− // Move beyond distance threshold and composition time to ensure recognition
277− while (m_fakeTimerFactory->timeSource()->msecsSinceReference() <= edgeDragArea->d->compositionTime ||
278− (touchPoint - initialTouchPos).manhattanLength() <= edgeDragArea->d->distanceThreshold) {
280− QCOMPARE(edgeDragArea->d->status == DirectionalDragAreaPrivate::Undecided, fakeTimer->isRunning());
282− touchPoint += touchMovement;
283− passTime(timeStepMs);
284− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
287− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
288− QVERIFY(!fakeTimer->isRunning());
292− Checks that it informs the X coordinate of the touch point in local and scene coordinates
295−void tst_DirectionalDragArea::sceneXAndX()
297− DirectionalDragArea *edgeDragArea =
298− m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
299− QVERIFY(edgeDragArea != 0);
300− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
301− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
302− edgeDragArea->setImmediateRecognition(true);
304− QPointF touchScenePos(m_view->width() - (edgeDragArea->width()/2.0f), m_view->height()/2.0f);
306− sendTouchPress(0 /* timestamp */, 0 /* id */, touchScenePos);
308− QSignalSpy touchXSpy(edgeDragArea, &DirectionalDragArea::touchXChanged);
309− QSignalSpy touchSceneXSpy(edgeDragArea, &DirectionalDragArea::touchSceneXChanged);
311− touchScenePos.rx() = m_view->width() / 2;
312− sendTouchUpdate(50 /* timestamp */, 0 /* id */, touchScenePos);
314− QCOMPARE(touchXSpy.count(), 1);
315− QCOMPARE(touchSceneXSpy.count(), 1);
316− QCOMPARE(edgeDragArea->touchX(), touchScenePos.x() - edgeDragArea->x());
317− QCOMPARE(edgeDragArea->touchSceneX(), touchScenePos.x());
321− Checks that it informs the Y coordinate of the touch point in local and scene coordinates
324−void tst_DirectionalDragArea::sceneYAndY()
326− DirectionalDragArea *edgeDragArea =
327− m_view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea");
328− QVERIFY(edgeDragArea != 0);
329− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
330− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
331− edgeDragArea->setImmediateRecognition(true);
333− QPointF touchScenePos(m_view->width()/2.0f, m_view->height() - (edgeDragArea->height()/2.0f));
335− sendTouchPress(0 /* timestamp */, 0 /* id */, touchScenePos);
337− QSignalSpy touchYSpy(edgeDragArea, &DirectionalDragArea::touchYChanged);
338− QSignalSpy touchSceneYSpy(edgeDragArea, &DirectionalDragArea::touchSceneYChanged);
340− touchScenePos.ry() = m_view->height() / 2;
341− sendTouchUpdate(50 /* timestamp */, 0 /* id */, touchScenePos);
343− QCOMPARE(touchYSpy.count(), 1);
344− QCOMPARE(touchSceneYSpy.count(), 1);
345− QCOMPARE(edgeDragArea->touchY(), touchScenePos.y() - edgeDragArea->y());
346− QCOMPARE(edgeDragArea->touchSceneY(), touchScenePos.y());
350− Regression test for https://bugs.launchpad.net/bugs/1228336
352− Perform a quick two-finger double-tap and check that DirectionalDragArea properly
353− rejects those touch points. In the bug above it got confused and crashed.
355−void tst_DirectionalDragArea::twoFingerTap()
357− DirectionalDragArea *edgeDragArea =
358− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
359− QVERIFY(edgeDragArea != 0);
360− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
361− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
363− // Make touches evenly spaced along the edgeDragArea
364− QPoint touchAPos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
365− QPoint touchBPos(edgeDragArea->width()/2.0f, m_view->height()*0.66f);
367− qint64 timeStepMsecs = 5; // some arbitrary, small value
369− // Perform the first two-finger tap
370− // NB: using move() instead of stationary() becasue in the latter you cannot provide
371− // the touch position and therefore it's left with some garbage numbers.
372− QTest::touchEvent(m_view, m_device)
373− .press(0, touchAPos);
375− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
377− passTime(timeStepMsecs);
378− QTest::touchEvent(m_view, m_device)
380− .press(1, touchBPos);
382− // A second touch point appeared during recognition, reject immediately as this
383− // can't be a single-touch gesture anymore.
384− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
386− passTime(timeStepMsecs);
387− QTest::touchEvent(m_view, m_device)
388− .release(0, touchAPos)
389− .move(1, touchBPos);
391− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
393− passTime(timeStepMsecs);
394− QTest::touchEvent(m_view, m_device)
395− .release(1, touchBPos);
397− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
399− // Perform the second two-finger tap
401− passTime(timeStepMsecs);
402− QTest::touchEvent(m_view, m_device)
403− .press(0, touchAPos);
405− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
407− passTime(timeStepMsecs);
408− QTest::touchEvent(m_view, m_device)
410− .press(1, touchBPos);
412− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
414− passTime(timeStepMsecs);
415− QTest::touchEvent(m_view, m_device)
416− .release(0, touchAPos)
417− .move(1, touchBPos);
419− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
421− passTime(timeStepMsecs);
422− QTest::touchEvent(m_view, m_device)
423− .release(1, touchBPos);
425− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
429− Tests that gesture recognition works normally even if the DirectionalDragArea moves
431− This effectively means that we have to do gesture recognition with scene coordinates
432− instead of local item coordinates.
434−void tst_DirectionalDragArea::movingDDA()
436− QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
437− Q_ASSERT(rightwardsLauncher != 0);
439− DirectionalDragArea *edgeDragArea =
440− rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
441− Q_ASSERT(edgeDragArea != 0);
442− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
443− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
445− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
446− QPointF touchPoint = initialTouchPos;
448− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
449− QPointF dragDirectionVector(1.0f, 0.0f);
451− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
452− QPointF touchMovement = dragDirectionVector * movementStepDistance;
453− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
454− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
456− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
458− // Move it far ahead along the direction of the gesture
459− // rightwardsLauncher is a parent of our DirectionalDragArea. So moving it will move our DDA
460− rightwardsLauncher->setX(rightwardsLauncher->x() + edgeDragArea->d->distanceThreshold * 5.0f);
462− for (int i = 0; i < totalMovementSteps; ++i) {
463− touchPoint += touchMovement;
464− passTime(movementTimeStepMs);
465− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
468− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
470− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
474− The presence of and old, rejected, touch point lying on the DirectionalDragArea
475− shouldn't impede the recognition of a gesture from a new touch point.
477−void tst_DirectionalDragArea::ignoreOldFinger()
479− DirectionalDragArea *edgeDragArea =
480− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
481− Q_ASSERT(edgeDragArea != 0);
482− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
483− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
485− // Make touches evenly spaced along the edgeDragArea
486− QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
487− QPoint touch1Pos(edgeDragArea->width()/2.0f, m_view->height()*0.66f);
489− QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
491− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
493− // leave it lying around for some time
494− passTime(edgeDragArea->d->maxTime * 10);
496− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
498− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
499− QPointF dragDirectionVector(1.0f, 0.0f);
501− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
502− QPointF touchMovement = dragDirectionVector * movementStepDistance;
503− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
504− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
506− QTest::touchEvent(m_view, m_device)
508− .press(1, touch1Pos);
510− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
512− for (int i = 0; i < totalMovementSteps; ++i) {
513− touch1Pos += touchMovement.toPoint();
514− passTime(movementTimeStepMs);
515− QTest::touchEvent(m_view, m_device)
517− .move(1, touch1Pos);
520− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
522− QTest::touchEvent(m_view, m_device)
524− .release(1, touch1Pos);
526− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
530− A Rightwards DDA that is rotated 90 degrees clockwise should recognize gestures
531− that are done downwards in scene coordinates. I.e. the gesture recognition direction
532− should be in local coordinates, not scene coordinates.
534−void tst_DirectionalDragArea::rotated()
536− QQuickItem *baseItem = m_view->rootObject()->findChild<QQuickItem*>("baseItem");
537− baseItem->setRotation(90.);
539− QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
540− Q_ASSERT(rightwardsLauncher != 0);
542− DirectionalDragArea *edgeDragArea =
543− rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
544− Q_ASSERT(edgeDragArea != 0);
545− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
546− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
548− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
549− QPointF touchPoint = initialTouchPos;
551− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
552− QPointF dragDirectionVector(0.0f, 1.0f);
554− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
555− QPointF touchMovement = dragDirectionVector * movementStepDistance;
556− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
557− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
559− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
561− for (int i = 0; i < totalMovementSteps; ++i) {
562− touchPoint += touchMovement;
563− passTime(movementTimeStepMs);
564− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
567− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
569− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
572−void tst_DirectionalDragArea::sceneDistance()
574− QQuickItem *baseItem = m_view->rootObject()->findChild<QQuickItem*>("baseItem");
575− QFETCH(qreal, rotation);
576− QFETCH(QPointF, dragDirectionVector);
577− baseItem->setRotation(rotation);
579− QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
580− Q_ASSERT(rightwardsLauncher != 0);
582− DirectionalDragArea *edgeDragArea =
583− rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
584− Q_ASSERT(edgeDragArea != 0);
585− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
586− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
588− // to disable the position smoothing so that we can more easily check sceneDistance values
589− edgeDragArea->setImmediateRecognition(true);
591− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
592− QPointF touchPoint = initialTouchPos;
594− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
596− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
597− QPointF touchMovement = dragDirectionVector * movementStepDistance;
598− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
599− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
601− qint64 timestamp = 0;
603− sendTouchPress(timestamp, 0, touchPoint);
605− for (int i = 0; i < totalMovementSteps; ++i) {
606− touchPoint += touchMovement;
607− timestamp += movementTimeStepMs;
608− sendTouchUpdate(timestamp, 0, touchPoint);
611− qreal actualDragDistance = ((qreal)totalMovementSteps) * movementStepDistance;
613− // DirectionalDragArea::sceneDistance() must match the actual drag distance as the
614− // drag was aligned with the gesture direction
615− // NB: qFuzzyCompare(), used internally by QCOMPARE(), is broken.
616− QVERIFY(qAbs(edgeDragArea->sceneDistance() - actualDragDistance) < 0.001);
618− timestamp += movementTimeStepMs;
619− sendTouchRelease(timestamp, 0, touchPoint);
622−void tst_DirectionalDragArea::sceneDistance_data()
624− QTest::addColumn<qreal>("rotation");
625− QTest::addColumn<QPointF>("dragDirectionVector");
627− QTest::newRow("not rotated") << 0. << QPointF(1., 0.);
628− QTest::newRow("rotated by 90 degrees") << 90. << QPointF(0., 1.);
632− Regression test for https://bugs.launchpad.net/unity8/+bug/1276122
635− If setting "enabled: false" while the DirectionalDragArea's (DDA) dragging
636− property is true, the DDA stays in that state and doesn't recover any more.
638−void tst_DirectionalDragArea::disabledWhileDragging()
640− DirectionalDragArea *edgeDragArea =
641− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
642− Q_ASSERT(edgeDragArea != 0);
643− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
644− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
646− QPointF touchPoint = calculateInitialTouchPos(edgeDragArea);
648− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
649− QPointF dragDirectionVector(1., 0.); // horizontal positive
651− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
652− QPointF touchMovement = dragDirectionVector * movementStepDistance;
653− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
654− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
656− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
658− for (int i = 0; i < totalMovementSteps; ++i) {
659− touchPoint += touchMovement;
660− passTime(movementTimeStepMs);
661− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
664− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
665− QCOMPARE(edgeDragArea->dragging(), true);
667− // disable the dragArea while it's being dragged.
668− edgeDragArea->setEnabled(false);
670− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
671− QCOMPARE(edgeDragArea->dragging(), false);
673− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
676−void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
678− DirectionalDragArea *edgeDragArea =
679− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
680− Q_ASSERT(edgeDragArea != 0);
681− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
682− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
684− // Disable some constraints we're not interested in
685− edgeDragArea->d->setMaxTime(60 * 1000);
687− // And ensure others have the values we want
688− edgeDragArea->d->compositionTime = 60;
690− // Put an item right behind edgeDragArea to receive the touches ignored by it
691− DummyItem *dummyItem = new DummyItem;
692− dummyItem->setParentItem(edgeDragArea->parentItem());
693− dummyItem->setX(edgeDragArea->x());
694− dummyItem->setY(edgeDragArea->y());
695− dummyItem->setZ(edgeDragArea->z() - 1.0);
696− dummyItem->setWidth(edgeDragArea->width());
697− dummyItem->setHeight(edgeDragArea->height());
699− // Make touches evenly spaced along the edgeDragArea
700− QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
701− QPoint touch1Pos(edgeDragArea->width()/2.0f, m_view->height()*0.66f);
703− QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
705− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
707− // We are now going to be way beyond compositionTime
708− passTime(edgeDragArea->d->compositionTime*3);
710− QTest::touchEvent(m_view, m_device)
712− .press(1, touch1Pos);
714− // A new touch has come, but as it can't be composed with touch 0, it should be
715− // ignored/rejected by the DirectionalDragArea
716− // Therefore the last event received by dummyItem must have both touch points (0 and 1)
718− TouchMemento &touchMemento = dummyItem->touchEvents.last();
719− QCOMPARE(touchMemento.touchPoints.count(), 2);
720− QVERIFY(touchMemento.containsTouchWithId(0));
721− QVERIFY(touchMemento.containsTouchWithId(1));
726− QTest::touchEvent(m_view, m_device)
728− .move(1, touch1Pos);
730− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
734− QTest::touchEvent(m_view, m_device)
735− .release(0, touch0Pos)
736− .move(1, touch1Pos);
738− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
742− QTest::touchEvent(m_view, m_device)
743− .release(1, touch1Pos);
745− // Shouldn't be keepping info about touches that no longer exist or interest us
746− QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
751−void tst_DirectionalDragArea::givesUpWhenLosesTouch()
753− DirectionalDragArea *edgeDragArea =
754− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
755− Q_ASSERT(edgeDragArea != 0);
756− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
757− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
759− // Disable some constraints we're not interested in
760− edgeDragArea->d->setMaxTime(60 * 1000);
762− // Put an item right in front of edgeDragArea
763− DummyItem *dummyItem = new DummyItem(edgeDragArea->parentItem());
764− dummyItem->setX(edgeDragArea->x());
765− dummyItem->setY(edgeDragArea->y());
766− dummyItem->setZ(edgeDragArea->z() + 1.0);
767− dummyItem->setWidth(edgeDragArea->width());
768− dummyItem->setHeight(edgeDragArea->height());
770− QPoint touchPos(edgeDragArea->width()/2.0f, m_view->height()/2.0f);
772− dummyItem->touchEventHandler = [&](QTouchEvent *event) {
773− m_touchRegistry->addCandidateOwnerForTouch(0, dummyItem);
777− QTest::touchEvent(m_view, m_device).press(0, touchPos);
779− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
781− m_touchRegistry->requestTouchOwnership(0, dummyItem);
783− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
785− dummyItem->grabTouchPoints({0});
786− dummyItem->touchEventHandler = [&](QTouchEvent *event) { event->accept(); };
789− QTest::touchEvent(m_view, m_device).release(0, touchPos);
791− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
793− QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
796−void tst_DirectionalDragArea::threeFingerDrag()
798− DirectionalDragArea *edgeDragArea =
799− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
800− Q_ASSERT(edgeDragArea != 0);
801− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
802− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
804− // Disable some constraints we're not interested in
805− edgeDragArea->d->setMaxTime(60 * 1000);
807− // And ensure others have the values we want
808− edgeDragArea->d->compositionTime = 60;
810− // Make touches evenly spaced along the edgeDragArea
811− QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.25f);
812− QPoint touch1Pos(edgeDragArea->width()/2.0f, m_view->height()*0.50f);
813− QPoint touch2Pos(edgeDragArea->width()/2.0f, m_view->height()*0.75f);
815− QTest::touchEvent(m_view, m_device)
816− .press(0, touch0Pos);
818− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
821− QTest::touchEvent(m_view, m_device)
823− .press(1, touch1Pos);
825− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
828− QTest::touchEvent(m_view, m_device)
831− .press(2, touch2Pos);
833− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
836− QTest::touchEvent(m_view, m_device)
839− .move(2, touch2Pos);
842− QTest::touchEvent(m_view, m_device)
844− .release(1, touch1Pos)
845− .move(2, touch2Pos);
848− QTest::touchEvent(m_view, m_device)
850− .release(2, touch2Pos);
853− QTest::touchEvent(m_view, m_device)
854− .release(0, touch0Pos);
856− // Shouldn't be keepping info about touches that no longer exist or interest us
857− QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
861− If all the relevant gesture recognition constraints/parameters have been disabled,
862− it means that the gesture recognition itself has been disabled and DirectionalDragArea
863− will therefore work like a simple touch area, merely reporting touch movement.
865−void tst_DirectionalDragArea::immediateRecognitionWhenConstraintsDisabled()
867− DirectionalDragArea *edgeDragArea =
868− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
869− Q_ASSERT(edgeDragArea != 0);
870− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
871− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
873− // Disable the minimum amount of constraints to ensure immediate recognition
874− edgeDragArea->d->setDistanceThreshold(0);
875− edgeDragArea->d->compositionTime = 0;
877− // Put an item right behind edgeDragArea to receive the touches ignored by it
878− DummyItem *dummyItem = new DummyItem;
879− dummyItem->setParentItem(edgeDragArea->parentItem());
880− dummyItem->setX(edgeDragArea->x());
881− dummyItem->setY(edgeDragArea->y());
882− dummyItem->setZ(edgeDragArea->z() - 1.0);
883− dummyItem->setWidth(edgeDragArea->width());
884− dummyItem->setHeight(edgeDragArea->height());
886− QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()/2.0f);
888− QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
890− // check for immediate recognition
891− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
893− // and therefore it should have immediately grabbed the touch point,
894− // not letting it leak to items behind him.
895− QCOMPARE(dummyItem->touchEvents.count(), 0);
898−void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition()
900− DirectionalDragArea *edgeDragArea =
901− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
902− Q_ASSERT(edgeDragArea != 0);
903− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
904− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
906− QPointF touchPoint = calculateInitialTouchPos(edgeDragArea);
908− // Move less than the minimum needed for the drag gesture recognition
909− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 0.5f;
910− QPointF dragDirectionVector(1., 0.); // horizontal positive
912− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
913− QPointF touchMovement = dragDirectionVector * movementStepDistance;
914− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
915− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 0.8f) / totalMovementSteps;
917− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
919− for (int i = 0; i < totalMovementSteps; ++i) {
920− touchPoint += touchMovement;
921− passTime(movementTimeStepMs);
922− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
925− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
927− // edgeDragArea should be an undecided candidate
929− auto touchInfo = m_touchRegistry->findTouchInfo(0);
930− QCOMPARE(touchInfo->candidates.size(), 1);
931− QCOMPARE(touchInfo->candidates.at(0).item.data(), edgeDragArea);
932− QCOMPARE(touchInfo->candidates.at(0).state, TouchRegistry::CandidateInfo::Undecided);
935− // disable the dragArea while it's still recognizing a possible drag gesture.
936− QFETCH(bool, disable);
938− edgeDragArea->setEnabled(false);
940− edgeDragArea->setVisible(false);
943− // edgeDragArea should no longer be a candidate
945− auto touchInfo = m_touchRegistry->findTouchInfo(0);
946− QCOMPARE(touchInfo->candidates.size(), 0);
949− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
951− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
954−void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition_data()
956− QTest::addColumn<bool>("disable");
958− QTest::newRow("disabled") << true;
959− QTest::newRow("invisible") << false;
962−void tst_DirectionalDragArea::gettingTouchOwnershipMakesMouseAreaBehindGetCanceled()
964− DirectionalDragArea *edgeDragArea =
965− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
966− QVERIFY(edgeDragArea != nullptr);
967− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
968− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
970− QQuickMouseArea *mouseArea =
971− m_view->rootObject()->findChild<QQuickMouseArea*>("mouseArea");
972− QVERIFY(mouseArea != nullptr);
974− MouseAreaSpy mouseAreaSpy(mouseArea);
976− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
977− QPointF touchPoint = initialTouchPos;
979− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2;
980− QPointF dragDirectionVector(1.0f, 0.0f); // rightwards
981− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
982− QPointF touchMovement = dragDirectionVector * movementStepDistance;
983− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
984− int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
986− QCOMPARE(mouseArea->pressed(), false);
988− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
990− // The TouchBegin passes through the DirectionalDragArea and reaches the MouseArea behind it,
991− // where it's converted to a MouseEvent by QQuickWindow and sent to the MouseArea which then
992− // accepts it. Making it get pressed.
993− QCOMPARE(mouseArea->pressed(), true);
994− QCOMPARE(mouseAreaSpy.canceledCount, 0);
996− for (int i = 0; i < totalMovementSteps; ++i) {
997− touchPoint += touchMovement;
998− passTime(movementTimeStepMs);
999− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
1002− // As the DirectionalDragArea recognizes the gesture, it grabs the touch from the MouseArea,
1003− // which should make the MouseArea get a cancelation event, which will then cause it to
1004− // reset its state (going back to "unpressed"/"released").
1005− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1006− QCOMPARE(mouseArea->pressed(), false);
1007− QCOMPARE(mouseAreaSpy.canceledCount, 1);
1009− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
1012−void tst_DirectionalDragArea::interleavedTouches()
1014− DirectionalDragArea *edgeDragArea =
1015− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1016− QVERIFY(edgeDragArea != 0);
1017− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
1018− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1020− QPointF touch0 = edgeDragArea->mapToScene(
1021− QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.3));
1023− qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2;
1024− QPointF dragDirectionVector(1.0f, 0.0f); // rightwards
1025− qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
1026− QPointF touchMovement = dragDirectionVector * movementStepDistance;
1027− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
1028− int movementTimeStepMs = (edgeDragArea->d->maxTime * 0.4f) / totalMovementSteps;
1030− QTest::touchEvent(m_view, m_device).press(0, touch0.toPoint());
1031− for (int i = 0; i < totalMovementSteps; ++i) {
1032− touch0 += touchMovement;
1033− passTime(movementTimeStepMs);
1034− QTest::touchEvent(m_view, m_device).move(0, touch0.toPoint());
1036− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1038− QPointF touch1 = edgeDragArea->mapToScene(
1039− QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.6));
1041− QTest::touchEvent(m_view, m_device)
1042− .move(0, touch0.toPoint())
1043− .press(1, touch1.toPoint());
1045− touch1 += touchMovement;
1046− passTime(movementTimeStepMs);
1047− QTest::touchEvent(m_view, m_device)
1048− .move(0, touch0.toPoint())
1049− .move(1, touch1.toPoint());
1051− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1053− QTest::touchEvent(m_view, m_device)
1054− .release(0, touch0.toPoint())
1055− .move(1, touch1.toPoint());
1057− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1059− touch1 += touchMovement;
1060− passTime(movementTimeStepMs);
1061− QTest::touchEvent(m_view, m_device)
1062− .move(1, touch1.toPoint());
1064− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1066− QPointF touch2 = edgeDragArea->mapToScene(
1067− QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.9));
1069− passTime(edgeDragArea->d->compositionTime + movementTimeStepMs);
1070− QTest::touchEvent(m_view, m_device)
1071− .move(1, touch1.toPoint())
1072− .press(2, touch2.toPoint());
1074− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
1075− QCOMPARE(edgeDragArea->d->touchId, 2);
1077− touch2 += touchMovement;
1078− passTime(movementTimeStepMs);
1079− QTest::touchEvent(m_view, m_device)
1080− .move(1, touch1.toPoint())
1081− .move(2, touch2.toPoint());
1083− touch1 += touchMovement;
1084− passTime(movementTimeStepMs);
1085− QTest::touchEvent(m_view, m_device)
1086− .move(1, touch1.toPoint())
1087− .move(2, touch2.toPoint());
1089− passTime(movementTimeStepMs);
1090− QTest::touchEvent(m_view, m_device)
1091− .release(1, touch1.toPoint())
1092− .move(2, touch2.toPoint());
1094− passTime(movementTimeStepMs);
1095− QTest::touchEvent(m_view, m_device)
1096− .release(2, touch2.toPoint());
1098− QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1102− A valid right-edge drag performed on mako
1104−void tst_DirectionalDragArea::makoRightEdgeDrag()
1106− m_view->resize(768, 1280);
1109− DirectionalDragArea *edgeDragArea =
1110− m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
1111− QVERIFY(edgeDragArea != nullptr);
1112− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
1113− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1115− StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1117− edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1119− sendTouchPress(319744, 0, QPointF(767.001, 719.719));
1120− sendTouchUpdate(319765, 0, QPointF(765.744,729.973));
1121− sendTouchUpdate(319784, 0, QPointF(740.879,752.182));
1122− sendTouchUpdate(319803, 0, QPointF(689.698,795.795));
1123− sendTouchUpdate(319826, 0, QPointF(616.978,856.212));
1124− sendTouchUpdate(319845, 0, QPointF(558.769,906.157));
1125− sendTouchUpdate(319859, 0, QPointF(513.219,945.266));
1126− sendTouchUpdate(319878, 0, QPointF(481.31,975.496));
1127− sendTouchUpdate(319902, 0, QPointF(460.016,997.439));
1128− sendTouchUpdate(319920, 0, QPointF(449.761,1008.6));
1129− sendTouchUpdate(319929, 0, QPointF(445.891,1012.42));
1130− sendTouchUpdate(319947, 0, QPointF(444.884,1013.93));
1131− sendTouchUpdate(319965, 0, QPointF(444.461,1014.35));
1132− sendTouchUpdate(320057, 0, QPointF(444.71,1013.56));
1133− sendTouchUpdate(320138, 0, QPointF(445.434,1013.6));
1134− sendTouchUpdate(320154, 0, QPointF(446.338,1012.98));
1135− sendTouchUpdate(320171, 0, QPointF(447.232,1012.08));
1136− sendTouchRelease(320171, 0, QPointF(447.232,1012.08));
1138− QCOMPARE(statusSpy->recognized(), true);
1144− A vertical, downwards swipe performed on mako near its right edge.
1146− The DirectionalDragArea on the right edge must not recognize this
1149−void tst_DirectionalDragArea::makoRightEdgeDrag_verticalDownwards()
1151− m_view->resize(768, 1280);
1154− DirectionalDragArea *edgeDragArea =
1155− m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
1156− QVERIFY(edgeDragArea != nullptr);
1157− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
1158− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1160− edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1162− StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1164− sendTouchPress(12012445, 26, QPointF(767.001,461.82));
1165− sendTouchUpdate(12012472, 26, QPointF(767.001,462.569));
1166− sendTouchUpdate(12012528, 26, QPointF(767.001,463.334));
1167− sendTouchUpdate(12012546, 26, QPointF(767.001,466.856));
1168− sendTouchUpdate(12012571, 26, QPointF(767.001,473.291));
1169− sendTouchUpdate(12012587, 26, QPointF(767.001,487.31));
1170− sendTouchUpdate(12012604, 26, QPointF(765.364,507.521));
1171− sendTouchUpdate(12012618, 26, QPointF(765.364,507.521));
1172− sendTouchUpdate(12012627, 26, QPointF(762.642,534.317));
1173− sendTouchUpdate(12012655, 26, QPointF(760.846,573.406));
1174− sendTouchUpdate(12012667, 26, QPointF(759.838,625.295));
1175− sendTouchUpdate(12012675, 26, QPointF(758.875,703.207));
1176− sendTouchUpdate(12012696, 26, QPointF(761.52,777.015));
1177− sendTouchUpdate(12012713, 26, QPointF(765.659,835.591));
1178− sendTouchUpdate(12012731, 26, QPointF(766.778,883.206));
1179− sendTouchUpdate(12012748, 26, QPointF(767.001,922.937));
1180− sendTouchUpdate(12012779, 26, QPointF(767.001,967.558));
1181− sendTouchUpdate(12012798, 26, QPointF(767.001,1006.12));
1182− sendTouchUpdate(12012809, 26, QPointF(767.001,1033.1));
1183− sendTouchRelease(12012810, 26, QPointF(767.001,1033.1));
1185− QCOMPARE(statusSpy->recognized(), false);
1191− A valid left-edge drag performed on mako. This one starts a bit slow than speeds up
1193−void tst_DirectionalDragArea::makoLeftEdgeDrag_slowStart()
1195− m_view->resize(768, 1280);
1198− DirectionalDragArea *edgeDragArea =
1199− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1200− QVERIFY(edgeDragArea != nullptr);
1201− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
1202− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1204− edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1206− StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1208− sendTouchPress(4002267, 77, QPointF(0,885.154));
1209− sendTouchUpdate(4002275, 77, QPointF(0,886.214));
1210− sendTouchUpdate(4002311, 77, QPointF(1.09568,887.75));
1211− sendTouchUpdate(4002329, 77, QPointF(3.53647,890.191));
1212− sendTouchUpdate(4002347, 77, QPointF(7.87434,892.879));
1213− sendTouchUpdate(4002366, 77, QPointF(12.3036,895.075));
1214− sendTouchUpdate(4002384, 77, QPointF(15.8885,896.849));
1215− sendTouchUpdate(4002406, 77, QPointF(18.4504,897.88));
1216− sendTouchUpdate(4002420, 77, QPointF(20.2429,898.149));
1217− sendTouchUpdate(4002439, 77, QPointF(20.9945,898.149));
1218− sendTouchUpdate(4002457, 77, QPointF(21.8819,898.149));
1219− sendTouchUpdate(4002480, 77, QPointF(22.7454,897.389));
1220− sendTouchUpdate(4002493, 77, QPointF(23.5456,896.589));
1221− sendTouchUpdate(4002511, 77, QPointF(24.5435,895.031));
1222− sendTouchUpdate(4002529, 77, QPointF(25.4271,892.32));
1223− sendTouchUpdate(4002548, 77, QPointF(26.3145,889.658));
1224− sendTouchUpdate(4002566, 77, QPointF(27.2004,886.999));
1225− sendTouchUpdate(4002584, 77, QPointF(28.035,885.048));
1226− sendTouchUpdate(4002603, 77, QPointF(29.9684,883.167));
1227− sendTouchUpdate(4002620, 77, QPointF(33.3591,881.403));
1228− sendTouchUpdate(4002639, 77, QPointF(44.1017,879.642));
1229− sendTouchUpdate(4002657, 77, QPointF(64.828,878.502));
1230− sendTouchUpdate(4002675, 77, QPointF(87.9486,878.157));
1231− sendTouchUpdate(4002693, 77, QPointF(112.96,877.742));
1232− sendTouchUpdate(4002711, 77, QPointF(138.903,877.157));
1233− sendTouchUpdate(4002729, 77, QPointF(163.204,877.157));
1234− sendTouchUpdate(4002747, 77, QPointF(182.127,877.157));
1235− sendTouchUpdate(4002765, 77, QPointF(194.478,877.657));
1236− sendTouchUpdate(4002785, 77, QPointF(201.474,878.508));
1237− sendTouchUpdate(4002803, 77, QPointF(204.855,879.401));
1238− sendTouchUpdate(4002822, 77, QPointF(206.616,880.281));
1239− sendTouchUpdate(4002839, 77, QPointF(207.115,880.906));
1240− sendTouchUpdate(4002894, 77, QPointF(206.865,881.184));
1241− sendTouchUpdate(4002912, 77, QPointF(206.865,882.143));
1242− sendTouchUpdate(4002930, 77, QPointF(206.865,883.106));
1243− sendTouchUpdate(4002949, 77, QPointF(206.526,883.994));
1244− sendTouchUpdate(4002967, 77, QPointF(205.866,884.88));
1245− sendTouchUpdate(4002985, 77, QPointF(205.866,885.766));
1246− sendTouchUpdate(4003005, 77, QPointF(205.866,886.654));
1247− sendTouchUpdate(4003021, 77, QPointF(205.366,887.537));
1248− sendTouchUpdate(4003039, 77, QPointF(204.592,888.428));
1249− sendTouchUpdate(4003050, 77, QPointF(204.367,888.653));
1250− sendTouchRelease(4003050, 77, QPointF(204.367,888.653));
1252− QCOMPARE(statusSpy->recognized(), true);
1257−void tst_DirectionalDragArea::makoLeftEdgeDrag_movesSlightlyBackwardsOnStart()
1259− m_view->resize(768, 1280);
1262− DirectionalDragArea *edgeDragArea =
1263− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1264− QVERIFY(edgeDragArea != nullptr);
1265− edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer(edgeDragArea));
1266− edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1268− edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1270− StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1272− sendTouchPress(41097, 24, QPointF(13.9909,827.177));
1273− sendTouchUpdate(41120, 24, QPointF(19.2375,825.677));
1274− sendTouchUpdate(41138, 24, QPointF(18.4057,826.177));
1275− sendTouchUpdate(41161, 24, QPointF(20.1067,825.867));
1276− sendTouchUpdate(41177, 24, QPointF(21.8869,824.977));
1277− sendTouchUpdate(41193, 24, QPointF(24.7603,823.494));
1278− sendTouchUpdate(41211, 24, QPointF(28.3889,821.725));
1279− sendTouchUpdate(41229, 24, QPointF(32.2909,819.955));
1280− sendTouchUpdate(41247, 24, QPointF(38.2251,817.431));
1281− sendTouchUpdate(41266, 24, QPointF(52.4182,814.223));
1282− sendTouchUpdate(41284, 24, QPointF(85.8465,809.483));
1283− sendTouchUpdate(41302, 24, QPointF(126.091,802.741));
1284− sendTouchUpdate(41320, 24, QPointF(153.171,797.977));
1285− sendTouchUpdate(41338, 24, QPointF(170.565,795.077));
1286− sendTouchUpdate(41356, 24, QPointF(178.685,794.101));
1287− sendTouchUpdate(41375, 24, QPointF(183.706,793.225));
1288− sendTouchUpdate(41393, 24, QPointF(186.112,793.19));
1289− sendTouchUpdate(41411, 24, QPointF(187.634,793.19));
1290− sendTouchUpdate(41429, 24, QPointF(188.505,793.19));
1291− sendTouchUpdate(41532, 24, QPointF(187.816,793.19));
1292− sendTouchUpdate(41538, 24, QPointF(186.902,793.19));
1293− sendTouchUpdate(41557, 24, QPointF(186.01,793.19));
1294− sendTouchUpdate(41575, 24, QPointF(185.125,793.444));
1295− sendTouchUpdate(41593, 24, QPointF(184.229,793.69));
1296− sendTouchUpdate(41605, 24, QPointF(183.88,793.69));
1297− sendTouchRelease(41607, 24, QPointF(183.88,793.69));
1299− QCOMPARE(statusSpy->recognized(), true);
1304−QTEST_MAIN(tst_DirectionalDragArea)
1306−#include "tst_DirectionalDragArea.moc"