From c89f7a221b7c31a0a4e1b0eed2e91d7633f4eab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Mon, 14 Oct 2019 14:39:48 +0200 Subject: Fix a layout bug caused by a delegate item that was moved by the user The position of the first item in the list of visualItems was used to know how to layout the rest of the visual items. However, this did not work if the first item was actually moved (e.g. due to a DnD operation). We therefore store the position of the first visual item after each time we arrange it, and use that as a basis on where to start layouting from. Task-number: QTBUG-78076 Change-Id: I837f5b7d61a13d98d23287685c6fd66817360906 Reviewed-by: Richard Moe Gustavsen --- src/quick/items/qquickitemview.cpp | 6 +++++- src/quick/items/qquickitemview_p_p.h | 6 ++++++ src/quick/items/qquicklistview.cpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 120eeb13d5..370ecee01d 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1784,6 +1784,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) if (prevCount != itemCount) emit q->countChanged(); } while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()); + storeFirstVisibleItemPosition(); } void QQuickItemViewPrivate::regenerate(bool orientationChanged) @@ -1870,6 +1871,7 @@ void QQuickItemViewPrivate::layout() updateSections(); layoutVisibleItems(); + storeFirstVisibleItemPosition(); int lastIndexInView = findLastIndexInView(); refill(); @@ -1954,7 +1956,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult prevFirstItemInViewPos = prevFirstItemInView->position(); prevFirstItemInViewIndex = prevFirstItemInView->index; } - qreal prevVisibleItemsFirstPos = visibleItems.count() ? visibleItems.constFirst()->position() : 0.0; + qreal prevVisibleItemsFirstPos = visibleItems.count() ? firstVisibleItemPosition : 0.0; totalInsertionResult->visiblePos = prevFirstItemInViewPos; totalRemovalResult->visiblePos = prevFirstItemInViewPos; @@ -2000,6 +2002,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult if (!insertions.isEmpty()) { repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult); layoutVisibleItems(removals.first().index); + storeFirstVisibleItemPosition(); } } @@ -2020,6 +2023,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult if (i < insertions.count() - 1) { repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult); layoutVisibleItems(insertions[i].index); + storeFirstVisibleItemPosition(); } itemCount += insertions[i].count; } diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 1f42c847b3..325b91d190 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -258,6 +258,12 @@ public: MovementReason moveReason; QList visibleItems; + qreal firstVisibleItemPosition = 0; + void storeFirstVisibleItemPosition() { + if (!visibleItems.isEmpty()) { + firstVisibleItemPosition = visibleItems.constFirst()->position(); + } + } int visibleIndex; int currentIndex; FxViewItem *currentItem; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 8b70ffd0d7..ebae4d14ea 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -805,6 +805,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex) FxViewItem *firstItem = *visibleItems.constBegin(); bool fixedCurrent = currentItem && firstItem->item == currentItem->item; + firstVisibleItemPosition = firstItem->position(); qreal sum = firstItem->size(); qreal pos = firstItem->position() + firstItem->size() + spacing; firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to); -- cgit v1.2.3