aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-02-28 13:44:47 +0100
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-03-05 13:33:24 +0100
commit6c56852fd1f044792df9c91b29c219ff022857ca (patch)
treebe6a6031254646821159b189c4def32ab7809eeb
parentd958aae44739436aac26ee16b8ac6dd048919cf6 (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.cpp24
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp58
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);
}