diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-02-28 13:44:47 +0100 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-03-05 13:33:24 +0100 |
commit | 6c56852fd1f044792df9c91b29c219ff022857ca (patch) | |
tree | be6a6031254646821159b189c4def32ab7809eeb | |
parent | d958aae44739436aac26ee16b8ac6dd048919cf6 (diff) |
QQuickTableView: change cellAtPos() so that any loaded cell is found
The current implementation would only find cells that were
inside the bounding rect of the view. By changing the function so
that it also find cells that are halfway outside the view (as long as
they are loaded), it becomes useful also for implementing selection support
(finding cells under the current selection, even those cells that are
halfway outside the viewport).
Task-number: QTBUG-100696
Change-Id: Ie54dc9b8773e7295ead0c9644dbbc5052b8e40fc
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 24 | ||||
-rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 58 |
2 files changed, 49 insertions, 33 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index e5a4eae4ce..ff3ef6638d 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -556,8 +556,8 @@ /*! \qmlmethod Point QtQuick::TableView::cellAtPos(point position, bool includeSpacing) - Returns the cell at the given \a position in the view. If no cell intersects with - \a position, the return value will be \c point(-1, -1). + Returns the cell at the given \a position in the view. If no \l {isRowLoaded()}{loaded} + cell intersects with \a position, the return value will be \c point(-1, -1). If \a includeSpacing is set to \c true, a cell's bounding box will be considered to include half the adjacent \l rowSpacing and \l columnSpacing on each side. The @@ -4014,27 +4014,29 @@ QPoint QQuickTableView::cellAtPos(const QPointF &position, bool includeSpacing) { Q_D(const QQuickTableView); - if (!boundingRect().contains(position)) + const QPointF localPos = mapToItem(d->contentItem, position); + if (!d->loadedTableOuterRect.contains(localPos)) return QPoint(-1, -1); const qreal hSpace = d->cellSpacing.width(); const qreal vSpace = d->cellSpacing.height(); - qreal currentColumnEnd = d->loadedTableOuterRect.x() - contentX(); - qreal currentRowEnd = d->loadedTableOuterRect.y() - contentY(); + qreal currentColumnEnd = d->loadedTableOuterRect.x(); + qreal currentRowEnd = d->loadedTableOuterRect.y(); + int foundColumn = -1; int foundRow = -1; for (const int column : d->loadedColumns) { currentColumnEnd += d->getEffectiveColumnWidth(column); - if (position.x() < currentColumnEnd) { + if (localPos.x() < currentColumnEnd) { foundColumn = column; break; } currentColumnEnd += hSpace; - if (!includeSpacing && position.x() < currentColumnEnd) { + if (!includeSpacing && localPos.x() < currentColumnEnd) { // Hit spacing return QPoint(-1, -1); - } else if (includeSpacing && position.x() < currentColumnEnd - (hSpace / 2)) { + } else if (includeSpacing && localPos.x() < currentColumnEnd - (hSpace / 2)) { foundColumn = column; break; } @@ -4042,16 +4044,16 @@ QPoint QQuickTableView::cellAtPos(const QPointF &position, bool includeSpacing) for (const int row : d->loadedRows) { currentRowEnd += d->getEffectiveRowHeight(row); - if (position.y() < currentRowEnd) { + if (localPos.y() < currentRowEnd) { foundRow = row; break; } currentRowEnd += vSpace; - if (!includeSpacing && position.y() < currentRowEnd) { + if (!includeSpacing && localPos.y() < currentRowEnd) { // Hit spacing return QPoint(-1, -1); } - if (includeSpacing && position.y() < currentRowEnd - (vSpace / 2)) { + if (includeSpacing && localPos.y() < currentRowEnd - (vSpace / 2)) { foundRow = row; break; } diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index c6eda28529..cdcd704f98 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -3070,9 +3070,10 @@ void tst_QQuickTableView::replaceModel() void tst_QQuickTableView::cellAtPos_data() { QTest::addColumn<QPointF>("contentStartPos"); - QTest::addColumn<QPointF>("position"); + QTest::addColumn<QPointF>("localPos"); QTest::addColumn<bool>("includeSpacing"); QTest::addColumn<QPoint>("expectedCell"); + QTest::addColumn<QSizeF>("margins"); const int spacing = 10; const QPointF cellSize(100, 50); @@ -3085,49 +3086,62 @@ void tst_QQuickTableView::cellAtPos_data() return QPointF(x, y); }; - QTest::newRow("1") << QPointF(0, 0) << cellStart(0, 0) << false << QPoint(0, 0); - QTest::newRow("2") << QPointF(0, 0) << cellStart(1, 0) << false << QPoint(1, 0); - QTest::newRow("3") << QPointF(0, 0) << cellStart(0, 1) << false << QPoint(0, 1); - QTest::newRow("4") << QPointF(0, 0) << cellStart(1, 1) << false << QPoint(1, 1); + QTest::newRow("1") << QPointF(0, 0) << cellStart(0, 0) << false << QPoint(0, 0) << QSizeF(0, 0); + QTest::newRow("2") << QPointF(0, 0) << cellStart(1, 0) << false << QPoint(1, 0) << QSizeF(0, 0); + QTest::newRow("3") << QPointF(0, 0) << cellStart(0, 1) << false << QPoint(0, 1) << QSizeF(0, 0); + QTest::newRow("4") << QPointF(0, 0) << cellStart(1, 1) << false << QPoint(1, 1) << QSizeF(0, 0); - QTest::newRow("5") << QPointF(0, 0) << cellStart(1, 1) - quadSpace << false << QPoint(-1, -1); - QTest::newRow("6") << QPointF(0, 0) << cellStart(0, 0) + cellSize + quadSpace << false << QPoint(-1, -1); - QTest::newRow("7") << QPointF(0, 0) << cellStart(0, 1) + cellSize + quadSpace << false << QPoint(-1, -1); + QTest::newRow("5") << QPointF(0, 0) << cellStart(1, 1) - quadSpace << false << QPoint(-1, -1) << QSizeF(0, 0); + QTest::newRow("6") << QPointF(0, 0) << cellStart(0, 0) + cellSize + quadSpace << false << QPoint(-1, -1) << QSizeF(0, 0); + QTest::newRow("7") << QPointF(0, 0) << cellStart(0, 1) + cellSize + quadSpace << false << QPoint(-1, -1) << QSizeF(0, 0); - QTest::newRow("8") << QPointF(0, 0) << cellStart(1, 1) - quadSpace << true << QPoint(1, 1); - QTest::newRow("9") << QPointF(0, 0) << cellStart(0, 0) + cellSize + quadSpace << true << QPoint(0, 0); - QTest::newRow("10") << QPointF(0, 0) << cellStart(0, 1) + cellSize + quadSpace << true << QPoint(0, 1); + QTest::newRow("8") << QPointF(0, 0) << cellStart(1, 1) - quadSpace << true << QPoint(1, 1) << QSizeF(0, 0); + QTest::newRow("9") << QPointF(0, 0) << cellStart(0, 0) + cellSize + quadSpace << true << QPoint(0, 0) << QSizeF(0, 0); + QTest::newRow("10") << QPointF(0, 0) << cellStart(0, 1) + cellSize + quadSpace << true << QPoint(0, 1) << QSizeF(0, 0); - QTest::newRow("11") << cellStart(50, 50) << cellStart(0, 0) << false << QPoint(50, 50); - QTest::newRow("12") << cellStart(50, 50) << cellStart(4, 4) << false << QPoint(54, 54); - QTest::newRow("13") << cellStart(50, 50) << cellStart(4, 4) - quadSpace << false << QPoint(-1, -1); - QTest::newRow("14") << cellStart(50, 50) << cellStart(4, 4) + cellSize + quadSpace << false << QPoint(-1, -1); - QTest::newRow("15") << cellStart(50, 50) << cellStart(4, 4) - quadSpace << true << QPoint(54, 54); - QTest::newRow("16") << cellStart(50, 50) << cellStart(4, 4) + cellSize + quadSpace << true << QPoint(54, 54); + QTest::newRow("11") << cellStart(50, 50) << cellStart(50, 50) << false << QPoint(50, 50) << QSizeF(0, 0); + QTest::newRow("12") << cellStart(50, 50) << cellStart(54, 54) << false << QPoint(54, 54) << QSizeF(0, 0); + QTest::newRow("13") << cellStart(50, 50) << cellStart(54, 54) - quadSpace << false << QPoint(-1, -1) << QSizeF(0, 0); + QTest::newRow("14") << cellStart(50, 50) << cellStart(54, 54) + cellSize + quadSpace << false << QPoint(-1, -1) << QSizeF(0, 0); + QTest::newRow("15") << cellStart(50, 50) << cellStart(54, 54) - quadSpace << true << QPoint(54, 54) << QSizeF(0, 0); + QTest::newRow("16") << cellStart(50, 50) << cellStart(54, 54) + cellSize + quadSpace << true << QPoint(54, 54) << QSizeF(0, 0); - QTest::newRow("17") << cellStart(50, 50) + halfCell << cellStart(0, 0) << false << QPoint(50, 50); - QTest::newRow("18") << cellStart(50, 50) + halfCell << cellStart(1, 1) << false << QPoint(51, 51); - QTest::newRow("19") << cellStart(50, 50) + halfCell << cellStart(4, 4) << false << QPoint(54, 54); + QTest::newRow("17") << cellStart(50, 50) + halfCell << cellStart(50, 50) << false << QPoint(50, 50) << QSizeF(0, 0); + QTest::newRow("18") << cellStart(50, 50) + halfCell << cellStart(51, 51) << false << QPoint(51, 51) << QSizeF(0, 0); + QTest::newRow("19") << cellStart(50, 50) + halfCell << cellStart(54, 54) << false << QPoint(54, 54) << QSizeF(0, 0); + + QTest::newRow("20") << QPointF(0, 0) << cellStart(0, 0) << false << QPoint(0, 0) << QSizeF(150, 150); + QTest::newRow("20") << QPointF(0, 0) << cellStart(5, 5) << false << QPoint(5, 5) << QSizeF(150, 150); + + QTest::newRow("20") << QPointF(-150, -150) << cellStart(0, 0) << false << QPoint(0, 0) << QSizeF(150, 150); + QTest::newRow("21") << QPointF(-150, -150) << cellStart(4, 0) + halfCell << false << QPoint(4, 0) << QSizeF(150, 150); + QTest::newRow("22") << QPointF(-150, -150) << cellStart(0, 4) + halfCell << false << QPoint(0, 4) << QSizeF(150, 150); + QTest::newRow("23") << QPointF(-150, -150) << cellStart(4, 4) + halfCell << false << QPoint(4, 4) << QSizeF(150, 150); } void tst_QQuickTableView::cellAtPos() { QFETCH(QPointF, contentStartPos); - QFETCH(QPointF, position); + QFETCH(QPointF, localPos); QFETCH(bool, includeSpacing); QFETCH(QPoint, expectedCell); + QFETCH(QSizeF, margins); LOAD_TABLEVIEW("plaintableview.qml"); auto model = TestModelAsVariant(100, 100); tableView->setModel(model); tableView->setRowSpacing(10); tableView->setColumnSpacing(10); + tableView->setLeftMargin(margins.width()); + tableView->setLeftMargin(margins.height()); + tableView->setTopMargin(margins.height()); tableView->setContentX(contentStartPos.x()); tableView->setContentY(contentStartPos.y()); WAIT_UNTIL_POLISHED; - QPoint cell = tableView->cellAtPos(position, includeSpacing); + const QPointF posInView = tableView->mapFromItem(tableView->contentItem(), localPos); + QPoint cell = tableView->cellAtPos(posInView, includeSpacing); QCOMPARE(cell, expectedCell); } |