diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-04-28 09:34:24 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-05-05 15:20:55 +0200 |
commit | f83efd3feb564cf8b929b9dfde6787853a561069 (patch) | |
tree | 3891b0db82c09dc8af57a4a9015cb393edf78365 /src/quick/items/qquickitem.cpp | |
parent | f2aaa182528008bfa6b3859e98263fa9470b1594 (diff) |
Use QQDeliveryAgent::sceneTransform, if set, in QQuickItem::mapFromGlobal
During dragging of a QEventPoint, Flickable computes the drag delta as
pos - mapFromGlobal(point.globalPressPosition())
We cannot use only the global position delta, because the Flickable
might be transformed in 2D (by setting rotation on it or in a parent, as
in tst_qquickflickable::clickAndDragWhenTransformed) or in 3D (by mapping
it onto a Model object). So we really need QQuickItem::mapFromGlobal()
to actually work regardless how many of these transformations are in
place. This is just the beginning: we have a lot of these mapFrom/To
functions; but it's enough for the Flickable in the quick3d/dynamictexture
example to work better. Without this fix, if you tried to drag a yellow
note on the door panel, at the very first drag ListView saw a large
delta and considered its drag threshold exceeded immediately, whereas
the DragHandler on the note saw a very small delta; so ListView grabbed
and DragHandler did not steal it: it relies on having "first dibs".
When the drag threshold is exceeded, Flickable merely plans to grab on
the next event rather than grabbing immediately, and therefore a child
has a chance to grab first. Therefore it's normally OK for DragHandler
to simply become the first exclusive grabber when the drag threshold is
exceeded, and not steal the grab from another item (although
grabPermissions can be changed to allow stealing if necessary).
However this means that we continue to enforce the drag threshold in
local (transformed) coordinates: if Flickable should wait until the
user drags 10 pixels, but it's scaled to half-size, it will start
dragging after only 5 pixels of movement, for example.
Pick-to: 6.1
Task-number: QTBUG-92944
Change-Id: Id01cc833ca80850ca18a965adf47f435e43e20ed
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 9e9e1a62d8..6bcd7da92a 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -8181,6 +8181,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} @@ -8188,7 +8194,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); } /*! |