aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp')
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp165
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);