diff options
Diffstat (limited to 'tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp')
-rw-r--r-- | tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp | 165 |
1 files changed, 144 insertions, 21 deletions
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp index a61cbd76db..78483c5bdb 100644 --- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QtTest> #include <QtTest/QSignalSpy> @@ -34,6 +34,8 @@ private slots: void scaleThreeFingers(); void scaleNativeGesture_data(); void scaleNativeGesture(); + void cumulativeNativeGestures_data(); + void cumulativeNativeGestures(); void pan(); void dragAxesEnabled_data(); void dragAxesEnabled(); @@ -43,8 +45,8 @@ private slots: void transformedpinchHandler(); private: - QPointingDevice *touchscreen = QTest::createTouchDevice(); - QPointingDevice *touchpad = QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad); + QScopedPointer<QPointingDevice> touchscreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); + QScopedPointer<QPointingDevice> touchpad = QScopedPointer<QPointingDevice>(QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad)); }; void tst_QQuickPinchHandler::cleanupTestCase() @@ -230,13 +232,13 @@ void tst_QQuickPinchHandler::scale() QVERIFY(pinchHandler != nullptr); QQuickItem *blackRect = (hasTarget ? pinchHandler->target() : pinchHandler->parentItem()); QVERIFY(blackRect != nullptr); - QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint))); + QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition,QEventPoint))); QSignalSpy scaleChangedSpy(pinchHandler, &QQuickPinchHandler::scaleChanged); if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); QPoint p0(80, 80); QPoint p1(100, 100); - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&window, touchscreen.get()); pinchSequence.press(0, p0, &window).commit(); QQuickTouchUtils::flush(&window); // In order for the stationary point to remember its previous position, @@ -383,7 +385,7 @@ void tst_QQuickPinchHandler::scaleThreeFingers() QPoint p1(220, 80); QPoint p2(150, 220); { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get()); pinchSequence.press(0, p0, window).commit(); QQuickTouchUtils::flush(window); // In order for the stationary point to remember its previous position, @@ -488,10 +490,10 @@ void tst_QQuickPinchHandler::scaleNativeGesture() // so as to compensate for the change in size, to hold the centroid in place const QPointF expectedPos = targetPos + QPointF( (pinchPos.x() - target->x()) * (expectedScale - 1), (pinchPos.y() - target->y()) * (expectedScale - 1) ); - QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(), Qt::BeginNativeGesture, pinchPos, pinchPos); if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); - QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad.get(), Qt::ZoomNativeGesture, scale - 1, pinchPos, pinchPos); if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); QTRY_COMPARE(target->scale(), expectedScale); @@ -509,7 +511,7 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QCOMPARE(pinchHandler->activeRotation(), 0); QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), 0); QCOMPARE(pinchHandler->rotationAxis()->activeValue(), 0); - QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(), Qt::EndNativeGesture, pinchPos, pinchPos); QTRY_COMPARE(pinchHandler->active(), false); QCOMPARE(target->scale(), expectedScale); @@ -528,9 +530,9 @@ void tst_QQuickPinchHandler::scaleNativeGesture() const qreal reverseScale = (1 / expectedScale); pinchPos = QPointF(110, 110); pinchLocalPos = target->mapFromScene(pinchPos); - QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(), Qt::BeginNativeGesture, pinchPos, pinchPos); - QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad.get(), Qt::ZoomNativeGesture, reverseScale - 1, pinchPos, pinchPos); QTRY_COMPARE(target->scale(), 1); QCOMPARE(pinchHandler->active(), true); @@ -541,7 +543,7 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QCOMPARE(pinchHandler->persistentScale(), 1); QCOMPARE(pinchHandler->activeScale(), reverseScale); QCOMPARE(pinchHandler->scaleAxis()->activeValue(), reverseScale); - QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, + QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(), Qt::EndNativeGesture, pinchPos, pinchPos); QTRY_COMPARE(pinchHandler->active(), false); QCOMPARE(target->scale(), 1); @@ -550,6 +552,127 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QCOMPARE(pinchHandler->scaleAxis()->activeValue(), 1); } +void tst_QQuickPinchHandler::cumulativeNativeGestures_data() +{ + QTest::addColumn<const QPointingDevice*>("device"); + QTest::addColumn<Qt::NativeGestureType>("gesture"); + QTest::addColumn<qreal>("value"); + QTest::addColumn<QList<QPoint>>("expectedTargetTranslations"); + + const auto *touchpadDevice = touchpad.get(); + const auto *mouse = QPointingDevice::primaryPointingDevice(); + + QTest::newRow("touchpad: rotate") << touchpadDevice << Qt::RotateNativeGesture << 5.0 + << QList<QPoint>{{-2, 2}, {-5, 4}, {-7, 6}, {-10, 7}}; + QTest::newRow("touchpad: scale") << touchpadDevice << Qt::ZoomNativeGesture << 0.1 + << QList<QPoint>{{3, 3}, {5, 5}, {8, 8}, {12, 12}}; + if (mouse->type() == QInputDevice::DeviceType::Mouse) { + QTest::newRow("mouse: rotate") << mouse << Qt::RotateNativeGesture << 5.0 + << QList<QPoint>{{-2, 2}, {-5, 4}, {-7, 6}, {-10, 7}}; + QTest::newRow("mouse: scale") << mouse << Qt::ZoomNativeGesture << 0.1 + << QList<QPoint>{{3, 3}, {5, 5}, {8, 8}, {12, 12}}; + } else { + qCWarning(lcPointerTests) << "skipping mouse tests: primary device is not a mouse" << mouse; + } +} + +void tst_QQuickPinchHandler::cumulativeNativeGestures() +{ + QFETCH(const QPointingDevice*, device); + QFETCH(Qt::NativeGestureType, gesture); + QFETCH(qreal, value); + QFETCH(QList<QPoint>, expectedTargetTranslations); + + QCOMPARE(expectedTargetTranslations.size(), 4); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("pinchproperties.qml"))); + QVERIFY(window.rootObject() != nullptr); + qApp->processEvents(); + + QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject()); + QVERIFY(root != nullptr); + QQuickPinchHandler *pinchHandler = root->findChild<QQuickPinchHandler*>("pinchHandler"); + QVERIFY(pinchHandler != nullptr); + QQuickItem *target = root->findChild<QQuickItem*>("blackrect"); + QVERIFY(target != nullptr); + QCOMPARE(pinchHandler->target(), target); + + ulong ts = 1; + qreal expectedScale = 1; + qreal expectedRotation = 0; + QPointF pinchPos(75, 75); + const QPointF initialTargetPos(target->position()); + QWindowSystemInterface::handleGestureEvent(&window, ts++, device, + Qt::BeginNativeGesture, pinchPos, pinchPos); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + for (int i = 1; i <= 4; ++i) { + QWindowSystemInterface::handleGestureEventWithRealValue(&window, ts++, device, + gesture, value, pinchPos, pinchPos); + qApp->processEvents(); + switch (gesture) { + case Qt::ZoomNativeGesture: + expectedScale = qBound(qreal(0.5), qPow(1 + value, i), qreal(4)); + break; + case Qt::RotateNativeGesture: + expectedRotation = qBound(qreal(0), value * i, qreal(90)); + break; + default: + break; // PinchHandler doesn't react to the others + } + + qCDebug(lcPointerTests) << i << gesture << "with value" << value + << ": scale" << target->scale() << "expected" << expectedScale + << ": rotation" << target->rotation() << "expected" << expectedRotation; + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QCOMPARE(target->scale(), expectedScale); + QCOMPARE(target->rotation(), expectedRotation); + QCOMPARE(pinchHandler->persistentScale(), expectedScale); + QCOMPARE(pinchHandler->activeScale(), expectedScale); + QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), expectedScale); + QCOMPARE(pinchHandler->scaleAxis()->activeValue(), expectedScale); + QCOMPARE(pinchHandler->persistentRotation(), expectedRotation); + QCOMPARE(pinchHandler->activeRotation(), expectedRotation); + QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), expectedRotation); + QCOMPARE(pinchHandler->rotationAxis()->activeValue(), expectedRotation); + // The target gets transformed around the gesture position, for which + // QQuickItemPrivate::adjustedPosForTransform() computes its new position to compensate. + QPointF delta = target->position() - initialTargetPos; + qCDebug(lcPointerTests) << "target moved by" << delta << "to" << target->position() + << "active trans" << pinchHandler->activeTranslation() + << "perst trans" << pinchHandler->persistentTranslation(); + QCOMPARE_NE(target->position(), initialTargetPos); + QCOMPARE(delta.toPoint(), expectedTargetTranslations.at(i - 1)); + // The native pinch gesture cannot include a translation component (and + // the cursor doesn't move while you are performing the gesture on a touchpad). + QCOMPARE(pinchHandler->activeTranslation(), QPointF()); + // The target only moves to compensate for scale and rotation changes, and that's + // not reflected in PinchHandler.persistentTranslation. + QCOMPARE(pinchHandler->persistentTranslation(), QPointF()); + } + QCOMPARE(pinchHandler->active(), true); + qCDebug(lcPointerTests) << "centroid: local" << pinchHandler->centroid().position() + << "scene" << pinchHandler->centroid().scenePosition(); + QCOMPARE(pinchHandler->persistentScale(), expectedScale); + QCOMPARE(pinchHandler->activeScale(), expectedScale); + QCOMPARE(pinchHandler->scaleAxis()->activeValue(), expectedScale); + QWindowSystemInterface::handleGestureEvent(&window, ts++, device, + Qt::EndNativeGesture, pinchPos, pinchPos); + QTRY_COMPARE(pinchHandler->active(), false); + QCOMPARE(target->scale(), expectedScale); + QCOMPARE(target->rotation(), expectedRotation); + QCOMPARE(pinchHandler->persistentScale(), expectedScale); + QCOMPARE(pinchHandler->activeScale(), 1); + QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), expectedScale); + QCOMPARE(pinchHandler->scaleAxis()->activeValue(), 1); + QCOMPARE(pinchHandler->persistentRotation(), expectedRotation); + QCOMPARE(pinchHandler->activeRotation(), 0); + QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), expectedRotation); + QCOMPARE(pinchHandler->rotationAxis()->activeValue(), 0); + QCOMPARE(pinchHandler->activeTranslation(), QPointF()); + QCOMPARE(pinchHandler->persistentTranslation(), QPointF()); +} + void tst_QQuickPinchHandler::pan() { QQuickView *window = QQuickViewTestUtils::createView(); @@ -575,7 +698,7 @@ void tst_QQuickPinchHandler::pan() QPoint p1(100, 100); { const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get()); pinchSequence.press(0, p0, window).commit(); QQuickTouchUtils::flush(window); // In order for the stationary point to remember its previous position, @@ -649,7 +772,7 @@ void tst_QQuickPinchHandler::pan() // pan x beyond bound p0 += QPoint(100,100); p1 += QPoint(100,100); - QTest::touchEvent(window, touchscreen).move(0, p0, window).move(1, p1, window); + QTest::touchEvent(window, touchscreen.get()).move(0, p0, window).move(1, p1, window); QQuickTouchUtils::flush(window); QCOMPARE(blackRect->x(), 140.0); @@ -657,7 +780,7 @@ void tst_QQuickPinchHandler::pan() QCOMPARE(translationChangedSpy.size(), 5); QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(100, 100)); - QTest::touchEvent(window, touchscreen).release(0, p0, window).release(1, p1, window); + QTest::touchEvent(window, touchscreen.get()).release(0, p0, window).release(1, p1, window); QQuickTouchUtils::flush(window); QVERIFY(!root->property("pinchActive").toBool()); } @@ -697,7 +820,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled() QPoint blackRectPos = blackRect->position().toPoint(); // press two points, one above the rectangle's center and one below - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get()); pinchSequence.press(0, p0, window).press(1, p1, window).commit(); QQuickTouchUtils::flush(window); @@ -734,7 +857,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled() QCOMPARE(blackRect->position().toPoint().x(), xEnabled ? 140 : blackRectPos.x()); // because of xAxis.maximum QCOMPARE(blackRect->position().toPoint().y(), yEnabled ? 170 : blackRectPos.y()); // because of yAxis.maximum - QTest::touchEvent(window, touchscreen).release(0, p0, window).release(1, p1, window); + QTest::touchEvent(window, touchscreen.get()).release(0, p0, window).release(1, p1, window); QQuickTouchUtils::flush(window); } @@ -763,7 +886,7 @@ void tst_QQuickPinchHandler::retouch() QPoint p0(80, 80); QPoint p1(100, 100); { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get()); pinchSequence.press(0, p0, window).commit(); QQuickTouchUtils::flush(window); // In order for the stationary point to remember its previous position, @@ -846,7 +969,7 @@ void tst_QQuickPinchHandler::cancel() QPoint p0(80, 80); QPoint p1(100, 100); { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get()); pinchSequence.press(0, p0, window).commit(); QQuickTouchUtils::flush(window); // In order for the stationary point to remember its previous position, @@ -876,7 +999,7 @@ void tst_QQuickPinchHandler::cancel() QSKIP("cancel is not supported atm"); - QTouchEvent cancelEvent(QEvent::TouchCancel, touchscreen); + QTouchEvent cancelEvent(QEvent::TouchCancel, touchscreen.get()); QCoreApplication::sendEvent(window, &cancelEvent); QQuickTouchUtils::flush(window); @@ -932,7 +1055,7 @@ void tst_QQuickPinchHandler::transformedpinchHandler() const int threshold = qApp->styleHints()->startDragDistance(); { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, touchscreen); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, touchscreen.get()); // start pinchHandler pinchSequence.press(0, p0, view).commit(); QQuickTouchUtils::flush(view); |