From 4df05c5a8995158922c7b7aacfef442ac8ae6fdd Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 17 Sep 2019 21:36:59 +0300 Subject: SL-6109 Keyaboard support ready --- indra/newview/llviewerkeyboard.cpp | 56 ++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'indra/newview/llviewerkeyboard.cpp') diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 6914e0fc2b..1c93a2e954 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -605,6 +605,12 @@ void start_gesture( EKeystate s ) } } +void toggle_parcel_media(EKeystate s) +{ + bool pause = LLViewerMedia::isAnyMediaPlaying(); + LLViewerMedia::setAllMediaPaused(pause); +} + #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); REGISTER_KEYBOARD_ACTION("jump", agent_jump); REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); @@ -646,6 +652,7 @@ REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward) REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); REGISTER_KEYBOARD_ACTION("start_chat", start_chat); REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); +REGISTER_KEYBOARD_ACTION("toggle_parcel_media", toggle_parcel_media); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() @@ -807,7 +814,7 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c mBindings[mode][index].mFunction = function; if (index == mBindingCount[mode]) - mBindingCount[mode]++; + mBindingCount[mode]++; return TRUE; } @@ -818,21 +825,25 @@ LLViewerKeyboard::KeyBinding::KeyBinding() command("command") {} -LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode) -: bindings("binding"), - mode(_mode) +LLViewerKeyboard::KeyMode::KeyMode() +: bindings("binding") {} LLViewerKeyboard::Keys::Keys() -: first_person("first_person", KeyMode(MODE_FIRST_PERSON)), - third_person("third_person", KeyMode(MODE_THIRD_PERSON)), - edit("edit", KeyMode(MODE_EDIT)), - sitting("sitting", KeyMode(MODE_SITTING)), - edit_avatar("edit_avatar", KeyMode(MODE_EDIT_AVATAR)) +: first_person("first_person"), + third_person("third_person"), + edit("edit"), + sitting("sitting"), + edit_avatar("edit_avatar") {} S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) { + for (S32 i = 0; i < MODE_COUNT; i++) + { + mBindingCount[i] = 0; + } + S32 binding_count = 0; Keys keys; LLSimpleXUIParser parser; @@ -840,16 +851,16 @@ S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) if (parser.readXUI(filename, keys) && keys.validateBlock()) { - binding_count += loadBindingMode(keys.first_person); - binding_count += loadBindingMode(keys.third_person); - binding_count += loadBindingMode(keys.edit); - binding_count += loadBindingMode(keys.sitting); - binding_count += loadBindingMode(keys.edit_avatar); + binding_count += loadBindingMode(keys.first_person, MODE_FIRST_PERSON); + binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON); + binding_count += loadBindingMode(keys.edit, MODE_EDIT); + binding_count += loadBindingMode(keys.sitting, MODE_SITTING); + binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); } return binding_count; } -S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode) +S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, S32 mode) { S32 binding_count = 0; for (LLInitParam::ParamIterator::const_iterator it = keymode.bindings.begin(), @@ -857,12 +868,15 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode) it != end_it; ++it) { - KEY key; - MASK mask; - LLKeyboard::keyFromString(it->key, &key); - LLKeyboard::maskFromString(it->mask, &mask); - bindKey(keymode.mode, key, mask, it->command); - binding_count++; + if (!it->key.getValue().empty()) + { + KEY key; + MASK mask; + LLKeyboard::keyFromString(it->key, &key); + LLKeyboard::maskFromString(it->mask, &mask); + bindKey(mode, key, mask, it->command); + binding_count++; + } } return binding_count; -- cgit v1.2.3 From c60b929fbb615f8d73f7bf42849b5628bf0f8f7a Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 25 Sep 2019 17:54:36 +0300 Subject: SL-6109 Mouse support ready --- indra/newview/llviewerkeyboard.cpp | 424 ++++++++++++++++++++++++++++++++----- 1 file changed, 370 insertions(+), 54 deletions(-) (limited to 'indra/newview/llviewerkeyboard.cpp') diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1c93a2e954..fb1f33c6b0 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -605,12 +605,50 @@ void start_gesture( EKeystate s ) } } -void toggle_parcel_media(EKeystate s) +void toggle_run(EKeystate s) { + if (KEYSTATE_DOWN != s) return; + bool run = gAgent.getAlwaysRun(); + if (run) + { + gAgent.clearAlwaysRun(); + gAgent.clearRunning(); + } + else + { + gAgent.setAlwaysRun(); + gAgent.setRunning(); + } + gAgent.sendWalkRun(!run); +} + +void toggle_sit(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return; + if (gAgent.isSitting()) + { + gAgent.standUp(); + } + else + { + gAgent.sitDown(); + } +} + +void toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar +{ + if (KEYSTATE_DOWN != s) return; bool pause = LLViewerMedia::isAnyMediaPlaying(); LLViewerMedia::setAllMediaPaused(pause); } +void toggle_enable_media(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return; + bool pause = LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isAnyMediaShowing(); + LLViewerMedia::setAllMediaEnabled(!pause); +} + #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); REGISTER_KEYBOARD_ACTION("jump", agent_jump); REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); @@ -652,20 +690,24 @@ REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward) REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); REGISTER_KEYBOARD_ACTION("start_chat", start_chat); REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); -REGISTER_KEYBOARD_ACTION("toggle_parcel_media", toggle_parcel_media); +REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run); +REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit); +REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); +REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() { - for (S32 i = 0; i < MODE_COUNT; i++) - { - mBindingCount[i] = 0; - } + resetBindings(); for (S32 i = 0; i < KEY_COUNT; i++) { mKeyHandledByUI[i] = FALSE; - } + } + for (S32 i = 0; i < CLICK_COUNT; i++) + { + mMouseLevel[i] = MOUSE_STATE_SILENT; + } // we want the UI to never see these keys so that they can always control the avatar/camera for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) { @@ -673,7 +715,7 @@ LLViewerKeyboard::LLViewerKeyboard() } } -BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) +BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) const { if (string == "FIRST_PERSON") { @@ -707,6 +749,40 @@ BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) } } +BOOL LLViewerKeyboard::mouseFromString(const std::string& string, EMouseClickType *mode) const +{ + if (string == "LMB") + { + *mode = CLICK_LEFT; + return TRUE; + } + else if (string == "DLMB") + { + *mode = CLICK_DOUBLELEFT; + return TRUE; + } + else if (string == "MMB") + { + *mode = CLICK_MIDDLE; + return TRUE; + } + else if (string == "MB4") + { + *mode = CLICK_BUTTON4; + return TRUE; + } + else if (string == "MB5") + { + *mode = CLICK_BUTTON5; + return TRUE; + } + else + { + *mode = CLICK_NONE; + return FALSE; + } +} + BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) { // check for re-map @@ -750,7 +826,7 @@ BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) return gViewerWindow->handleKeyUp(translated_key, translated_mask); } -BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) +BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name) { S32 index; typedef boost::function function_t; @@ -791,11 +867,22 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c } // check for duplicate first and overwrite - for (index = 0; index < mBindingCount[mode]; index++) - { - if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask) - break; - } + if (ignore) + { + for (index = 0; index < mKeyIgnoreMaskCount[mode]; index++) + { + if (key == mKeyIgnoreMask[mode][index].mKey) + break; + } + } + else + { + for (index = 0; index < mKeyBindingCount[mode]; index++) + { + if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) + break; + } + } if (index >= MAX_KEY_BINDINGS) { @@ -809,20 +896,102 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c return FALSE; } - mBindings[mode][index].mKey = key; - mBindings[mode][index].mMask = mask; - mBindings[mode][index].mFunction = function; + if (ignore) + { + mKeyIgnoreMask[mode][index].mKey = key; + mKeyIgnoreMask[mode][index].mFunction = function; + + if (index == mKeyIgnoreMaskCount[mode]) + mKeyIgnoreMaskCount[mode]++; + } + else + { + mKeyBindings[mode][index].mKey = key; + mKeyBindings[mode][index].mMask = mask; + mKeyBindings[mode][index].mFunction = function; - if (index == mBindingCount[mode]) - mBindingCount[mode]++; + if (index == mKeyBindingCount[mode]) + mKeyBindingCount[mode]++; + } return TRUE; } +BOOL LLViewerKeyboard::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name) +{ + S32 index; + typedef boost::function function_t; + function_t function = NULL; + + function_t* result = LLKeyboardActionRegistry::getValue(function_name); + if (result) + { + function = *result; + } + + if (!function) + { + LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; + return FALSE; + } + + // check for duplicate first and overwrite + if (ignore) + { + for (index = 0; index < mMouseIgnoreMaskCount[mode]; index++) + { + if (mouse == mMouseIgnoreMask[mode][index].mMouse) + break; + } + } + else + { + for (index = 0; index < mMouseBindingCount[mode]; index++) + { + if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) + break; + } + } + + if (index >= MAX_KEY_BINDINGS) + { + LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; + return FALSE; + } + + if (mode >= MODE_COUNT) + { + LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; + return FALSE; + } + + if (ignore) + { + mMouseIgnoreMask[mode][index].mMouse = mouse; + mMouseIgnoreMask[mode][index].mFunction = function; + + if (index == mMouseIgnoreMaskCount[mode]) + mMouseIgnoreMaskCount[mode]++; + } + else + { + mMouseBindings[mode][index].mMouse = mouse; + mMouseBindings[mode][index].mMask = mask; + mMouseBindings[mode][index].mFunction = function; + + if (index == mMouseBindingCount[mode]) + mMouseBindingCount[mode]++; + } + + return TRUE; +} + LLViewerKeyboard::KeyBinding::KeyBinding() : key("key"), + mouse("mouse"), mask("mask"), - command("command") + command("command"), + ignore("ignore", false) {} LLViewerKeyboard::KeyMode::KeyMode() @@ -837,12 +1006,20 @@ LLViewerKeyboard::Keys::Keys() edit_avatar("edit_avatar") {} +void LLViewerKeyboard::resetBindings() +{ + for (S32 i = 0; i < MODE_COUNT; i++) + { + mKeyBindingCount[i] = 0; + mKeyIgnoreMaskCount[i] = 0; + mMouseBindingCount[i] = 0; + mMouseIgnoreMaskCount[i] = 0; + } +} + S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) { - for (S32 i = 0; i < MODE_COUNT; i++) - { - mBindingCount[i] = 0; - } + resetBindings(); S32 binding_count = 0; Keys keys; @@ -872,9 +1049,20 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, { KEY key; MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; LLKeyboard::keyFromString(it->key, &key); LLKeyboard::maskFromString(it->mask, &mask); - bindKey(mode, key, mask, it->command); + bindKey(mode, key, mask, ignore, it->command); + binding_count++; + } + else if (it->mouse.isProvided() && !it->mouse.getValue().empty()) + { + EMouseClickType mouse; + MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; + mouseFromString(it->mouse.getValue(), &mouse); + LLKeyboard::maskFromString(it->mask, &mask); + bindMouse(mode, mouse, mask, ignore, it->command); binding_count++; } } @@ -966,7 +1154,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) } // bind key - if (bindKey(mode, key, mask, function_string)) + if (bindKey(mode, key, mask, false, function_string)) { binding_count++; } @@ -978,7 +1166,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) } -EKeyboardMode LLViewerKeyboard::getMode() +EKeyboardMode LLViewerKeyboard::getMode() const { if ( gAgentCamera.cameraMouselook() ) { @@ -998,56 +1186,184 @@ EKeyboardMode LLViewerKeyboard::getMode() } } - -// Called from scanKeyboard. -void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) +bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, + S32 binding_count, + KEY key, + MASK mask, + BOOL key_down, + BOOL key_up, + BOOL key_level, + bool repeat) const { - if (LLApp::isExiting()) - { - return; - } - - S32 mode = getMode(); - // Consider keyboard scanning as NOT mouse event. JC - MASK mask = gKeyboard->currentMask(FALSE); - - LLKeyBinding* binding = mBindings[mode]; - S32 binding_count = mBindingCount[mode]; - - - if (mKeyHandledByUI[key]) - { - return; - } - - // don't process key down on repeated keys - BOOL repeat = gKeyboard->getKeyRepeated(key); - for (S32 i = 0; i < binding_count; i++) { - //for (S32 key = 0; key < KEY_COUNT; key++) if (binding[i].mKey == key) { - //if (binding[i].mKey == key && binding[i].mMask == mask) if (binding[i].mMask == mask) { if (key_down && !repeat) { // ...key went down this frame, call function binding[i].mFunction( KEYSTATE_DOWN ); + return true; } else if (key_up) { // ...key went down this frame, call function binding[i].mFunction( KEYSTATE_UP ); + return true; } else if (key_level) { // ...key held down from previous frame // Not windows, just call the function. binding[i].mFunction( KEYSTATE_LEVEL ); + return true; }//if + // Key+Mask combinations are supposed to be unique, so we won't find anything else + return false; }//if - }//for + }//if }//for + return false; +} + +// Called from scanKeyboard. +void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const +{ + if (LLApp::isExiting()) + { + return; + } + + S32 mode = getMode(); + // Consider keyboard scanning as NOT mouse event. JC + MASK mask = gKeyboard->currentMask(FALSE); + + if (mKeyHandledByUI[key]) + { + return; + } + + // don't process key down on repeated keys + BOOL repeat = gKeyboard->getKeyRepeated(key); + + if (scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat)) + { + // Nothing found, try ignore list + scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); + } +} + +BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) +{ + BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down); + + if (clicktype != CLICK_NONE) + { + // special case + // if UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set + // handle !down as if we are handling doubleclick + bool override_lmb = (clicktype == CLICK_LEFT + && (mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_DOWN || mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_LEVEL)); + + if (override_lmb && !down) + { + // process doubleclick instead + clicktype = CLICK_DOUBLELEFT; + } + + if (override_lmb && down) + { + // else-supress + } + // if UI handled 'down', it should handle 'up' as well + // if we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI + else if (handled && mMouseLevel[clicktype] != MOUSE_STATE_SILENT) + { + // UI handled new 'down' so iterupt whatever state we were in. + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } + else if (down) + { + if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) + { + // this is repeated hit (mouse does not repeat event until release) + // for now treat rapid clicking like mouse being held + mMouseLevel[clicktype] = MOUSE_STATE_LEVEL; + } + else + { + mMouseLevel[clicktype] = MOUSE_STATE_DOWN; + } + } + else + { + // Released mouse key + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } + } + + return handled; +} + +bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const +{ + for (S32 i = 0; i < binding_count; i++) + { + if (binding[i].mMouse == mouse && binding[i].mMask == mask) + { + switch (state) + { + case MOUSE_STATE_DOWN: + binding[i].mFunction(KEYSTATE_DOWN); + break; + case MOUSE_STATE_LEVEL: + binding[i].mFunction(KEYSTATE_LEVEL); + break; + case MOUSE_STATE_UP: + binding[i].mFunction(KEYSTATE_UP); + break; + default: + break; + } + // Key+Mask combinations are supposed to be unique, no need to continue + return true; + } + } + return false; +} + +// todo: this recods key, scanMouse() triggers functions with EKeystate +bool LLViewerKeyboard::scanMouse(EMouseClickType click, EMouseState state) const +{ + bool res = false; + S32 mode = getMode(); + MASK mask = gKeyboard->currentMask(TRUE); + res = scanMouse(mMouseBindings[mode], mMouseBindingCount[mode], click, mask, state); + if (!res) + { + res = scanMouse(mMouseIgnoreMask[mode], mMouseIgnoreMaskCount[mode], click, MASK_NONE, state); + } + return res; +} + +void LLViewerKeyboard::scanMouse() +{ + for (S32 i = 0; i < CLICK_COUNT; i++) + { + if (mMouseLevel[i] != MOUSE_STATE_SILENT) + { + scanMouse((EMouseClickType)i, mMouseLevel[i]); + if (mMouseLevel[i] == MOUSE_STATE_DOWN) + { + // mouse doesn't support 'continued' state like keyboard does, so after handling, switch to LEVEL + mMouseLevel[i] = MOUSE_STATE_LEVEL; + } + else if (mMouseLevel[i] == MOUSE_STATE_UP) + { + mMouseLevel[i] = MOUSE_STATE_SILENT; + } + } + } } -- cgit v1.2.3 From 4ae2165c4516a74012d30610b4c53de6d3ccaf90 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 25 Sep 2019 22:23:09 +0300 Subject: SL-6109 LMB DLMB in progress --- indra/newview/llviewerkeyboard.cpp | 114 ++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 28 deletions(-) (limited to 'indra/newview/llviewerkeyboard.cpp') diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index fb1f33c6b0..abc7346616 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -38,6 +38,7 @@ #include "llmorphview.h" #include "llmoveview.h" #include "lltoolfocus.h" +#include "lltoolpie.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llfloatercamera.h" @@ -567,7 +568,7 @@ void edit_avatar_move_backward( EKeystate s ) void stop_moving( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_DOWN != s ) return; // stop agent gAgent.setControlFlags(AGENT_CONTROL_STOP); @@ -581,7 +582,8 @@ void start_chat( EKeystate s ) { return; // can't talk, gotta go, kthxbye! } - + if (KEYSTATE_DOWN != s) return; + // start chat LLFloaterIMNearbyChat::startChat(NULL); } @@ -649,6 +651,19 @@ void toggle_enable_media(EKeystate s) LLViewerMedia::setAllMediaEnabled(!pause); } +void walk_to(EKeystate s) +{ + LL_WARNS() << "processing " << LLSD(s).asString() << LL_ENDL; + if (KEYSTATE_DOWN != s) return; + LLToolPie::getInstance()->walkToClickedLocation(); +} + +void teleport_to(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return; + LLToolPie::getInstance()->teleportToClickedLocation(); +} + #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); REGISTER_KEYBOARD_ACTION("jump", agent_jump); REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); @@ -694,6 +709,8 @@ REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run); REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit); 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); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() @@ -756,7 +773,7 @@ BOOL LLViewerKeyboard::mouseFromString(const std::string& string, EMouseClickTyp *mode = CLICK_LEFT; return TRUE; } - else if (string == "DLMB") + else if (string == "Double LMB") { *mode = CLICK_DOUBLELEFT; return TRUE; @@ -1045,24 +1062,44 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, it != end_it; ++it) { + bool processed = false; if (!it->key.getValue().empty()) { KEY key; - MASK mask; - bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; LLKeyboard::keyFromString(it->key, &key); - LLKeyboard::maskFromString(it->mask, &mask); - bindKey(mode, key, mask, ignore, it->command); - binding_count++; + if (key != KEY_NONE) + { + MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; + LLKeyboard::maskFromString(it->mask, &mask); + bindKey(mode, key, mask, ignore, it->command); + processed = true; + } + else + { + LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; + } } - else if (it->mouse.isProvided() && !it->mouse.getValue().empty()) + if (!processed && it->mouse.isProvided() && !it->mouse.getValue().empty()) { EMouseClickType mouse; - MASK mask; - bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; mouseFromString(it->mouse.getValue(), &mouse); - LLKeyboard::maskFromString(it->mask, &mask); - bindMouse(mode, mouse, mask, ignore, it->command); + if (mouse != CLICK_NONE) + { + MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; + LLKeyboard::maskFromString(it->mask, &mask); + bindMouse(mode, mouse, mask, ignore, it->command); + processed = true; + } + else + { + LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; + } + } + if (processed) + { + // total binding_count++; } } @@ -1261,28 +1298,41 @@ BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK ma if (clicktype != CLICK_NONE) { - // special case - // if UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set + // Special case + // If UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set // handle !down as if we are handling doubleclick - bool override_lmb = (clicktype == CLICK_LEFT - && (mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_DOWN || mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_LEVEL)); - if (override_lmb && !down) + bool double_click_sp = (clicktype == CLICK_LEFT + && (mMouseLevel[CLICK_DOUBLELEFT] != MOUSE_STATE_SILENT) + && mMouseLevel[CLICK_LEFT] == MOUSE_STATE_SILENT); + if (double_click_sp && !down) { - // process doubleclick instead + // Process doubleclick instead clicktype = CLICK_DOUBLELEFT; } - if (override_lmb && down) + + if (double_click_sp && down) { - // else-supress + // Consume click. + // Due to handling, double click that is not handled will be immediately followed by LMB click } - // if UI handled 'down', it should handle 'up' as well - // if we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI - else if (handled && mMouseLevel[clicktype] != MOUSE_STATE_SILENT) + // If UI handled 'down', it should handle 'up' as well + // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI + else if (handled) { // UI handled new 'down' so iterupt whatever state we were in. - mMouseLevel[clicktype] = MOUSE_STATE_UP; + if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) + { + if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) + { + mMouseLevel[clicktype] = MOUSE_STATE_CLICK; + } + else + { + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } + } } else if (down) { @@ -1297,10 +1347,17 @@ BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK ma mMouseLevel[clicktype] = MOUSE_STATE_DOWN; } } - else + else if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) { // Released mouse key - mMouseLevel[clicktype] = MOUSE_STATE_UP; + if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) + { + mMouseLevel[clicktype] = MOUSE_STATE_CLICK; + } + else + { + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } } } @@ -1316,6 +1373,7 @@ bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_coun switch (state) { case MOUSE_STATE_DOWN: + case MOUSE_STATE_CLICK: binding[i].mFunction(KEYSTATE_DOWN); break; case MOUSE_STATE_LEVEL: @@ -1360,7 +1418,7 @@ void LLViewerKeyboard::scanMouse() // mouse doesn't support 'continued' state like keyboard does, so after handling, switch to LEVEL mMouseLevel[i] = MOUSE_STATE_LEVEL; } - else if (mMouseLevel[i] == MOUSE_STATE_UP) + else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK) { mMouseLevel[i] = MOUSE_STATE_SILENT; } -- cgit v1.2.3 From 2532a2ee9ee9003e2c6b72f8da19979a9e3dd2f6 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 26 Sep 2019 22:28:18 +0300 Subject: SL-6109 Conflict resolution --- indra/newview/llviewerkeyboard.cpp | 473 ++++++++++++++++++++----------------- 1 file changed, 255 insertions(+), 218 deletions(-) (limited to 'indra/newview/llviewerkeyboard.cpp') diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index abc7346616..2647abc74c 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -26,19 +26,21 @@ #include "llviewerprecompiledheaders.h" +#include "llviewerkeyboard.h" + #include "llappviewer.h" #include "llfloaterreg.h" -#include "llviewerkeyboard.h" #include "llmath.h" #include "llagent.h" #include "llagentcamera.h" #include "llfloaterimnearbychat.h" -#include "llviewercontrol.h" #include "llfocusmgr.h" +#include "llkeybind.h" // LLKeyData #include "llmorphview.h" #include "llmoveview.h" #include "lltoolfocus.h" #include "lltoolpie.h" +#include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llfloatercamera.h" @@ -55,21 +57,23 @@ const F32 NUDGE_TIME = 0.25f; // in seconds const S32 NUDGE_FRAMES = 2; const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed +const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true); + struct LLKeyboardActionRegistry -: public LLRegistrySingleton, LLKeyboardActionRegistry> +: public LLRegistrySingleton, LLKeyboardActionRegistry> { LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); }; LLViewerKeyboard gViewerKeyboard; -void agent_jump( EKeystate s ) +bool agent_jump( EKeystate s ) { static BOOL first_fly_attempt(TRUE); if (KEYSTATE_UP == s) { first_fly_attempt = TRUE; - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); @@ -87,12 +91,14 @@ void agent_jump( EKeystate s ) first_fly_attempt = FALSE; gAgent.moveUp(1); } + return true; } -void agent_push_down( EKeystate s ) +bool agent_push_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.moveUp(-1); + return true; } static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode) @@ -152,11 +158,11 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo } } -void camera_move_forward( EKeystate s ); +bool camera_move_forward( EKeystate s ); -void agent_push_forward( EKeystate s ) +bool agent_push_forward( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) @@ -167,13 +173,14 @@ void agent_push_forward( EKeystate s ) { agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); } + return true; } -void camera_move_backward( EKeystate s ); +bool camera_move_backward( EKeystate s ); -void agent_push_backward( EKeystate s ) +bool agent_push_backward( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) @@ -188,6 +195,7 @@ void agent_push_backward( EKeystate s ) { agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } + return true; } static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) @@ -208,31 +216,33 @@ static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleT } -void agent_slide_left( EKeystate s ) +bool agent_slide_left( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); + return true; } -void agent_slide_right( EKeystate s ) +bool agent_slide_right( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); + return true; } -void camera_spin_around_cw( EKeystate s ); +bool camera_spin_around_cw( EKeystate s ); -void agent_turn_left( EKeystate s ) +bool agent_turn_left(EKeystate s) { //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_spin_around_cw(s); - return; + return true; } - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return false; if (LLToolCamera::getInstance()->mouseSteerMode()) { @@ -244,25 +254,26 @@ void agent_turn_left( EKeystate s ) { // Check temporary running. In case user released 'left' key with shift already released. agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT); - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); } + return true; } -void camera_spin_around_ccw( EKeystate s ); +bool camera_spin_around_ccw( EKeystate s ); -void agent_turn_right( EKeystate s ) +bool agent_turn_right( EKeystate s ) { //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_spin_around_ccw(s); - return; + return true; } - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return false; if (LLToolCamera::getInstance()->mouseSteerMode()) { @@ -274,35 +285,39 @@ void agent_turn_right( EKeystate s ) { // Check temporary running. In case user released 'right' key with shift already released. agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT); - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); } + return true; } -void agent_look_up( EKeystate s ) +bool agent_look_up( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.movePitch(-1); //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); + return true; } -void agent_look_down( EKeystate s ) +bool agent_look_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.movePitch(1); //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); + return true; } -void agent_toggle_fly( EKeystate s ) +bool agent_toggle_fly( EKeystate s ) { // Only catch the edge if (KEYSTATE_DOWN == s ) { LLAgent::toggleFlying(); } + return true; } F32 get_orbit_rate() @@ -320,24 +335,26 @@ F32 get_orbit_rate() } } -void camera_spin_around_ccw( EKeystate s ) +bool camera_spin_around_ccw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); + return true; } -void camera_spin_around_cw( EKeystate s ) +bool camera_spin_around_cw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitRightKey( get_orbit_rate() ); + return true; } -void camera_spin_around_ccw_sitting( EKeystate s ) +bool camera_spin_around_ccw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true; if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera @@ -349,12 +366,13 @@ void camera_spin_around_ccw_sitting( EKeystate s ) gAgentCamera.unlockView(); gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } + return true; } -void camera_spin_around_cw_sitting( EKeystate s ) +bool camera_spin_around_cw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true; if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera @@ -366,27 +384,30 @@ void camera_spin_around_cw_sitting( EKeystate s ) gAgentCamera.unlockView(); gAgentCamera.setOrbitRightKey( get_orbit_rate() ); } + return true; } -void camera_spin_over( EKeystate s ) +bool camera_spin_over( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitUpKey( get_orbit_rate() ); + return true; } -void camera_spin_under( EKeystate s ) +bool camera_spin_under( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitDownKey( get_orbit_rate() ); + return true; } -void camera_spin_over_sitting( EKeystate s ) +bool camera_spin_over_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera @@ -397,12 +418,13 @@ void camera_spin_over_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } + return true; } -void camera_spin_under_sitting( EKeystate s ) +bool camera_spin_under_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera @@ -413,26 +435,29 @@ void camera_spin_under_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitDownKey( get_orbit_rate() ); } + return true; } -void camera_move_forward( EKeystate s ) +bool camera_move_forward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitInKey( get_orbit_rate() ); + return true; } -void camera_move_backward( EKeystate s ) +bool camera_move_backward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitOutKey( get_orbit_rate() ); + return true; } -void camera_move_forward_sitting( EKeystate s ) +bool camera_move_forward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true; if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) { agent_push_forward(s); @@ -441,12 +466,13 @@ void camera_move_forward_sitting( EKeystate s ) { gAgentCamera.setOrbitInKey( get_orbit_rate() ); } + return true; } -void camera_move_backward_sitting( EKeystate s ) +bool camera_move_backward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true; if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) { @@ -456,139 +482,156 @@ void camera_move_backward_sitting( EKeystate s ) { gAgentCamera.setOrbitOutKey( get_orbit_rate() ); } + return true; } -void camera_pan_up( EKeystate s ) +bool camera_pan_up( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanUpKey( get_orbit_rate() ); + return true; } -void camera_pan_down( EKeystate s ) +bool camera_pan_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanDownKey( get_orbit_rate() ); + return true; } -void camera_pan_left( EKeystate s ) +bool camera_pan_left( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanLeftKey( get_orbit_rate() ); + return true; } -void camera_pan_right( EKeystate s ) +bool camera_pan_right( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanRightKey( get_orbit_rate() ); + return true; } -void camera_pan_in( EKeystate s ) +bool camera_pan_in( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanInKey( get_orbit_rate() ); + return true; } -void camera_pan_out( EKeystate s ) +bool camera_pan_out( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanOutKey( get_orbit_rate() ); + return true; } -void camera_move_forward_fast( EKeystate s ) +bool camera_move_forward_fast( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitInKey(2.5f); + return true; } -void camera_move_backward_fast( EKeystate s ) +bool camera_move_backward_fast( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitOutKey(2.5f); + return true; } -void edit_avatar_spin_ccw( EKeystate s ) +bool edit_avatar_spin_ccw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); //gMorphView->orbitLeft( get_orbit_rate() ); + return true; } -void edit_avatar_spin_cw( EKeystate s ) +bool edit_avatar_spin_cw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitRightKey( get_orbit_rate() ); //gMorphView->orbitRight( get_orbit_rate() ); + return true; } -void edit_avatar_spin_over( EKeystate s ) +bool edit_avatar_spin_over( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitUpKey( get_orbit_rate() ); //gMorphView->orbitUp( get_orbit_rate() ); + return true; } -void edit_avatar_spin_under( EKeystate s ) +bool edit_avatar_spin_under( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitDownKey( get_orbit_rate() ); //gMorphView->orbitDown( get_orbit_rate() ); + return true; } -void edit_avatar_move_forward( EKeystate s ) +bool edit_avatar_move_forward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitInKey( get_orbit_rate() ); //gMorphView->orbitIn(); + return true; } -void edit_avatar_move_backward( EKeystate s ) +bool edit_avatar_move_backward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitOutKey( get_orbit_rate() ); //gMorphView->orbitOut(); + return true; } -void stop_moving( EKeystate s ) +bool stop_moving( EKeystate s ) { - if( KEYSTATE_DOWN != s ) return; + if( KEYSTATE_DOWN != s ) return true; // stop agent gAgent.setControlFlags(AGENT_CONTROL_STOP); // cancel autopilot gAgent.stopAutoPilot(); + return true; } -void start_chat( EKeystate s ) +bool start_chat( EKeystate s ) { if (LLAppViewer::instance()->quitRequested()) { - return; // can't talk, gotta go, kthxbye! + return true; // can't talk, gotta go, kthxbye! } - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; // start chat LLFloaterIMNearbyChat::startChat(NULL); + return true; } -void start_gesture( EKeystate s ) +bool start_gesture( EKeystate s ) { LLUICtrl* focus_ctrlp = dynamic_cast(gFocusMgr.getKeyboardFocus()); if (KEYSTATE_UP == s && @@ -605,11 +648,12 @@ void start_gesture( EKeystate s ) LLFloaterIMNearbyChat::startChat(NULL); } } + return true; } -void toggle_run(EKeystate s) +bool toggle_run(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool run = gAgent.getAlwaysRun(); if (run) { @@ -622,11 +666,12 @@ void toggle_run(EKeystate s) gAgent.setRunning(); } gAgent.sendWalkRun(!run); + return true; } -void toggle_sit(EKeystate s) +bool toggle_sit(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; if (gAgent.isSitting()) { gAgent.standUp(); @@ -635,33 +680,75 @@ void toggle_sit(EKeystate s) { gAgent.sitDown(); } + return true; } -void toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar +bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool pause = LLViewerMedia::isAnyMediaPlaying(); LLViewerMedia::setAllMediaPaused(pause); + return true; } -void toggle_enable_media(EKeystate s) +bool toggle_enable_media(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool pause = LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isAnyMediaShowing(); LLViewerMedia::setAllMediaEnabled(!pause); + return true; } -void walk_to(EKeystate s) +bool walk_to(EKeystate s) { - LL_WARNS() << "processing " << LLSD(s).asString() << LL_ENDL; - if (KEYSTATE_DOWN != s) return; - LLToolPie::getInstance()->walkToClickedLocation(); + if (KEYSTATE_DOWN != s) return true; + return LLToolPie::getInstance()->walkToClickedLocation(); +} + +bool teleport_to(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return true; + return LLToolPie::getInstance()->teleportToClickedLocation(); +} + +bool toggle_voice(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return true; + if (!LLAgent::isActionAllowed("speak")) return false; + LLVoiceClient::getInstance()->toggleUserPTTState(); + return true; +} + +bool voice_follow_key(EKeystate s) +{ + if (KEYSTATE_DOWN == s) + { + if (!LLAgent::isActionAllowed("speak")) return false; + LLVoiceClient::getInstance()->setUserPTTState(true); + return true; + } + else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState()) + { + LLVoiceClient::getInstance()->setUserPTTState(false); + return true; + } + return false; } -void teleport_to(EKeystate s) +bool agen_control_lbutton_handle(EKeystate s) { - if (KEYSTATE_DOWN != s) return; - LLToolPie::getInstance()->teleportToClickedLocation(); + switch (s) + { + case KEYSTATE_DOWN: + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + break; + case KEYSTATE_UP: + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + break; + default: + break; + } + return true; } #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); @@ -711,6 +798,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); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() @@ -846,7 +935,7 @@ BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name) { S32 index; - typedef boost::function function_t; + typedef boost::function function_t; function_t function = NULL; std::string name; @@ -937,7 +1026,7 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c BOOL LLViewerKeyboard::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name) { S32 index; - typedef boost::function function_t; + typedef boost::function function_t; function_t function = NULL; function_t* result = LLKeyboardActionRegistry::getValue(function_name); @@ -1107,102 +1196,6 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, return binding_count; } -S32 LLViewerKeyboard::loadBindings(const std::string& filename) -{ - LLFILE *fp; - const S32 BUFFER_SIZE = 2048; - char buffer[BUFFER_SIZE]; /* Flawfinder: ignore */ - // *NOTE: This buffer size is hard coded into scanf() below. - char mode_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char key_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char mask_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char function_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - S32 mode = MODE_THIRD_PERSON; - KEY key = 0; - MASK mask = 0; - S32 tokens_read; - S32 binding_count = 0; - S32 line_count = 0; - - if(filename.empty()) - { - LL_ERRS() << " No filename specified" << LL_ENDL; - return 0; - } - - fp = LLFile::fopen(filename, "r"); - - if (!fp) - { - return 0; - } - - - while (!feof(fp)) - { - line_count++; - if (!fgets(buffer, BUFFER_SIZE, fp)) - break; - - // skip over comments, blank lines - if (buffer[0] == '#' || buffer[0] == '\n') continue; - - // grab the binding strings - tokens_read = sscanf( /* Flawfinder: ignore */ - buffer, - "%254s %254s %254s %254s", - mode_string, - key_string, - mask_string, - function_string); - - if (tokens_read == EOF) - { - LL_INFOS() << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << LL_ENDL; - fclose(fp); - return 0; - } - else if (tokens_read < 4) - { - LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // convert mode - if (!modeFromString(mode_string, &mode)) - { - LL_INFOS() << "Unknown mode on line " << line_count << " of key binding file " << filename << LL_ENDL; - LL_INFOS() << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << LL_ENDL; - continue; - } - - // convert key - if (!LLKeyboard::keyFromString(key_string, &key)) - { - LL_INFOS() << "Can't interpret key on line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // convert mask - if (!LLKeyboard::maskFromString(mask_string, &mask)) - { - LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // bind key - if (bindKey(mode, key, mask, false, function_string)) - { - binding_count++; - } - } - - fclose(fp); - - return binding_count; -} - - EKeyboardMode LLViewerKeyboard::getMode() const { if ( gAgentCamera.cameraMouselook() ) @@ -1238,27 +1231,26 @@ bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, { if (binding[i].mMask == mask) { + bool res = false; if (key_down && !repeat) { // ...key went down this frame, call function - binding[i].mFunction( KEYSTATE_DOWN ); + res = binding[i].mFunction( KEYSTATE_DOWN ); return true; } else if (key_up) { // ...key went down this frame, call function - binding[i].mFunction( KEYSTATE_UP ); - return true; + res = binding[i].mFunction( KEYSTATE_UP ); } else if (key_level) { // ...key held down from previous frame // Not windows, just call the function. - binding[i].mFunction( KEYSTATE_LEVEL ); - return true; + res = binding[i].mFunction( KEYSTATE_LEVEL ); }//if // Key+Mask combinations are supposed to be unique, so we won't find anything else - return false; + return res; }//if }//if }//for @@ -1266,7 +1258,7 @@ bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, } // Called from scanKeyboard. -void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const +bool LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const { if (LLApp::isExiting()) { @@ -1279,17 +1271,31 @@ void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_lev if (mKeyHandledByUI[key]) { - return; + return false; } // don't process key down on repeated keys BOOL repeat = gKeyboard->getKeyRepeated(key); - if (scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat)) + bool res = scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat); + if (!res) { // Nothing found, try ignore list - scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); + res = scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); } + + if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) + { + if (key_down && !repeat) + { + res = agen_control_lbutton_handle(KEYSTATE_DOWN); + } + if (key_up) + { + res = agen_control_lbutton_handle(KEYSTATE_UP); + } + } + return res; } BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) @@ -1370,23 +1376,30 @@ bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_coun { if (binding[i].mMouse == mouse && binding[i].mMask == mask) { + bool res = false; switch (state) { case MOUSE_STATE_DOWN: + res = binding[i].mFunction(KEYSTATE_DOWN); + break; case MOUSE_STATE_CLICK: - binding[i].mFunction(KEYSTATE_DOWN); + // Button went down and up in scope of single frame + // might not work best with some functions, + // but some function need specific states specifically + res = binding[i].mFunction(KEYSTATE_DOWN); + res |= binding[i].mFunction(KEYSTATE_UP); break; case MOUSE_STATE_LEVEL: - binding[i].mFunction(KEYSTATE_LEVEL); + res = binding[i].mFunction(KEYSTATE_LEVEL); break; case MOUSE_STATE_UP: - binding[i].mFunction(KEYSTATE_UP); + res = binding[i].mFunction(KEYSTATE_UP); break; default: break; } // Key+Mask combinations are supposed to be unique, no need to continue - return true; + return res; } } return false; @@ -1403,6 +1416,30 @@ bool LLViewerKeyboard::scanMouse(EMouseClickType click, EMouseState state) const { res = scanMouse(mMouseIgnoreMask[mode], mMouseIgnoreMaskCount[mode], click, MASK_NONE, state); } + // 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)) + { + switch (state) + { + case MOUSE_STATE_DOWN: + agen_control_lbutton_handle(KEYSTATE_DOWN); + res = true; + break; + case MOUSE_STATE_CLICK: + // might not work best with some functions, + // but some function need specific states too specifically + agen_control_lbutton_handle(KEYSTATE_DOWN); + agen_control_lbutton_handle(KEYSTATE_UP); + res = true; + break; + case MOUSE_STATE_UP: + agen_control_lbutton_handle(KEYSTATE_UP); + res = true; + break; + default: + break; + } + } return res; } @@ -1415,7 +1452,7 @@ void LLViewerKeyboard::scanMouse() scanMouse((EMouseClickType)i, mMouseLevel[i]); if (mMouseLevel[i] == MOUSE_STATE_DOWN) { - // mouse doesn't support 'continued' state like keyboard does, so after handling, switch to LEVEL + // mouse doesn't support 'continued' state, so after handling, switch to LEVEL mMouseLevel[i] = MOUSE_STATE_LEVEL; } else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK) -- cgit v1.2.3 From b12cf6696348520556cf70f96e0562776479fe70 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 27 Sep 2019 15:25:47 +0300 Subject: SL-6109 Small reorganisation --- indra/newview/llviewerkeyboard.cpp | 1464 ------------------------------------ 1 file changed, 1464 deletions(-) delete mode 100644 indra/newview/llviewerkeyboard.cpp (limited to 'indra/newview/llviewerkeyboard.cpp') diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp deleted file mode 100644 index 2647abc74c..0000000000 --- a/indra/newview/llviewerkeyboard.cpp +++ /dev/null @@ -1,1464 +0,0 @@ -/** - * @file llviewerkeyboard.cpp - * @brief LLViewerKeyboard class implementation - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewerkeyboard.h" - -#include "llappviewer.h" -#include "llfloaterreg.h" -#include "llmath.h" -#include "llagent.h" -#include "llagentcamera.h" -#include "llfloaterimnearbychat.h" -#include "llfocusmgr.h" -#include "llkeybind.h" // LLKeyData -#include "llmorphview.h" -#include "llmoveview.h" -#include "lltoolfocus.h" -#include "lltoolpie.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llvoavatarself.h" -#include "llfloatercamera.h" -#include "llinitparam.h" - -// -// Constants -// - -const F32 FLY_TIME = 0.5f; -const F32 FLY_FRAMES = 4; - -const F32 NUDGE_TIME = 0.25f; // in seconds -const S32 NUDGE_FRAMES = 2; -const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed - -const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true); - -struct LLKeyboardActionRegistry -: public LLRegistrySingleton, LLKeyboardActionRegistry> -{ - LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); -}; - -LLViewerKeyboard gViewerKeyboard; - -bool agent_jump( EKeystate s ) -{ - static BOOL first_fly_attempt(TRUE); - if (KEYSTATE_UP == s) - { - first_fly_attempt = TRUE; - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - if( time < FLY_TIME - || frame_count <= FLY_FRAMES - || gAgent.upGrabbed() - || !gSavedSettings.getBOOL("AutomaticFly")) - { - gAgent.moveUp(1); - } - else - { - gAgent.setFlying(TRUE, first_fly_attempt); - first_fly_attempt = FALSE; - gAgent.moveUp(1); - } - return true; -} - -bool agent_push_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgent.moveUp(-1); - return true; -} - -static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode) -{ - if (gAgent.mDoubleTapRunMode == mode && - gAgent.getRunning() && - !gAgent.getAlwaysRun()) - { - // Turn off temporary running. - gAgent.clearRunning(); - gAgent.sendWalkRun(gAgent.getRunning()); - } -} - -static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode) -{ - if (KEYSTATE_UP == s) - { - // Note: in case shift is already released, slide left/right run - // will be released in agent_turn_left()/agent_turn_right() - agent_check_temporary_run(mode); - } - else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") && - KEYSTATE_DOWN == s && - !gAgent.getRunning()) - { - if (gAgent.mDoubleTapRunMode == mode && - gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME) - { - // Same walk-key was pushed again quickly; this is a - // double-tap so engage temporary running. - gAgent.setRunning(); - gAgent.sendWalkRun(gAgent.getRunning()); - } - - // Pressing any walk-key resets the double-tap timer - gAgent.mDoubleTapRunTimer.reset(); - gAgent.mDoubleTapRunMode = mode; - } -} - -static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) -{ - agent_handle_doubletap_run(s, mode); - if (KEYSTATE_UP == s) return; - - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) - { - gAgent.moveAtNudge(direction); - } - else - { - gAgent.moveAt(direction); - } -} - -bool camera_move_forward( EKeystate s ); - -bool agent_push_forward( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_move_forward(s); - } - else - { - agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); - } - return true; -} - -bool camera_move_backward( EKeystate s ); - -bool agent_push_backward( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_move_backward(s); - } - else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook")) - { - gAgentCamera.changeCameraToThirdPerson(); - } - else - { - agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); - } - return true; -} - -static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) -{ - agent_handle_doubletap_run(s, mode); - if( KEYSTATE_UP == s ) return; - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) - { - gAgent.moveLeftNudge(direction); - } - else - { - gAgent.moveLeft(direction); - } -} - - -bool agent_slide_left( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); - return true; -} - - -bool agent_slide_right( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); - return true; -} - -bool camera_spin_around_cw( EKeystate s ); - -bool agent_turn_left(EKeystate s) -{ - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_spin_around_cw(s); - return true; - } - - if(gAgent.isMovementLocked()) return false; - - if (LLToolCamera::getInstance()->mouseSteerMode()) - { - agent_slide_left(s); - } - else - { - if (KEYSTATE_UP == s) - { - // Check temporary running. In case user released 'left' key with shift already released. - agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT); - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); - } - return true; -} - -bool camera_spin_around_ccw( EKeystate s ); - -bool agent_turn_right( EKeystate s ) -{ - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_spin_around_ccw(s); - return true; - } - - if(gAgent.isMovementLocked()) return false; - - if (LLToolCamera::getInstance()->mouseSteerMode()) - { - agent_slide_right(s); - } - else - { - if (KEYSTATE_UP == s) - { - // Check temporary running. In case user released 'right' key with shift already released. - agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT); - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); - } - return true; -} - -bool agent_look_up( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgent.movePitch(-1); - //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); - return true; -} - - -bool agent_look_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgent.movePitch(1); - //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); - return true; -} - -bool agent_toggle_fly( EKeystate s ) -{ - // Only catch the edge - if (KEYSTATE_DOWN == s ) - { - LLAgent::toggleFlying(); - } - return true; -} - -F32 get_orbit_rate() -{ - F32 time = gKeyboard->getCurKeyElapsedTime(); - if( time < NUDGE_TIME ) - { - F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; - //LL_INFOS() << rate << LL_ENDL; - return rate; - } - else - { - return 1; - } -} - -bool camera_spin_around_ccw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - return true; -} - - -bool camera_spin_around_cw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - return true; -} - -bool camera_spin_around_ccw_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true; - if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) - { - //send keystrokes, but do not change camera - agent_turn_right(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.unlockView(); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_around_cw_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true; - if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) - { - //send keystrokes, but do not change camera - agent_turn_left(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.unlockView(); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_over( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - return true; -} - - -bool camera_spin_under( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - return true; -} - -bool camera_spin_over_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) - { - //send keystrokes, but do not change camera - agent_jump(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_under_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) - { - //send keystrokes, but do not change camera - agent_push_down(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - } - return true; -} - -bool camera_move_forward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - return true; -} - - -bool camera_move_backward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - return true; -} - -bool camera_move_forward_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true; - if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) - { - agent_push_forward(s); - } - else - { - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_move_backward_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true; - - if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) - { - agent_push_backward(s); - } - else - { - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - } - return true; -} - -bool camera_pan_up( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanUpKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanDownKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_left( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanLeftKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_right( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanRightKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_in( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanInKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_out( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanOutKey( get_orbit_rate() ); - return true; -} - -bool camera_move_forward_fast( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitInKey(2.5f); - return true; -} - -bool camera_move_backward_fast( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitOutKey(2.5f); - return true; -} - - -bool edit_avatar_spin_ccw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - //gMorphView->orbitLeft( get_orbit_rate() ); - return true; -} - - -bool edit_avatar_spin_cw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - //gMorphView->orbitRight( get_orbit_rate() ); - return true; -} - -bool edit_avatar_spin_over( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - //gMorphView->orbitUp( get_orbit_rate() ); - return true; -} - - -bool edit_avatar_spin_under( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - //gMorphView->orbitDown( get_orbit_rate() ); - return true; -} - -bool edit_avatar_move_forward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - //gMorphView->orbitIn(); - return true; -} - - -bool edit_avatar_move_backward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - //gMorphView->orbitOut(); - return true; -} - -bool stop_moving( EKeystate s ) -{ - if( KEYSTATE_DOWN != s ) return true; - // stop agent - gAgent.setControlFlags(AGENT_CONTROL_STOP); - - // cancel autopilot - gAgent.stopAutoPilot(); - return true; -} - -bool start_chat( EKeystate s ) -{ - if (LLAppViewer::instance()->quitRequested()) - { - return true; // can't talk, gotta go, kthxbye! - } - if (KEYSTATE_DOWN != s) return true; - - // start chat - LLFloaterIMNearbyChat::startChat(NULL); - return true; -} - -bool start_gesture( EKeystate s ) -{ - LLUICtrl* focus_ctrlp = dynamic_cast(gFocusMgr.getKeyboardFocus()); - if (KEYSTATE_UP == s && - ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) - { - if ((LLFloaterReg::getTypedInstance("nearby_chat"))->getCurrentChat().empty()) - { - // No existing chat in chat editor, insert '/' - LLFloaterIMNearbyChat::startChat("/"); - } - else - { - // Don't overwrite existing text in chat editor - LLFloaterIMNearbyChat::startChat(NULL); - } - } - return true; -} - -bool toggle_run(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - bool run = gAgent.getAlwaysRun(); - if (run) - { - gAgent.clearAlwaysRun(); - gAgent.clearRunning(); - } - else - { - gAgent.setAlwaysRun(); - gAgent.setRunning(); - } - gAgent.sendWalkRun(!run); - return true; -} - -bool toggle_sit(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - if (gAgent.isSitting()) - { - gAgent.standUp(); - } - else - { - gAgent.sitDown(); - } - return true; -} - -bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar -{ - if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::isAnyMediaPlaying(); - LLViewerMedia::setAllMediaPaused(pause); - return true; -} - -bool toggle_enable_media(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isAnyMediaShowing(); - LLViewerMedia::setAllMediaEnabled(!pause); - return true; -} - -bool walk_to(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - return LLToolPie::getInstance()->walkToClickedLocation(); -} - -bool teleport_to(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - return LLToolPie::getInstance()->teleportToClickedLocation(); -} - -bool toggle_voice(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - if (!LLAgent::isActionAllowed("speak")) return false; - LLVoiceClient::getInstance()->toggleUserPTTState(); - return true; -} - -bool voice_follow_key(EKeystate s) -{ - if (KEYSTATE_DOWN == s) - { - if (!LLAgent::isActionAllowed("speak")) return false; - LLVoiceClient::getInstance()->setUserPTTState(true); - return true; - } - else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState()) - { - LLVoiceClient::getInstance()->setUserPTTState(false); - return true; - } - return false; -} - -bool agen_control_lbutton_handle(EKeystate s) -{ - switch (s) - { - case KEYSTATE_DOWN: - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); - break; - case KEYSTATE_UP: - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); - break; - default: - break; - } - return true; -} - -#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); -REGISTER_KEYBOARD_ACTION("jump", agent_jump); -REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); -REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward); -REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward); -REGISTER_KEYBOARD_ACTION("look_up", agent_look_up); -REGISTER_KEYBOARD_ACTION("look_down", agent_look_down); -REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly); -REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left); -REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right); -REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left); -REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right); -REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw); -REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw); -REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting); -REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting); -REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over); -REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under); -REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting); -REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting); -REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward); -REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward); -REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting); -REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting); -REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up); -REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down); -REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left); -REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right); -REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in); -REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out); -REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast); -REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under); -REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward); -REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward); -REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); -REGISTER_KEYBOARD_ACTION("start_chat", start_chat); -REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); -REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run); -REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit); -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); -#undef REGISTER_KEYBOARD_ACTION - -LLViewerKeyboard::LLViewerKeyboard() -{ - resetBindings(); - - for (S32 i = 0; i < KEY_COUNT; i++) - { - mKeyHandledByUI[i] = FALSE; - } - for (S32 i = 0; i < CLICK_COUNT; i++) - { - mMouseLevel[i] = MOUSE_STATE_SILENT; - } - // we want the UI to never see these keys so that they can always control the avatar/camera - for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) - { - mKeysSkippedByUI.insert(k); - } -} - -BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) const -{ - if (string == "FIRST_PERSON") - { - *mode = MODE_FIRST_PERSON; - return TRUE; - } - else if (string == "THIRD_PERSON") - { - *mode = MODE_THIRD_PERSON; - return TRUE; - } - else if (string == "EDIT") - { - *mode = MODE_EDIT; - return TRUE; - } - else if (string == "EDIT_AVATAR") - { - *mode = MODE_EDIT_AVATAR; - return TRUE; - } - else if (string == "SITTING") - { - *mode = MODE_SITTING; - return TRUE; - } - else - { - *mode = MODE_THIRD_PERSON; - return FALSE; - } -} - -BOOL LLViewerKeyboard::mouseFromString(const std::string& string, EMouseClickType *mode) const -{ - if (string == "LMB") - { - *mode = CLICK_LEFT; - return TRUE; - } - else if (string == "Double LMB") - { - *mode = CLICK_DOUBLELEFT; - return TRUE; - } - else if (string == "MMB") - { - *mode = CLICK_MIDDLE; - return TRUE; - } - else if (string == "MB4") - { - *mode = CLICK_BUTTON4; - return TRUE; - } - else if (string == "MB5") - { - *mode = CLICK_BUTTON5; - return TRUE; - } - else - { - *mode = CLICK_NONE; - return FALSE; - } -} - -BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) -{ - // check for re-map - EKeyboardMode mode = gViewerKeyboard.getMode(); - U32 keyidx = (translated_mask<<16) | translated_key; - key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx); - if (iter != mRemapKeys[mode].end()) - { - translated_key = (iter->second) & 0xff; - translated_mask = (iter->second)>>16; - } - - // No repeats of F-keys - BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12); - if (!repeatable_key && repeated) - { - return FALSE; - } - - LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL; - // skip skipped keys - if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) - { - mKeyHandledByUI[translated_key] = FALSE; - LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL; - } - else - { - // it is sufficient to set this value once per call to handlekey - // without clearing it, as it is only used in the subsequent call to scanKey - mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask); - // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress) - // NOT whether some UI shortcut wishes to handle the keypress - - } - return mKeyHandledByUI[translated_key]; -} - -BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) -{ - return gViewerWindow->handleKeyUp(translated_key, translated_mask); -} - -BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name) -{ - S32 index; - typedef boost::function function_t; - function_t function = NULL; - std::string name; - - // Allow remapping of F2-F12 - if (function_name[0] == 'F') - { - int c1 = function_name[1] - '0'; - int c2 = function_name[2] ? function_name[2] - '0' : -1; - if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9) - { - int idx = c1; - if (c2 >= 0) - idx = idx*10 + c2; - if (idx >=2 && idx <= 12) - { - U32 keyidx = ((mask<<16)|key); - (mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1))); - return TRUE; - } - } - } - - // Not remapped, look for a function - - function_t* result = LLKeyboardActionRegistry::getValue(function_name); - if (result) - { - function = *result; - } - - if (!function) - { - LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; - return FALSE; - } - - // check for duplicate first and overwrite - if (ignore) - { - for (index = 0; index < mKeyIgnoreMaskCount[mode]; index++) - { - if (key == mKeyIgnoreMask[mode][index].mKey) - break; - } - } - else - { - for (index = 0; index < mKeyBindingCount[mode]; index++) - { - if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) - break; - } - } - - if (index >= MAX_KEY_BINDINGS) - { - LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; - return FALSE; - } - - if (mode >= MODE_COUNT) - { - LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; - return FALSE; - } - - if (ignore) - { - mKeyIgnoreMask[mode][index].mKey = key; - mKeyIgnoreMask[mode][index].mFunction = function; - - if (index == mKeyIgnoreMaskCount[mode]) - mKeyIgnoreMaskCount[mode]++; - } - else - { - mKeyBindings[mode][index].mKey = key; - mKeyBindings[mode][index].mMask = mask; - mKeyBindings[mode][index].mFunction = function; - - if (index == mKeyBindingCount[mode]) - mKeyBindingCount[mode]++; - } - - return TRUE; -} - -BOOL LLViewerKeyboard::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name) -{ - S32 index; - typedef boost::function function_t; - function_t function = NULL; - - function_t* result = LLKeyboardActionRegistry::getValue(function_name); - if (result) - { - function = *result; - } - - if (!function) - { - LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; - return FALSE; - } - - // check for duplicate first and overwrite - if (ignore) - { - for (index = 0; index < mMouseIgnoreMaskCount[mode]; index++) - { - if (mouse == mMouseIgnoreMask[mode][index].mMouse) - break; - } - } - else - { - for (index = 0; index < mMouseBindingCount[mode]; index++) - { - if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) - break; - } - } - - if (index >= MAX_KEY_BINDINGS) - { - LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; - return FALSE; - } - - if (mode >= MODE_COUNT) - { - LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; - return FALSE; - } - - if (ignore) - { - mMouseIgnoreMask[mode][index].mMouse = mouse; - mMouseIgnoreMask[mode][index].mFunction = function; - - if (index == mMouseIgnoreMaskCount[mode]) - mMouseIgnoreMaskCount[mode]++; - } - else - { - mMouseBindings[mode][index].mMouse = mouse; - mMouseBindings[mode][index].mMask = mask; - mMouseBindings[mode][index].mFunction = function; - - if (index == mMouseBindingCount[mode]) - mMouseBindingCount[mode]++; - } - - return TRUE; -} - -LLViewerKeyboard::KeyBinding::KeyBinding() -: key("key"), - mouse("mouse"), - mask("mask"), - command("command"), - ignore("ignore", false) -{} - -LLViewerKeyboard::KeyMode::KeyMode() -: bindings("binding") -{} - -LLViewerKeyboard::Keys::Keys() -: first_person("first_person"), - third_person("third_person"), - edit("edit"), - sitting("sitting"), - edit_avatar("edit_avatar") -{} - -void LLViewerKeyboard::resetBindings() -{ - for (S32 i = 0; i < MODE_COUNT; i++) - { - mKeyBindingCount[i] = 0; - mKeyIgnoreMaskCount[i] = 0; - mMouseBindingCount[i] = 0; - mMouseIgnoreMaskCount[i] = 0; - } -} - -S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) -{ - resetBindings(); - - S32 binding_count = 0; - Keys keys; - LLSimpleXUIParser parser; - - if (parser.readXUI(filename, keys) - && keys.validateBlock()) - { - binding_count += loadBindingMode(keys.first_person, MODE_FIRST_PERSON); - binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON); - binding_count += loadBindingMode(keys.edit, MODE_EDIT); - binding_count += loadBindingMode(keys.sitting, MODE_SITTING); - binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); - } - return binding_count; -} - -S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, S32 mode) -{ - S32 binding_count = 0; - for (LLInitParam::ParamIterator::const_iterator it = keymode.bindings.begin(), - end_it = keymode.bindings.end(); - it != end_it; - ++it) - { - bool processed = false; - if (!it->key.getValue().empty()) - { - KEY key; - LLKeyboard::keyFromString(it->key, &key); - if (key != KEY_NONE) - { - MASK mask; - bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; - LLKeyboard::maskFromString(it->mask, &mask); - bindKey(mode, key, mask, ignore, it->command); - processed = true; - } - else - { - LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; - } - } - if (!processed && it->mouse.isProvided() && !it->mouse.getValue().empty()) - { - EMouseClickType mouse; - mouseFromString(it->mouse.getValue(), &mouse); - if (mouse != CLICK_NONE) - { - MASK mask; - bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; - LLKeyboard::maskFromString(it->mask, &mask); - bindMouse(mode, mouse, mask, ignore, it->command); - processed = true; - } - else - { - LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; - } - } - if (processed) - { - // total - binding_count++; - } - } - - return binding_count; -} - -EKeyboardMode LLViewerKeyboard::getMode() const -{ - if ( gAgentCamera.cameraMouselook() ) - { - return MODE_FIRST_PERSON; - } - else if ( gMorphView && gMorphView->getVisible()) - { - return MODE_EDIT_AVATAR; - } - else if (isAgentAvatarValid() && gAgentAvatarp->isSitting()) - { - return MODE_SITTING; - } - else - { - return MODE_THIRD_PERSON; - } -} - -bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, - S32 binding_count, - KEY key, - MASK mask, - BOOL key_down, - BOOL key_up, - BOOL key_level, - bool repeat) const -{ - for (S32 i = 0; i < binding_count; i++) - { - if (binding[i].mKey == key) - { - if (binding[i].mMask == mask) - { - bool res = false; - if (key_down && !repeat) - { - // ...key went down this frame, call function - res = binding[i].mFunction( KEYSTATE_DOWN ); - return true; - } - else if (key_up) - { - // ...key went down this frame, call function - res = binding[i].mFunction( KEYSTATE_UP ); - } - else if (key_level) - { - // ...key held down from previous frame - // Not windows, just call the function. - res = binding[i].mFunction( KEYSTATE_LEVEL ); - }//if - // Key+Mask combinations are supposed to be unique, so we won't find anything else - return res; - }//if - }//if - }//for - return false; -} - -// Called from scanKeyboard. -bool LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const -{ - if (LLApp::isExiting()) - { - return; - } - - S32 mode = getMode(); - // Consider keyboard scanning as NOT mouse event. JC - MASK mask = gKeyboard->currentMask(FALSE); - - if (mKeyHandledByUI[key]) - { - return false; - } - - // don't process key down on repeated keys - BOOL repeat = gKeyboard->getKeyRepeated(key); - - bool res = scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat); - if (!res) - { - // Nothing found, try ignore list - res = scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); - } - - if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) - { - if (key_down && !repeat) - { - res = agen_control_lbutton_handle(KEYSTATE_DOWN); - } - if (key_up) - { - res = agen_control_lbutton_handle(KEYSTATE_UP); - } - } - return res; -} - -BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) -{ - BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down); - - if (clicktype != CLICK_NONE) - { - // Special case - // If UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set - // handle !down as if we are handling doubleclick - - bool double_click_sp = (clicktype == CLICK_LEFT - && (mMouseLevel[CLICK_DOUBLELEFT] != MOUSE_STATE_SILENT) - && mMouseLevel[CLICK_LEFT] == MOUSE_STATE_SILENT); - if (double_click_sp && !down) - { - // Process doubleclick instead - clicktype = CLICK_DOUBLELEFT; - } - - - if (double_click_sp && down) - { - // Consume click. - // Due to handling, double click that is not handled will be immediately followed by LMB click - } - // If UI handled 'down', it should handle 'up' as well - // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI - else if (handled) - { - // UI handled new 'down' so iterupt whatever state we were in. - if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) - { - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - mMouseLevel[clicktype] = MOUSE_STATE_CLICK; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_UP; - } - } - } - else if (down) - { - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - // this is repeated hit (mouse does not repeat event until release) - // for now treat rapid clicking like mouse being held - mMouseLevel[clicktype] = MOUSE_STATE_LEVEL; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_DOWN; - } - } - else if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) - { - // Released mouse key - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - mMouseLevel[clicktype] = MOUSE_STATE_CLICK; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_UP; - } - } - } - - return handled; -} - -bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const -{ - for (S32 i = 0; i < binding_count; i++) - { - if (binding[i].mMouse == mouse && binding[i].mMask == mask) - { - bool res = false; - switch (state) - { - case MOUSE_STATE_DOWN: - res = binding[i].mFunction(KEYSTATE_DOWN); - break; - case MOUSE_STATE_CLICK: - // Button went down and up in scope of single frame - // might not work best with some functions, - // but some function need specific states specifically - res = binding[i].mFunction(KEYSTATE_DOWN); - res |= binding[i].mFunction(KEYSTATE_UP); - break; - case MOUSE_STATE_LEVEL: - res = binding[i].mFunction(KEYSTATE_LEVEL); - break; - case MOUSE_STATE_UP: - res = binding[i].mFunction(KEYSTATE_UP); - break; - default: - break; - } - // Key+Mask combinations are supposed to be unique, no need to continue - return res; - } - } - return false; -} - -// todo: this recods key, scanMouse() triggers functions with EKeystate -bool LLViewerKeyboard::scanMouse(EMouseClickType click, EMouseState state) const -{ - bool res = false; - S32 mode = getMode(); - MASK mask = gKeyboard->currentMask(TRUE); - res = scanMouse(mMouseBindings[mode], mMouseBindingCount[mode], click, mask, state); - if (!res) - { - res = scanMouse(mMouseIgnoreMask[mode], mMouseIgnoreMaskCount[mode], click, MASK_NONE, state); - } - // 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)) - { - switch (state) - { - case MOUSE_STATE_DOWN: - agen_control_lbutton_handle(KEYSTATE_DOWN); - res = true; - break; - case MOUSE_STATE_CLICK: - // might not work best with some functions, - // but some function need specific states too specifically - agen_control_lbutton_handle(KEYSTATE_DOWN); - agen_control_lbutton_handle(KEYSTATE_UP); - res = true; - break; - case MOUSE_STATE_UP: - agen_control_lbutton_handle(KEYSTATE_UP); - res = true; - break; - default: - break; - } - } - return res; -} - -void LLViewerKeyboard::scanMouse() -{ - for (S32 i = 0; i < CLICK_COUNT; i++) - { - if (mMouseLevel[i] != MOUSE_STATE_SILENT) - { - scanMouse((EMouseClickType)i, mMouseLevel[i]); - if (mMouseLevel[i] == MOUSE_STATE_DOWN) - { - // mouse doesn't support 'continued' state, so after handling, switch to LEVEL - mMouseLevel[i] = MOUSE_STATE_LEVEL; - } - else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK) - { - mMouseLevel[i] = MOUSE_STATE_SILENT; - } - } - } -} -- cgit v1.2.3