diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-11-10 16:08:26 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-11-11 20:29:45 +0000 |
commit | 7894b7551b5f74127cddf455c76260aa98239375 (patch) | |
tree | 08535f927ced6b76219f5142f342a18f62521a81 | |
parent | 1a6a7b312123b6c407a5594b0a1df12248557296 (diff) |
QQuickTableView: detect if syncView topLeft has changed
It can happen that the top left cell in syncView changes
after a normal relayout. This is especially prone to
happen if the cells used to be large, but are suddenly
made much smaller, such that the top left cell ends
up outside the viewport.
This patch will detect this case, and ensure that the
top left is being recalculated when they are no
longer in sync.
Change-Id: I80cad2859a35e0f3bc58f101696112be7c084175
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit f15528407033057fb5c6e6ba5bbe8e5936fe346b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquicktableview/data/syncviewsimple.qml | 7 | ||||
-rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 37 |
3 files changed, 56 insertions, 2 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 2483b5781b..8aaf00c775 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -3720,6 +3720,13 @@ void QQuickTableViewPrivate::syncSyncView() q->setLeftMargin(syncView->leftMargin()); q->setRightMargin(syncView->rightMargin()); updateContentWidth(); + + if (syncView->leftColumn() != q->leftColumn()) { + // The left column is no longer the same as the left + // column in syncView. This requires a rebuild. + scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftColumn; + scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly); + } } if (syncVertically) { @@ -3728,6 +3735,13 @@ void QQuickTableViewPrivate::syncSyncView() q->setTopMargin(syncView->topMargin()); q->setBottomMargin(syncView->bottomMargin()); updateContentHeight(); + + if (syncView->topRow() != q->topRow()) { + // The top row is no longer the same as the top + // row in syncView. This requires a rebuild. + scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow; + scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly); + } } if (syncView && loadedItems.isEmpty() && !tableSize.isEmpty()) { diff --git a/tests/auto/quick/qquicktableview/data/syncviewsimple.qml b/tests/auto/quick/qquicktableview/data/syncviewsimple.qml index 73c47e859c..880554b129 100644 --- a/tests/auto/quick/qquicktableview/data/syncviewsimple.qml +++ b/tests/auto/quick/qquicktableview/data/syncviewsimple.qml @@ -13,6 +13,9 @@ Item { property alias tableViewV: tableViewV property alias tableViewHV: tableViewHV + property real delegateWidth: 30 + property real delegateHeight: 60 + Column { spacing: 10 TableView { @@ -89,8 +92,8 @@ Item { objectName: "tableViewDelegate" color: "lightgray" border.width: 1 - implicitWidth: 30 - implicitHeight: 60 + implicitWidth: delegateWidth + implicitHeight: delegateHeight Text { anchors.centerIn: parent diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index e4325dbdad..67e32d80de 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -160,6 +160,7 @@ private slots: void checkSyncView_connect_late(); void checkSyncView_pageFlicking(); void checkSyncView_emptyModel(); + void checkSyncView_topLeftChanged(); void delegateWithRequiredProperties(); void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable(); void replaceModel(); @@ -3097,6 +3098,42 @@ void tst_QQuickTableView::checkSyncView_emptyModel() QCOMPARE(tableViewVPrivate->loadedTableOuterRect.left(), 0); } +void tst_QQuickTableView::checkSyncView_topLeftChanged() +{ + LOAD_TABLEVIEW("syncviewsimple.qml"); + GET_QML_TABLEVIEW(tableViewH); + GET_QML_TABLEVIEW(tableViewV); + GET_QML_TABLEVIEW(tableViewHV); + QQuickTableView *views[] = {tableViewH, tableViewV, tableViewHV}; + + auto model = TestModelAsVariant(100, 100); + tableView->setModel(model); + + for (auto view : views) + view->setModel(model); + + tableView->setColumnWidthProvider(QJSValue()); + tableView->setRowHeightProvider(QJSValue()); + view->rootObject()->setProperty("delegateWidth", 300); + view->rootObject()->setProperty("delegateHeight", 300); + tableView->forceLayout(); + + tableViewHV->setContentX(350); + tableViewHV->setContentY(350); + + WAIT_UNTIL_POLISHED; + + QCOMPARE(tableViewH->leftColumn(), tableView->leftColumn()); + QCOMPARE(tableViewV->topRow(), tableView->topRow()); + + view->rootObject()->setProperty("delegateWidth", 50); + view->rootObject()->setProperty("delegateHeight", 50); + tableView->forceLayout(); + + QCOMPARE(tableViewH->leftColumn(), tableView->leftColumn()); + QCOMPARE(tableViewV->topRow(), tableView->topRow()); +} + void tst_QQuickTableView::checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable() { LOAD_TABLEVIEW("plaintableview.qml"); |