diff options
Diffstat (limited to 'indra/newview/llviewerinput.cpp')
-rw-r--r-- | indra/newview/llviewerinput.cpp | 180 |
1 files changed, 146 insertions, 34 deletions
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index c0eaa88f54..6629a2ffac 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,33 @@ 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; + S32 mode = getMode(); + if (down) + { + res = scanMouse(mGlobalMouseBindings[mode], mGlobalMouseBindings[mode].size(), clicktype, mask, MOUSE_STATE_DOWN, true); + } + else + { + res = scanMouse(mGlobalMouseBindings[mode], mGlobalMouseBindings[mode].size(), clicktype, mask, MOUSE_STATE_UP, true); + } + return res; +} + BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) { S32 index; @@ -1061,39 +1104,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_ERRS() << "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 +1172,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_ERRS() << "Can't bind 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 +1255,8 @@ void LLViewerInput::resetBindings() { for (S32 i = 0; i < MODE_COUNT; i++) { + mGlobalKeyBindings[i].clear(); + mGlobalMouseBindings[i].clear(); mKeyBindings[i].clear(); mMouseBindings[i].clear(); } @@ -1439,11 +1534,18 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, return handled; } -bool LLViewerInput::scanMouse(const std::vector<LLMouseBinding> &binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const +bool LLViewerInput::scanMouse( + const std::vector<LLMouseBinding> &binding, + S32 binding_count, + EMouseClickType mouse, + MASK mask, + EMouseState state, + bool ignore_additional_masks +) const { for (S32 i = 0; i < binding_count; i++) { - if (binding[i].mMouse == mouse && (binding[i].mMask & mask) == binding[i].mMask) + if (binding[i].mMouse == mouse && (ignore_additional_masks ? (binding[i].mMask & mask) == binding[i].mMask : binding[i].mMask == mask)) { bool res = false; switch (state) @@ -1480,7 +1582,11 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const bool res = false; S32 mode = getMode(); MASK mask = gKeyboard->currentMask(TRUE); - res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state); + + // By default mouse clicks require exact mask + // Todo: support for mIgnoreMasks because some functions like teleports + // expect to be canceled, but for voice it's prefered to ignore mask. + res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false); // no user defined actions found or those actions can't handle the key/button, handle control if nessesary if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) { @@ -1536,5 +1642,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; } |