SL-15594 Reimplement previous voice keybind behavior

Also fixed dupplicate checks
master
Andrey Kleshchev 2021-07-16 22:45:41 +03:00
parent 3bdabd80de
commit 2d855a9fd7
3 changed files with 150 additions and 32 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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)