diff options
Diffstat (limited to 'indra/newview/llviewerkeyboard.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llviewerkeyboard.cpp | 445 |
1 files changed, 266 insertions, 179 deletions
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 2dc317e067..ada829eb4b 100644..100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -2,41 +2,37 @@ * @file llviewerkeyboard.cpp * @brief LLViewerKeyboard class implementation * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 "llappviewer.h" +#include "llfloaterreg.h" #include "llviewerkeyboard.h" #include "llmath.h" #include "llagent.h" -#include "llnearbychatbar.h" +#include "llagentcamera.h" +#include "llfloaterimnearbychat.h" #include "llviewercontrol.h" #include "llfocusmgr.h" #include "llmorphview.h" @@ -45,6 +41,7 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llfloatercamera.h" +#include "llinitparam.h" // // Constants @@ -56,7 +53,11 @@ 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 F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed + +struct LLKeyboardActionRegistry +: public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry> +{ +}; LLViewerKeyboard gViewerKeyboard; @@ -64,7 +65,7 @@ void agent_jump( EKeystate s ) { if( KEYSTATE_UP == s ) return; F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount()); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); if( time < FLY_TIME || frame_count <= FLY_FRAMES @@ -86,20 +87,27 @@ void agent_push_down( EKeystate s ) gAgent.moveUp(-1); } +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) { - if (gAgent.mDoubleTapRunMode == mode && - gAgent.getRunning() && - !gAgent.getAlwaysRun()) - { - // Turn off temporary running. - gAgent.clearRunning(); - gAgent.sendWalkRun(gAgent.getRunning()); - } + // 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 (gAllowTapTapHoldRun && + else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") && KEYSTATE_DOWN == s && !gAgent.getRunning()) { @@ -124,7 +132,7 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo if (KEYSTATE_UP == s) return; F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount()); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) { @@ -140,26 +148,38 @@ void camera_move_forward( EKeystate s ); void agent_push_forward( EKeystate s ) { + if(gAgent.isMovementLocked()) return; + //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_move_forward(s); - return; } - agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); + else + { + agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); + } } void camera_move_backward( EKeystate s ); void agent_push_backward( EKeystate s ) { + if(gAgent.isMovementLocked()) return; + //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_move_backward(s); - return; } - agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); + else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook")) + { + gAgentCamera.changeCameraToThirdPerson(); + } + else + { + agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); + } } static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) @@ -167,7 +187,7 @@ static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleT agent_handle_doubletap_run(s, mode); if( KEYSTATE_UP == s ) return; F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount()); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) { @@ -182,12 +202,14 @@ static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleT void agent_slide_left( EKeystate s ) { + if(gAgent.isMovementLocked()) return; agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); } void agent_slide_right( EKeystate s ) { + if(gAgent.isMovementLocked()) return; agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); } @@ -202,13 +224,20 @@ void agent_turn_left( EKeystate s ) return; } + if(gAgent.isMovementLocked()) return; + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_left(s); } else { - if (KEYSTATE_UP == s) return; + 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; + } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); } @@ -225,13 +254,20 @@ void agent_turn_right( EKeystate s ) return; } + if(gAgent.isMovementLocked()) return; + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_right(s); } else { - if (KEYSTATE_UP == s) return; + 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; + } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); } @@ -267,7 +303,7 @@ F32 get_orbit_rate() if( time < NUDGE_TIME ) { F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; - //llinfos << rate << llendl; + //LL_INFOS() << rate << LL_ENDL; return rate; } else @@ -279,22 +315,22 @@ F32 get_orbit_rate() void camera_spin_around_ccw( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } void camera_spin_around_cw( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); } void camera_spin_around_ccw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; - if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled()) + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return; + if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera agent_turn_right(s); @@ -302,15 +338,15 @@ void camera_spin_around_ccw_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } } void camera_spin_around_cw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; - if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled()) + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return; + if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera agent_turn_left(s); @@ -318,7 +354,7 @@ void camera_spin_around_cw_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); } } @@ -326,22 +362,22 @@ void camera_spin_around_cw_sitting( EKeystate s ) void camera_spin_over( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } void camera_spin_under( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); } void camera_spin_over_sitting( EKeystate s ) { if( KEYSTATE_UP == s ) return; - if (gAgent.upGrabbed() || gAgent.sitCameraEnabled()) + if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera agent_jump(s); @@ -349,7 +385,7 @@ void camera_spin_over_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } } @@ -357,7 +393,7 @@ void camera_spin_over_sitting( EKeystate s ) void camera_spin_under_sitting( EKeystate s ) { if( KEYSTATE_UP == s ) return; - if (gAgent.downGrabbed() || gAgent.sitCameraEnabled()) + if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera agent_push_down(s); @@ -365,107 +401,107 @@ void camera_spin_under_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); } } void camera_move_forward( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); } void camera_move_backward( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); } void camera_move_forward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; - if (gAgent.forwardGrabbed() || gAgent.sitCameraEnabled()) + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return; + if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { agent_push_forward(s); } else { - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); } } void camera_move_backward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return; - if (gAgent.backwardGrabbed() || gAgent.sitCameraEnabled()) + if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { agent_push_backward(s); } else { - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); } } void camera_pan_up( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanUpKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanUpKey( get_orbit_rate() ); } void camera_pan_down( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanDownKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanDownKey( get_orbit_rate() ); } void camera_pan_left( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanLeftKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanLeftKey( get_orbit_rate() ); } void camera_pan_right( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanRightKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanRightKey( get_orbit_rate() ); } void camera_pan_in( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanInKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanInKey( get_orbit_rate() ); } void camera_pan_out( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanOutKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanOutKey( get_orbit_rate() ); } void camera_move_forward_fast( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitInKey(2.5f); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey(2.5f); } void camera_move_backward_fast( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitOutKey(2.5f); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey(2.5f); } @@ -473,7 +509,7 @@ void edit_avatar_spin_ccw( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); //gMorphView->orbitLeft( get_orbit_rate() ); } @@ -482,7 +518,7 @@ void edit_avatar_spin_cw( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); //gMorphView->orbitRight( get_orbit_rate() ); } @@ -490,7 +526,7 @@ void edit_avatar_spin_over( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); //gMorphView->orbitUp( get_orbit_rate() ); } @@ -499,7 +535,7 @@ void edit_avatar_spin_under( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); //gMorphView->orbitDown( get_orbit_rate() ); } @@ -507,7 +543,7 @@ void edit_avatar_move_forward( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); //gMorphView->orbitIn(); } @@ -516,7 +552,7 @@ void edit_avatar_move_backward( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); //gMorphView->orbitOut(); } @@ -532,74 +568,78 @@ void stop_moving( EKeystate s ) void start_chat( EKeystate s ) { + if (LLAppViewer::instance()->quitRequested()) + { + return; // can't talk, gotta go, kthxbye! + } + // start chat - LLNearbyChatBar::startChat(NULL); + LLFloaterIMNearbyChat::startChat(NULL); } void start_gesture( EKeystate s ) { + LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (KEYSTATE_UP == s && - !(gFocusMgr.getKeyboardFocus() && dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus())->acceptsTextInput())) + ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) { - if (LLNearbyChatBar::getInstance()->getCurrentChat().empty()) + if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty()) { // No existing chat in chat editor, insert '/' - LLNearbyChatBar::startChat("/"); + LLFloaterIMNearbyChat::startChat("/"); } else { // Don't overwrite existing text in chat editor - LLNearbyChatBar::startChat(NULL); + LLFloaterIMNearbyChat::startChat(NULL); } } } -void bind_keyboard_functions() -{ - gViewerKeyboard.bindNamedFunction("jump", agent_jump); - gViewerKeyboard.bindNamedFunction("push_down", agent_push_down); - gViewerKeyboard.bindNamedFunction("push_forward", agent_push_forward); - gViewerKeyboard.bindNamedFunction("push_backward", agent_push_backward); - gViewerKeyboard.bindNamedFunction("look_up", agent_look_up); - gViewerKeyboard.bindNamedFunction("look_down", agent_look_down); - gViewerKeyboard.bindNamedFunction("toggle_fly", agent_toggle_fly); - gViewerKeyboard.bindNamedFunction("turn_left", agent_turn_left); - gViewerKeyboard.bindNamedFunction("turn_right", agent_turn_right); - gViewerKeyboard.bindNamedFunction("slide_left", agent_slide_left); - gViewerKeyboard.bindNamedFunction("slide_right", agent_slide_right); - gViewerKeyboard.bindNamedFunction("spin_around_ccw", camera_spin_around_ccw); - gViewerKeyboard.bindNamedFunction("spin_around_cw", camera_spin_around_cw); - gViewerKeyboard.bindNamedFunction("spin_around_ccw_sitting", camera_spin_around_ccw_sitting); - gViewerKeyboard.bindNamedFunction("spin_around_cw_sitting", camera_spin_around_cw_sitting); - gViewerKeyboard.bindNamedFunction("spin_over", camera_spin_over); - gViewerKeyboard.bindNamedFunction("spin_under", camera_spin_under); - gViewerKeyboard.bindNamedFunction("spin_over_sitting", camera_spin_over_sitting); - gViewerKeyboard.bindNamedFunction("spin_under_sitting", camera_spin_under_sitting); - gViewerKeyboard.bindNamedFunction("move_forward", camera_move_forward); - gViewerKeyboard.bindNamedFunction("move_backward", camera_move_backward); - gViewerKeyboard.bindNamedFunction("move_forward_sitting", camera_move_forward_sitting); - gViewerKeyboard.bindNamedFunction("move_backward_sitting", camera_move_backward_sitting); - gViewerKeyboard.bindNamedFunction("pan_up", camera_pan_up); - gViewerKeyboard.bindNamedFunction("pan_down", camera_pan_down); - gViewerKeyboard.bindNamedFunction("pan_left", camera_pan_left); - gViewerKeyboard.bindNamedFunction("pan_right", camera_pan_right); - gViewerKeyboard.bindNamedFunction("pan_in", camera_pan_in); - gViewerKeyboard.bindNamedFunction("pan_out", camera_pan_out); - gViewerKeyboard.bindNamedFunction("move_forward_fast", camera_move_forward_fast); - gViewerKeyboard.bindNamedFunction("move_backward_fast", camera_move_backward_fast); - gViewerKeyboard.bindNamedFunction("edit_avatar_spin_ccw", edit_avatar_spin_ccw); - gViewerKeyboard.bindNamedFunction("edit_avatar_spin_cw", edit_avatar_spin_cw); - gViewerKeyboard.bindNamedFunction("edit_avatar_spin_over", edit_avatar_spin_over); - gViewerKeyboard.bindNamedFunction("edit_avatar_spin_under", edit_avatar_spin_under); - gViewerKeyboard.bindNamedFunction("edit_avatar_move_forward", edit_avatar_move_forward); - gViewerKeyboard.bindNamedFunction("edit_avatar_move_backward", edit_avatar_move_backward); - gViewerKeyboard.bindNamedFunction("stop_moving", stop_moving); - gViewerKeyboard.bindNamedFunction("start_chat", start_chat); - gViewerKeyboard.bindNamedFunction("start_gesture", start_gesture); -} - -LLViewerKeyboard::LLViewerKeyboard() : - mNamedFunctionCount(0) +#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); +#undef REGISTER_KEYBOARD_ACTION + +LLViewerKeyboard::LLViewerKeyboard() { for (S32 i = 0; i < MODE_COUNT; i++) { @@ -617,16 +657,6 @@ LLViewerKeyboard::LLViewerKeyboard() : } } - -void LLViewerKeyboard::bindNamedFunction(const std::string& name, LLKeyFunc func) -{ - S32 i = mNamedFunctionCount; - mNamedFunctions[i].mName = name; - mNamedFunctions[i].mFunction = func; - mNamedFunctionCount++; -} - - BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) { if (string == "FIRST_PERSON") @@ -680,17 +710,21 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL return FALSE; } - lldebugst(LLERR_USER_INPUT) << "keydown -" << translated_key << "-" << llendl; + LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL; // skip skipped keys if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) { mKeyHandledByUI[translated_key] = FALSE; + LL_INFOS("Keyboard Handling") << "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[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]; } @@ -699,8 +733,9 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) { - S32 i,index; - void (*function)(EKeystate keystate) = NULL; + S32 index; + typedef boost::function<void(EKeystate)> function_t; + function_t function = NULL; std::string name; // Allow remapping of F2-F12 @@ -723,18 +758,16 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c } // Not remapped, look for a function - for (i = 0; i < mNamedFunctionCount; i++) + + function_t* result = LLKeyboardActionRegistry::getValue(function_name); + if (result) { - if (function_name == mNamedFunctions[i].mName) - { - function = mNamedFunctions[i].mFunction; - name = mNamedFunctions[i].mName; - } + function = *result; } if (!function) { - llerrs << "Can't bind key to function " << function_name << ", no function with this name found" << llendl; + LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; return FALSE; } @@ -747,19 +780,18 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c if (index >= MAX_KEY_BINDINGS) { - llerrs << "LLKeyboard::bindKey() - too many keys for mode " << mode << llendl; + LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; return FALSE; } if (mode >= MODE_COUNT) { - llerror("LLKeyboard::bindKey() - unknown mode passed", mode); + LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; return FALSE; } mBindings[mode][index].mKey = key; mBindings[mode][index].mMask = mask; -// mBindings[mode][index].mName = name; mBindings[mode][index].mFunction = function; if (index == mBindingCount[mode]) @@ -768,6 +800,61 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c return TRUE; } +LLViewerKeyboard::KeyBinding::KeyBinding() +: key("key"), + mask("mask"), + command("command") +{} + +LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode) +: bindings("binding"), + mode(_mode) +{} + +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)) +{} + +S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) +{ + S32 binding_count = 0; + Keys keys; + LLSimpleXUIParser parser; + + 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); + } + return binding_count; +} + +S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode) +{ + S32 binding_count = 0; + for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(), + end_it = keymode.bindings.end(); + 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++; + } + + return binding_count; +} S32 LLViewerKeyboard::loadBindings(const std::string& filename) { @@ -788,7 +875,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) if(filename.empty()) { - llerrs << " No filename specified" << llendl; + LL_ERRS() << " No filename specified" << LL_ENDL; return 0; } @@ -820,35 +907,35 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) if (tokens_read == EOF) { - llinfos << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << llendl; + 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) { - llinfos << "Can't read line " << line_count << " of key binding file " << filename << llendl; + LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL; continue; } // convert mode if (!modeFromString(mode_string, &mode)) { - llinfos << "Unknown mode on line " << line_count << " of key binding file " << filename << llendl; - llinfos << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << llendl; + 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)) { - llinfos << "Can't interpret key on line " << line_count << " of key binding file " << filename << llendl; + 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)) { - llinfos << "Can't interpret mask on line " << line_count << " of key binding file " << filename << llendl; + LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL; continue; } @@ -867,7 +954,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) EKeyboardMode LLViewerKeyboard::getMode() { - if ( gAgent.cameraMouselook() ) + if ( gAgentCamera.cameraMouselook() ) { return MODE_FIRST_PERSON; } @@ -875,7 +962,7 @@ EKeyboardMode LLViewerKeyboard::getMode() { return MODE_EDIT_AVATAR; } - else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting()) + else if (isAgentAvatarValid() && gAgentAvatarp->isSitting()) { return MODE_SITTING; } @@ -916,18 +1003,18 @@ void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_lev if (key_down && !repeat) { // ...key went down this frame, call function - (*binding[i].mFunction)( KEYSTATE_DOWN ); + binding[i].mFunction( KEYSTATE_DOWN ); } else if (key_up) { // ...key went down this frame, call function - (*binding[i].mFunction)( KEYSTATE_UP ); + 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 ); + binding[i].mFunction( KEYSTATE_LEVEL ); }//if }//if }//for |