aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2016-07-26 20:56:56 +0200
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2016-07-26 19:55:57 +0000
commitba201c73edb4ff452bfb13fa5afd6af6a02c4af0 (patch)
tree7ae6995f153172136dc83ba7e3f07cf1a37e75da /src/quick/items
parentb3324d6285204661d16fd39483758b4076104d83 (diff)
Touch handling: remove acceptedNewPoints
We keep track of the state inside the individual points, simplify the code. Change-Id: I6716f3ad9bc21ab066888a3b373719c5e4f30af2 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickevents.cpp30
-rw-r--r--src/quick/items/qquickevents_p_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp49
-rw-r--r--src/quick/items/qquickwindow_p.h2
4 files changed, 35 insertions, 48 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 4a531b09ba..393d8345ec 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -764,29 +764,43 @@ const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int point
/*!
\internal
Make a new QTouchEvent, giving it a subset of the original touch points.
+
+ Returns a nullptr if all points are stationary or there are no points inside the item.
*/
-QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const
+QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item) const
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates eventStates;
// TODO maybe add QQuickItem::mapVector2DFromScene(QVector2D) to avoid needing QQuickItemPrivate here
// Or else just document that velocity is always scene-relative and is not scaled and rotated with the item
// but that would require changing tst_qquickwindow::touchEvent_velocity(): it expects transformed velocity
- QMatrix4x4 transformMatrix(QQuickItemPrivate::get(relativeTo)->windowToItemTransform());
- for (const QQuickEventPoint * p : newPoints) {
+
+ QMatrix4x4 transformMatrix(QQuickItemPrivate::get(item)->windowToItemTransform());
+ for (int i = 0; i < m_pointCount; ++i) {
+ auto p = m_touchPoints.at(i);
+ if (p->isAccepted())
+ continue;
+ bool isGrabber = p->grabber() == item;
+ bool isPressInside = p->state() == Qt::TouchPointPressed && item->contains(item->mapFromScene(p->scenePos()));
+ if (!(isGrabber || isPressInside))
+ continue;
+
const QTouchEvent::TouchPoint *tp = touchPointById(p->pointId());
if (tp) {
eventStates |= tp->state();
QTouchEvent::TouchPoint tpCopy = *tp;
- tpCopy.setPos(relativeTo->mapFromScene(tpCopy.scenePos()));
- tpCopy.setLastPos(relativeTo->mapFromScene(tpCopy.lastScenePos()));
- tpCopy.setStartPos(relativeTo->mapFromScene(tpCopy.startScenePos()));
- tpCopy.setRect(relativeTo->mapRectFromScene(tpCopy.sceneRect()));
+ tpCopy.setPos(item->mapFromScene(tpCopy.scenePos()));
+ tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos()));
+ tpCopy.setStartPos(item->mapFromScene(tpCopy.startScenePos()));
+ tpCopy.setRect(item->mapRectFromScene(tpCopy.sceneRect()));
tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D());
touchPoints << tpCopy;
}
}
+ if (eventStates == Qt::TouchPointStationary || touchPoints.isEmpty())
+ return nullptr;
+
// if all points have the same state, set the event type accordingly
const QTouchEvent &event = *asTouchEvent();
QEvent::Type eventType = event.type();
@@ -804,7 +818,7 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(const QList<const QQuick
QTouchEvent *touchEvent = new QTouchEvent(eventType);
touchEvent->setWindow(event.window());
- touchEvent->setTarget(relativeTo);
+ touchEvent->setTarget(item);
touchEvent->setDevice(event.device());
touchEvent->setModifiers(event.modifiers());
touchEvent->setTouchPoints(touchPoints);
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 82f58efb7a..2375ae797b 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -423,7 +423,7 @@ public:
void clearGrabbers() const override;
QMouseEvent *syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const;
- QTouchEvent *touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const;
+ QTouchEvent *touchEventForItem(QQuickItem *item) const;
QTouchEvent *asTouchEvent() const;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index baf0e196dd..805011ca41 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2285,44 +2285,22 @@ bool QQuickWindowPrivate::deliverPoints(QQuickItem *item, QQuickPointerTouchEven
// set of IDs of "interesting" new points
QSet<quint64> matchingNewPoints;
- // set of points which this item has previously accepted, for starters
- QList<const QQuickEventPoint *> matchingPoints = (*updatedPoints)[item];
// now add the new points which are inside this item's bounds
if (newPoints.count() > 0 && acceptedNewPoints->count() < newPoints.count()) {
for (int i = 0; i < newPoints.count(); i++) {
const QQuickEventPoint * point = newPoints[i];
- if (acceptedNewPoints->contains(point->pointId()))
+ if (acceptedNewPoints->contains(point->pointId())) {
+ Q_ASSERT(point->isAccepted());
continue;
+ }
QPointF p = item->mapFromScene(point->scenePos());
- if (item->contains(p)) {
+ if (item->contains(p))
matchingNewPoints.insert(point->pointId());
- matchingPoints << point;
- }
- }
- }
- // If there are no matching new points, and the existing points are all stationary,
- // there's no need to send an event to this item. This is required by a test in
- // tst_qquickwindow::touchEvent_basic:
- // a single stationary press on an item shouldn't cause an event
- if (matchingNewPoints.isEmpty()) {
- bool stationaryOnly = true;
-
- for (const QQuickEventPoint *tp : matchingPoints) {
- if (tp->state() != Qt::TouchPointStationary) {
- stationaryOnly = false;
- break;
- }
}
-
- if (stationaryOnly)
- matchingPoints.clear();
}
- if (!matchingPoints.isEmpty()) {
- // Now we know this item might be interested in the event. Copy and send it, but
- // with only the subset of TouchPoints which are relevant to that item: that's matchingPoints.
- deliverMatchingPointsToItem(item, event, acceptedNewPoints, matchingNewPoints, matchingPoints, hasFiltered);
- }
+ // This item might be interested in the event.
+ deliverMatchingPointsToItem(item, event, acceptedNewPoints, matchingNewPoints, hasFiltered);
// record the fact that this item has been visited already
updatedPoints->remove(item);
@@ -2336,15 +2314,15 @@ bool QQuickWindowPrivate::deliverPoints(QQuickItem *item, QQuickPointerTouchEven
// matchingPoints to already be that set of interesting points.
// They are all pre-transformed, too.
bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet<quint64> *acceptedNewPoints,
- const QSet<quint64> &matchingNewPoints, const QList<const QQuickEventPoint *> &matchingPoints,
+ const QSet<quint64> &matchingNewPoints,
QSet<QQuickItem *> *hasFiltered)
{
- QScopedPointer<QTouchEvent> touchEvent(event->touchEventForItem(matchingPoints, item));
- if (touchEvent.data()->touchPoints().isEmpty())
+ QScopedPointer<QTouchEvent> touchEvent(event->touchEventForItem(item));
+ if (!touchEvent)
return false;
- bool touchEventAccepted = false;
qCDebug(DBG_TOUCH) << " - considering delivering " << touchEvent.data() << " to " << item;
+ bool touchEventAccepted = false;
// First check whether the parent wants to be a filter,
// and if the parent accepts the event we are done.
@@ -2359,12 +2337,6 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, const QQ
return true;
}
- // Since it can change in sendEvent, update itemForTouchPointId now
- foreach (int id, matchingNewPoints) {
- qCDebug(DBG_TOUCH_TARGET) << "TP" << id << "->" << item;
- event->pointById(id)->setGrabber(item);
- }
-
// Deliver the touch event to the given item
qCDebug(DBG_TOUCH) << " - actually delivering " << touchEvent.data() << " to " << item;
QCoreApplication::sendEvent(item, touchEvent.data());
@@ -2383,6 +2355,7 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, const QQ
// update acceptedNewPoints.
foreach (int id, matchingNewPoints) {
event->pointById(id)->setAccepted();
+ event->pointById(id)->setGrabber(item);
acceptedNewPoints->insert(id);
}
} else {
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 3f4fc50e31..36414f5b6f 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -168,7 +168,7 @@ public:
bool deliverTouchCancelEvent(QTouchEvent *);
bool deliverPoints(QQuickItem *, QQuickPointerTouchEvent *, const QList<const QQuickEventPoint *> &,
QSet<quint64> *, QHash<QQuickItem *, QList<const QQuickEventPoint *> > *, QSet<QQuickItem *> *);
- bool deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet<quint64> *acceptedNewPoints, const QSet<quint64> &matchingNewPoints, const QList<const QQuickEventPoint *> &matchingPoints, QSet<QQuickItem*> *filtered);
+ bool deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet<quint64> *acceptedNewPoints, const QSet<quint64> &matchingNewPoints, QSet<QQuickItem*> *filtered);
static QTouchEvent *touchEventForItem(QQuickItem *target, const QTouchEvent &originalEvent, bool alwaysCheckBounds = false);
static QTouchEvent *touchEventWithPoints(const QTouchEvent &event, const QList<QTouchEvent::TouchPoint> &newPoints);
bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event, QSet<QQuickItem*> *filtered);