diff options
-rw-r--r-- | indra/newview/llviewerinput.cpp | 159 | ||||
-rw-r--r-- | indra/newview/llviewerinput.h | 11 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 12 |
3 files changed, 150 insertions, 32 deletions
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index f269be035e..77b0c8e37b 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -60,8 +60,21 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true); +struct LLKeybindFunctionData +{ + LLKeybindFunctionData(boost::function<bool(EKeystate keystate)> function, bool global) + : + mFunction(function), + mIsGlobal(global) + { + } + boost::function<bool(EKeystate keystate)> mFunction; + // todo: might be good idea to make this into enum, like: global/inworld/menu + bool mIsGlobal; +}; + struct LLKeyboardActionRegistry -: public LLRegistrySingleton<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry> +: public LLRegistrySingleton<const std::string, LLKeybindFunctionData, LLKeyboardActionRegistry> { LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); }; @@ -852,7 +865,10 @@ bool agen_control_lbutton_handle(EKeystate s) return true; } -#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); +// In-world keybindings, like walking or camera +#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, LLKeybindFunctionData(ACTION, false)); +// Global keybindings that should work even with floaters focused, like voice +#define REGISTER_KEYBOARD_GLOBAL_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, LLKeybindFunctionData(ACTION, true)); REGISTER_KEYBOARD_ACTION("jump", agent_jump); REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward); @@ -903,8 +919,8 @@ REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media); REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to); REGISTER_KEYBOARD_ACTION("walk_to", walk_to); -REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice); -REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice); +REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key); #undef REGISTER_KEYBOARD_ACTION LLViewerInput::LLViewerInput() @@ -1034,6 +1050,29 @@ BOOL LLViewerInput::handleKeyUp(KEY translated_key, MASK translated_mask) return gViewerWindow->handleKeyUp(translated_key, translated_mask); } +bool LLViewerInput::handleGlobalBindsKeyDown(KEY key, MASK mask) +{ + S32 mode = getMode(); + return scanKey(mGlobalKeyBindings[mode], mGlobalKeyBindings[mode].size(), key, mask, TRUE, FALSE, FALSE, FALSE); +} + +bool LLViewerInput::handleGlobalBindsKeyUp(KEY key, MASK mask) +{ + S32 mode = getMode(); + return scanKey(mGlobalKeyBindings[mode], mGlobalKeyBindings[mode].size(), key, mask, FALSE, TRUE, FALSE, FALSE); +} + +bool LLViewerInput::handleGlobalBindsMouse(EMouseClickType clicktype, MASK mask, bool down) +{ + bool res = false; + if (down) + { + S32 mode = getMode(); + res = scanMouse(mGlobalMouseBindings[mode], mGlobalMouseBindings[mode].size(), clicktype, mask, MOUSE_STATE_DOWN); + } + return res; +} + BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) { S32 index; @@ -1061,39 +1100,64 @@ BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, cons } // Not remapped, look for a function - - function_t* result = LLKeyboardActionRegistry::getValue(function_name); + + LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name); if (result) { - function = *result; + function = result->mFunction; } if (!function) { - LL_WARNS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; + LL_WARNS_ONCE() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; return FALSE; } - // check for duplicate first and overwrite - S32 size = mKeyBindings[mode].size(); - for (index = 0; index < size; index++) + if (mode >= MODE_COUNT) { - if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) - break; + LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; + return FALSE; } - if (mode >= MODE_COUNT) - { - LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; - return FALSE; - } + // check for duplicate first and overwrite + if (result->mIsGlobal) + { + S32 size = mGlobalKeyBindings[mode].size(); + for (index = 0; index < size; index++) + { + if (key == mGlobalKeyBindings[mode][index].mKey && mask == mGlobalKeyBindings[mode][index].mMask) + { + mGlobalKeyBindings[mode][index].mFunction = function; + return TRUE; + } + } + } + else + { + S32 size = mKeyBindings[mode].size(); + for (index = 0; index < size; index++) + { + if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) + { + mKeyBindings[mode][index].mFunction = function; + return TRUE; + } + } + } LLKeyboardBinding bind; bind.mKey = key; bind.mMask = mask; bind.mFunction = function; - mKeyBindings[mode].push_back(bind); + if (result->mIsGlobal) + { + mGlobalKeyBindings[mode].push_back(bind); + } + else + { + mKeyBindings[mode].push_back(bind); + } return TRUE; } @@ -1104,38 +1168,63 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const typedef boost::function<bool(EKeystate)> function_t; function_t function = NULL; - function_t* result = LLKeyboardActionRegistry::getValue(function_name); + LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name); if (result) { - function = *result; + function = result->mFunction; } if (!function) { - LL_WARNS() << "Can't bind mouse key to function " << function_name << ", no function with this name found" << LL_ENDL; + LL_WARNS_ONCE() << "Can't bind mouse key to function " << function_name << ", no function with this name found" << LL_ENDL; return FALSE; } - // check for duplicate first and overwrite - S32 size = mMouseBindings[mode].size(); - for (index = 0; index < size; index++) - { - if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) - break; - } - if (mode >= MODE_COUNT) { LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; return FALSE; } + // check for duplicate first and overwrite + if (result->mIsGlobal) + { + S32 size = mGlobalMouseBindings[mode].size(); + for (index = 0; index < size; index++) + { + if (mouse == mGlobalMouseBindings[mode][index].mMouse && mask == mGlobalMouseBindings[mode][index].mMask) + { + mGlobalMouseBindings[mode][index].mFunction = function; + return true; + } + } + } + else + { + S32 size = mMouseBindings[mode].size(); + for (index = 0; index < size; index++) + { + if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) + { + mMouseBindings[mode][index].mFunction = function; + return true; + } + } + } + LLMouseBinding bind; bind.mMouse = mouse; bind.mMask = mask; bind.mFunction = function; - mMouseBindings[mode].push_back(bind); + if (result->mIsGlobal) + { + mGlobalMouseBindings[mode].push_back(bind); + } + else + { + mMouseBindings[mode].push_back(bind); + } return TRUE; } @@ -1162,6 +1251,8 @@ void LLViewerInput::resetBindings() { for (S32 i = 0; i < MODE_COUNT; i++) { + mGlobalKeyBindings[i].clear(); + mGlobalMouseBindings[i].clear(); mKeyBindings[i].clear(); mMouseBindings[i].clear(); } @@ -1536,5 +1627,11 @@ bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) return true; } + size = mGlobalMouseBindings[mode].size(); + for (S32 index = 0; index < size; index++) + { + if (mouse == mGlobalMouseBindings[mode][index].mMouse && mask == mGlobalMouseBindings[mode][index].mMask) + return true; + } return false; } diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index 281a209896..8401f8cd95 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -109,6 +109,13 @@ public: BOOL handleKey(KEY key, MASK mask, BOOL repeated); BOOL handleKeyUp(KEY key, MASK mask); + // Handle 'global' keybindings that do not consume event, + // yet need to be processed early + // Example: we want voice to toggle even if some floater is focused + bool handleGlobalBindsKeyDown(KEY key, MASK mask); + bool handleGlobalBindsKeyUp(KEY key, MASK mask); + bool handleGlobalBindsMouse(EMouseClickType clicktype, MASK mask, bool down); + S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error EKeyboardMode getMode() const; @@ -164,6 +171,10 @@ private: std::vector<LLKeyboardBinding> mKeyBindings[MODE_COUNT]; std::vector<LLMouseBinding> mMouseBindings[MODE_COUNT]; + // keybindings that do not consume event and are handled earlier, before floaters + std::vector<LLKeyboardBinding> mGlobalKeyBindings[MODE_COUNT]; + std::vector<LLMouseBinding> mGlobalMouseBindings[MODE_COUNT]; + typedef std::map<U32, U32> key_remap_t; key_remap_t mRemapKeys[MODE_COUNT]; std::set<KEY> mKeysSkippedByUI; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 21985d5a8a..b0462f8ba7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -54,7 +54,6 @@ #include "llslurl.h" #include "llrender.h" -#include "llvoiceclient.h" // for push-to-talk button handling #include "stringize.h" // @@ -1057,6 +1056,9 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m x = ll_round((F32)x / mDisplayScale.mV[VX]); y = ll_round((F32)y / mDisplayScale.mV[VY]); + // Handle non-consuming global keybindings, like voice + gViewerInput.handleGlobalBindsMouse(clicktype, mask, down); + // only send mouse clicks to UI if UI is visible if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { @@ -1577,6 +1579,10 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) { + // Handle non-consuming global keybindings, like voice + // Never affects event processing. + gViewerInput.handleGlobalBindsKeyDown(key, mask); + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) { gAgent.clearAFK(); @@ -1601,6 +1607,10 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) { + // Handle non-consuming global keybindings, like voice + // Never affects event processing. + gViewerInput.handleGlobalBindsKeyUp(key, mask); + // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) |