From 4c26627622afdea02276556ee7fc61c505f60e6b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 30 Dec 2015 17:14:40 -0800 Subject: [PATCH] Add navigation actions and wire them up in the standard controller --- interface/resources/controllers/standard.json | 9 +++ interface/src/Application.cpp | 55 ++++++++++++++++++- .../controllers/src/controllers/Actions.cpp | 9 +++ .../controllers/src/controllers/Actions.h | 10 ++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index 6a8fc0d803..47c3b3ef17 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -1,6 +1,15 @@ { "name": "Standard to Action", "channels": [ + { "from": "Standard.DU", "when": "Application.NavigationFocused", "to": "Actions.UiNavUp" }, + { "from": "Standard.DD", "when": "Application.NavigationFocused", "to": "Actions.UiNavDown" }, + { "from": "Standard.DL", "when": "Application.NavigationFocused", "to": "Actions.UiNavLeft" }, + { "from": "Standard.DR", "when": "Application.NavigationFocused", "to": "Actions.UiNavRight" }, + { "from": "Standard.A", "when": "Application.NavigationFocused", "to": "Actions.UiNavSelect" }, + { "from": "Standard.B", "when": "Application.NavigationFocused", "to": "Actions.UiNavBack" }, + { "from": "Standard.LB", "when": "Application.NavigationFocused", "to": "Actions.UiNavPreviousGroup" }, + { "from": "Standard.RB", "when": "Application.NavigationFocused", "to": "Actions.UiNavNextGroup" }, + { "from": "Standard.LY", "to": "Actions.TranslateZ" }, { "from": "Standard.LX", "to": "Actions.TranslateX" }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7c789992dd..abd08d6d07 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,6 +11,8 @@ #include "Application.h" +#include + #include #include #include @@ -34,6 +36,7 @@ #include #include +#include #include #include @@ -684,6 +687,50 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Setup the userInputMapper with the actions auto userInputMapper = DependencyManager::get(); connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) { + using namespace controller; + static auto offscreenUi = DependencyManager::get(); + if (offscreenUi->navigationFocused()) { + auto actionEnum = static_cast(action); + int key = Qt::Key_unknown; + switch (actionEnum) { + case Action::UI_NAV_UP: + key = Qt::Key_Up; + break; + case Action::UI_NAV_DOWN: + key = Qt::Key_Down; + break; + case Action::UI_NAV_LEFT: + key = Qt::Key_Left; + break; + case Action::UI_NAV_RIGHT: + key = Qt::Key_Right; + break; + case Action::UI_NAV_BACK: + key = Qt::Key_Escape; + break; + case Action::UI_NAV_SELECT: + key = Qt::Key_Return; + break; + case Action::UI_NAV_NEXT_GROUP: + key = Qt::Key_Tab; + break; + case Action::UI_NAV_PREVIOUS_GROUP: + key = Qt::Key_Backtab; + break; + } + + if (key != Qt::Key_unknown) { + if (state) { + QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier); + sendEvent(offscreenUi->getWindow(), &event); + } else { + QKeyEvent event(QEvent::KeyRelease, key, Qt::NoModifier); + sendEvent(offscreenUi->getWindow(), &event); + } + return; + } + } + if (action == controller::toInt(controller::Action::RETICLE_CLICK)) { auto globalPos = QCursor::pos(); auto localPos = _glWidget->mapFromGlobal(globalPos); @@ -754,6 +801,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float { return (float)qApp->getMyAvatar()->getCharacterController()->onGround(); })); + _applicationStateDevice->addInputVariant(QString("NavigationFocused"), controller::StateController::ReadLambda([]() -> float { + static auto offscreenUi = DependencyManager::get(); + return offscreenUi->navigationFocused() ? 1.0 : 0.0; + })); userInputMapper->registerDevice(_applicationStateDevice); @@ -1096,7 +1147,9 @@ void Application::initializeUi() { offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); offscreenUi->load("Root.qml"); offscreenUi->load("RootMenu.qml"); - + // FIXME either expose so that dialogs can set this themselves or + // do better detection in the offscreen UI of what has focus + offscreenUi->setNavigationFocused(false); auto rootContext = offscreenUi->getRootContext(); auto engine = rootContext->engine(); diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index 0bda52b237..2ff1b8ce0f 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -62,6 +62,15 @@ namespace controller { makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"), makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"), + makeButtonPair(Action::UI_NAV_UP, "UiNavUp"), + makeButtonPair(Action::UI_NAV_DOWN, "UiNavDown"), + makeButtonPair(Action::UI_NAV_LEFT, "UiNavLeft"), + makeButtonPair(Action::UI_NAV_RIGHT, "UiNavRight"), + makeButtonPair(Action::UI_NAV_SELECT, "UiNavSelect"), + makeButtonPair(Action::UI_NAV_BACK, "UiNavBack"), + makeButtonPair(Action::UI_NAV_NEXT_GROUP, "UiNavNextGroup"), + makeButtonPair(Action::UI_NAV_PREVIOUS_GROUP, "UiNavPreviousGroup"), + makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"), makeAxisPair(Action::RETICLE_X, "ReticleX"), makeAxisPair(Action::RETICLE_Y, "ReticleY"), diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index 56dd9660d9..d358a7a277 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -55,6 +55,15 @@ enum class Action { SHIFT, + UI_NAV_UP, + UI_NAV_DOWN, + UI_NAV_LEFT, + UI_NAV_RIGHT, + UI_NAV_SELECT, + UI_NAV_BACK, + UI_NAV_NEXT_GROUP, + UI_NAV_PREVIOUS_GROUP, + // Pointer/Reticle control RETICLE_CLICK, RETICLE_X, @@ -90,6 +99,7 @@ enum class Action { BOOM_IN, BOOM_OUT, + NUM_ACTIONS, };