aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp67
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h2
-rw-r--r--tests/manual/pointer/pinchHandler.qml96
3 files changed, 93 insertions, 72 deletions
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 417a45318d..09e4f9f17c 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -202,11 +202,15 @@ void QQuickPinchHandler::onActiveChanged()
if (active()) {
m_startScale = m_scale; // TODO incompatible with independent x/y scaling
m_startRotation = m_rotation;
- m_startAngles = angles(touchPointCentroid());
+ m_startCentroid = touchPointCentroid();
+ m_startAngles = angles(m_startCentroid);
+ m_startDistance = averageTouchPointDistance(m_startCentroid);
m_activeRotation = 0;
m_startMatrix = m_transform.matrix();
qCInfo(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
grabPoints(m_currentPoints);
+ } else {
+ qCInfo(lcPinchHandler) << "deactivated with scale" << m_scale << "rotation" << m_rotation;
}
}
@@ -230,16 +234,19 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
}
// TODO check m_pinchOrigin: right now it acts like it's set to PinchCenter
- QPointF startCentroid = startingCentroid();
m_centroid = touchPointCentroid();
- m_centroid = QPointF(qBound(m_minimumX, m_centroid.x(), m_maximumX),
- qBound(m_minimumY, m_centroid.y(), m_maximumY));
-
-
+ QRectF bounds(m_minimumX, m_minimumY, m_maximumX, m_maximumY);
+ // avoid mapping the minima and maxima, as they might have unmappable values
+ // such as -inf/+inf. Because of this we perform the bounding to min/max in local coords.
+ QPointF centroidLocalPos;
+ if (target() && target()->parentItem()) {
+ centroidLocalPos = target()->parentItem()->mapFromScene(m_centroid);
+ centroidLocalPos = QPointF(qBound(bounds.left(), centroidLocalPos.x(), bounds.right()),
+ qBound(bounds.top(), centroidLocalPos.y(), bounds.bottom()));
+ }
// 1. scale
- qreal startDist = averageStartingDistance(startCentroid);
qreal dist = averageTouchPointDistance(m_centroid);
- qreal activeScale = dist / startDist;
+ qreal activeScale = dist / m_startDistance;
activeScale = qBound(m_minimumScale/m_startScale, activeScale, m_maximumScale/m_startScale);
m_scale = m_startScale * activeScale;
@@ -252,26 +259,30 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
m_activeRotation += (m_rotation - totalRotation); //adjust for the potential bounding above
m_startAngles = std::move(newAngles);
- // 3. Drag/translate
- QPointF activeTranslation(m_centroid - startCentroid);
-
- // apply rotation + scaling around the centroid - then apply translation.
- QMatrix4x4 mat;
- QVector3D xlatOrigin(m_centroid - target()->position());
- mat.translate(xlatOrigin);
- mat.rotate(m_activeRotation, 0, 0, -1);
- mat.scale(activeScale);
- mat.translate(-xlatOrigin);
- mat.translate(QVector3D(activeTranslation));
-
- // TODO some translation inadvertently happens; try to hold the chosen pinch origin in place
-
- qCDebug(lcPinchHandler) << "startCentroid" << startCentroid << "centroid" << m_centroid << "dist" << dist << "starting dist" << startDist
- << "startScale" << m_startScale << "activeRotation" << m_activeRotation
- << "scale" << m_scale << "rotation" << m_rotation;
-
- mat = mat * m_startMatrix;
- m_transform.setMatrix(mat);
+ if (target() && target()->parentItem()) {
+ // 3. Drag/translate
+ QPointF activeTranslation(centroidLocalPos - target()->parentItem()->mapFromScene(m_startCentroid));
+
+ // apply rotation + scaling around the centroid - then apply translation.
+ QMatrix4x4 mat;
+ QVector3D xlatOrigin(centroidLocalPos - target()->position());
+ mat.translate(xlatOrigin);
+ mat.rotate(m_activeRotation, 0, 0, -1);
+ mat.scale(activeScale);
+ mat.translate(-xlatOrigin);
+ mat.translate(QVector3D(activeTranslation));
+
+ // TODO some translation inadvertently happens; try to hold the chosen pinch origin in place
+
+ qCDebug(lcPinchHandler) << "centroid" << m_startCentroid << "->" << m_centroid
+ << ", distance" << m_startDistance << "->" << dist
+ << ", startScale" << m_startScale << "->" << m_scale
+ << ", activeRotation" << m_activeRotation
+ << ", rotation" << m_rotation;
+
+ mat = mat * m_startMatrix;
+ m_transform.setMatrix(mat);
+ }
emit updated();
}
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
index 338b930373..5107a5c50b 100644
--- a/src/quick/handlers/qquickpinchhandler_p.h
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -155,6 +155,8 @@ private:
qreal m_startScale;
qreal m_startRotation;
qreal m_activeRotation;
+ QPointF m_startCentroid;
+ qreal m_startDistance;
QVector<PointData> m_startAngles;
QMatrix4x4 m_startMatrix;
diff --git a/tests/manual/pointer/pinchHandler.qml b/tests/manual/pointer/pinchHandler.qml
index d163343a3e..3ab196a10a 100644
--- a/tests/manual/pointer/pinchHandler.qml
+++ b/tests/manual/pointer/pinchHandler.qml
@@ -42,60 +42,68 @@ import QtQuick 2.8
import Qt.labs.handlers 1.0
Rectangle {
- id: root
width: 1024; height: 600
- color: "black"
-
+ color: "#eee"
Rectangle {
- width: 400
- height: 300
- color: "lightsteelblue"
- antialiasing: true
+ id: root
+ color: "black"
+ width: 900
+ height: 600
+ x: 100
- Text {
- anchors.centerIn: parent
- text: "Pinch with 2 fingers to scale, rotate and translate"
- + "\ncurrent rotation: " + pinch2.rotation.toFixed(1)
- + "\nscale: " + pinch2.scale.toFixed(1)
- + "\ntranslation: " + pinch2.translation
- }
+ Rectangle {
+ width: 400
+ height: 300
+ color: "lightsteelblue"
+ antialiasing: true
- PinchHandler {
- id: pinch2
- objectName: "2-finger pinch"
- minimumRotation: -45
- maximumRotation: 45
- minimumScale: 0.5
- maximumScale: 3
- minimumX: 0
- maximumX: 600
- pointDistanceThreshold: 150
+ Text {
+ anchors.centerIn: parent
+ text: "Pinch with 2 fingers to scale, rotate and translate"
+ + "\ncurrent rotation: " + pinch2.rotation.toFixed(1)
+ + "\nscale: " + pinch2.scale.toFixed(1)
+ + "\ntranslation: " + pinch2.translation
+ }
+
+ PinchHandler {
+ id: pinch2
+ objectName: "2-finger pinch"
+ minimumRotation: -45
+ maximumRotation: 45
+ minimumScale: 0.5
+ maximumScale: 3
+ minimumX: 0
+ maximumX: 600
+ pointDistanceThreshold: 150
+ }
}
- }
- Rectangle {
- x: 512
- width: 400
- height: 300
- color: "wheat"
- antialiasing: true
+ Rectangle {
+ x: 500
+ width: 400
+ height: 300
+ color: "wheat"
+ antialiasing: true
- Text {
- anchors.centerIn: parent
- text: "Pinch with 3 fingers to scale, rotate and translate\nDrag with 1 finger"
- + "\ncurrent rotation " + pinch3.rotation.toFixed(1)
- }
- DragHandler { objectName: "DragHandler" }
+ Text {
+ anchors.centerIn: parent
+ text: "Pinch with 3 fingers to scale, rotate and translate\nDrag with 1 finger"
+ + "\ncurrent rotation " + pinch3.rotation.toFixed(1)
+ + "\nscale: " + pinch3.scale.toFixed(1)
+ + "\ntranslation: " + pinch3.translation
+ }
+ DragHandler { objectName: "DragHandler" }
- PinchHandler {
- id: pinch3
- objectName: "3-finger pinch"
- requiredPointCount: 3
- minimumScale: 0.1
- maximumScale: 10
+ PinchHandler {
+ id: pinch3
+ objectName: "3-finger pinch"
+ requiredPointCount: 3
+ minimumScale: 0.1
+ maximumScale: 10
+ }
}
- }
+ }
Rectangle {
id: centroidIndicator
property QtObject pincher: pinch2.active ? pinch2 : pinch3