aboutsummaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'plugin')
-rw-r--r--plugin/cursornavigation.cpp92
-rw-r--r--plugin/cursornavigation.h12
-rw-r--r--plugin/cursornavigationalgorithm.cpp1
-rw-r--r--plugin/cursornavigationattached.cpp21
-rw-r--r--plugin/cursornavigationattached.h17
-rw-r--r--plugin/inputadapter.cpp4
-rw-r--r--plugin/inputtypes.h36
-rw-r--r--plugin/itemregister.cpp51
-rw-r--r--plugin/itemregister.h35
-rw-r--r--plugin/plugin.pro2
10 files changed, 150 insertions, 121 deletions
diff --git a/plugin/cursornavigation.cpp b/plugin/cursornavigation.cpp
index 7e4ba81..0011cb2 100644
--- a/plugin/cursornavigation.cpp
+++ b/plugin/cursornavigation.cpp
@@ -9,33 +9,26 @@ const char CursorNavigation::windowPropertyName[] = "cursor_navigation";
CursorNavigation::CursorNavigation(QQuickWindow *parent)
:QObject(parent)
,m_window(parent)
-,m_inputAdapter(parent, this)
+,m_inputAdapter(m_window->contentItem(), this)
,m_currentItem(nullptr)
-,m_rootItem(nullptr)
+,m_rootItem(new CursorNavigationAttached(nullptr))
{
+ m_rootItem->setParent(m_window->contentItem());
+
m_algorithms.push_back(new SpatialNavigation4Dir());
connect(m_window, &QQuickWindow::activeFocusItemChanged, this, &CursorNavigation::onActiveFocusItemChanged);
onActiveFocusItemChanged();
}
-bool CursorNavigation::inputCommand(CursorNavigationCommand cmd)
+bool CursorNavigation::inputCommand(const CursorNavigationCommand &cmd)
{
- CursorNavigationAttached *nextItem = nullptr;
-
- QList<CursorNavigationAttached*> &candidates = m_currentItem ?
- m_currentItem->m_parentNavigable->m_children :
- m_rootItem.m_children;
- for (auto alg : m_algorithms) {
- nextItem = alg->getNextCandidate(candidates, m_currentItem, cmd);
- if (nextItem) {
- setCursorOnItem(nextItem);
- break;
- }
+ if (cmd.action == CursorNavigationCommand::NoAction) {
+ return handleDirectionCommand(cmd);
+ } else {
+ return handleActionCommand(cmd);
}
-
- return true;
}
CursorNavigationAttached *CursorNavigation::qmlAttachedProperties(QObject *object)
@@ -96,7 +89,8 @@ void CursorNavigation::setCursorOnItem(CursorNavigationAttached *item)
if (item) {
item->setHasCursor(true);
m_currentItem = item;
- m_currentItem->item()->setFocus(true);
+ m_currentItem->item()->forceActiveFocus();
+ //m_currentItem->item()->setFocus(true);
qWarning() << "Set cursor to " << item->item();
} else {
qWarning() << "Set cursor to NULL";
@@ -130,8 +124,8 @@ void CursorNavigation::registerItem(CursorNavigationAttached* item)
item->m_parentNavigable=parentCNA;
parentCNA->m_children.append(item);
} else {
- m_rootItem.m_children.append(item);
- item->m_parentNavigable=&m_rootItem;
+ m_rootItem->m_children.append(item);
+ item->m_parentNavigable=m_rootItem;
}
}
@@ -145,3 +139,63 @@ void CursorNavigation::unregisterItem(CursorNavigationAttached* item)
item->m_parentNavigable->m_children.removeOne(item);
}
+bool CursorNavigation::handleDirectionCommand(const CursorNavigationCommand &cmd)
+{
+ qWarning() << "handleDirectionCommand";
+ CursorNavigationAttached *nextItem = nullptr;
+
+ QList<CursorNavigationAttached*> &candidates = m_currentItem ?
+ m_currentItem->m_parentNavigable->m_children :
+ m_rootItem->m_children;
+
+ for (auto alg : m_algorithms) {
+ nextItem = alg->getNextCandidate(candidates, m_currentItem, cmd);
+ if (nextItem) {
+ setCursorOnItem(nextItem);
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool CursorNavigation::handleActionCommand(const CursorNavigationCommand &cmd)
+{
+ qWarning() << "handleActionCommand, cmd.action= " << cmd.action;
+ switch (cmd.action) {
+ case CursorNavigationCommand::Forward:
+ break;
+ case CursorNavigationCommand::Back:
+ break;
+ case CursorNavigationCommand::Activate:
+ break;
+ case CursorNavigationCommand::Escape: {
+ /* if item has escapeTrgate defined, set focus to that. otherwise leave
+ * scope, ie. go back to parent's parent in the hierarchy and set focus
+ * (back) to it (setting the focus further to one of its children
+ * depends on the focus mechanism).
+ * if we are already at the root item's children, nothing happens
+ */
+ if (!m_currentItem)
+ break;
+
+ QQuickItem *escapeTarget = m_currentItem->m_parentNavigable->escapeTarget();
+ if (!escapeTarget) {
+ if (m_currentItem->m_parentNavigable == m_rootItem) {
+ break;
+ }
+ escapeTarget = m_currentItem->m_parentNavigable->m_parentNavigable->item();
+ }
+ qWarning() << "escaping, target = " << escapeTarget;
+ setCursorOnItem(nullptr);
+ escapeTarget->forceActiveFocus();
+ onActiveFocusItemChanged();
+ //escapeTarget->setFocus(true);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
diff --git a/plugin/cursornavigation.h b/plugin/cursornavigation.h
index 7e61ee9..12468e4 100644
--- a/plugin/cursornavigation.h
+++ b/plugin/cursornavigation.h
@@ -2,12 +2,12 @@
#define CURSORNAVIGATION_H
#include "cursornavigationattached.h"
-#include "itemregister.h"
#include "inputtypes.h"
#include "inputadapter.h"
#include <QObject>
#include <qqml.h>
+#include <QStack>
class QQuickItem;
class CursorNavigationAlgorithm;
@@ -19,7 +19,9 @@ class CursorNavigation : public QObject
public:
CursorNavigation(QQuickWindow *parent);
- bool inputCommand(CursorNavigationCommand cmd);
+ bool inputCommand(const CursorNavigationCommand &cmd);
+ void move(QVector2D moveVector);
+ void action();
static CursorNavigationAttached *qmlAttachedProperties(QObject *object);
@@ -33,6 +35,9 @@ private:
void registerItem(CursorNavigationAttached* item);
void unregisterItem(CursorNavigationAttached* item);
+ bool handleDirectionCommand(const CursorNavigationCommand &cmd);
+ bool handleActionCommand(const CursorNavigationCommand &cmd);
+
private:
static const char windowPropertyName[];
QQuickWindow *m_window;
@@ -40,7 +45,8 @@ private:
CursorNavigationAttached *m_currentItem; //item that currently has the cursor
QList<CursorNavigationAlgorithm*> m_algorithms;
//a root item that is not tied to any actual QQuickItem
- CursorNavigationAttached m_rootItem;
+ CursorNavigationAttached *m_rootItem;
+ QStack<CursorNavigationAttached*> m_scopeStack;
friend class CursorNavigationAttached;
};
diff --git a/plugin/cursornavigationalgorithm.cpp b/plugin/cursornavigationalgorithm.cpp
index 0676434..c08761f 100644
--- a/plugin/cursornavigationalgorithm.cpp
+++ b/plugin/cursornavigationalgorithm.cpp
@@ -1,5 +1,4 @@
#include "cursornavigationalgorithm.h"
-#include "itemregister.h"
CursorNavigationAlgorithm::CursorNavigationAlgorithm()
{
diff --git a/plugin/cursornavigationattached.cpp b/plugin/cursornavigationattached.cpp
index 9d4aafe..9a939ff 100644
--- a/plugin/cursornavigationattached.cpp
+++ b/plugin/cursornavigationattached.cpp
@@ -8,7 +8,8 @@ CursorNavigationAttached::CursorNavigationAttached(QQuickItem *parent)
m_cursorNavigation(nullptr),
m_parentNavigable(nullptr),
m_acceptsCursor(true),
-m_hasCursor(false)
+m_hasCursor(false),
+m_escapeTarget(nullptr)
{
if (parent)
connect(parent, &QQuickItem::windowChanged, this, &CursorNavigationAttached::onWindowChanged);
@@ -82,6 +83,20 @@ QQuickItem *CursorNavigationAttached::item() const
return static_cast<QQuickItem *>(parent());
}
+QQuickItem *CursorNavigationAttached::escapeTarget() const
+{
+ return m_escapeTarget;
+}
+
+void CursorNavigationAttached::setEscapeTarget(QQuickItem *escapeTarget)
+{
+ if (m_escapeTarget == escapeTarget)
+ return;
+
+ m_escapeTarget = escapeTarget;
+ emit escapeTargetChanged(m_escapeTarget);
+}
+
void CursorNavigationAttached::setHasCursor(bool hasCursor)
{
if (hasCursor != m_hasCursor) {
@@ -90,7 +105,7 @@ void CursorNavigationAttached::setHasCursor(bool hasCursor)
}
}
-QList<CursorNavigationAttached *> &CursorNavigationAttached::siblings()
+/*QList<CursorNavigationAttached *> &CursorNavigationAttached::siblings()
{
return m_parentNavigable->m_children;
-}
+}*/
diff --git a/plugin/cursornavigationattached.h b/plugin/cursornavigationattached.h
index 1a8314c..0f3f927 100644
--- a/plugin/cursornavigationattached.h
+++ b/plugin/cursornavigationattached.h
@@ -20,6 +20,8 @@ class CursorNavigationAttached : public QObject
Q_PROPERTY(bool childHasCursor READ hasCursor NOTIFY hasCursorChanged)
//traps cursor. a trapped cursor can not be traversed outside of the item that traps it until the escape input is given
Q_PROPERTY(bool trapsCursor READ trapsCursor WRITE setTrapsCursor NOTIFY trapsCursorChanged)
+ //item to select when
+ Q_PROPERTY(QQuickItem *escapeTarget READ escapeTarget WRITE setEscapeTarget NOTIFY escapeTargetChanged)
public:
@@ -27,26 +29,30 @@ public:
~CursorNavigationAttached();
bool acceptsCursor() const;
- void setAcceptsCursor(bool acceptsCursor);
-
bool hasCursor() const;
-
bool trapsCursor() const;
- void setTrapsCursor(bool trapsCursor);
+ QQuickItem *escapeTarget() const;
QQuickItem *item() const;
+public slots:
+ void setAcceptsCursor(bool acceptsCursor);
+ void setTrapsCursor(bool trapsCursor);
+ void setEscapeTarget(QQuickItem * escapeTarget);
+
signals:
void acceptsCursorChanged(bool acceptsCursor);
void hasCursorChanged(bool hasCursor);
void trapsCursorChanged(bool trapsCursor);
+ void escapeTargetChanged(QQuickItem * escapeTarget);
+
private slots:
void onWindowChanged(QQuickWindow *window);
private:
void setHasCursor(bool hasCursor);
- QList<CursorNavigationAttached*> &siblings();
+ //QList<CursorNavigationAttached*> &siblings();
CursorNavigation *m_cursorNavigation;
CursorNavigationAttached *m_parentNavigable;
@@ -57,6 +63,7 @@ private:
bool m_trapsCursor;
friend class CursorNavigation;
+ QQuickItem * m_escapeTarget;
};
#endif // CURSORNAVIGATIONATTACHED_H
diff --git a/plugin/inputadapter.cpp b/plugin/inputadapter.cpp
index 5814e5d..99eeb4f 100644
--- a/plugin/inputadapter.cpp
+++ b/plugin/inputadapter.cpp
@@ -58,10 +58,10 @@ bool InputAdapter::handleKeyEvent(QKeyEvent *event)
cmd.action = CursorNavigationCommand::Escape;
break;
case Qt::Key_Tab:
- cmd.action = CursorNavigationCommand::Escape;
+ cmd.action = CursorNavigationCommand::Forward;
break;
case Qt::Key_Backtab:
- cmd.action = CursorNavigationCommand::Escape;
+ cmd.action = CursorNavigationCommand::Back;
break;
default:
return false;
diff --git a/plugin/inputtypes.h b/plugin/inputtypes.h
index bf7e82e..efe7f8a 100644
--- a/plugin/inputtypes.h
+++ b/plugin/inputtypes.h
@@ -1,6 +1,9 @@
#ifndef INPUTTYPES_H
#define INPUTTYPES_H
+//TODO: make these into classes w accessors
+
+//generic of way of describing the input that cursor management can handle
struct CursorNavigationCommand
{
enum Action
@@ -30,4 +33,37 @@ struct CursorNavigationCommand
};
+/*feedback datatype returned for commands, describing command results
+ *this could be used for example to indicate that a end of a list has been reached,
+ *that might produce force feedback on certain inut devices
+ */
+enum CommandResult
+{
+ Succesful = 0,
+ AreaBoundsReached,
+ ListEndReached
+};
+
+//describing which boundary was met
+enum Boundary {
+ Undefined = 0,
+ Top = 1,
+ Bottom = 2,
+ Right = 4,
+ Left = 8
+};
+
+class CursorNavigationFeedback
+{
+// Q_GADGET
+// Q_PROPERTY(CommandResult READ commandResult NOTIFY commandResultChanged )
+// Q_PROPERTY(CommandResult READ commandResult NOTIFY commandResultChanged )
+
+ //feedback cases;
+ //-cmd succesfull
+ //-end of list reached (or just the end of whatever selection area maybe)
+ //-fell back to the previous scope
+};
+
+
#endif // INPUTTYPES_H
diff --git a/plugin/itemregister.cpp b/plugin/itemregister.cpp
deleted file mode 100644
index 24c6b07..0000000
--- a/plugin/itemregister.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*#include "itemregister.h"
-#include "cursornavigation.h"
-#include <QQuickItem>
-
-ItemRegister::ItemRegister()
-{
-
-}
-
-void ItemRegister::registerItem(QQuickItem* item)
-{
- if (!item)
- return;
-
- //find first cursor navigable parent
- QQuickItem *parentItem = item->parentItem();
- CursorNavigationAttached *parentCNA;
- while (parentItem) {
- if ((parentCNA=CursorNavigation::cursorNavigationAttachment(parentItem)))
- break;
- parentItem = parentItem->parentItem();
- }
-
- if (parentCNA)
- parentCNA->m_children.append();
-
- m_items.append(item);
- connect(item, &QQuickItem::destroyed, this, &ItemRegister::onItemDestroyed);
-}
-
-void ItemRegister::unregisterItem(QQuickItem* item)
-{
- if (!item)
- return;
-
- disconnect(item, &QQuickItem::destroyed, this, &ItemRegister::onItemDestroyed);
- m_items.removeOne(item);
-}
-
-const QList<QQuickItem*> ItemRegister::siblingItems(QQuickItem *item) const
-{
- //find the items that are within the same scope as the argument item
- return m_items;
-}
-
-void ItemRegister::onItemDestroyed(QObject *obj)
-{
- QQuickItem *item=static_cast<QQuickItem*>(obj);
- m_items.removeOne(item);
-}
-*/
diff --git a/plugin/itemregister.h b/plugin/itemregister.h
deleted file mode 100644
index 9c9430a..0000000
--- a/plugin/itemregister.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*#ifndef ITEMREGISTER_H
-#define ITEMREGISTER_H
-
-#include <QObject>
-
-class QQuickItem;
-
-//keeps track of items that are cursor navigable
-class ItemRegister : public QObject
-{
- Q_OBJECT
-
-public:
- ItemRegister();
-
- void registerItem(QQuickItem* item);
- void unregisterItem(QQuickItem* item);
-
- //find the items that are within the same scope as the argument item
- const QList<QQuickItem*> siblingItems(QQuickItem* item) const;
-
-private Q_SLOTS:
- void onItemDestroyed(QObject *obj);
-
-private:
- //find the item's first parent that is cursor navigable
- QQuickItem *findParent(QQuickItem* item);
-
- //for now the data structure is just a list. could be replaced with something more efficient for the final purpose
- QList<QQuickItem*> m_items;
-
-};
-
-#endif // ITEMREGISTER_H
-*/
diff --git a/plugin/plugin.pro b/plugin/plugin.pro
index 72c6b96..6f1a4c3 100644
--- a/plugin/plugin.pro
+++ b/plugin/plugin.pro
@@ -12,7 +12,6 @@ SOURCES += \
plugin.cpp \
cursornavigation.cpp \
cursornavigationattached.cpp \
- itemregister.cpp \
inputadapter.cpp \
cursornavigationalgorithm.cpp \
spatialnavigation4dir.cpp \
@@ -22,7 +21,6 @@ HEADERS += \
plugin.h \
cursornavigation.h \
cursornavigationattached.h \
- itemregister.h \
inputadapter.h \
inputtypes.h \
cursornavigationalgorithm.h \