From 52954268e9202e33eb8c2db93a51d55a2596051b Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 25 Nov 2015 16:37:12 +0100 Subject: GridView: add keyNavigationEnabled property It is useful for applications that need to selectively enable or disable mouse and keyboard interaction. [ChangeLog][QtQuick][GridView] added keyNavigationEnabled property to allow mouse and keyboard interaction to be selectively enabled/disabled. Change-Id: Idba0e00c2f228b79ca4c32d9856f22f7eaea98dd Task-number: QTBUG-17051 Reviewed-by: J-P Nurmi --- src/quick/items/qquickgridview.cpp | 22 ++++++- src/quick/items/qquickitemsmodule.cpp | 1 + .../quick/qquickgridview/tst_qquickgridview.cpp | 67 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 65d7362e84..150fa6a415 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -1502,6 +1502,25 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight) By default, key navigation is not wrapped. */ + +/*! + \qmlproperty bool QtQuick::GridView::keyNavigationEnabled + \since 5.7 + + This property holds whether the key navigation of the grid is enabled. + + If this is \c true, the user can navigate the view with a keyboard. + It is useful for applications that need to selectively enable or + disable mouse and keyboard interaction. + + By default, the value of this property is bound to + \l {Flickable::}{interactive} to ensure behavior compatibility for + existing applications. When explicitly set, it will cease to be bound to + the interactive property. + + \sa \l {Flickable::}{interactive} +*/ + /*! \qmlproperty int QtQuick::GridView::cacheBuffer This property determines whether delegates are retained outside the @@ -2076,7 +2095,8 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient) void QQuickGridView::keyPressEvent(QKeyEvent *event) { Q_D(QQuickGridView); - if (d->model && d->model->count() && d->interactive) { + if (d->model && d->model->count() && ((d->interactive && !d->explicitKeyNavigationEnabled) + || (d->explicitKeyNavigationEnabled && d->keyNavigationEnabled))) { d->moveReason = QQuickGridViewPrivate::SetIndex; int oldCurrent = currentIndex(); switch (event->key()) { diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index fcb52bdcb5..70915584fd 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -276,6 +276,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType(uri, 2, 6, "ShaderEffectSource"); qmlRegisterType(uri, 2, 7, "ListView"); + qmlRegisterType(uri, 2, 7, "GridView"); } static void initResources() diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 3699bef56d..e8261be675 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -211,6 +211,8 @@ private slots: void QTBUG_45640(); + void keyNavigationEnabled(); + private: QList toIntList(const QVariantList &list); void matchIndexLists(const QVariantList &indexLists, const QList &expectedIndexes); @@ -6566,6 +6568,71 @@ void tst_QQuickGridView::QTBUG_45640() delete window; } +void tst_QQuickGridView::keyNavigationEnabled() +{ + QScopedPointer window(createView()); + window->setSource(testFileUrl("gridview4.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickGridView *gridView = qobject_cast(window->rootObject()); + QVERIFY(gridView); + QCOMPARE(gridView->isKeyNavigationEnabled(), true); + + gridView->setFocus(true); + QVERIFY(gridView->hasActiveFocus()); + + gridView->setHighlightMoveDuration(0); + + // If keyNavigationEnabled is not explicitly set to true, respect the original behavior + // of disabling both mouse and keyboard interaction. + QSignalSpy enabledSpy(gridView, SIGNAL(keyNavigationEnabledChanged())); + gridView->setInteractive(false); + QCOMPARE(enabledSpy.count(), 1); + QCOMPARE(gridView->isKeyNavigationEnabled(), false); + + flick(window.data(), QPoint(200, 175), QPoint(200, 50), 100); + QVERIFY(!gridView->isMoving()); + QCOMPARE(gridView->contentY(), 0.0); + QCOMPARE(gridView->currentIndex(), 0); + + QTest::keyClick(window.data(), Qt::Key_Right); + QCOMPARE(gridView->currentIndex(), 0); + + // Check that isKeyNavigationEnabled implicitly follows the value of interactive. + gridView->setInteractive(true); + QCOMPARE(enabledSpy.count(), 2); + QCOMPARE(gridView->isKeyNavigationEnabled(), true); + + // Change it back again for the next check. + gridView->setInteractive(false); + QCOMPARE(enabledSpy.count(), 3); + QCOMPARE(gridView->isKeyNavigationEnabled(), false); + + // Setting keyNavigationEnabled to true shouldn't enable mouse interaction. + gridView->setKeyNavigationEnabled(true); + QCOMPARE(enabledSpy.count(), 4); + flick(window.data(), QPoint(200, 175), QPoint(200, 50), 100); + QVERIFY(!gridView->isMoving()); + QCOMPARE(gridView->contentY(), 0.0); + QCOMPARE(gridView->currentIndex(), 0); + + // Should now work. + QTest::keyClick(window.data(), Qt::Key_Right); + QCOMPARE(gridView->currentIndex(), 1); + + // Changing interactive now shouldn't result in keyNavigationEnabled changing, + // since we broke the "binding". + gridView->setInteractive(true); + QCOMPARE(enabledSpy.count(), 4); + + // Keyboard interaction shouldn't work now. + gridView->setKeyNavigationEnabled(false); + QTest::keyClick(window.data(), Qt::Key_Right); + QCOMPARE(gridView->currentIndex(), 1); +} + QTEST_MAIN(tst_QQuickGridView) #include "tst_qquickgridview.moc" -- cgit v1.2.3