diff options
author | Oliver Eftevaag <oliver.eftevaag@qt.io> | 2022-08-02 14:28:56 +0200 |
---|---|---|
committer | Jan Arve Sæther <jan-arve.saether@qt.io> | 2022-09-06 10:58:37 +0200 |
commit | 31d3c4bfbf1b90b9f1b69cde2fd6e4b81465190c (patch) | |
tree | da358a032c985fe41b8cb97b6c4f8a22b07ec903 /src/quick | |
parent | f5962820d569865d943be57a633edb4c606831fd (diff) |
Flickable: let changing contentItem pos also affect the drag starting pos
When calling the setContentX(qreal) and setContentY(qreal) functions,
the flickable would not update the drag starting position if they were
called in the middle of a dragging operation.
This patch makes those function update the drag starting position, so
that the drag will take into account the external changes to the
contentItem position, and not make any massive leaps on the next call to
drag() after changing the contentItem position directly.
Note that vData.pressPos and hData.pressPos are set to the x and y
position of the contentItem at the beginning of a drag operation.
They are unrelated to the mouse position.
The bug QTBUG-104966 will be fixed from this, since QQuickItemView::setModel() calls
QQuickListViewPrivate::setPosition() which calls
QQuickFlickable::setContentX/Y().
The QQuickFlickable::setContentX/Y functions are public (part of the public
API). They will update the timeline value for the x and y axis, which
will as a result also call setViewportX/Y, which calls setX/Y for the
contentItem itself.
Done-with: Jan Arve Sæther <jan-arve.saether@qt.io>
Fixes: QTBUG-104966
Change-Id: Id5165e1ff37a07b94be8c1cc152e86dfcc13d1c6
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
(cherry picked from commit 5647527a8cde84b51fff66fc482f02435770b3dd)
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 28 | ||||
-rw-r--r-- | src/quick/items/qquickflickable_p_p.h | 4 |
2 files changed, 25 insertions, 7 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 5fd8aac232..ca629bf50b 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -353,7 +353,7 @@ void QQuickFlickablePrivate::AxisData::updateVelocity() } } -void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) +void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeom) { Q_Q(QQuickFlickable); if (item == contentItem) { @@ -362,8 +362,14 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr orient |= Qt::Horizontal; if (change.yChange()) orient |= Qt::Vertical; - if (orient) + if (orient) { q->viewportMoved(orient); + const QPointF deltaMoved = item->position() - oldGeom.topLeft(); + if (hData.contentPositionChangedExternallyDuringDrag) + hData.pressPos += deltaMoved.x(); + if (vData.contentPositionChangedExternallyDuringDrag) + vData.pressPos += deltaMoved.y(); + } if (orient & Qt::Horizontal) emit q->contentXChanged(); if (orient & Qt::Vertical) @@ -823,8 +829,11 @@ void QQuickFlickable::setContentX(qreal pos) d->hData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(true, false); - if (!qFuzzyCompare(-pos, d->hData.move.value())) + if (!qFuzzyCompare(-pos, d->hData.move.value())) { + d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging; d->hData.move.setValue(-pos); + d->hData.contentPositionChangedExternallyDuringDrag = false; + } } qreal QQuickFlickable::contentY() const @@ -841,8 +850,11 @@ void QQuickFlickable::setContentY(qreal pos) d->vData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(false, true); - if (!qFuzzyCompare(-pos, d->vData.move.value())) + if (!qFuzzyCompare(-pos, d->vData.move.value())) { + d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging; d->vData.move.setValue(-pos); + d->vData.contentPositionChangedExternallyDuringDrag = false; + } } /*! @@ -2242,9 +2254,11 @@ void QQuickFlickable::setContentWidth(qreal w) d->contentItem->setWidth(w); d->hData.markExtentsDirty(); // Make sure that we're entirely in view. - if (!d->pressed && !d->hData.moving && !d->vData.moving) { + if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->hData.dragging) { + d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging; d->fixupMode = QQuickFlickablePrivate::Immediate; d->fixupX(); + d->hData.contentPositionChangedExternallyDuringDrag = false; } else if (!d->pressed && d->hData.fixingUp) { d->fixupMode = QQuickFlickablePrivate::ExtentChanged; d->fixupX(); @@ -2271,9 +2285,11 @@ void QQuickFlickable::setContentHeight(qreal h) d->contentItem->setHeight(h); d->vData.markExtentsDirty(); // Make sure that we're entirely in view. - if (!d->pressed && !d->hData.moving && !d->vData.moving) { + if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->vData.dragging) { + d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging; d->fixupMode = QQuickFlickablePrivate::Immediate; d->fixupY(); + d->vData.contentPositionChangedExternallyDuringDrag = false; } else if (!d->pressed && d->vData.fixingUp) { d->fixupMode = QQuickFlickablePrivate::ExtentChanged; d->fixupY(); diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index fad63c1ef1..6a3317ef6b 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -109,6 +109,7 @@ public: , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false) , dragging(false), extentsChanged(false) , explicitValue(false), minExtentDirty(true), maxExtentDirty(true) + , contentPositionChangedExternallyDuringDrag(false) , unused(0) {} @@ -169,7 +170,8 @@ public: bool explicitValue : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; - uint unused : 19; + bool contentPositionChangedExternallyDuringDrag : 1; + uint unused : 18; }; bool flickX(qreal velocity); |