diff options
-rw-r--r-- | DemoApplication/CNButton.qml | 1 | ||||
-rw-r--r-- | DemoApplication/Page1Form.qml | 114 | ||||
-rw-r--r-- | DemoApplication/Page2Form.qml | 72 | ||||
-rw-r--r-- | plugin/cursornavigation.cpp | 53 | ||||
-rw-r--r-- | plugin/cursornavigation.h | 3 | ||||
-rw-r--r-- | tests/tst_cursornavigation.cpp | 7 |
6 files changed, 183 insertions, 67 deletions
diff --git a/DemoApplication/CNButton.qml b/DemoApplication/CNButton.qml index edd44cf..b4b28bf 100644 --- a/DemoApplication/CNButton.qml +++ b/DemoApplication/CNButton.qml @@ -12,6 +12,7 @@ Button { border.color: "red" anchors.fill: parent visible: button.hasCursor + color: "transparent" } } diff --git a/DemoApplication/Page1Form.qml b/DemoApplication/Page1Form.qml index cd2007c..fb7f09e 100644 --- a/DemoApplication/Page1Form.qml +++ b/DemoApplication/Page1Form.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 +import CursorNavigation 1.0 Page { width: 600 @@ -8,67 +9,76 @@ Page { title: qsTr("Page 1") - Label { - text: qsTr("You are on Page 1.") - anchors.centerIn: parent - } + FocusScope { + CursorNavigation.acceptsCursor: true - CNButton { - id: button - x: 52 - y: 50 - text: qsTr("Button") - } + anchors.fill: parent - CNButton { - id: button1 - x: 110 - y: 138 - text: qsTr("Button") - } + //this seems to be the way to force focus on a newly opened dialog? + Component.onCompleted: forceActiveFocus() - CNButton { - id: button2 - x: 202 - y: 241 - text: qsTr("Button") - } + Label { + text: qsTr("You are on Page 1.") + anchors.centerIn: parent + } - CNButton { - id: button3 - x: 383 - y: 241 - text: qsTr("Button") - } + CNButton { + id: button + x: 52 + y: 50 + text: qsTr("Button") + } - CNButton { - id: button4 - x: 383 - y: 322 - text: qsTr("Button") - } + CNButton { + id: button1 + x: 110 + y: 138 + text: qsTr("Button") + } - CNButton { - id: button5 - x: 383 - y: 138 - text: qsTr("Button") - } + CNButton { + id: button2 + x: 202 + y: 241 + text: qsTr("Button with default focus") + focus: true + } - CNButton { - id: button6 - x: 383 - y: 50 - text: qsTr("Button") - } + CNButton { + id: button3 + x: 383 + y: 241 + text: qsTr("Button") + } - CNButton { - id: button7 - x: 62 - y: 241 - text: qsTr("Button") - } + CNButton { + id: button4 + x: 383 + y: 322 + text: qsTr("Button") + } + CNButton { + id: button5 + x: 383 + y: 138 + text: qsTr("Button") + } + CNButton { + id: button6 + x: 383 + y: 50 + text: qsTr("Button") + } + + CNButton { + id: button7 + x: 62 + y: 241 + text: qsTr("Button") + } + + } } diff --git a/DemoApplication/Page2Form.qml b/DemoApplication/Page2Form.qml index 34b9dc6..552c3e5 100644 --- a/DemoApplication/Page2Form.qml +++ b/DemoApplication/Page2Form.qml @@ -1,5 +1,6 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 +import CursorNavigation 1.0 Page { width: 600 @@ -11,4 +12,75 @@ Page { text: qsTr("You are on Page 2.") anchors.centerIn: parent } + + ListView { + id: listView + x: 385 + y: 19 + width: 198 + height: 359 + delegate: Item { + x: 5 + width: 80 + height: 40 + + Row { + id: row1 + Rectangle { + width: 40 + height: 40 + color: colorCode + } + + Text { + text: name + anchors.verticalCenter: parent.verticalCenter + font.bold: true + } + spacing: 10 + } + } + model: ListModel { + ListElement { + name: "Grey" + colorCode: "grey" + } + + ListElement { + name: "Red" + colorCode: "red" + } + + ListElement { + name: "Blue" + colorCode: "blue" + } + + ListElement { + name: "Green" + colorCode: "green" + } + } + } + + CNButton { + id: button + x: 95 + y: 54 + text: qsTr("Button") + } + + CNButton { + id: button1 + x: 95 + y: 158 + text: qsTr("Button") + } + + CNButton { + id: button2 + x: 95 + y: 266 + text: qsTr("Button") + } } diff --git a/plugin/cursornavigation.cpp b/plugin/cursornavigation.cpp index 5cb9545..83abae2 100644 --- a/plugin/cursornavigation.cpp +++ b/plugin/cursornavigation.cpp @@ -8,33 +8,29 @@ const char CursorNavigation::windowPropertyName[] = "cursor_navigation"; CursorNavigation::CursorNavigation(QQuickWindow *parent) :QObject(parent) +,m_window(parent) ,m_inputAdapter(parent, this) ,m_currentItem(nullptr) { m_algorithms.push_back(new SpatialNavigation4Dir(&m_itemRegister)); + + connect(m_window, &QQuickWindow::activeFocusItemChanged, this, &CursorNavigation::onActiveFocusItemChanged); + onActiveFocusItemChanged(); } bool CursorNavigation::inputCommand(CursorNavigationCommand cmd) { - QQuickItem *nextItem; + QQuickItem *nextItem = nullptr; for (auto alg : m_algorithms) { nextItem = alg->getNextCandidate(m_itemRegister.items(), m_currentItem, cmd); - if (nextItem) + if (nextItem) { + setCursorOnItem(nextItem); break; - } - - if (nextItem) { - if (m_currentItem) { - CursorNavigationAttached *current=cursorNavigationAttachment(m_currentItem); - Q_ASSERT(current); - current->setHasCursor(false); } - CursorNavigationAttached *next=cursorNavigationAttachment(nextItem); - Q_ASSERT(next); - next->setHasCursor(true); - m_currentItem = nextItem; } + + return true; } CursorNavigationAttached *CursorNavigation::qmlAttachedProperties(QObject *object) @@ -45,7 +41,7 @@ CursorNavigationAttached *CursorNavigation::qmlAttachedProperties(QObject *objec } if (!qobject_cast<QQuickItem *>(object)) { - qWarning("Cannot manage focus for a non-Item!"); + qWarning("Cannot manage cursor for a non-Item!"); return nullptr; } @@ -79,9 +75,36 @@ CursorNavigation *CursorNavigation::cursorNavigationForWindow(QQuickWindow *wind return cursorNavigation; } +void CursorNavigation::setCursorOnItem(QQuickItem *item) +{ + if (item != m_currentItem) { + if (m_currentItem) { + CursorNavigationAttached *current=cursorNavigationAttachment(m_currentItem); + Q_ASSERT(current); + m_currentItem->setFocus(false); + current->setHasCursor(false); + } + CursorNavigationAttached *next=cursorNavigationAttachment(item); + if (next) { + next->setHasCursor(true); + m_currentItem = item; + m_currentItem->setFocus(true); + qWarning() << "Set cursor to " << item; + } else { + qWarning() << "Set cursor to NULL"; + m_currentItem = nullptr; + } + } +} + +void CursorNavigation::onActiveFocusItemChanged() +{ + qWarning() << "onActiveFocusItemChanged, item:" << m_window->activeFocusItem(); + setCursorOnItem(m_window->activeFocusItem()); +} + CursorNavigationAttached *CursorNavigation::cursorNavigationAttachment(QQuickItem *item) { - Q_ASSERT(item); return static_cast<CursorNavigationAttached *>(qmlAttachedPropertiesObject<CursorNavigation>(item, false)); } diff --git a/plugin/cursornavigation.h b/plugin/cursornavigation.h index a9309fb..2217679 100644 --- a/plugin/cursornavigation.h +++ b/plugin/cursornavigation.h @@ -27,10 +27,13 @@ public: private: void setCursorOnItem(QQuickItem *item); + void onActiveFocusItemChanged(); + static CursorNavigationAttached *cursorNavigationAttachment(QQuickItem *item); private: static const char windowPropertyName[]; + QQuickWindow *m_window; InputAdapter m_inputAdapter; QQuickItem *m_currentItem; //item that currently has the cursor QList<CursorNavigationAlgorithm*> m_algorithms; diff --git a/tests/tst_cursornavigation.cpp b/tests/tst_cursornavigation.cpp index d61f635..0001f77 100644 --- a/tests/tst_cursornavigation.cpp +++ b/tests/tst_cursornavigation.cpp @@ -13,6 +13,7 @@ public: private slots: void test_pluginLoading(); void test_registering(); + void test_followsFocus(); void test_withKeyNavigation(); void test_spatial4Directions(); @@ -41,6 +42,12 @@ void TestCursorNavigation::test_registering() //unsetting the property should unregister the item } +void TestCursorNavigation::test_followsFocus() +{ + //test that the cursor follows focus; means cursor is moved between the + //items when the focus is changed some other way +} + void TestCursorNavigation::test_withKeyNavigation() { //test that element that additionally uses KeyNavigation, behaves primarily according to the KeyNavigation |