diff options
-rw-r--r-- | src/quick/handlers/qquickpointerhandler.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 13 | ||||
-rw-r--r-- | src/quick/util/qquickdeliveryagent.cpp | 29 | ||||
-rw-r--r-- | src/quick/util/qquickdeliveryagent_p.h | 1 | ||||
-rw-r--r-- | src/quick/util/qquickdeliveryagent_p_p.h | 1 |
5 files changed, 44 insertions, 3 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 11c29ee812..254f91cfe1 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -302,7 +302,8 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QPointin */ void QQuickPointerHandler::setPassiveGrab(QPointerEvent *event, const QEventPoint &point, bool grab) { - qCDebug(lcPointerHandlerGrab) << point << grab; + qCDebug(lcPointerHandlerGrab) << this << point << grab << "via" + << QQuickDeliveryAgentPrivate::currentOrItemDeliveryAgent(parentItem()); if (grab) { event->addPassiveGrabber(point, this); } else { diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 464076cbf8..05e50d8e75 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -8178,6 +8178,12 @@ QPointF QQuickItem::mapFromScene(const QPointF &point) const treated only as a hint. So, the resulting window position may differ from what is expected. + \note If this item is in a subscene, e.g. mapped onto a 3D + \l [QtQuick3D QML] {Model}{Model} object, the UV mapping is incorporated + into this transformation, so that it really goes from screen coordinates to + this item's coordinates, as long as \a point is actually within this item's bounds. + The other mapping functions do not yet work that way. + \since 5.7 \sa {Concepts - Visual Coordinates in Qt Quick} @@ -8185,7 +8191,12 @@ QPointF QQuickItem::mapFromScene(const QPointF &point) const QPointF QQuickItem::mapFromGlobal(const QPointF &point) const { Q_D(const QQuickItem); - return mapFromScene(d->globalToWindowTransform().map(point)); + QPointF scenePoint = d->globalToWindowTransform().map(point); + if (auto da = QQuickDeliveryAgentPrivate::currentOrItemDeliveryAgent(this)) { + if (auto sceneTransform = da->sceneTransform()) + scenePoint = sceneTransform->map(scenePoint); + } + return mapFromScene(scenePoint); } /*! diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp index a38ac410d4..3b045ed8e4 100644 --- a/src/quick/util/qquickdeliveryagent.cpp +++ b/src/quick/util/qquickdeliveryagent.cpp @@ -626,6 +626,21 @@ void QQuickDeliveryAgentPrivate::updateFocusItemTransform() } /*! \internal + If called during event delivery, returns the agent that is delivering the + event, without checking whether \a item is reachable from there. + Otherwise returns QQuickItemPrivate::deliveryAgent() (the delivery agent for + the narrowest subscene containing \a item), or \c null if \a item is \c null. +*/ +QQuickDeliveryAgent *QQuickDeliveryAgentPrivate::currentOrItemDeliveryAgent(const QQuickItem *item) +{ + if (currentEventDeliveryAgent) + return currentEventDeliveryAgent; + if (item) + return QQuickItemPrivate::get(const_cast<QQuickItem *>(item))->deliveryAgent(); + return nullptr; +} + +/*! \internal QQuickDeliveryAgent delivers events to a tree of Qt Quick Items, beginning with the given root item, which is usually QQuickWindow::rootItem() but may alternatively be embedded into a Qt Quick 3D scene or something else. @@ -650,8 +665,20 @@ QQuickItem *QQuickDeliveryAgent::rootItem() const } /*! \internal + Returns the object that was set in setSceneTransform(): a functor that + transforms from scene coordinates in the parent scene to scene coordinates + within this DA's subscene, or \c null if none was set. +*/ +QQuickDeliveryAgent::Transform *QQuickDeliveryAgent::sceneTransform() const +{ + Q_D(const QQuickDeliveryAgent); + return d->sceneTransform; +} + +/*! \internal QQuickDeliveryAgent takes ownership of the given \a transform, which - encapsulates the ability to transform viewport coordinates to rootItem coordinates. + encapsulates the ability to transform parent scene coordinates to rootItem + (subscene) coordinates. */ void QQuickDeliveryAgent::setSceneTransform(QQuickDeliveryAgent::Transform *transform) { diff --git a/src/quick/util/qquickdeliveryagent_p.h b/src/quick/util/qquickdeliveryagent_p.h index 9b73d9b9b9..df8c97b368 100644 --- a/src/quick/util/qquickdeliveryagent_p.h +++ b/src/quick/util/qquickdeliveryagent_p.h @@ -81,6 +81,7 @@ public: QQuickItem *rootItem() const; + Transform *sceneTransform() const; void setSceneTransform(Transform *transform); bool event(QEvent *ev) override; diff --git a/src/quick/util/qquickdeliveryagent_p_p.h b/src/quick/util/qquickdeliveryagent_p_p.h index ad1eece36e..f931cfd70b 100644 --- a/src/quick/util/qquickdeliveryagent_p_p.h +++ b/src/quick/util/qquickdeliveryagent_p_p.h @@ -121,6 +121,7 @@ public: static bool subsceneAgentsExist; // QQuickDeliveryAgent::event() sets this to the one that's currently (trying to) handle the event static QQuickDeliveryAgent *currentEventDeliveryAgent; + static QQuickDeliveryAgent *currentOrItemDeliveryAgent(const QQuickItem *item); Qt::FocusReason lastFocusReason = Qt::OtherFocusReason; int pointerEventRecursionGuard = 0; |