Fix bug when highlight was not respected after currentIndex changed

QQuickListViewPrivate::fixup() seems to only do "fixup" if

  moveReason != QQuickListViewPrivate::SetIndex

By default, moveReason is set to Other. In the snippet given in
QTBUG-77418, this is why the highlight was respected when resizing the
ListView initially. However, after the currentIndex was changed,
moveReason was changed to SetIndex. When we then resized the ListView, it
still had the value SetIndex, and would fail to "fixup" properly.

Since the ListView preferredHighlightBegin is bound to width, we should
set moveReason to Other in the property setters that are related to
highlight. This is then consistent with how setCurrentIndex() does it (it
similarly sets d->moveReason = QQuickItemViewPrivate::SetIndex;)

Change-Id: I7edf77fc977e8c7e3fc656ff5bb22b4dd01afbe4
Task-number: QTBUG-77418
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Jan Arve Sæther 2019-09-24 15:56:50 +02:00
parent 8f543f6913
commit 8b9a67dd7b
2 changed files with 38 additions and 4 deletions

View File

@ -599,6 +599,7 @@ void QQuickItemView::setHighlightRangeMode(HighlightRangeMode mode)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
emit highlightRangeModeChanged();
@ -621,8 +622,10 @@ void QQuickItemView::setPreferredHighlightBegin(qreal start)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightBeginChanged();
}
@ -636,8 +639,10 @@ void QQuickItemView::resetPreferredHighlightBegin()
d->highlightRangeStart = 0;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightBeginChanged();
}
@ -658,8 +663,10 @@ void QQuickItemView::setPreferredHighlightEnd(qreal end)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightEndChanged();
}
@ -673,8 +680,10 @@ void QQuickItemView::resetPreferredHighlightEnd()
d->highlightRangeEnd = 0;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightEndChanged();
}

View File

@ -1943,6 +1943,31 @@ void tst_QQuickListView::enforceRange()
QTRY_COMPARE(listview->currentIndex(), 6);
// Test for [QTBUG-77418] {
// explicit set current index
listview->setCurrentIndex(5);
QTRY_COMPARE(listview->contentY(), 0);
// then check if contentY changes if the highlight range is changed
listview->setPreferredHighlightBegin(80);
listview->setPreferredHighlightEnd(80);
QTRY_COMPARE(listview->contentY(), 20);
// verify that current index does not change with no highlight
listview->setHighlightRangeMode(QQuickListView::NoHighlightRange);
listview->setContentY(100);
QTRY_COMPARE(listview->currentIndex(), 5);
// explicit set current index, contentY should not change now
listview->setCurrentIndex(6);
QTRY_COMPARE(listview->contentY(), 100);
QTest::qWait(50); // This was needed in order to reproduce a failure for the following test
// verify that contentY changes if we turn on highlight again
listview->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
QTRY_COMPARE(listview->contentY(), 40);
// } Test for [QTBUG-77418]
// change model
QaimModel model2;
for (int i = 0; i < 5; i++)