aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp43
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h13
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp9
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp82
-rw-r--r--tests/manual/pointer/content/LeftDrawer.qml4
-rw-r--r--tests/manual/pointer/map.qml13
-rw-r--r--tests/manual/pointer/map2.qml9
7 files changed, 136 insertions, 37 deletions
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 809adfd043..233516c3a3 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -165,6 +165,7 @@ void QQuickDragHandler::onActiveChanged()
// mouse grab too, whenever dragging occurs in an enabled direction
parent->setKeepMouseGrab(true);
}
+ m_startTranslation = m_persistentTranslation;
} else {
m_pressTargetPos = QPointF();
m_pressedInsideTarget = false;
@@ -210,7 +211,7 @@ void QQuickDragHandler::handlePointerEventImpl(QPointerEvent *event)
accumulatedDragDelta.setX(0);
if (!m_yAxis.enabled())
accumulatedDragDelta.setY(0);
- setTranslation(accumulatedDragDelta);
+ setActiveTranslation(accumulatedDragDelta);
} else {
// Check that all points have been dragged past the drag threshold,
// to the extent that the constraints allow,
@@ -316,11 +317,24 @@ void QQuickDragHandler::enforceAxisConstraints(QPointF *localPos)
localPos->setY(qBound(m_yAxis.minimum(), localPos->y(), m_yAxis.maximum()));
}
-void QQuickDragHandler::setTranslation(const QVector2D &trans)
+void QQuickDragHandler::setPersistentTranslation(const QVector2D &trans)
{
- if (trans == m_translation) // fuzzy compare?
+ if (trans == m_persistentTranslation)
return;
- m_translation = trans;
+
+ m_persistentTranslation = trans;
+ emit translationChanged();
+}
+
+void QQuickDragHandler::setActiveTranslation(const QVector2D &trans)
+{
+ if (trans == m_activeTranslation)
+ return;
+
+ m_activeTranslation = trans;
+ m_persistentTranslation = m_startTranslation + trans;
+ qCDebug(lcDragHandler) << "translation: start" << m_startTranslation
+ << "active" << m_activeTranslation << "accumulated" << m_persistentTranslation;
emit translationChanged();
}
@@ -357,8 +371,27 @@ void QQuickDragHandler::setTranslation(const QVector2D &trans)
/*!
\readonly
\qmlproperty QVector2D QtQuick::DragHandler::translation
+ \deprecated Use activeTranslation
+*/
+
+/*!
+ \qmlproperty QVector2D QtQuick::DragHandler::persistentTranslation
+
+ The translation to be applied to the \l target if it is not \c null.
+ Otherwise, bindings can be used to do arbitrary things with this value.
+ While the drag gesture is being performed, \l activeTranslation is
+ continuously added to it; after the gesture ends, it stays the same.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::DragHandler::activeTranslation
- The translation since the gesture began.
+ The translation while the drag gesture is being performed.
+ It is \c {0, 0} when the gesture begins, and increases as the event
+ point(s) are dragged downward and to the right. After the gesture ends, it
+ stays the same; and when the next drag gesture begins, it is reset to
+ \c {0, 0} again.
*/
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index a0dce10314..a42281819c 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -62,6 +62,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
+ Q_PROPERTY(QVector2D activeTranslation READ activeTranslation NOTIFY translationChanged REVISION(6, 2))
+ Q_PROPERTY(QVector2D persistentTranslation READ persistentTranslation WRITE setPersistentTranslation NOTIFY translationChanged REVISION(6, 2))
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION(2, 14))
QML_NAMED_ELEMENT(DragHandler)
QML_ADDED_IN_VERSION(2, 12)
@@ -82,8 +84,11 @@ public:
QQuickDragAxis *xAxis() { return &m_xAxis; }
QQuickDragAxis *yAxis() { return &m_yAxis; }
- QVector2D translation() const { return m_translation; }
- void setTranslation(const QVector2D &trans);
+ QVector2D translation() const { return m_activeTranslation; }
+ QVector2D activeTranslation() const { return m_activeTranslation; }
+ void setActiveTranslation(const QVector2D &trans);
+ QVector2D persistentTranslation() const { return m_persistentTranslation; }
+ void setPersistentTranslation(const QVector2D &trans);
QQuickDragHandler::SnapMode snapMode() const;
void setSnapMode(QQuickDragHandler::SnapMode mode);
@@ -107,7 +112,9 @@ private:
QPointF m_pressTargetPos; // We must also store the local targetPos, because we cannot deduce
// the press target pos from the scene pos in case there was e.g a
// flick in one of the ancestors during the drag.
- QVector2D m_translation;
+ QVector2D m_activeTranslation;
+ QVector2D m_persistentTranslation;
+ QVector2D m_startTranslation;
QQuickDragAxis m_xAxis;
QQuickDragAxis m_yAxis;
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index 54951b82b3..c3149983c0 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -100,17 +100,14 @@ void QQuickHandlerPoint::reset()
void QQuickHandlerPoint::reset(const QPointerEvent *event, const QEventPoint &point)
{
+ const bool isTouch = QQuickDeliveryAgentPrivate::isTouchEvent(event);
m_id = point.id();
m_device = event->pointingDevice();
- switch (point.state()) {
- case QEventPoint::Pressed:
+ const auto state = (isTouch ? static_cast<const QTouchEvent *>(event)->touchPointStates() : point.state());
+ if (state.testFlag(QEventPoint::Pressed)) {
m_pressPosition = point.position();
m_scenePressPosition = point.scenePosition();
- break;
- default:
- break;
}
- const bool isTouch = QQuickDeliveryAgentPrivate::isTouchEvent(event);
if (!isTouch)
m_pressedButtons = static_cast<const QSinglePointEvent *>(event)->buttons();
m_pressedModifiers = event->modifiers();
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index b6c86a7d88..059f06f469 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -127,7 +127,8 @@ void tst_DragHandler::defaultPropertyValues()
QVERIFY(dragHandler);
QCOMPARE(dragHandler->acceptedButtons(), Qt::LeftButton);
- QCOMPARE(dragHandler->translation(), QVector2D());
+ QCOMPARE(dragHandler->persistentTranslation(), QVector2D());
+ QCOMPARE(dragHandler->activeTranslation(), QVector2D());
QCOMPARE(dragHandler->centroid().position(), QPointF());
QCOMPARE(dragHandler->centroid().scenePosition(), QPointF());
QCOMPARE(dragHandler->centroid().pressPosition(), QPointF());
@@ -191,7 +192,8 @@ void tst_DragHandler::touchDrag()
QTRY_VERIFY(dragHandler->active());
QCOMPARE(translationChangedSpy.count(), 0);
QCOMPARE(centroidChangedSpy.count(), 3);
- QCOMPARE(dragHandler->translation().x(), 0.0);
+ QCOMPARE(dragHandler->persistentTranslation().x(), 0);
+ QCOMPARE(dragHandler->activeTranslation().x(), 0);
QPointF sceneGrabPos = p1;
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
p1 += QPoint(19, 0);
@@ -203,8 +205,10 @@ void tst_DragHandler::touchDrag()
QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter));
QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
- QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
- QCOMPARE(dragHandler->translation().y(), 0.0);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold + 20);
+ QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + 20);
+ QCOMPARE(dragHandler->persistentTranslation().y(), 0);
+ QCOMPARE(dragHandler->activeTranslation().y(), 0);
QVERIFY(dragHandler->centroid().velocity().x() > 0);
QCOMPARE(centroidChangedSpy.count(), 4);
QTest::touchEvent(window, touchDevice).release(1, p1, window);
@@ -215,6 +219,55 @@ void tst_DragHandler::touchDrag()
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
QCOMPARE(translationChangedSpy.count(), 1);
QCOMPARE(centroidChangedSpy.count(), 5);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold + 20);
+
+ // Drag again: activeTranslation starts over, while persistentTranslation accumulates
+ p1 = ball->mapToScene(ballCenter).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold + 20);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler->active());
+ p1 += QPoint(9, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + 20);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold * 2 + 40);
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+
+ // Call setPersistentTranslation and drag yet again:
+ // activeTranslation starts over, while persistentTranslation adds the drags onto the new basis
+ dragHandler->setPersistentTranslation({10, 10});
+ p1 = ball->mapToScene(ballCenter).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(dragHandler->persistentTranslation().x(), 10);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler->active());
+ p1 += QPoint(9, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + 20);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold + 30);
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
}
void tst_DragHandler::mouseDrag_data()
@@ -282,7 +335,8 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(translationChangedSpy.count(), 0);
if (shouldDrag)
QCOMPARE(centroidChangedSpy.count(), 3);
- QCOMPARE(dragHandler->translation().x(), 0.0);
+ QCOMPARE(dragHandler->persistentTranslation().x(), 0.0);
+ QCOMPARE(dragHandler->activeTranslation().x(), 0.0);
QPointF sceneGrabPos = p1;
if (shouldDrag)
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
@@ -295,8 +349,10 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter));
QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
- QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
- QCOMPARE(dragHandler->translation().y(), 0.0);
+ QCOMPARE(dragHandler->persistentTranslation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->persistentTranslation().y(), 0.0);
+ QCOMPARE(dragHandler->activeTranslation().y(), 0.0);
// QVERIFY(dragHandler->centroid().velocity().x() > 0); // TODO QTBUG-33891
QCOMPARE(centroidChangedSpy.count(), 4);
#if QT_CONFIG(cursor)
@@ -537,16 +593,18 @@ void tst_DragHandler::touchDragMulti()
QPoint p2 = scenePressPos2.toPoint();
QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
- touchSeq.press(1, p1, window).press(2, p2, window).commit();
+ touchSeq.press(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ touchSeq.stationary(1).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
- QCOMPARE(centroidChangedSpy1.count(), 1);
+ QCOMPARE(centroidChangedSpy1.count(), 2);
QCOMPARE(dragHandler1->centroid().position(), ball1Center);
QCOMPARE(dragHandler1->centroid().pressPosition(), ball1Center);
QCOMPARE(dragHandler1->centroid().scenePosition(), scenePressPos1);
QCOMPARE(dragHandler1->centroid().scenePressPosition(), scenePressPos1);
QVERIFY(!dragHandler2->active());
- QCOMPARE(centroidChangedSpy2.count(), 1);
+ QCOMPARE(centroidChangedSpy2.count(), 2);
QCOMPARE(dragHandler2->centroid().position(), ball2Center);
QCOMPARE(dragHandler2->centroid().pressPosition(), ball2Center);
QCOMPARE(dragHandler2->centroid().scenePosition(), scenePressPos2);
@@ -556,13 +614,13 @@ void tst_DragHandler::touchDragMulti()
touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
- QCOMPARE(centroidChangedSpy1.count(), 2);
+ QCOMPARE(centroidChangedSpy1.count(), 3);
QCOMPARE(dragHandler1->centroid().position(), ball1Center + QPointF(dragThreshold, 0));
QCOMPARE(dragHandler1->centroid().pressPosition(), ball1Center);
QCOMPARE(dragHandler1->centroid().scenePosition().toPoint(), p1);
QCOMPARE(dragHandler1->centroid().scenePressPosition(), scenePressPos1);
QVERIFY(!dragHandler2->active());
- QCOMPARE(centroidChangedSpy2.count(), 2);
+ QCOMPARE(centroidChangedSpy2.count(), 3);
QCOMPARE(dragHandler2->centroid().position(), ball2Center + QPointF(0, dragThreshold));
QCOMPARE(dragHandler2->centroid().pressPosition(), ball2Center);
QCOMPARE(dragHandler2->centroid().scenePosition().toPoint(), p2);
diff --git a/tests/manual/pointer/content/LeftDrawer.qml b/tests/manual/pointer/content/LeftDrawer.qml
index 08f2f67b5c..6e93fd4933 100644
--- a/tests/manual/pointer/content/LeftDrawer.qml
+++ b/tests/manual/pointer/content/LeftDrawer.qml
@@ -58,9 +58,9 @@ Item {
if (!active) {
if (xbr.returnToBounds())
return;
- if (translation.x > 0)
+ if (activeTranslation.x > 0)
open()
- if (translation.x < 0)
+ if (activeTranslation.x < 0)
close()
}
}
diff --git a/tests/manual/pointer/map.qml b/tests/manual/pointer/map.qml
index 0e815ccd9c..a45443f562 100644
--- a/tests/manual/pointer/map.qml
+++ b/tests/manual/pointer/map.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -26,7 +26,7 @@
**
****************************************************************************/
-import QtQuick 2.14
+import QtQuick
Item {
width: 640
@@ -39,7 +39,13 @@ Item {
y: (parent.height - height) / 2
width: image.width
height: image.height
- transform: Rotation { id: tilt; origin.x: width / 2; origin.y: height / 2; axis { x: 1; y: 0; z: 0 } }
+ transform: Rotation {
+ id: tilt
+ origin.x: width / 2
+ origin.y: height / 2
+ axis { x: 1; y: 0; z: 0 }
+ angle: tiltHandler.persistentTranslation.y / -2
+ }
WheelHandler {
id: wheelHandler
@@ -82,7 +88,6 @@ Item {
maximumPointCount: 2
xAxis.enabled: false
target: null
- onTranslationChanged: tilt.angle = translation.y / -2
}
PinchHandler {
diff --git a/tests/manual/pointer/map2.qml b/tests/manual/pointer/map2.qml
index 0f45013e92..1df17ffafb 100644
--- a/tests/manual/pointer/map2.qml
+++ b/tests/manual/pointer/map2.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -26,7 +26,7 @@
**
****************************************************************************/
-import QtQuick 2.12
+import QtQuick
Item {
width: 640
@@ -70,9 +70,8 @@ Item {
startDrag = map.center
}
- onTranslationChanged: {
- if (!target)
- map.setCenter(startDrag.x + translation.x, startDrag.y + translation.y)
+ onActiveTranslationChanged: {
+ map.setCenter(startDrag.x + activeTranslation.x, startDrag.y + activeTranslation.y)
}
}
}