diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2018-04-26 16:06:45 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2018-06-29 14:42:11 +0000 |
commit | da722fb448f06cf43780e6f857a1ccd9f07176d6 (patch) | |
tree | 3bea83e40d751c361f76bb1f76fc1d591330d34e /src/quick/items | |
parent | dd333172e2ade1db6d0af72b4ed44262c2b4d8c7 (diff) |
Replace MultiPtHndlr.pointDistanceThreshold with PointerHandler.margin
It's not just useful for PinchHandler: TapHandler has a good use for it
too. But unfortunately if the handler's parent Item has a custom mask,
we don't have a way to augment the mask with a margin; so if margin is
set, we assume the bounds are rectangular.
QQuickMultiPointHandler::eligiblePoints() now calls wantsEventPoint()
rather than bounds-checking the point directly: this adds flexibility,
potentially allowing an override in subclasses, if we need it later.
Task-number: QTBUG-68077
Change-Id: I65c95f00c532044a5862654e58c9c5f8c973df81
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 11 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 23 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 2 |
4 files changed, 26 insertions, 11 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 3b1402fe16..b09dbdad84 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -5140,6 +5140,17 @@ void QQuickItemPrivate::deliverShortcutOverrideEvent(QKeyEvent *event) } } +bool QQuickItemPrivate::anyPointerHandlerWants(QQuickEventPoint *point) const +{ + if (!hasPointerHandlers()) + return false; + for (QQuickPointerHandler *handler : extra->pointerHandlers) { + if (handler->wantsEventPoint(point)) + return true; + } + return false; +} + /*! \internal Deliver the \a event to all PointerHandlers which are in the pre-determined diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index f43f04ed39..bb63bc1ee4 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -582,6 +582,7 @@ public: #endif void deliverShortcutOverrideEvent(QKeyEvent *); + bool anyPointerHandlerWants(QQuickEventPoint *point) const; virtual bool handlePointerEvent(QQuickPointerEvent *, bool avoidExclusiveGrabber = false); virtual void setVisible(bool visible); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index e53ca7f8de..759bb573b1 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1789,7 +1789,7 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven // If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order if (!pointerEvent->allPointsGrabbed() && pointerEvent->buttons()) { - QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePosition(), false, false); + QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point, false, false); for (QQuickItem *item : targetItems) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (!itemPrivate->extra.isAllocated() || itemPrivate->extra->pointerHandlers.isEmpty()) @@ -1924,7 +1924,7 @@ bool QQuickWindowPrivate::deliverSinglePointEventUntilAccepted(QQuickPointerEven { Q_ASSERT(event->pointCount() == 1); QQuickEventPoint *point = event->point(0); - QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePosition(), false, false); + QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point, false, false); for (QQuickItem *item : targetItems) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); @@ -2340,16 +2340,16 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) --pointerEventRecursionGuard; } -// check if item or any of its child items contain the point +// check if item or any of its child items contain the point, or if any pointer handler "wants" the point // FIXME: should this be iterative instead of recursive? // If checkMouseButtons is true, it means we are finding targets for a mouse event, so no item for which acceptedMouseButtons() is NoButton will be added. // If checkAcceptsTouch is true, it means we are finding targets for a touch event, so either acceptTouchEvents() must return true OR // it must accept a synth. mouse event, thus if acceptTouchEvents() returns false but acceptedMouseButtons() is true, gets added; if not, it doesn't. -QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, const QPointF &scenePos, bool checkMouseButtons, bool checkAcceptsTouch) const +QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, QQuickEventPoint *point, bool checkMouseButtons, bool checkAcceptsTouch) const { QVector<QQuickItem *> targets; auto itemPrivate = QQuickItemPrivate::get(item); - QPointF itemPos = item->mapFromScene(scenePos); + QPointF itemPos = item->mapFromScene(point->scenePosition()); // if the item clips, we can potentially return early if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { if (!item->contains(itemPos)) @@ -2363,11 +2363,15 @@ QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, cons auto childPrivate = QQuickItemPrivate::get(child); if (!child->isVisible() || !child->isEnabled() || childPrivate->culled) continue; - targets << pointerTargets(child, scenePos, checkMouseButtons, checkAcceptsTouch); + targets << pointerTargets(child, point, checkMouseButtons, checkAcceptsTouch); } bool relevant = item->contains(itemPos); - if (!(itemPrivate->hasPointerHandlers())) { + if (itemPrivate->hasPointerHandlers()) { + if (!relevant) + if (itemPrivate->anyPointerHandlerWants(point)) + relevant = true; + } else { if (relevant && checkMouseButtons && item->acceptedMouseButtons() == Qt::NoButton) relevant = false; if (relevant && checkAcceptsTouch && !(item->acceptTouchEvents() || item->acceptedMouseButtons())) @@ -2477,7 +2481,7 @@ void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve QQuickEventPoint *point = event->point(i); if (point->state() == QQuickEventPoint::Pressed) continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints - QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false); + QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point, false, false); if (targetItems.count()) { targetItems = mergePointerTargets(targetItems, targetItemsForPoint); } else { @@ -2507,7 +2511,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, point->setAccepted(false); // because otherwise touchEventForItem will ignore it if (point->grabberPointerHandler() && point->state() == QQuickEventPoint::Released) point->setGrabberPointerHandler(nullptr, true); - QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), !isTouchEvent, isTouchEvent); + QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point, !isTouchEvent, isTouchEvent); if (targetItems.count()) { targetItems = mergePointerTargets(targetItems, targetItemsForPoint); } else { @@ -2567,7 +2571,6 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo // synthetic events - flickable sends one when setPressDelay is used. auto oldMouseGrabber = q->mouseGrabberItem(); QPointF localPos = item->mapFromScene(point->scenePosition()); - Q_ASSERT(item->contains(localPos)); // transform is checked already QMouseEvent *me = event->asMouseEvent(localPos); me->accept(); QCoreApplication::sendEvent(item, me); diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index eb2f4d20fa..9a83e8523b 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -175,7 +175,7 @@ public: void deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event); void deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, bool handlersOnly = false); - QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &, bool checkMouseButtons, bool checkAcceptsTouch) const; + QVector<QQuickItem *> pointerTargets(QQuickItem *, QQuickEventPoint *point, bool checkMouseButtons, bool checkAcceptsTouch) const; QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const; // hover delivery |