aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-05-06 15:05:59 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-05-10 16:41:00 +0000
commitc8ec32c64c6867826d4555ed1f561ae52a574322 (patch)
tree50dfaa4e781045f6a74664645bd38b15a4c9c92b /tests/auto/quick
parenta46d508ef00180244ce1f4d9364217336f8b8326 (diff)
QQuickGridView: return accurate row position when no rows are available
QQuickGridViewPrivate::rowPosAt() returns the position of a row for a given index. At start-up, when no rows are yet loaded, a plain "(modelIndex / columns) * rowSize()" fallback calculation is sufficient. But as the user flicks around, and new rows are moving into the viewport, the current logic shifts to rely on the position of an already visible row to calculate the position of a new one. This is because the fallback calculation above will assume that row 0 always starts at contentY == 0, which is not always true for GridView - sometimes it will place rows outside the content item to make room for rows that were added after start-up. Likewise, if the cellWidth/Height changes, it might force existing rows to be placed outside the content item. So using an already loaded row as a reference becomes more accurate, especially when flicking slowly. The problem is that the fallback calculation is not only used at start-up. It's also used when e.g moving the content item a long distance in one go by e.g setting contentY directly, call positionViewAtBeginning(), or scroll using a ScrollBar. In that case, there will be no existing rows to rely on, since they have all been moved out of the viewport. Instead the error prone fallback calculation will be used. This patch will therefore adjust the fallback calculation to take all the necessary information into account, so that rowAtPos() returns the right position of a row, even when no rows are available as a reference. This will fix at least two bugs that happen because row 0 actually starts at a negative contentY, rather than at contentY == 0. Fixes: QTBUG-91461 Fixes: QTBUG-92868 Change-Id: I21be6846809ddedf3dba0c3212693e8063411166 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> (cherry picked from commit d0d6f70c91b1463e9f5b7a25d4e391cffb4fa5af) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquickgridview/data/qtbug91461.qml81
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp29
2 files changed, 110 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickgridview/data/qtbug91461.qml b/tests/auto/quick/qquickgridview/data/qtbug91461.qml
new file mode 100644
index 0000000000..50ab04e828
--- /dev/null
+++ b/tests/auto/quick/qquickgridview/data/qtbug91461.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick
+
+Item {
+ width: 640
+ height: 800
+
+ property real cellSize: 100
+
+ GridView {
+ id: grid
+ anchors.fill: parent
+ model: 1000
+ cellWidth: cellSize
+ cellHeight: cellSize
+ cacheBuffer: 0
+ currentIndex: 0
+
+ delegate: Rectangle {
+ implicitWidth: grid.cellWidth - 10
+ implicitHeight: grid.cellHeight - 10
+ color: GridView.isCurrentItem ? "green" : "lightgreen"
+ radius: 5
+ border.width: GridView.isCurrentItem ? 3 : 1
+ border.color: "black"
+
+ Text {
+ anchors.centerIn: parent
+ text: model.index
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 11840f2391..9532aa546c 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -212,6 +212,7 @@ private slots:
void QTBUG_45640();
void QTBUG_49218();
+ void positionViewAtBeginningAfterResizingCells();
void QTBUG_48870_fastModelUpdates();
void QTBUG_86255();
void resizeDynamicCellWidthRtL();
@@ -6698,6 +6699,34 @@ void tst_QQuickGridView::QTBUG_49218()
delete window;
}
+void tst_QQuickGridView::positionViewAtBeginningAfterResizingCells()
+{
+ // Check that positionViewAtBeginning() ends up showing row 0, even
+ // if the cells are resized while the viewport is deep down in the list (QTBUG-91461).
+ std::unique_ptr<QQuickView> window(createView());
+ window->setSource(testFileUrl("qtbug91461.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.get()));
+
+ QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
+ QQuickGridView *gridview = qobject_cast<QQuickGridView *>(rootItem->childItems().first());
+ QVERIFY(gridview != nullptr);
+
+ gridview->positionViewAtEnd();
+ QVERIFY(QQuickTest::qWaitForItemPolished(gridview));
+ rootItem->setProperty("cellSize", 200);
+ QVERIFY(QQuickTest::qWaitForItemPolished(gridview));
+ gridview->positionViewAtBeginning();
+ QVERIFY(QQuickTest::qWaitForItemPolished(gridview));
+
+ const QPointF topLeftCorner = window->contentItem()->mapToItem(gridview->contentItem(), QPointF(20, 20));
+ const auto item0 = gridview->itemAt(topLeftCorner.x(), topLeftCorner.y());
+ QVERIFY(item0);
+
+ const int index = qmlContext(item0)->contextProperty("index").toInt();
+ QCOMPARE(index, 0);
+}
+
void tst_QQuickGridView::keyNavigationEnabled()
{
QScopedPointer<QQuickView> window(createView());