aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml33
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp51
-rw-r--r--tests/manual/pointer/pinchNullTarget.qml50
4 files changed, 133 insertions, 5 deletions
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 467bedd3bf..2c8272301f 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -203,8 +203,8 @@ void QQuickPinchHandler::onActiveChanged()
m_startRotation = t->rotation();
m_startPos = t->position();
} else {
- m_startScale = 1;
- m_startRotation = 0;
+ m_startScale = m_accumulatedScale;
+ m_startRotation = 0; // TODO m_accumulatedRotation (QTBUG-94168)
}
qCDebug(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
} else {
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml
new file mode 100644
index 0000000000..a348938aca
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml
@@ -0,0 +1,33 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick 2.15
+
+Item {
+ width: 320; height: 320
+ property alias pinchScale: pinch.scale
+
+ Rectangle {
+ objectName: "blackrect"
+ width: 200; height: 200
+ color: "black"
+ antialiasing: true
+ scale: pinch.scale
+ rotation: pinch.rotation
+ x: pinch.translation.x
+ y: pinch.translation.y
+
+ PinchHandler {
+ id: pinch
+ target: null
+ minimumScale: 0.5
+ maximumScale: 4
+ }
+
+ Text {
+ color: "cyan"
+ anchors.centerIn: parent
+ text: "scale " + pinch.scale.toFixed(2) + " activeScale " + pinch.activeScale.toFixed(2)
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
index 5ffc49f802..4104fea7e2 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
@@ -29,6 +29,7 @@ public:
private slots:
void cleanupTestCase();
void pinchProperties();
+ void scale_data();
void scale();
void scaleThreeFingers();
void scaleNativeGesture_data();
@@ -179,16 +180,26 @@ QEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i)
return touchPoint;
}
+void tst_QQuickPinchHandler::scale_data()
+{
+ QTest::addColumn<QUrl>("qmlfile");
+ QTest::addColumn<bool>("hasTarget");
+ QTest::newRow("targetModifying") << testFileUrl("pinchproperties.qml") << true;
+ QTest::newRow("nullTarget") << testFileUrl("nullTarget.qml") << false;
+}
+
void tst_QQuickPinchHandler::scale()
{
- QQuickView window;
- QVERIFY(QQuickTest::showView(window, testFileUrl("pinchproperties.qml")));
+ QFETCH(QUrl, qmlfile);
+ QFETCH(bool, hasTarget);
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, qmlfile));
QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject());
QVERIFY(root != nullptr);
auto *pinchHandler = static_cast<PinchHandler *>(root->findChild<QQuickPinchHandler*>());
QVERIFY(pinchHandler != nullptr);
- QQuickItem *blackRect = pinchHandler->target();
+ QQuickItem *blackRect = (hasTarget ? pinchHandler->target() : pinchHandler->parentItem());
QVERIFY(blackRect != nullptr);
QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
@@ -240,6 +251,40 @@ void tst_QQuickPinchHandler::scale()
QCOMPARE(pinchHandler->centroid().scenePosition(), expectedCentroid);
}
+ qreal lastScale = pinchHandler->scale();
+ pinchSequence.release(0, p0, &window).release(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ // scale property is persistent after release
+ QCOMPARE(pinchHandler->scale(), lastScale);
+
+ // pinch a second time: scale picks up where we left off
+ p0 = QPoint(80, 80);
+ p1 = QPoint(100, 100);
+ pinchSequence.press(0, p0, &window).press(1, p1, &window).commit();
+ // move one point until PinchHandler activates
+ for (int pi = 0; pi < 10 && !pinchHandler->active(); ++pi) {
+ p1 += pd;
+ pinchSequence.stationary(0).move(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ }
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(pinchHandler->active(), true);
+ QCOMPARE(pinchHandler->scale(), lastScale); // just activated, not scaling further yet
+ for (int i = 0; i < 2; ++i) {
+ lastScale = pinchHandler->scale();
+ p1 += pd;
+ pinchSequence.stationary(0).move(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE_GT(pinchHandler->scale(), lastScale);
+ line.setP2(p1);
+ qreal expectedActiveScale = line.length() / startLength;
+ QVERIFY(qFloatDistance(pinchHandler->activeScale(), expectedActiveScale) < 10);
+ QCOMPARE(pinchHandler->scale(), root->property("pinchScale").toReal());
+ QCOMPARE_NE(pinchHandler->scale(), pinchHandler->activeScale()); // not in sync anymore
+ }
+
// scale beyond maximumScale
p1 = QPoint(310, 310);
pinchSequence.stationary(0).move(1, p1, &window).commit();
diff --git a/tests/manual/pointer/pinchNullTarget.qml b/tests/manual/pointer/pinchNullTarget.qml
new file mode 100644
index 0000000000..79c6047991
--- /dev/null
+++ b/tests/manual/pointer/pinchNullTarget.qml
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick 2.15
+
+Rectangle {
+ width: 1024; height: 600
+ color: "#eee"
+
+ function getTransformationDetails(item, pinchhandler) {
+ return "\n\npinch.scale:" + pinchhandler.scale.toFixed(2)
+ + "\npinch.activeScale:" + pinchhandler.activeScale.toFixed(2)
+ + "\npinch.rotation:" + pinchhandler.rotation.toFixed(2)
+ + "\npinch.translation:" + "(" + pinchhandler.translation.x.toFixed(2) + "," + pinchhandler.translation.y.toFixed(2) + ")"
+ + "\nrect.scale: " + item.scale.toFixed(2)
+ + "\nrect.rotation: " + item.rotation.toFixed(2)
+ + "\nrect.position: " + "(" + item.x.toFixed(2) + "," + item.y.toFixed(2) + ")"
+ }
+
+ Rectangle {
+ width: parent.width - 100; height: parent.height - 100; x: 50; y: 50
+ color: "lightsteelblue"
+ antialiasing: true
+ scale: pinch.scale
+
+ PinchHandler {
+ id: pinch
+ target: null
+ minimumScale: 0.5
+ maximumScale: 3
+ }
+
+ Text {
+ text: "Pinch with 2 fingers to scale, rotate and translate"
+ + getTransformationDetails(parent, pinch)
+ }
+ }
+
+ Rectangle {
+ id: centroidIndicator
+ x: pinch.centroid.scenePosition.x - radius
+ y: pinch.centroid.scenePosition.y - radius
+ z: 1
+ visible: pinch.active
+ radius: width / 2
+ width: 10
+ height: width
+ color: "red"
+ }
+}