diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/handlers/qquickhandlerpoint.cpp | 38 | ||||
-rw-r--r-- | src/quick/handlers/qquickhandlerpoint_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler.cpp | 54 | ||||
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickpinchhandler.cpp | 15 |
5 files changed, 61 insertions, 50 deletions
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp index 4bd5d2cbfb..ac24924689 100644 --- a/src/quick/handlers/qquickhandlerpoint.cpp +++ b/src/quick/handlers/qquickhandlerpoint.cpp @@ -133,46 +133,42 @@ void QQuickHandlerPoint::reset(const QQuickEventPoint *point) m_velocity = point->velocity(); } -void QQuickHandlerPoint::reset(const QVector<QQuickEventPoint *> &points) +void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) { if (points.isEmpty()) { qWarning("reset: no points"); return; } if (points.count() == 1) { - reset(points.first()); + *this = points.first(); // copy all values return; } // all points are required to be from the same event - const QQuickPointerEvent *event = points.first()->pointerEvent(); QPointF posSum; QPointF scenePosSum; + QPointF pressPosSum; + QPointF scenePressPosSum; QVector2D velocitySum; qreal pressureSum = 0; QSizeF ellipseDiameterSum; - bool press = false; - const QQuickPointerTouchEvent *touchEvent = event->asPointerTouchEvent(); - for (const QQuickEventPoint *point : qAsConst(points)) { - posSum += point->position(); - scenePosSum += point->scenePosition(); - velocitySum += point->velocity(); - if (touchEvent) { - pressureSum += static_cast<const QQuickEventTouchPoint *>(point)->pressure(); - ellipseDiameterSum += static_cast<const QQuickEventTouchPoint *>(point)->ellipseDiameters(); - } - if (point->state() == QQuickEventPoint::Pressed) - press = true; + for (const QQuickHandlerPoint &point : points) { + posSum += point.position(); + scenePosSum += point.scenePosition(); + pressPosSum += point.pressPosition(); + scenePressPosSum += point.scenePressPosition(); + velocitySum += point.velocity(); + pressureSum += point.pressure(); + ellipseDiameterSum += point.ellipseDiameters(); } m_id = 0; m_uniqueId = QPointingDeviceUniqueId(); - m_pressedButtons = event->buttons(); - m_pressedModifiers = event->modifiers(); + // all points are required to be from the same event, so pressed buttons and modifiers should be the same + m_pressedButtons = points.first().pressedButtons(); + m_pressedModifiers = points.first().modifiers(); m_position = posSum / points.size(); m_scenePosition = scenePosSum / points.size(); - if (press) { - m_pressPosition = m_position; - m_scenePressPosition = m_scenePosition; - } + m_pressPosition = pressPosSum / points.size(); + m_scenePressPosition = scenePressPosSum / points.size(); m_velocity = velocitySum / points.size(); m_rotation = 0; // averaging the rotations of all the points isn't very sensible m_pressure = pressureSum / points.size(); diff --git a/src/quick/handlers/qquickhandlerpoint_p.h b/src/quick/handlers/qquickhandlerpoint_p.h index 1dff52942a..946b9aac0b 100644 --- a/src/quick/handlers/qquickhandlerpoint_p.h +++ b/src/quick/handlers/qquickhandlerpoint_p.h @@ -93,7 +93,7 @@ public: void reset(); void reset(const QQuickEventPoint *point); - void reset(const QVector<QQuickEventPoint *> &points); + void reset(const QVector<QQuickHandlerPoint> &points); private: int m_id; diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index 9a3732ff84..b08b00e5a7 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -85,15 +85,31 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event) const QVector<QQuickEventPoint *> candidatePoints = eligiblePoints(event); const bool ret = (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount()); - if (ret) - m_currentPoints = candidatePoints; + if (ret) { + const int c = candidatePoints.count(); + m_currentPoints.resize(c); + for (int i = 0; i < c; ++i) + m_currentPoints[i].reset(candidatePoints[i]); + } else { + m_currentPoints.clear(); + } return ret; } void QQuickMultiPointHandler::handlePointerEventImpl(QQuickPointerEvent *event) { QQuickPointerHandler::handlePointerEventImpl(event); + // event's points can be reordered since the previous event, which is why m_currentPoints + // is _not_ a shallow copy of the QQuickPointerTouchEvent::m_touchPoints vector. + // So we have to update our m_currentPoints instances based on the given event. + for (QQuickHandlerPoint &p : m_currentPoints) { + const QQuickEventPoint *ep = event->pointById(p.id()); + if (ep) + p.reset(ep); + } + QPointF sceneGrabPos = m_centroid.sceneGrabPosition(); m_centroid.reset(m_currentPoints); + m_centroid.m_sceneGrabPosition = sceneGrabPos; // preserve as it was emit centroidChanged(); } @@ -175,24 +191,18 @@ void QQuickMultiPointHandler::setMaximumPointCount(int maximumPointCount) bool QQuickMultiPointHandler::hasCurrentPoints(QQuickPointerEvent *event) { - bool ret = true; - int c = event->pointCount(); - if (c < m_currentPoints.size()) + if (event->pointCount() < m_currentPoints.size() || m_currentPoints.size() == 0) return false; // TODO optimize: either ensure the points are sorted, // or use std::equal with a predicate - for (int i = 0; ret && i < c; ++i) { - if (event->point(i)->state() == QQuickEventPoint::Released) + for (const QQuickHandlerPoint &p : qAsConst(m_currentPoints)) { + const QQuickEventPoint *ep = event->pointById(p.id()); + if (!ep) + return false; + if (ep->state() == QQuickEventPoint::Released) return false; - bool found = false; - int pointId = event->point(i)->pointId(); - for (QQuickEventPoint *o : qAsConst(m_currentPoints)) - if (o && pointId == o->pointId()) - found = true; - if (!found) - ret = false; } - return ret; + return true; } qreal QQuickMultiPointHandler::averageTouchPointDistance(const QPointF &ref) @@ -200,8 +210,8 @@ qreal QQuickMultiPointHandler::averageTouchPointDistance(const QPointF &ref) qreal ret = 0; if (Q_UNLIKELY(m_currentPoints.size() == 0)) return ret; - for (QQuickEventPoint *point : qAsConst(m_currentPoints)) - ret += QVector2D(point->scenePosition() - ref).length(); + for (const QQuickHandlerPoint &p : m_currentPoints) + ret += QVector2D(p.scenePosition() - ref).length(); return ret / m_currentPoints.size(); } @@ -211,8 +221,8 @@ qreal QQuickMultiPointHandler::averageStartingDistance(const QPointF &ref) qreal ret = 0; if (Q_UNLIKELY(m_currentPoints.size() == 0)) return ret; - for (QQuickEventPoint *point : qAsConst(m_currentPoints)) - ret += QVector2D(point->sceneGrabPosition() - ref).length(); + for (const QQuickHandlerPoint &p : m_currentPoints) + ret += QVector2D(p.sceneGrabPosition() - ref).length(); return ret / m_currentPoints.size(); } @@ -220,9 +230,9 @@ QVector<QQuickMultiPointHandler::PointData> QQuickMultiPointHandler::angles(cons { QVector<PointData> angles; angles.reserve(m_currentPoints.count()); - for (QQuickEventPoint *point : qAsConst(m_currentPoints)) { - qreal angle = QLineF(ref, point->scenePosition()).angle(); - angles.append(PointData(point->pointId(), -angle)); // convert to clockwise, to be consistent with QQuickItem::rotation + for (const QQuickHandlerPoint &p : m_currentPoints) { + qreal angle = QLineF(ref, p.scenePosition()).angle(); + angles.append(PointData(p.id(), -angle)); // convert to clockwise, to be consistent with QQuickItem::rotation } return angles; } diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h index 06045771fb..d1cf67b2cb 100644 --- a/src/quick/handlers/qquickmultipointhandler_p.h +++ b/src/quick/handlers/qquickmultipointhandler_p.h @@ -106,7 +106,7 @@ protected: bool grabPoints(QVector<QQuickEventPoint *> points); protected: - QVector<QQuickEventPoint *> m_currentPoints; + QVector<QQuickHandlerPoint> m_currentPoints; QQuickHandlerPoint m_centroid; int m_minimumPointCount; int m_maximumPointCount; diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp index c251ae6d36..e0b798b638 100644 --- a/src/quick/handlers/qquickpinchhandler.cpp +++ b/src/quick/handlers/qquickpinchhandler.cpp @@ -317,8 +317,8 @@ void QQuickPinchHandler::onActiveChanged() void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) { if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) { - for (QQuickEventPoint *point : qAsConst(m_currentPoints)) - qCDebug(lcPinchHandler) << point->state() << point->sceneGrabPosition() << "->" << point->scenePosition(); + for (const QQuickHandlerPoint &p : m_currentPoints) + qCDebug(lcPinchHandler) << hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition(); } QQuickMultiPointHandler::handlePointerEventImpl(event); @@ -354,10 +354,15 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) #endif // QT_CONFIG(gestures) { bool containsReleasedPoints = event->isReleaseEvent(); + QVector<QQuickEventPoint *> chosenPoints; + for (const QQuickHandlerPoint &p : m_currentPoints) { + QQuickEventPoint *ep = event->pointById(p.id()); + chosenPoints << ep; + } if (!active()) { // Verify that at least one of the points has moved beyond threshold needed to activate the handler - for (QQuickEventPoint *point : qAsConst(m_currentPoints)) { - if (!containsReleasedPoints && QQuickWindowPrivate::dragOverThreshold(point) && grabPoints(m_currentPoints)) { + for (QQuickEventPoint *point : qAsConst(chosenPoints)) { + if (!containsReleasedPoints && QQuickWindowPrivate::dragOverThreshold(point) && grabPoints(chosenPoints)) { setActive(true); break; } else { @@ -386,7 +391,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) m_startAngles = std::move(newAngles); if (!containsReleasedPoints) - acceptPoints(m_currentPoints); + acceptPoints(chosenPoints); } QPointF centroidParentPos; |