diff options
-rw-r--r-- | src/quick/handlers/qquickdraghandler.cpp | 43 | ||||
-rw-r--r-- | src/quick/handlers/qquickdraghandler_p.h | 13 | ||||
-rw-r--r-- | src/quick/handlers/qquickhandlerpoint.cpp | 9 | ||||
-rw-r--r-- | tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp | 82 | ||||
-rw-r--r-- | tests/manual/pointer/content/LeftDrawer.qml | 4 | ||||
-rw-r--r-- | tests/manual/pointer/map.qml | 13 | ||||
-rw-r--r-- | tests/manual/pointer/map2.qml | 9 |
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) } } } |