From 5c75a9e125ca636dbc29767805b2279a80deb8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20H=C3=B6ltt=C3=A4?= Date: Mon, 26 Nov 2018 15:39:51 +0100 Subject: Bugfixes to 360 algorithm, added cooldown for gamepad control Joystick produce change events very rapidly and continuously, so a cooldown time is needed so that the cursor wont jump over multiple items --- plugin/cursornavigation.cpp | 26 +++++++------------------- plugin/cursornavigation.h | 5 +---- plugin/spatialnavigation360.cpp | 30 +++++++++--------------------- 3 files changed, 17 insertions(+), 44 deletions(-) (limited to 'plugin') diff --git a/plugin/cursornavigation.cpp b/plugin/cursornavigation.cpp index 4eaff64..1a81f76 100644 --- a/plugin/cursornavigation.cpp +++ b/plugin/cursornavigation.cpp @@ -26,18 +26,14 @@ void CursorNavigation::move(qreal angle, qreal tolerance, bool discrete) { qreal a = qDegreesToRadians(angle); qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); - qWarning() << "move, angle = " << a << " tolerance = " << t << " discrete = " << discrete; - CursorNavigationCommand cmd(a, t); - handleMove(cmd, discrete); + handleMove(a, t, discrete); } void CursorNavigation::move(const QVector2D& vector, qreal tolerance, bool discrete) { - qreal angle = qAtan2(vector.y(), vector.x()); + qreal a = qAtan2(vector.y(), vector.x()); qreal t = qDegreesToRadians(qFabs(std::fmod(tolerance, 180))); - qWarning() << "move(vector2d), angle = " << angle << " tolerance = " << t << " discrete = " << discrete; - CursorNavigationCommand cmd(angle, tolerance); - handleMove(cmd, discrete); + handleMove(a, t, discrete); } void CursorNavigation::action(Action action) @@ -80,16 +76,6 @@ void CursorNavigation::action(Action action) } } -/*bool CursorNavigation::inputCommand(const CursorNavigationCommand &cmd) -{ - - if (cmd.action == CursorNavigationCommand::NoAction) { - return handleDirectionCommand(cmd); - } else { - return handleActionCommand(cmd); - } -}*/ - CursorNavigationAttached *CursorNavigation::qmlAttachedProperties(QObject *object) { // if the object is a window, use its contentItem instead @@ -198,11 +184,13 @@ void CursorNavigation::unregisterItem(CursorNavigationAttached* item) item->m_parentNavigable->m_children.removeOne(item); } -bool CursorNavigation::handleMove(const CursorNavigationCommand &cmd, bool discrete) +bool CursorNavigation::handleMove(qreal angle, qreal tolerance, bool discrete) { - qWarning() << "handleDirectionCommand"; CursorNavigationAttached *nextItem = nullptr; + qWarning() << "handleMove, angle = " << angle << " tolerance = " << tolerance << " discrete = " << discrete; + CursorNavigationCommand cmd(angle, tolerance); + QList &candidates = m_currentItem ? m_currentItem->m_parentNavigable->m_children : m_rootItem->m_children; diff --git a/plugin/cursornavigation.h b/plugin/cursornavigation.h index 956d900..5c7d7f8 100644 --- a/plugin/cursornavigation.h +++ b/plugin/cursornavigation.h @@ -20,7 +20,6 @@ class CursorNavigation : public QObject public: CursorNavigation(QQuickWindow *parent); - //bool inputCommand(const CursorNavigationCommand &cmd); void move(qreal angle, qreal tolerance, bool discrete); void move(const QVector2D& vector, qreal tolerance, bool discrete); void action(Action action); @@ -37,19 +36,17 @@ private: void registerItem(CursorNavigationAttached* item); void unregisterItem(CursorNavigationAttached* item); - bool handleMove(const CursorNavigationCommand &cmd, bool discrete); + bool handleMove(qreal angle, qreal tolerance, bool discrete); private: static const char windowPropertyName[]; QQuickWindow *m_window; InputAdapter m_inputAdapter; CursorNavigationAttached *m_currentItem; //item that currently has the cursor - //QList m_algorithms; SpatialNavigation360 m_navigation360; SpatialNavigation4Dir m_navigation4Dir; //a root item that is not tied to any actual QQuickItem CursorNavigationAttached *m_rootItem; - //QStack m_scopeStack; friend class CursorNavigationAttached; }; diff --git a/plugin/spatialnavigation360.cpp b/plugin/spatialnavigation360.cpp index 9898b07..8dd0b20 100644 --- a/plugin/spatialnavigation360.cpp +++ b/plugin/spatialnavigation360.cpp @@ -12,10 +12,10 @@ SpatialNavigation360::SpatialNavigation360() //test if point is contained in at least one of the given quadrants bool isPointIncluded(const std::vector &q, const QPointF &p, const QPointF &o) { - return (q[0] && (p.x()-o.x()) >= 0 && (p.y()-o.y()) >= 0) || - (q[1] && (p.x()-o.x()) >= 0 && (p.y()-o.y()) < 0) || - (q[2] && (p.x()-o.x()) < 0 && (p.y()-o.y()) < 0) || - (q[3] && (p.x()-o.x()) < 0 && (p.y()-o.y()) >= 0); + return (q[0] && (p.x() > o.x()) && (p.y() > o.y())) || + (q[1] && (p.x() < o.x()) && (p.y() > o.y())) || + (q[2] && (p.x() < o.x()) && (p.y() < o.y())) || + (q[3] && (p.x() > o.x()) && (p.y() < o.y())); } //test if rect is contained in at least one of the given quadrants @@ -115,7 +115,7 @@ CursorNavigationAttached* SpatialNavigation360::getNextCandidate( * -remember to use current item's coord system as the reference!!! */ - qWarning() << "##### navigation360: start, angle = " << cmd.angle; + qWarning() << "##### navigation360: start, angle = " << cmd.angle << " tolerance = " << cmd.angleTolerance; if (candidates.isEmpty()) return nullptr; @@ -129,29 +129,17 @@ CursorNavigationAttached* SpatialNavigation360::getNextCandidate( std::vector quadrants(4); //define selector beam sector -// int angle1_deg, angle2_deg; qreal angle1, angle2; angle1 = CursorNavigationCommand::fitAngle(cmd.angle - cmd.angleTolerance); angle2 = CursorNavigationCommand::fitAngle(cmd.angle + cmd.angleTolerance); - -// angle1_deg = (cmd.angle - cmd.angleTolerance) % 360; -// if (angle1_deg < 0) -// angle1_deg = 360 + angle1_deg; -// angle2_deg = (cmd.angle + cmd.angleTolerance) % 360; - -// int a=angle2_deg-angle1_deg; -// while (a > 0) { -// quadrants[(angle1_deg/90+a/90) % 4] = true; -// a -= 90; -// } - quadrants[0] = sectorsOverlap(angle1, angle2, 0, M_PI_2); quadrants[1] = sectorsOverlap(angle1, angle2, M_PI_2, M_PI); quadrants[2] = sectorsOverlap(angle1, angle2, -M_PI, -M_PI_2); quadrants[3] = sectorsOverlap(angle1, angle2, -M_PI_2, 0); + qWarning() << "navigation360: beam angles: " << angle1 << " , " << angle2; qWarning() << "navigation360: quadrants = " << quadrants; const QRectF currentItemSceneRect = currentItem->item()->mapRectToScene( @@ -176,7 +164,7 @@ CursorNavigationAttached* SpatialNavigation360::getNextCandidate( if (iter == currentItem || !iter->item()->isVisible() || !iter->item()->isEnabled()) continue; - //if (isRectIncluded(quadrants, itemSceneRect, origin)) { + if (isRectIncluded(quadrants, itemSceneRect, origin)) { std::pair sector = getSector(itemSceneRect, origin); qWarning() << "item " << iter->item() << " rect = " << itemSceneRect << " sector " << sector; @@ -191,12 +179,12 @@ CursorNavigationAttached* SpatialNavigation360::getNextCandidate( } else if (!directHitItem && sectorsOverlap(angle1, angle2, sector.first, sector.second)) { qWarning() << "is within tolerances"; qreal dist = rectDistance(itemSceneRect, currentItemSceneRect); - if (dist < withinToleranceDistance) { + if (!withinToleranceItem || dist < withinToleranceDistance) { withinToleranceDistance = dist; withinToleranceItem = iter; } } - //} + } } qWarning() << "##### end, directHit = " << -- cgit v1.2.3