From 8e0ea24115bcc9bf88ff09572feb05493ebc35c4 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 6 Jan 2012 09:58:27 +1000 Subject: [PATCH] Add itemAt(x,y) function to GridView and ListView. Task-number: QTBUG-21592 Change-Id: I3169e789da701ce261250421239584abd7f29b57 Reviewed-by: Bea Lam --- src/quick/items/qquickgridview.cpp | 13 +++++++++ src/quick/items/qquickitemview.cpp | 12 ++++++++ src/quick/items/qquickitemview_p.h | 1 + src/quick/items/qquicklistview.cpp | 13 +++++++++ .../qtquick2/qquickgridview/tst_qquickgridview.cpp | 34 +++++++++++++++++----- .../qtquick2/qquicklistview/tst_qquicklistview.cpp | 34 +++++++++++++++++----- 6 files changed, 93 insertions(+), 14 deletions(-) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index b3734e3..582f462 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -1975,6 +1975,19 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co \bold Note: methods should only be called after the Component has completed. */ +/*! + \qmlmethod Item QtQuick2::GridView::itemAt(int x, int y) + + Returns the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible null is returned. + + If the item is outside the visible area, null is returned, regardless of + whether an item will exist at that point when scrolled into view. + + \bold Note: methods should only be called after the Component has completed. +*/ + QQuickGridViewAttached *QQuickGridView::qmlAttachedProperties(QObject *obj) { return new QQuickGridViewAttached(obj); diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 927d107..879c02f 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -700,6 +700,18 @@ int QQuickItemView::indexAt(qreal x, qreal y) const return -1; } +QQuickItem *QQuickItemView::itemAt(qreal x, qreal y) const +{ + Q_D(const QQuickItemView); + for (int i = 0; i < d->visibleItems.count(); ++i) { + const FxViewItem *item = d->visibleItems.at(i); + if (item->contains(x, y)) + return item->item; + } + + return 0; +} + void QQuickItemViewPrivate::applyPendingChanges() { Q_Q(QQuickItemView); diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index 99aafc9..c659893 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -147,6 +147,7 @@ public: Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(qreal x, qreal y) const; + Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const; Q_INVOKABLE void positionViewAtBeginning(); Q_INVOKABLE void positionViewAtEnd(); diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 960565a..b2e9c61 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -2550,6 +2550,19 @@ bool QQuickListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::In \bold Note: methods should only be called after the Component has completed. */ +/*! + \qmlmethod Item QtQuick2::ListView::itemAt(int x, int y) + + Returns the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible null is returned. + + If the item is outside the visible area, null is returned, regardless of + whether an item will exist at that point when scrolled into view. + + \bold Note: methods should only be called after the Component has completed. +*/ + QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) { return new QQuickListViewAttached(obj); diff --git a/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp index a4a7679..fa42ddb 100644 --- a/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp @@ -103,7 +103,8 @@ private slots: void header(); void header_data(); void resizeViewAndRepaint(); - void indexAt(); + void indexAt_itemAt_data(); + void indexAt_itemAt(); void onAdd(); void onAdd_data(); void onRemove(); @@ -2986,8 +2987,25 @@ void tst_QQuickGridView::resizeViewAndRepaint() delete canvas; } -void tst_QQuickGridView::indexAt() +void tst_QQuickGridView::indexAt_itemAt_data() { + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("index"); + + QTest::newRow("Item 0 - 0, 0") << 0. << 0. << 0; + QTest::newRow("Item 0 - 79, 59") << 79. << 59. << 0; + QTest::newRow("Item 1 - 80, 0") << 80. << 0. << 1; + QTest::newRow("Item 3 - 0, 60") << 0. << 60. << 3; + QTest::newRow("No Item - 240, 0") << 240. << 0. << -1; +} + +void tst_QQuickGridView::indexAt_itemAt() +{ + QFETCH(qreal, x); + QFETCH(qreal, y); + QFETCH(int, index); + QQuickView *canvas = createView(); TestModel model; @@ -3015,11 +3033,13 @@ void tst_QQuickGridView::indexAt() QTRY_COMPARE(gridview->count(), model.count()); - QCOMPARE(gridview->indexAt(0, 0), 0); - QCOMPARE(gridview->indexAt(79, 59), 0); - QCOMPARE(gridview->indexAt(80, 0), 1); - QCOMPARE(gridview->indexAt(0, 60), 3); - QCOMPARE(gridview->indexAt(240, 0), -1); + QQuickItem *item = 0; + if (index >= 0) { + item = findItem(contentItem, "wrapper", index); + QVERIFY(item); + } + QCOMPARE(gridview->indexAt(x, y), index); + QVERIFY(gridview->itemAt(x, y) == item); delete canvas; } diff --git a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp index 2e03a14..7312e44 100644 --- a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp @@ -138,7 +138,8 @@ private slots: void resizeDelegate(); void resizeFirstDelegate(); void QTBUG_16037(); - void indexAt(); + void indexAt_itemAt_data(); + void indexAt_itemAt(); void incrementalModel(); void onAdd(); void onAdd_data(); @@ -3686,8 +3687,25 @@ void tst_QQuickListView::QTBUG_16037() delete canvas; } -void tst_QQuickListView::indexAt() +void tst_QQuickListView::indexAt_itemAt_data() { + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("index"); + + QTest::newRow("Item 0 - 0, 0") << 0. << 0. << 0; + QTest::newRow("Item 0 - 0, 19") << 0. << 19. << 0; + QTest::newRow("Item 0 - 239, 19") << 239. << 19. << 0; + QTest::newRow("Item 1 - 0, 20") << 0. << 20. << 1; + QTest::newRow("No Item - 240, 20") << 240. << 20. << -1; +} + +void tst_QQuickListView::indexAt_itemAt() +{ + QFETCH(qreal, x); + QFETCH(qreal, y); + QFETCH(int, index); + QQuickView *canvas = createView(); TestModel model; @@ -3709,11 +3727,13 @@ void tst_QQuickListView::indexAt() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - QCOMPARE(listview->indexAt(0,0), 0); - QCOMPARE(listview->indexAt(0,19), 0); - QCOMPARE(listview->indexAt(239,19), 0); - QCOMPARE(listview->indexAt(0,20), 1); - QCOMPARE(listview->indexAt(240,20), -1); + QQuickItem *item = 0; + if (index >= 0) { + item = findItem(contentItem, "wrapper", index); + QVERIFY(item); + } + QCOMPARE(listview->indexAt(x,y), index); + QVERIFY(listview->itemAt(x,y) == item); delete canvas; delete testObject; -- 2.7.4