Skip to content

Commit 1bcce82

Browse files
isolovevQt Cherry-pick Bot
authored andcommitted
ListView: take section size into account while snapping an item into place
In case the sections are displayed using ViewSection.CurrentLabelAtStart, the section size should be taken into account while snapping the items. This patch extends the fixup() method to perform such checks. The drawback of this approach is that the position adjustment takes some time (because of the animation) and happens after the scrolling is finished. A better solution would be to fix the scrolling process in such a way, that no adjustment is needed during fixup. Fixes: QTBUG-30768 Pick-to: 6.2 Change-Id: I31a1a3af55afe8be4e8d7980cbb163622e3283bc Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit 249fe4b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit b29bfa7) (cherry picked from commit 174e6b5)
1 parent 2fea384 commit 1bcce82

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

src/quick/items/qquicklistview.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,19 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
17971797
QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
17981798
return;
17991799
}
1800+
// If we have the CurrentLabelAtStart flag set, then we need to consider
1801+
// the section size while calculating the position
1802+
if (sectionCriteria
1803+
&& (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart)
1804+
&& currentSectionItem) {
1805+
auto sectionSize = (orient == QQuickListView::Vertical) ? currentSectionItem->height()
1806+
: currentSectionItem->width();
1807+
if (isContentFlowReversed())
1808+
pos += sectionSize;
1809+
else
1810+
pos -= sectionSize;
1811+
}
1812+
18001813
pos = qBound(-minExtent, pos, -maxExtent);
18011814

18021815
qreal dist = qAbs(data.move + pos);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import QtQuick
2+
3+
ListView {
4+
id: listView
5+
width: 240
6+
height: 300
7+
8+
model: ListModel {
9+
ListElement { section: "section 1" }
10+
ListElement { section: "section 1" }
11+
ListElement { section: "section 1" }
12+
ListElement { section: "section 2" }
13+
ListElement { section: "section 2" }
14+
ListElement { section: "section 2" }
15+
ListElement { section: "section 3" }
16+
ListElement { section: "section 3" }
17+
ListElement { section: "section 3" }
18+
ListElement { section: "section 4" }
19+
ListElement { section: "section 4" }
20+
ListElement { section: "section 4" }
21+
ListElement { section: "section 5" }
22+
ListElement { section: "section 5" }
23+
ListElement { section: "section 5" }
24+
}
25+
26+
section.property: "section"
27+
section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
28+
section.delegate: Rectangle {
29+
width: listView.width
30+
height: 30
31+
Text {
32+
anchors.fill: parent
33+
text: section
34+
}
35+
color: "lightblue"
36+
}
37+
38+
snapMode: ListView.SnapToItem
39+
40+
delegate: Rectangle {
41+
width: listView.width
42+
height: 30
43+
Text {
44+
anchors.fill: parent
45+
text: index
46+
}
47+
border {
48+
width: 1
49+
color: "black"
50+
}
51+
}
52+
}

tests/auto/quick/qquicklistview/tst_qquicklistview.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ private slots:
171171
void headerSnapToItem_data();
172172
void headerSnapToItem();
173173
void snapToItemWithSpacing_QTBUG_59852();
174+
void snapToItemWithSectionAtStart();
174175
void snapOneItemResize_QTBUG_43555();
175176
void snapOneItem_data();
176177
void snapOneItem();
@@ -5395,6 +5396,27 @@ void tst_QQuickListView::snapToItemWithSpacing_QTBUG_59852()
53955396
releaseView(window);
53965397
}
53975398

5399+
void tst_QQuickListView::snapToItemWithSectionAtStart() // QTBUG-30768
5400+
{
5401+
QQuickView window;
5402+
QVERIFY(QQuickTest::showView(window, testFileUrl("snapToItemWithSectionAtStart.qml")));
5403+
QQuickListView *listView = qobject_cast<QQuickListView *>(window.rootObject());
5404+
QTRY_VERIFY(listView);
5405+
5406+
// Both sections and elements are 30px high. The list height is 300px, so
5407+
// it fits exactly 10 elements. We can do some random flicks, but the
5408+
// content position always MUST be divisible by 30.
5409+
for (int i = 0; i < 10; ++i) {
5410+
const bool even = (i % 2 == 0);
5411+
const QPoint start = even ? QPoint(20, 100 + i * 5) : QPoint(20, 20 + i * 3);
5412+
const QPoint end = even ? start - QPoint(0, 50 + i * 10) : start + QPoint(0, 50 + i * 5);
5413+
5414+
flick(&window, start, end, 180);
5415+
QTRY_COMPARE(listView->isMoving(), false); // wait until it stops
5416+
QCOMPARE(int(listView->contentY()) % 30, 0);
5417+
}
5418+
}
5419+
53985420
static void drag_helper(QWindow *window, QPoint *startPos, const QPoint &delta)
53995421
{
54005422
QPoint pos = *startPos;

0 commit comments

Comments
 (0)