aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2018-06-11 07:38:46 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2018-07-19 10:56:06 +0000
commitca7cdd71ee33f0d77eb6bf1367d2532e26155cb2 (patch)
treeaf1b30bffea87bedb23e8cd795f23692f29b50a9
parentd310ca768bb5f45bae4fcec9a5d8151b6a366b8d (diff)
Make DragHandler a MultiPointHandler
That is, minimumPointCount can now be set to a value > 1 to require multiple fingers to do the dragging, or to track the displacement of multiple fingers to adjust some value (such as the tilt of a map). Task-number: QTBUG-68106 Change-Id: Ib35823e36deb81c8b277d3070fcc758c7c019564 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp190
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h14
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp30
-rw-r--r--src/quick/handlers/qquickmultipointhandler_p.h4
-rw-r--r--src/quick/items/qquickwindow.cpp12
-rw-r--r--src/quick/items/qquickwindow_p.h1
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp2
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp71
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml7
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp120
-rw-r--r--tests/manual/pointer/content/FakeFlickable.qml2
-rw-r--r--tests/manual/pointer/flingAnimation.qml6
-rw-r--r--tests/manual/pointer/map.qml14
-rw-r--r--tests/manual/pointer/singlePointHandlerProperties.qml43
14 files changed, 318 insertions, 198 deletions
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 8bb8612fb3..707b247f72 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -43,6 +43,10 @@
QT_BEGIN_NAMESPACE
+static const qreal DragAngleToleranceDegrees = 10;
+
+Q_LOGGING_CATEGORY(lcDragHandler, "qt.quick.handler.drag")
+
/*!
\qmltype DragHandler
\instantiates QQuickDragHandler
@@ -71,13 +75,21 @@ QT_BEGIN_NAMESPACE
\snippet pointerHandlers/dragHandlerNullTarget.qml 0
+ If minimumPointCount and maximumPointCount are set to values larger than 1,
+ the user will need to drag that many fingers in the same direction to start
+ dragging. A multi-finger drag gesture can be detected independently of both
+ a (default) single-finger DragHandler and a PinchHandler on the same Item,
+ and thus can be used to adjust some other feature independently of the
+ usual pinch behavior: for example adjust a tilt transformation, or adjust
+ some other numeric value.
+
At this time, drag-and-drop is not yet supported.
\sa Drag, MouseArea
*/
QQuickDragHandler::QQuickDragHandler(QObject *parent)
- : QQuickSinglePointHandler(parent)
+ : QQuickMultiPointHandler(parent, 1, 1)
{
}
@@ -85,22 +97,15 @@ QQuickDragHandler::~QQuickDragHandler()
{
}
-bool QQuickDragHandler::wantsEventPoint(QQuickEventPoint *point)
-{
- // If we've already been interested in a point, stay interested, even if it has strayed outside bounds.
- return ((point->state() != QQuickEventPoint::Pressed && this->point().id() == point->pointId())
- || QQuickSinglePointHandler::wantsEventPoint(point));
-}
-
-bool QQuickDragHandler::targetContains(QQuickEventPoint *point)
+bool QQuickDragHandler::targetContainsCentroid()
{
Q_ASSERT(parentItem() && target());
- return target()->contains(localTargetPosition(point));
+ return target()->contains(targetCentroidPosition());
}
-QPointF QQuickDragHandler::localTargetPosition(QQuickEventPoint *point)
+QPointF QQuickDragHandler::targetCentroidPosition()
{
- QPointF pos = point->position();
+ QPointF pos = m_centroid.position();
if (target() != parentItem())
pos = parentItem()->mapToItem(target(), pos);
return pos;
@@ -108,82 +113,137 @@ QPointF QQuickDragHandler::localTargetPosition(QQuickEventPoint *point)
void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
{
+ QQuickMultiPointHandler::onGrabChanged(grabber, stateChange, point);
if (grabber == this && stateChange == QQuickEventPoint::GrabExclusive) {
// In case the grab got handed over from another grabber, we might not get the Press.
if (!m_pressedInsideTarget) {
if (target())
m_pressTargetPos = QPointF(target()->width(), target()->height()) / 2;
- m_pressScenePos = point->scenePosition();
} else if (m_pressTargetPos.isNull()) {
if (target())
- m_pressTargetPos = localTargetPosition(point);
- m_pressScenePos = point->scenePosition();
+ m_pressTargetPos = targetCentroidPosition();
}
}
- QQuickSinglePointHandler::onGrabChanged(grabber, stateChange, point);
}
void QQuickDragHandler::onActiveChanged()
{
- if (!active()) {
+ QQuickMultiPointHandler::onActiveChanged();
+ if (active()) {
+ if (auto parent = parentItem()) {
+ if (currentEvent()->asPointerTouchEvent())
+ parent->setKeepTouchGrab(true);
+ // tablet and mouse are treated the same by Item's legacy event handling, and
+ // touch becomes synth-mouse for Flickable, so we need to prevent stealing
+ // mouse grab too, whenever dragging occurs in an enabled direction
+ parent->setKeepMouseGrab(true);
+ }
+ } else {
m_pressTargetPos = QPointF();
- m_pressScenePos = m_pressTargetPos;
m_pressedInsideTarget = false;
+ if (auto parent = parentItem()) {
+ parent->setKeepTouchGrab(false);
+ parent->setKeepMouseGrab(false);
+ }
}
}
-void QQuickDragHandler::handleEventPoint(QQuickEventPoint *point)
+void QQuickDragHandler::handlePointerEventImpl(QQuickPointerEvent *event)
{
- point->setAccepted();
- switch (point->state()) {
- case QQuickEventPoint::Pressed:
- if (target()) {
- m_pressedInsideTarget = targetContains(point);
- m_pressTargetPos = localTargetPosition(point);
- }
- m_pressScenePos = point->scenePosition();
- setPassiveGrab(point);
- break;
- case QQuickEventPoint::Updated: {
- QVector2D accumulatedDragDelta = QVector2D(point->scenePosition() - m_pressScenePos);
- if (active()) {
- // update translation property. Make sure axis is respected for it.
- if (!m_xAxis.enabled())
+ QQuickMultiPointHandler::handlePointerEventImpl(event);
+ event->setAccepted(true);
+
+ if (active()) {
+ // Calculate drag delta, taking into account the axis enabled constraint
+ // i.e. if xAxis is not enabled, then ignore the horizontal component of the actual movement
+ QVector2D accumulatedDragDelta = QVector2D(m_centroid.scenePosition() - m_centroid.scenePressPosition());
+ if (!m_xAxis.enabled())
+ accumulatedDragDelta.setX(0);
+ if (!m_yAxis.enabled())
+ accumulatedDragDelta.setY(0);
+ setTranslation(accumulatedDragDelta);
+ } else {
+ // Check that all points have been dragged past the drag threshold,
+ // to the extent that the constraints allow,
+ // and in approximately the same direction
+ qreal minAngle = 361;
+ qreal maxAngle = -361;
+ bool allOverThreshold = !event->isReleaseEvent();
+ QVector <QQuickEventPoint *> chosenPoints;
+
+ if (event->isPressEvent())
+ m_pressedInsideTarget = target() && m_currentPoints.count() > 0;
+
+ for (const QQuickHandlerPoint &p : m_currentPoints) {
+ if (!allOverThreshold)
+ break;
+ QQuickEventPoint *point = event->pointById(p.id());
+ chosenPoints << point;
+ setPassiveGrab(point);
+ // Calculate drag delta, taking into account the axis enabled constraint
+ // i.e. if xAxis is not enabled, then ignore the horizontal component of the actual movement
+ QVector2D accumulatedDragDelta = QVector2D(point->scenePosition() - point->scenePressPosition());
+ if (!m_xAxis.enabled()) {
+ // If horizontal dragging is disallowed, but the user is dragging
+ // mostly horizontally, then don't activate.
+ if (qAbs(accumulatedDragDelta.x()) > qAbs(accumulatedDragDelta.y()))
+ accumulatedDragDelta.setY(0);
accumulatedDragDelta.setX(0);
- if (!m_yAxis.enabled())
+ }
+ if (!m_yAxis.enabled()) {
+ // If vertical dragging is disallowed, but the user is dragging
+ // mostly vertically, then don't activate.
+ if (qAbs(accumulatedDragDelta.y()) > qAbs(accumulatedDragDelta.x()))
+ accumulatedDragDelta.setX(0);
accumulatedDragDelta.setY(0);
- setTranslation(accumulatedDragDelta);
-
- if (target() && target()->parentItem()) {
- const QPointF newTargetTopLeft = localTargetPosition(point) - m_pressTargetPos;
- const QPointF xformOrigin = target()->transformOriginPoint();
- const QPointF targetXformOrigin = newTargetTopLeft + xformOrigin;
- QPointF pos = target()->parentItem()->mapFromItem(target(), targetXformOrigin);
- pos -= xformOrigin;
- QPointF targetItemPos = target()->position();
- if (!m_xAxis.enabled())
- pos.setX(targetItemPos.x());
- if (!m_yAxis.enabled())
- pos.setY(targetItemPos.y());
- enforceAxisConstraints(&pos);
- moveTarget(pos, point);
}
- } else if (!point->exclusiveGrabber() &&
- ((m_xAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta.x(), Qt::XAxis, point)) ||
- (m_yAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta.y(), Qt::YAxis, point)))) {
- setExclusiveGrab(point);
- if (auto parent = parentItem()) {
- if (point->pointerEvent()->asPointerTouchEvent())
- parent->setKeepTouchGrab(true);
- // tablet and mouse are treated the same by Item's legacy event handling, and
- // touch becomes synth-mouse for Flickable, so we need to prevent stealing
- // mouse grab too, whenever dragging occurs in an enabled direction
- parent->setKeepMouseGrab(true);
+ qreal angle = std::atan2(accumulatedDragDelta.y(), accumulatedDragDelta.x()) * 180 / M_PI;
+ bool overThreshold = QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta);
+ qCDebug(lcDragHandler) << "movement" << accumulatedDragDelta << "angle" << angle << "of point" << point
+ << "pressed @" << point->scenePressPosition() << "over threshold?" << overThreshold;
+ minAngle = qMin(angle, minAngle);
+ maxAngle = qMax(angle, maxAngle);
+ if (allOverThreshold && !overThreshold)
+ allOverThreshold = false;
+
+ if (event->isPressEvent()) {
+ // m_pressedInsideTarget should stay true iff ALL points in which DragHandler is interested
+ // have been pressed inside the target() Item. (E.g. in a Slider the parent might be the
+ // whole control while the target is just the knob.)
+ if (target()) {
+ const QPointF localPressPos = target()->mapFromScene(point->scenePressPosition());
+ m_pressedInsideTarget &= target()->contains(localPressPos);
+ m_pressTargetPos = targetCentroidPosition();
+ }
+ // QQuickWindowPrivate::deliverToPassiveGrabbers() skips subsequent delivery if the event is filtered.
+ // (That affects behavior for mouse but not for touch, because Flickable only handles mouse.)
+ // So we have to compensate by accepting the event here to avoid any parent Flickable from
+ // getting the event via direct delivery and grabbing too soon.
+ point->setAccepted(event->asPointerMouseEvent()); // stop propagation iff it's a mouse event
}
}
- } break;
- default:
- break;
+ if (allOverThreshold) {
+ qreal angleDiff = maxAngle - minAngle;
+ if (angleDiff > 180)
+ angleDiff = 360 - angleDiff;
+ qCDebug(lcDragHandler) << "angle min" << minAngle << "max" << maxAngle << "range" << angleDiff;
+ if (angleDiff < DragAngleToleranceDegrees && grabPoints(chosenPoints))
+ setActive(true);
+ }
+ }
+ if (active() && target() && target()->parentItem()) {
+ const QPointF newTargetTopLeft = targetCentroidPosition() - m_pressTargetPos;
+ const QPointF xformOrigin = target()->transformOriginPoint();
+ const QPointF targetXformOrigin = newTargetTopLeft + xformOrigin;
+ QPointF pos = target()->parentItem()->mapFromItem(target(), targetXformOrigin);
+ pos -= xformOrigin;
+ QPointF targetItemPos = target()->position();
+ if (!m_xAxis.enabled())
+ pos.setX(targetItemPos.x());
+ if (!m_yAxis.enabled())
+ pos.setY(targetItemPos.y());
+ enforceAxisConstraints(&pos);
+ moveTarget(pos);
}
}
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index 7ba1021924..ea49d59902 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -51,12 +51,12 @@
// We mean it.
//
-#include "qquicksinglepointhandler_p.h"
+#include "qquickmultipointhandler_p.h"
#include "qquickdragaxis_p.h"
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QQuickDragHandler : public QQuickSinglePointHandler
+class Q_AUTOTEST_EXPORT QQuickDragHandler : public QQuickMultiPointHandler
{
Q_OBJECT
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
@@ -67,7 +67,7 @@ public:
explicit QQuickDragHandler(QObject *parent = nullptr);
~QQuickDragHandler();
- void handleEventPoint(QQuickEventPoint *point) override;
+ void handlePointerEventImpl(QQuickPointerEvent *event) override;
QQuickDragAxis *xAxis() { return &m_xAxis; }
QQuickDragAxis *yAxis() { return &m_yAxis; }
@@ -82,18 +82,16 @@ Q_SIGNALS:
void translationChanged();
protected:
- bool wantsEventPoint(QQuickEventPoint *point) override;
void onActiveChanged() override;
void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
private:
void ungrab();
void enforceAxisConstraints(QPointF *localPos);
- bool targetContains(QQuickEventPoint *point);
- QPointF localTargetPosition(QQuickEventPoint *point);
+ bool targetContainsCentroid();
+ QPointF targetCentroidPosition();
private:
- QPointF m_pressScenePos;
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.
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index b08b00e5a7..d688058c4e 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -59,10 +59,10 @@ QT_BEGIN_NAMESPACE
for any type of handler which requires and acts upon a specific number
of multiple touchpoints.
*/
-QQuickMultiPointHandler::QQuickMultiPointHandler(QObject *parent, int minimumPointCount)
+QQuickMultiPointHandler::QQuickMultiPointHandler(QObject *parent, int minimumPointCount, int maximumPointCount)
: QQuickPointerDeviceHandler(parent)
, m_minimumPointCount(minimumPointCount)
- , m_maximumPointCount(-1)
+ , m_maximumPointCount(maximumPointCount)
{
}
@@ -117,9 +117,27 @@ void QQuickMultiPointHandler::onActiveChanged()
{
if (active()) {
m_centroid.m_sceneGrabPosition = m_centroid.m_scenePosition;
+ } else {
+ // Don't call m_centroid.reset() here, because in a QML onActiveChanged
+ // callback, we'd like to see what the position _was_, what the velocity _was_, etc.
+ // (having them undefined is not useful)
+ // But pressedButtons and pressedModifiers are meant to be more real-time than those
+ // (which seems a bit inconsistent, from one side).
+ m_centroid.m_pressedButtons = Qt::NoButton;
+ m_centroid.m_pressedModifiers = Qt::NoModifier;
}
}
+void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *)
+{
+ // If another handler or item takes over this set of points, assume it has
+ // decided that it's the better fit for them. Don't immediately re-grab
+ // at the next opportunity. This should help to avoid grab cycles
+ // (e.g. between DragHandler and PinchHandler).
+ if (stateChange == QQuickEventPoint::UngrabExclusive || stateChange == QQuickEventPoint::CancelGrabExclusive)
+ m_currentPoints.clear();
+}
+
QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointerEvent *event)
{
QVector<QQuickEventPoint *> ret;
@@ -279,7 +297,7 @@ bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points)
{
bool allowed = true;
for (QQuickEventPoint* point : points) {
- if (!canGrab(point)) {
+ if (point->exclusiveGrabber() != this && !canGrab(point)) {
allowed = false;
break;
}
@@ -291,4 +309,10 @@ bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points)
return allowed;
}
+void QQuickMultiPointHandler::moveTarget(QPointF pos)
+{
+ target()->setPosition(pos);
+ m_centroid.m_position = target()->mapFromScene(m_centroid.m_scenePosition);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h
index d1cf67b2cb..80f6917d24 100644
--- a/src/quick/handlers/qquickmultipointhandler_p.h
+++ b/src/quick/handlers/qquickmultipointhandler_p.h
@@ -66,7 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHand
Q_PROPERTY(QQuickHandlerPoint centroid READ centroid NOTIFY centroidChanged)
public:
- explicit QQuickMultiPointHandler(QObject *parent = nullptr, int minimumPointCount = 2);
+ explicit QQuickMultiPointHandler(QObject *parent = nullptr, int minimumPointCount = 2, int maximumPointCount = -1);
~QQuickMultiPointHandler();
int minimumPointCount() const { return m_minimumPointCount; }
@@ -94,6 +94,7 @@ protected:
bool wantsPointerEvent(QQuickPointerEvent *event) override;
void handlePointerEventImpl(QQuickPointerEvent *event) override;
void onActiveChanged() override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
bool hasCurrentPoints(QQuickPointerEvent *event);
QVector<QQuickEventPoint *> eligiblePoints(QQuickPointerEvent *event);
qreal averageTouchPointDistance(const QPointF &ref);
@@ -104,6 +105,7 @@ protected:
static qreal averageAngleDelta(const QVector<PointData> &old, const QVector<PointData> &newAngles);
void acceptPoints(const QVector<QQuickEventPoint *> &points);
bool grabPoints(QVector<QQuickEventPoint *> points);
+ void moveTarget(QPointF pos);
protected:
QVector<QQuickHandlerPoint> m_currentPoints;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index f921e3962b..22425a96a6 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2511,6 +2511,12 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
int pointCount = event->pointCount();
QVector<QQuickItem *> targetItems;
bool isTouchEvent = (event->asPointerTouchEvent() != nullptr);
+ if (isTouchEvent && event->isPressEvent()) {
+ // When a second point is pressed, we're starting over with delivery, so
+ // don't let prior conception of which one is acting as a mouse interfere
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+ }
for (int i = 0; i < pointCount; ++i) {
auto point = event->point(i);
point->setAccepted(false); // because otherwise touchEventForItem will ignore it
@@ -2977,6 +2983,12 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent
return overThreshold;
}
+bool QQuickWindowPrivate::dragOverThreshold(QVector2D delta)
+{
+ int threshold = qApp->styleHints()->startDragDistance();
+ return qAbs(delta.x()) > threshold || qAbs(delta.y()) > threshold;
+}
+
/*!
\qmlproperty list<Object> Window::data
\default
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 9a83e8523b..10c8477417 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -302,6 +302,7 @@ public:
QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
}
+ static bool dragOverThreshold(QVector2D delta);
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index 6aa2eaa3cb..11a67cea82 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -93,7 +93,7 @@ void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const
window->show();
QVERIFY(QTest::qWaitForWindowActive(window.data()));
- QVERIFY(window->rootObject() != 0);
+ QVERIFY(window->rootObject() != nullptr);
}
void tst_FlickableInterop::initTestCase()
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
index 0561a9e4f1..5ea5a42044 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
@@ -105,12 +105,12 @@ void tst_MptaInterop::touchDrag()
// Press one touchpoint:
// DragHandler gets a passive grab
// PinchHandler declines, because it wants 3 touchpoints
- // MPTA doesn't get a chance, because DragHandler accepted the single EventPoint
+ // MPTA grabs because DragHandler doesn't accept the single EventPoint
QPoint p1 = mpta->mapToScene(QPointF(20, 20)).toPoint();
touch.press(1, p1).commit();
QQuickTouchUtils::flush(window);
auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(touchPointerDevice);
- QCOMPARE(tp.at(0)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), true);
QTRY_VERIFY(pointerEvent->point(0)->passiveGrabbers().contains(drag));
// Start moving
@@ -161,7 +161,7 @@ void tst_MptaInterop::touchesThenPinch()
QPoint p1 = mpta->mapToScene(QPointF(20, 20)).toPoint();
touch.press(1, p1).commit();
QQuickTouchUtils::flush(window);
- QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), nullptr);
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
QTRY_COMPARE(pointerEvent->point(0)->passiveGrabbers().first(), drag);
// Press a second touchpoint: MPTA grabs it
@@ -170,31 +170,21 @@ void tst_MptaInterop::touchesThenPinch()
QQuickTouchUtils::flush(window);
QVERIFY(tp.at(0)->property("pressed").toBool());
QTRY_VERIFY(tp.at(1)->property("pressed").toBool());
- QCOMPARE(mptaPressedSpy.count(), 1);
+ QCOMPARE(mptaPressedSpy.count(), 2);
- // ATM it's required that when PinchHandler sees the third touchpoint,
- // the pre-existing points must have moved far enough to exceed the drag threshold.
- // If MPTA is allowed to grab that third point, then PinchHandler won't steal.
- // TODO should we change that? make sure that if PH has a passive grab, it always gets updated even though MPTA has the grab?
- for (int i = 0; i < 2; ++i) {
- p1 += QPoint(dragThreshold, dragThreshold);
- p2 += QPoint(dragThreshold, dragThreshold);
- touch.move(1, p1).move(2, p2).commit();
- }
-
- // Press a third touchpoint: PinchHandler grabs, MPTA loses its grabs
+ // Press a third touchpoint: MPTA grabs it too
QPoint p3 = mpta->mapToScene(QPointF(110, 200)).toPoint();
touch.stationary(1).stationary(2).press(3, p3).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(tp.at(0)->property("pressed").toBool(), false);
- QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
- QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
- QCOMPARE(mptaPressedSpy.count(), 1);
- QCOMPARE(mptaCanceledSpy.count(), 1);
- QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), pinch);
- QTRY_COMPARE(pointerEvent->point(1)->exclusiveGrabber(), pinch);
- QTRY_COMPARE(pointerEvent->point(2)->exclusiveGrabber(), pinch);
- QVERIFY(pinch->active());
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), true);
+ QCOMPARE(mptaPressedSpy.count(), 3);
+ QCOMPARE(mptaCanceledSpy.count(), 0);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), mpta);
+ QVERIFY(!pinch->active());
// Start moving: PinchHandler steals the exclusive grab from MPTA as soon as dragThreshold is exceeded
int pinchStoleGrab = 0;
@@ -204,11 +194,12 @@ void tst_MptaInterop::touchesThenPinch()
p3 += QPoint(-dragThreshold / 2, dragThreshold / 2);
touch.move(1, p1).move(2, p2).move(3, p3).commit();
QQuickTouchUtils::flush(window);
- QTRY_COMPARE(tp.at(0)->property("pressed").toBool(), false);
- QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
- QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
- if (!pinchStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == pinch)
+ if (!pinchStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == pinch) {
pinchStoleGrab = i;
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
+ }
}
qCDebug(lcPointerTests) << "pinch started after" << pinchStoleGrab << "moves; ended with scale" << pinch->activeScale() << "rot" << pinch->rotation();
QTRY_VERIFY(pinch->rotation() > 4);
@@ -217,28 +208,26 @@ void tst_MptaInterop::touchesThenPinch()
// Press one more point (pinkie finger)
QPoint p4 = mpta->mapToScene(QPointF(300, 200)).toPoint();
touch.move(1, p1).move(2, p2).move(3, p3).press(4, p4).commit();
- // PinchHandler gives up its grabs (only on non-stationary points at this time: see QQuickPointerHandler::handlePointerEvent())
- // because it has minimum touch points 3, maximum touch points 3, and now there are 4 points.
- // MPTA grabs all points which are not already grabbed
- QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
- QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), mpta);
- QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), mpta);
+ // MPTA grabs the newly pressed point
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), pinch);
QCOMPARE(pointerEvent->point(3)->exclusiveGrabber(), mpta);
- // Move some more... MPTA keeps reacting
+ // Move some more... PinchHandler and MPTA both keep reacting
for (int i = 0; i < 8; ++i) {
p1 += QPoint(4, 4);
p2 += QPoint(4, 4);
p3 += QPoint(-4, 4);
p4 += QPoint(-4, -4);
touch.move(1, p1).move(2, p2).move(3, p3).move(4, p4).commit();
- QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
- QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), mpta);
- QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), pinch);
QCOMPARE(pointerEvent->point(3)->exclusiveGrabber(), mpta);
QCOMPARE(tp.at(0)->property("pressed").toBool(), true);
- QCOMPARE(tp.at(1)->property("pressed").toBool(), true);
- QCOMPARE(tp.at(2)->property("pressed").toBool(), true);
- QCOMPARE(tp.at(3)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(3)->property("pressed").toBool(), false);
}
// Release the pinkie: PinchHandler acquires passive grabs on the 3 remaining points
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
index e468280ea6..7b3601bea0 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
@@ -39,20 +39,21 @@ Item {
Rectangle {
id: ball
- objectName: "Ball " + index
+ objectName: "Ball " + (index + 1)
color: dragHandler.active ? "blue" : "lightsteelblue"
width: 80; height: 80; x: 200 + index * 200; y: 200; radius: width / 2
onParentChanged: console.log(this + " parent " + parent)
DragHandler {
id: dragHandler
- objectName: "DragHandler " + index
+ objectName: "DragHandler " + (index + 1)
}
Text {
color: "white"
anchors.centerIn: parent
- text: dragHandler.point.position.x.toFixed(1) + "," + dragHandler.point.position.y.toFixed(1)
+ horizontalAlignment: Text.AlignHCenter
+ text: ball.objectName + "\n" + dragHandler.centroid.position.x.toFixed(1) + "," + dragHandler.centroid.position.y.toFixed(1)
}
}
}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 0271924c9b..f71145c2bc 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -119,11 +119,11 @@ void tst_DragHandler::defaultPropertyValues()
QCOMPARE(dragHandler->acceptedButtons(), Qt::LeftButton);
QCOMPARE(dragHandler->translation(), QVector2D());
- QCOMPARE(dragHandler->point().position(), QPointF());
- QCOMPARE(dragHandler->point().scenePosition(), QPointF());
- QCOMPARE(dragHandler->point().pressPosition(), QPointF());
- QCOMPARE(dragHandler->point().scenePressPosition(), QPointF());
- QCOMPARE(dragHandler->point().sceneGrabPosition(), QPointF());
+ QCOMPARE(dragHandler->centroid().position(), QPointF());
+ QCOMPARE(dragHandler->centroid().scenePosition(), QPointF());
+ QCOMPARE(dragHandler->centroid().pressPosition(), QPointF());
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), QPointF());
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), QPointF());
}
void tst_DragHandler::touchDrag()
@@ -146,10 +146,10 @@ void tst_DragHandler::touchDrag()
QTest::touchEvent(window, touchDevice).press(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler->active());
- QCOMPARE(dragHandler->point().position(), ballCenter);
- QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
- QCOMPARE(dragHandler->point().scenePosition(), scenePressPos);
- QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
p1 += QPoint(dragThreshold, 0);
QTest::touchEvent(window, touchDevice).move(1, p1, window);
QQuickTouchUtils::flush(window);
@@ -161,22 +161,22 @@ void tst_DragHandler::touchDrag()
QCOMPARE(translationChangedSpy.count(), 0);
QCOMPARE(dragHandler->translation().x(), 0.0);
QPointF sceneGrabPos = p1;
- QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
p1 += QPoint(19, 0);
QTest::touchEvent(window, touchDevice).move(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(dragHandler->active());
- QCOMPARE(dragHandler->point().position(), ballCenter);
- QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
- QCOMPARE(dragHandler->point().scenePosition(), ball->mapToScene(ballCenter));
- QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
- QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ 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);
QTest::touchEvent(window, touchDevice).release(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!dragHandler->active());
- QCOMPARE(dragHandler->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
QCOMPARE(translationChangedSpy.count(), 1);
}
@@ -200,10 +200,10 @@ void tst_DragHandler::mouseDrag()
QPoint p1 = scenePressPos.toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
QVERIFY(!dragHandler->active());
- QCOMPARE(dragHandler->point().position(), ballCenter);
- QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
- QCOMPARE(dragHandler->point().scenePosition(), scenePressPos);
- QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
p1 += QPoint(dragThreshold, 0);
QTest::mouseMove(window, p1);
QVERIFY(!dragHandler->active());
@@ -213,20 +213,20 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(translationChangedSpy.count(), 0);
QCOMPARE(dragHandler->translation().x(), 0.0);
QPointF sceneGrabPos = p1;
- QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
p1 += QPoint(19, 0);
QTest::mouseMove(window, p1);
QTRY_VERIFY(dragHandler->active());
- QCOMPARE(dragHandler->point().position(), ballCenter);
- QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
- QCOMPARE(dragHandler->point().scenePosition(), ball->mapToScene(ballCenter));
- QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
- QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ 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);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
QTRY_VERIFY(!dragHandler->active());
- QCOMPARE(dragHandler->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
QCOMPARE(translationChangedSpy.count(), 1);
}
@@ -243,12 +243,14 @@ void tst_DragHandler::touchDragMulti()
QQuickDragHandler *dragHandler1 = ball1->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler1);
QSignalSpy translationChangedSpy1(dragHandler1, SIGNAL(translationChanged()));
+ QSignalSpy centroidChangedSpy1(dragHandler1, SIGNAL(centroidChanged()));
QQuickItem *ball2 = window->rootObject()->childItems().at(1);
QVERIFY(ball2);
QQuickDragHandler *dragHandler2 = ball2->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler2);
QSignalSpy translationChangedSpy2(dragHandler2, SIGNAL(translationChanged()));
+ QSignalSpy centroidChangedSpy2(dragHandler1, SIGNAL(centroidChanged()));
QPointF ball1Center = ball1->clipRect().center();
QPointF scenePressPos1 = ball1->mapToScene(ball1Center);
@@ -261,20 +263,33 @@ void tst_DragHandler::touchDragMulti()
touchSeq.press(1, p1, window).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
- QCOMPARE(dragHandler1->point().position(), ball1Center);
- QCOMPARE(dragHandler1->point().pressPosition(), ball1Center);
- QCOMPARE(dragHandler1->point().scenePosition(), scenePressPos1);
- QCOMPARE(dragHandler1->point().scenePressPosition(), scenePressPos1);
+ QCOMPARE(centroidChangedSpy1.count(), 1);
+ QCOMPARE(dragHandler1->centroid().position(), ball1Center);
+ QCOMPARE(dragHandler1->centroid().pressPosition(), ball1Center);
+ QCOMPARE(dragHandler1->centroid().scenePosition(), scenePressPos1);
+ QCOMPARE(dragHandler1->centroid().scenePressPosition(), scenePressPos1);
QVERIFY(!dragHandler2->active());
- QCOMPARE(dragHandler2->point().position(), ball2Center);
- QCOMPARE(dragHandler2->point().pressPosition(), ball2Center);
- QCOMPARE(dragHandler2->point().scenePosition(), scenePressPos2);
- QCOMPARE(dragHandler2->point().scenePressPosition(), scenePressPos2);
+ QCOMPARE(centroidChangedSpy2.count(), 1);
+ QCOMPARE(dragHandler2->centroid().position(), ball2Center);
+ QCOMPARE(dragHandler2->centroid().pressPosition(), ball2Center);
+ QCOMPARE(dragHandler2->centroid().scenePosition(), scenePressPos2);
+ QCOMPARE(dragHandler2->centroid().scenePressPosition(), scenePressPos2);
p1 += QPoint(dragThreshold, 0);
p2 += QPoint(0, dragThreshold);
touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
+ QCOMPARE(centroidChangedSpy1.count(), 2);
+ 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(dragHandler2->centroid().position(), ball2Center + QPointF(0, dragThreshold));
+ QCOMPARE(dragHandler2->centroid().pressPosition(), ball2Center);
+ QCOMPARE(dragHandler2->centroid().scenePosition().toPoint(), p2);
+ QCOMPARE(dragHandler2->centroid().scenePressPosition(), scenePressPos2);
p1 += QPoint(1, 0);
p2 += QPoint(0, 1);
touchSeq.move(1, p1, window).move(2, p2, window).commit();
@@ -285,37 +300,37 @@ void tst_DragHandler::touchDragMulti()
QCOMPARE(dragHandler1->translation().x(), 0.0);
QPointF sceneGrabPos1 = p1;
QPointF sceneGrabPos2 = p2;
- QCOMPARE(dragHandler1->point().sceneGrabPosition(), sceneGrabPos1);
- QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ QCOMPARE(dragHandler1->centroid().sceneGrabPosition(), sceneGrabPos1);
+ QCOMPARE(dragHandler2->centroid().sceneGrabPosition(), sceneGrabPos2);
p1 += QPoint(19, 0);
p2 += QPoint(0, 19);
QVERIFY(dragHandler2->active());
QCOMPARE(translationChangedSpy2.count(), 0);
QCOMPARE(dragHandler2->translation().x(), 0.0);
- QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ QCOMPARE(dragHandler2->centroid().sceneGrabPosition(), sceneGrabPos2);
touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(dragHandler1->active());
QVERIFY(dragHandler2->active());
- QCOMPARE(dragHandler1->point().position(), ball1Center);
- QCOMPARE(dragHandler1->point().pressPosition(), ball1Center);
- QCOMPARE(dragHandler1->point().scenePosition(), ball1->mapToScene(ball1Center));
- QCOMPARE(dragHandler1->point().scenePressPosition(), scenePressPos1);
- QCOMPARE(dragHandler1->point().sceneGrabPosition(), sceneGrabPos1);
+ QCOMPARE(dragHandler1->centroid().position(), ball1Center);
+ QCOMPARE(dragHandler1->centroid().pressPosition(), ball1Center);
+ QCOMPARE(dragHandler1->centroid().scenePosition(), ball1->mapToScene(ball1Center));
+ QCOMPARE(dragHandler1->centroid().scenePressPosition(), scenePressPos1);
+ QCOMPARE(dragHandler1->centroid().sceneGrabPosition(), sceneGrabPos1);
QCOMPARE(dragHandler1->translation().x(), dragThreshold + 20.0);
QCOMPARE(dragHandler1->translation().y(), 0.0);
- QCOMPARE(dragHandler2->point().position(), ball2Center);
- QCOMPARE(dragHandler2->point().pressPosition(), ball2Center);
- QCOMPARE(dragHandler2->point().scenePosition(), ball2->mapToScene(ball2Center));
- QCOMPARE(dragHandler2->point().scenePressPosition(), scenePressPos2);
- QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ QCOMPARE(dragHandler2->centroid().position(), ball2Center);
+ QCOMPARE(dragHandler2->centroid().pressPosition(), ball2Center);
+ QCOMPARE(dragHandler2->centroid().scenePosition(), ball2->mapToScene(ball2Center));
+ QCOMPARE(dragHandler2->centroid().scenePressPosition(), scenePressPos2);
+ QCOMPARE(dragHandler2->centroid().sceneGrabPosition(), sceneGrabPos2);
QCOMPARE(dragHandler2->translation().x(), 0.0);
QCOMPARE(dragHandler2->translation().y(), dragThreshold + 20.0);
touchSeq.release(1, p1, window).stationary(2).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!dragHandler1->active());
QVERIFY(dragHandler2->active());
- QCOMPARE(dragHandler1->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(dragHandler1->centroid().pressedButtons(), Qt::NoButton);
QCOMPARE(ball1->mapToScene(ball1Center).toPoint(), p1);
QCOMPARE(translationChangedSpy1.count(), 1);
touchSeq.release(2, p2, window).commit();
@@ -454,7 +469,12 @@ void tst_DragHandler::touchPassiveGrabbers()
QQuickDragHandler *dragHandler = nullptr;
for (QQuickPointerHandler *handler: expectedPassiveGrabbers) {
- QCOMPARE(static_cast<QQuickSinglePointHandler *>(handler)->point().scenePressPosition(), p1);
+ QPointF scenePressPos;
+ if (QQuickMultiPointHandler *mph = qmlobject_cast<QQuickMultiPointHandler *>(handler))
+ scenePressPos = mph->centroid().scenePressPosition();
+ else
+ scenePressPos = static_cast<QQuickSinglePointHandler *>(handler)->point().scenePressPosition();
+ QCOMPARE(scenePressPos, p1);
QQuickDragHandler *dh = qmlobject_cast<QQuickDragHandler *>(handler);
if (dh)
dragHandler = dh;
diff --git a/tests/manual/pointer/content/FakeFlickable.qml b/tests/manual/pointer/content/FakeFlickable.qml
index 5a20a6825a..ffb5c4e914 100644
--- a/tests/manual/pointer/content/FakeFlickable.qml
+++ b/tests/manual/pointer/content/FakeFlickable.qml
@@ -67,7 +67,7 @@ Item {
DragHandler {
id: dragHandler
- onActiveChanged: if (!active) anim.restart(point.velocity)
+ onActiveChanged: if (!active) anim.restart(centroid.velocity)
}
MomentumAnimation {
id: anim
diff --git a/tests/manual/pointer/flingAnimation.qml b/tests/manual/pointer/flingAnimation.qml
index b17429f4e4..2bc6de7065 100644
--- a/tests/manual/pointer/flingAnimation.qml
+++ b/tests/manual/pointer/flingAnimation.qml
@@ -90,7 +90,7 @@ Rectangle {
objectName: "dragHandler" + index
onActiveChanged: {
if (!active)
- anim.restart(point.velocity)
+ anim.restart(centroid.velocity)
}
}
Rectangle {
@@ -103,12 +103,12 @@ Rectangle {
Rectangle {
visible: width > 0
- width: dragHandler.point.velocity.length() * 100
+ width: dragHandler.centroid.velocity.length() * 100
height: 2
x: ball.width / 2
y: ball.height / 2
z: -1
- rotation: Math.atan2(dragHandler.point.velocity.y, dragHandler.point.velocity.x) * 180 / Math.PI
+ rotation: Math.atan2(dragHandler.centroid.velocity.y, dragHandler.centroid.velocity.x) * 180 / Math.PI
transformOrigin: Item.BottomLeft
antialiasing: true
diff --git a/tests/manual/pointer/map.qml b/tests/manual/pointer/map.qml
index ae7ec042d3..3ed732b523 100644
--- a/tests/manual/pointer/map.qml
+++ b/tests/manual/pointer/map.qml
@@ -39,6 +39,7 @@ 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 } }
Image {
id: image
@@ -57,16 +58,29 @@ Item {
PinchHandler {
id: pinch
+ objectName: "two-point pinch"
target: map
minimumScale: 0.1
maximumScale: 10
onActiveChanged: if (!active) reRenderIfNecessary()
+ grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started
}
DragHandler {
+ objectName: "single-point drag"
target: map
}
+ DragHandler {
+ id: tiltHandler
+ objectName: "two-point tilt"
+ minimumPointCount: 2
+ maximumPointCount: 2
+ xAxis.enabled: false
+ target: null
+ onTranslationChanged: tilt.angle = translation.y / -2
+ }
+
function reRenderIfNecessary() {
var newSourceWidth = image.sourceSize.width * pinch.scale
var ratio = newSourceWidth / image.sourceSize.width
diff --git a/tests/manual/pointer/singlePointHandlerProperties.qml b/tests/manual/pointer/singlePointHandlerProperties.qml
index 40a4f49e5e..6ee88f9f9d 100644
--- a/tests/manual/pointer/singlePointHandlerProperties.qml
+++ b/tests/manual/pointer/singlePointHandlerProperties.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -36,11 +36,11 @@ Rectangle {
Item {
id: crosshairs
- x: dragHandler.point.position.x - width / 2
- y: dragHandler.point.position.y - height / 2
+ x: dragHandler.centroid.position.x - width / 2
+ y: dragHandler.centroid.position.y - height / 2
width: parent.width / 2; height: parent.height / 2
visible: dragHandler.active
- rotation: dragHandler.point.rotation
+ rotation: dragHandler.centroid.rotation
Rectangle {
color: "goldenrod"
@@ -56,7 +56,7 @@ Rectangle {
}
Rectangle {
color: "goldenrod"
- width: Math.max(2, 50 * dragHandler.point.pressure)
+ width: Math.max(2, 50 * dragHandler.centroid.pressure)
height: width
radius: width / 2
anchors.centerIn: parent
@@ -69,9 +69,9 @@ Rectangle {
implicitHeight: label.implicitHeight
Text {
id: label
- text: 'id: ' + dragHandler.point.id.toString(16) + " uid: " + dragHandler.point.uniqueId.numericId +
- '\npos: (' + dragHandler.point.position.x.toFixed(2) + ', ' + dragHandler.point.position.y.toFixed(2) + ')' +
- '\nmodifiers: ' + dragHandler.point.modifiers.toString(16)
+ text: 'id: ' + dragHandler.centroid.id.toString(16) + " uid: " + dragHandler.centroid.uniqueId.numericId +
+ '\npos: (' + dragHandler.centroid.position.x.toFixed(2) + ', ' + dragHandler.centroid.position.y.toFixed(2) + ')' +
+ '\nmodifiers: ' + dragHandler.centroid.modifiers.toString(16)
}
}
}
@@ -79,8 +79,8 @@ Rectangle {
color: "transparent"
border.color: "white"
antialiasing: true
- width: dragHandler.point.ellipseDiameters.width
- height: dragHandler.point.ellipseDiameters.height
+ width: dragHandler.centroid.ellipseDiameters.width
+ height: dragHandler.centroid.ellipseDiameters.height
radius: Math.min(width / 2, height / 2)
anchors.centerIn: parent
}
@@ -88,11 +88,11 @@ Rectangle {
Rectangle {
id: velocityVector
visible: width > 0
- width: dragHandler.point.velocity.length() * 100
+ width: dragHandler.centroid.velocity.length() * 100
height: 2
- x: dragHandler.point.position.x
- y: dragHandler.point.position.y
- rotation: Math.atan2(dragHandler.point.velocity.y, dragHandler.point.velocity.x) * 180 / Math.PI
+ x: dragHandler.centroid.position.x
+ y: dragHandler.centroid.position.y
+ rotation: Math.atan2(dragHandler.centroid.velocity.y, dragHandler.centroid.velocity.x) * 180 / Math.PI
transformOrigin: Item.BottomLeft
antialiasing: true
@@ -138,15 +138,14 @@ Rectangle {
DragHandler {
id: dragHandler
target: null
- acceptedButtons: Qt.AllButtons
- onGrabChanged: if (active) { // 'point' is an implicit parameter referencing to a QQuickEventPoint instance
- console.log("grabbed " + point.pointId + " @ " + point.sceneGrabPos)
- grabbingLocationIndicator.createObject(root, {"x": point.sceneGrabPosition.x, "y": point.sceneGrabPosition.y - 16})
+// acceptedButtons: Qt.AllButtons // TODO: only SinglePointHandler has this so far
+ onGrabChanged: if (active) {
+ console.log("grabbed " + centroid.pointId + " @ " + centroid.sceneGrabPos)
+ grabbingLocationIndicator.createObject(root, {"x": centroid.sceneGrabPosition.x, "y": centroid.sceneGrabPosition.y - 16})
}
- onPointChanged: {
- // Here, 'point' is referring to the property of the DragHandler
- if (point.pressedButtons)
- mouseButtonIndicator.createObject(root, {"x": point.pressPosition.x - 44, "y": point.pressPosition.y - 64, "buttons": point.pressedButtons})
+ onCentroidChanged: {
+ if (centroid.pressedButtons)
+ mouseButtonIndicator.createObject(root, {"x": centroid.pressPosition.x - 44, "y": centroid.pressPosition.y - 64, "buttons": centroid.pressedButtons})
}
}
}