diff options
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/cursornavigation.cpp | 30 | ||||
-rw-r--r-- | plugin/cursornavigation.h | 4 | ||||
-rw-r--r-- | plugin/cursornavigationattached.cpp | 61 | ||||
-rw-r--r-- | plugin/cursornavigationattached.h | 12 | ||||
-rw-r--r-- | plugin/plugin.cpp | 2 | ||||
-rw-r--r-- | plugin/plugin.pro | 6 | ||||
-rw-r--r-- | plugin/redirect.cpp | 68 | ||||
-rw-r--r-- | plugin/redirect.h | 41 |
8 files changed, 193 insertions, 31 deletions
diff --git a/plugin/cursornavigation.cpp b/plugin/cursornavigation.cpp index bf2d390..e069efc 100644 --- a/plugin/cursornavigation.cpp +++ b/plugin/cursornavigation.cpp @@ -3,6 +3,7 @@ #include "spatialnavigation4dir.h" #include <QQuickWindow> #include <QQuickItem> +#include <QtMath> const char CursorNavigation::windowPropertyName[] = "cursor_navigation"; @@ -22,27 +23,38 @@ CursorNavigation::CursorNavigation(QQuickWindow *parent) bool CursorNavigation::move(qreal angle, qreal tolerance, bool discrete) { - CursorNavigationAttached *nextItem = find(angle, tolerance, discrete); + QQuickItem *foundItem = find(angle, tolerance, discrete); + CursorNavigationAttached *nextItem = cursorNavigationAttachment(foundItem); if (nextItem) { setCursorOnItem(nextItem); return true; + } else if (foundItem) { + foundItem->forceActiveFocus(); + return true; } return false; } -CursorNavigationAttached *CursorNavigation::find(qreal angle, qreal tolerance, bool discrete) +QQuickItem *CursorNavigation::find(qreal angle, qreal tolerance, bool discrete) { + if (!m_currentItem) + return defaultItem()->item(); + + if (m_currentItem->m_redirects.size()) { + for (auto redirect : m_currentItem->m_redirects) { + if (redirect->angleIsIncluded(angle)) { + if (!redirect->target()) + qWarning() << "Redirect target is null"; + return redirect->target(); + } + } + } + CursorNavigationAttached *nextItem = nullptr; CursorNavigationAttached *parent = m_currentItem ? m_currentItem->m_parentNavigable : m_rootItem; - - if (!m_currentItem) - return defaultItem(); - - //qWarning() << "find next item, angle = " << angle << " tolerance = " << tolerance << " discrete = " << discrete; - QList<CursorNavigationAttached*> candidates; do { @@ -64,7 +76,7 @@ CursorNavigationAttached *CursorNavigation::find(qreal angle, qreal tolerance, b nextItem = m_navigation360.getNextCandidate(candidates, m_currentItem, cmd); } - return nextItem; + return nextItem ? nextItem->item() : nullptr; } bool CursorNavigation::action(Action action) diff --git a/plugin/cursornavigation.h b/plugin/cursornavigation.h index a32a357..ad1cf31 100644 --- a/plugin/cursornavigation.h +++ b/plugin/cursornavigation.h @@ -25,10 +25,8 @@ public: //void setMagnitude(const QVector2D& vector); //move the cursor bool move(qreal angle, qreal tolerance, bool discrete); - bool move(const QVector2D& vector, qreal tolerance, bool discrete); //find the next item without moving the cursor - CursorNavigationAttached *find(qreal angle, qreal tolerance, bool discrete); - CursorNavigationAttached *find(const QVector2D& vector, qreal tolerance, bool discrete); + QQuickItem *find(qreal angle, qreal tolerance, bool discrete); bool action(Action action); static CursorNavigationAttached *qmlAttachedProperties(QObject *object); diff --git a/plugin/cursornavigationattached.cpp b/plugin/cursornavigationattached.cpp index a897327..133890e 100644 --- a/plugin/cursornavigationattached.cpp +++ b/plugin/cursornavigationattached.cpp @@ -92,10 +92,10 @@ void CursorNavigationAttached::setMagnitude(QVector2D vector) void CursorNavigationAttached::move(qreal angle, qreal tolerance) { - qWarning() << "move"; - qreal a = qDegreesToRadians(angle); - qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); if (m_cursorNavigation) { + qWarning() << "move"; + qreal a = qDegreesToRadians(angle); + qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); CursorNavigationAttached *item = m_cursorNavigation->m_currentItem; if (m_cursorNavigation->move(a, t, false) && item) item->moved(a,t); @@ -104,10 +104,10 @@ void CursorNavigationAttached::move(qreal angle, qreal tolerance) void CursorNavigationAttached::move(QVector2D vector, qreal tolerance) { - qWarning() << "move (vector)"; - qreal a = qAtan2(vector.y(), vector.x()); - qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); if (m_cursorNavigation) { + qWarning() << "move (vector)"; + qreal a = qAtan2(vector.y(), vector.x()); + qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); CursorNavigationAttached *item = m_cursorNavigation->m_currentItem; if (m_cursorNavigation->move(a, t, false) && item) item->moved(a,t); @@ -116,24 +116,20 @@ void CursorNavigationAttached::move(QVector2D vector, qreal tolerance) QQuickItem *CursorNavigationAttached::find(qreal angle, qreal tolerance) { - qreal a = qDegreesToRadians(angle); - qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); if (m_cursorNavigation) { - CursorNavigationAttached *item = m_cursorNavigation->find(a, t, false); - if (item) - return item->item(); + qreal a = qDegreesToRadians(angle); + qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); + return m_cursorNavigation->find(a, t, false); } return nullptr; } QQuickItem *CursorNavigationAttached::find(QVector2D vector, qreal tolerance) { - qreal a = qAtan2(vector.y(), vector.x()); - qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); if (m_cursorNavigation) { - CursorNavigationAttached *item = m_cursorNavigation->find(a, t, false); - if (item) - return item->item(); + qreal a = qAtan2(vector.y(), vector.x()); + qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); + return m_cursorNavigation->find(a, t, false); } return nullptr; } @@ -234,6 +230,15 @@ QQuickItem *CursorNavigationAttached::escapeTarget() const return m_escapeTarget; } +QQmlListProperty<Redirect> CursorNavigationAttached::redirects() +{ + return QQmlListProperty<Redirect>(this, this, + &CursorNavigationAttached::appendRedirect, + &CursorNavigationAttached::redirectCount, + &CursorNavigationAttached::redirect, + &CursorNavigationAttached::clearRedirects); +} + bool CursorNavigationAttached::available() const { if (m_acceptsCursor && item()->isVisible() && item()->isEnabled()) { @@ -252,3 +257,27 @@ void CursorNavigationAttached::setHasCursor(bool hasCursor) } } +void CursorNavigationAttached::appendRedirect(QQmlListProperty<Redirect> *property, Redirect *redirect) +{ + CursorNavigationAttached *cna = static_cast<CursorNavigationAttached*>(property->object); + cna->m_redirects.append(redirect); +} + +int CursorNavigationAttached::redirectCount(QQmlListProperty<Redirect> *property) +{ + CursorNavigationAttached *cna = static_cast<CursorNavigationAttached*>(property->object); + return cna->m_redirects.count(); +} + +Redirect *CursorNavigationAttached::redirect(QQmlListProperty<Redirect> *property, int index) +{ + CursorNavigationAttached *cna = static_cast<CursorNavigationAttached*>(property->object); + return cna->m_redirects.at(index); +} + +void CursorNavigationAttached::clearRedirects(QQmlListProperty<Redirect> *property) +{ + CursorNavigationAttached *cna = static_cast<CursorNavigationAttached*>(property->object); + cna->m_redirects.clear(); +} + diff --git a/plugin/cursornavigationattached.h b/plugin/cursornavigationattached.h index f3c729d..7c5e99a 100644 --- a/plugin/cursornavigationattached.h +++ b/plugin/cursornavigationattached.h @@ -4,6 +4,8 @@ //#include <qqml.h> #include <QObject> #include <QList> +#include <QQmlListProperty> +#include "redirect.h" class CursorNavigation; class QQuickItem; @@ -22,7 +24,7 @@ class CursorNavigationAttached : public QObject Q_PROPERTY(bool trapsCursor READ trapsCursor WRITE setTrapsCursor NOTIFY trapsCursorChanged) //item to select when Q_PROPERTY(QQuickItem *escapeTarget READ escapeTarget WRITE setEscapeTarget NOTIFY escapeTargetChanged) - + Q_PROPERTY(QQmlListProperty<Redirect> redirects READ redirects) public: CursorNavigationAttached(QQuickItem *parent); @@ -32,6 +34,8 @@ public: bool hasCursor() const; bool trapsCursor() const; QQuickItem *escapeTarget() const; + QQmlListProperty<Redirect> redirects(); + /* indicates if the item is currently available for the navigation. * item might not be availble if it is disabled, invisible, outside of its * parent's geometry or simply not accepting cursor @@ -93,6 +97,11 @@ private: void setHasCursor(bool hasCursor); //QList<CursorNavigationAttached*> &siblings(); + static void appendRedirect(QQmlListProperty<Redirect> *property, Redirect *redirect); + static int redirectCount(QQmlListProperty<Redirect> *property); + static Redirect *redirect(QQmlListProperty<Redirect> *property, int index); + static void clearRedirects(QQmlListProperty<Redirect> *property); + CursorNavigation *m_cursorNavigation; CursorNavigationAttached *m_parentNavigable; QList<CursorNavigationAttached*> m_children; @@ -103,6 +112,7 @@ private: friend class CursorNavigation; QQuickItem * m_escapeTarget; + QVector<Redirect*> m_redirects; }; #endif // CURSORNAVIGATIONATTACHED_H diff --git a/plugin/plugin.cpp b/plugin/plugin.cpp index 26d156a..87cc430 100644 --- a/plugin/plugin.cpp +++ b/plugin/plugin.cpp @@ -1,5 +1,6 @@ #include "plugin.h" #include "cursornavigation.h" +#include "redirect.h" #include "qqml.h" CursorNavigationPlugin::CursorNavigationPlugin() @@ -10,4 +11,5 @@ void CursorNavigationPlugin::registerTypes(const char *uri) { qmlRegisterUncreatableType<CursorNavigation>(uri, 1, 0, "CursorNavigation", QStringLiteral("CursorNavigation is not creatable, use the attached properties.")); + qmlRegisterType<Redirect>(uri, 1, 0, "Redirect"); } diff --git a/plugin/plugin.pro b/plugin/plugin.pro index 4d7fed9..b5cdee7 100644 --- a/plugin/plugin.pro +++ b/plugin/plugin.pro @@ -16,7 +16,8 @@ SOURCES += \ cursornavigationalgorithm.cpp \ spatialnavigation4dir.cpp \ inputtypes.cpp \ - spatialnavigation360.cpp + spatialnavigation360.cpp \ + redirect.cpp HEADERS += \ plugin.h \ @@ -26,7 +27,8 @@ HEADERS += \ inputtypes.h \ cursornavigationalgorithm.h \ spatialnavigation4dir.h \ - spatialnavigation360.h + spatialnavigation360.h \ + redirect.h pluginfiles.files += qmldir diff --git a/plugin/redirect.cpp b/plugin/redirect.cpp new file mode 100644 index 0000000..3c33571 --- /dev/null +++ b/plugin/redirect.cpp @@ -0,0 +1,68 @@ +#include "redirect.h" +#include <QQuickItem> +#include <QtMath> +#include "inputtypes.h" + +Redirect::Redirect(QObject *parent) +:QObject(parent) +,m_start(-1) +,m_end(-1) +,m_target(nullptr) +{ +} + +Redirect::~Redirect() +{ +} + +qreal Redirect::start() const +{ + return m_start; +} + +qreal Redirect::end() const +{ + return m_end; +} + +QQuickItem *Redirect::target() const +{ + return m_target; +} + +void Redirect::setStart(qreal start) +{ + m_start = start; + m_startR = CursorNavigationCommand::fitAngle(qDegreesToRadians(start)); +} + +void Redirect::setEnd(qreal end) +{ + m_end = end; + m_endR = CursorNavigationCommand::fitAngle(qDegreesToRadians(end)); +} + +void Redirect::setTarget(QQuickItem *target) +{ + if (m_target) { + disconnect(m_target, &QObject::destroyed, this, &Redirect::onTargetDestroyed); + } + m_target = target; + if (m_target) { + connect(m_target, &QObject::destroyed, this, &Redirect::onTargetDestroyed); + } +} + +bool Redirect::angleIsIncluded(qreal angle) +{ + if (m_startR > m_endR) + return angle >= m_startR || angle <= m_endR; + else + return angle >= m_startR && angle <= m_endR; +} + +void Redirect::onTargetDestroyed() +{ + m_target = nullptr; +} + diff --git a/plugin/redirect.h b/plugin/redirect.h new file mode 100644 index 0000000..232f07b --- /dev/null +++ b/plugin/redirect.h @@ -0,0 +1,41 @@ +#ifndef REDIRECT_H +#define REDIRECT_H + +#include <QObject> + +class QQuickItem; + +class Redirect : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal start READ start WRITE setStart) + Q_PROPERTY(qreal end READ end WRITE setEnd) + Q_PROPERTY(QQuickItem *target READ target WRITE setTarget) +public: + Redirect(QObject *parent = nullptr); + virtual ~Redirect(); + + qreal start() const; + qreal end() const; + QQuickItem *target() const; + + void setStart(qreal start); + void setEnd(qreal end); + void setTarget(QQuickItem *target); + + bool angleIsIncluded(qreal angle); + +private slots: + void onTargetDestroyed(); + +private: + qreal m_start; + qreal m_end; + //fitted angles in radians + qreal m_startR; + qreal m_endR; + QQuickItem *m_target; +}; + +#endif // REDIRECT_H |