diff options
| -rw-r--r-- | indra/newview/app_settings/key_bindings.xml | 8 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.cpp | 58 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.h | 4 | ||||
| -rw-r--r-- | indra/newview/lltoolcomp.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/lltoolpie.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerinput.cpp | 81 | ||||
| -rw-r--r-- | indra/newview/llviewerinput.h | 5 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/control_table_contents_media.xml | 10 | 
8 files changed, 158 insertions, 20 deletions
| diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 4f6deb1f98..ffc1b2e7cc 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -33,6 +33,8 @@      <binding key="DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </first_person>    <third_person>      <binding key="A" mask="NONE" command="turn_left"/> @@ -127,6 +129,8 @@      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>      <binding key="" mask="NONE" mouse="LMB" command="walk_to"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </third_person>    <sitting>      <binding key="A" mask="ALT" command="spin_around_cw"/> @@ -224,6 +228,8 @@      <binding key="DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </sitting>    <edit_avatar>      <!--Avatar editing camera controls--> @@ -251,5 +257,7 @@      <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </edit_avatar>  </keys> diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index d7a17b237e..58a740e16a 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -868,7 +868,7 @@ void LLKeyConflictHandler::resetKeyboardBindings()  void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)  { -    // These controls are meant to cause conflicts when user tries to assign same control somewhere else +    // These placeholds are meant to cause conflict resolution when user tries to assign same control somewhere else      // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks      if (load_mode == MODE_FIRST_PERSON) @@ -928,25 +928,73 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)          registerTemporaryControl("spin_around_ccw_sitting");          registerTemporaryControl("spin_around_cw_sitting");      } + + +    // Special case, mouse clicks passed to scripts have 'lowest' piority +    // thus do not conflict, everything else has a chance before them +    // also in ML they have highest priority, but only when script-grabbed, +    // thus do not conflict +    // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX) +    LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name]; +    type_data->mAssignable = true; +    type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE;  } -bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) +bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask)  {      if (conlict_mask == CONFLICT_NOTHING)      {          // Can't conflict          return true;      } + +    if (data.mMouse == CLICK_LEFT +        && data.mMask == MASK_NONE +        && data.mKey == KEY_NONE) +    { +        if ((conlict_mask & CONFLICT_LMOUSE) == 0) +        { +            // Can't conflict +            return true; +        } +        else +        { +            // simplify conflict mask +            conlict_mask = CONFLICT_LMOUSE; +        } +    } +    else +    { +        // simplify conflict mask +        conlict_mask &= ~CONFLICT_LMOUSE; +    } +      std::map<std::string, S32> conflict_list;      control_map_t::iterator cntrl_iter = mControlsMap.begin();      control_map_t::iterator cntrl_end = mControlsMap.end();      for (; cntrl_iter != cntrl_end; ++cntrl_iter)      { +        const U32 cmp_mask = cntrl_iter->second.mConflictMask; +        if ((cmp_mask & conlict_mask) == 0) +        { +            // can't conflict +            continue; +        }          S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); -        if (index >= 0 -            && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING -            && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) +        if (index >= 0)          { +            if (cmp_mask != U32_MAX) +            { +                const LLKeyData cmp_data = cntrl_iter->second.mKeyBind.getKeyData(index); +                if ((cmp_mask & CONFLICT_LMOUSE) == 0 +                    && cmp_data.mMouse == CLICK_LEFT +                    && cmp_data.mMask == MASK_NONE +                    && cmp_data.mKey == KEY_NONE) +                { +                    // Does not conflict +                    continue; +                } +            }              if (cntrl_iter->second.mAssignable)              {                  // Potentially we can have multiple conflict flags conflicting diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index 2926ca3aeb..e78d2fa33b 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -66,6 +66,7 @@ public:      };      const U32 CONFLICT_NOTHING = 0; +    const U32 CONFLICT_LMOUSE = 0x1 << 1;      // at the moment this just means that key will conflict with everything that is identical      const U32 CONFLICT_ANY = U32_MAX; @@ -145,6 +146,7 @@ private:      // at the moment these kind of control is not savable, but takes part in conflict resolution      void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); +    // conflict mask 0 means that any conflicts will be ignored      void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);      typedef std::map<std::string, LLKeyConflict> control_map_t; @@ -152,7 +154,7 @@ private:      bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);      void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values      // returns false in case user is trying to reuse control that can't be reassigned -    bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask); +    bool removeConflicts(const LLKeyData &data, U32 conlict_mask);      // removes flags and removes temporary file, returns 'true' if file was removed      bool clearUnsavedChanges(); diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index f9c327b46e..9ac1810964 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -44,6 +44,7 @@  #include "lltoolmgr.h"  #include "lltoolselectrect.h"  #include "lltoolplacer.h" +#include "llviewerinput.h"  #include "llviewermenu.h"  #include "llviewerobject.h"  #include "llviewerwindow.h" @@ -743,7 +744,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  {   	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) +	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))  	{  		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);  		return FALSE; @@ -760,7 +761,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)  {  	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) +	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))  	{  		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);  		return FALSE; @@ -794,7 +795,10 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)  { -	gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +    if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) +    { +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +    }  	setCurrentTool( (LLTool*) mGun );  	return TRUE;  } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 322d0bc727..543a93bf9b 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -746,7 +746,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  	else if (!mMouseOutsideSlop   		&& mMouseButtonDown  		// disable camera steering if click on land is not used for moving -		&& gViewerInput.isMouseBindUsed(CLICK_LEFT)) +		&& gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON))  	{  		S32 delta_x = x - mMouseDownX;  		S32 delta_y = y - mMouseDownY; diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index c0eaa88f54..8b3d406b78 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -61,7 +61,7 @@ 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<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry> +:	public LLRegistrySingleton<const std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry>  {  	LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);  }; @@ -836,7 +836,49 @@ bool voice_follow_key(EKeystate s)      return false;  } -bool agen_control_lbutton_handle(EKeystate s) +bool sript_trigger_lbutton(EKeystate s) +{ +    // Check for script overriding/expecting left mouse button. +    // Note that this does not pass event further and depends onto mouselook. +    // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook, +    // CONTROL_LBUTTON_DOWN_INDEX for normal camera +    if (gAgent.leftButtonGrabbed()) +    { +        bool mouselook = gAgentCamera.cameraMouselook(); +        switch (s) +        { +        case KEYSTATE_DOWN: +            // at the moment sript_trigger_lbutton is only intended for mouselook +            // but handling other modes just in case +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); +            } +            return true; +        case KEYSTATE_UP: +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); +            } +            return true; +        default: +            break; +        } +    } +    return false; +} + +// Used by scripts, for overriding/handling left mouse button +// see mControlsTakenCount +bool agent_control_lbutton_handle(EKeystate s)  {      switch (s)      { @@ -905,6 +947,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);  REGISTER_KEYBOARD_ACTION("walk_to", walk_to);  REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice);  REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, sript_trigger_lbutton);  #undef REGISTER_KEYBOARD_ACTION  LLViewerInput::LLViewerInput() @@ -1104,6 +1147,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const      typedef boost::function<bool(EKeystate)> function_t;      function_t function = NULL; +    if (mouse == CLICK_LEFT +        && mask == MASK_NONE +        && function_name == script_mouse_handler_name) +    { +        // Special case +        // Left click has script overrides and by default +        // is handled via agent_control_lbutton as last option +        // In case of mouselook and present overrides it has highest +        // priority even over UI and is handled in LLToolCompGun::handleMouseDown +        // so just mark it as having default handler +        mLMouseDefaultHandling[mode] = true; +        return TRUE; +    } +      function_t* result = LLKeyboardActionRegistry::getValue(function_name);      if (result)      { @@ -1164,6 +1221,7 @@ void LLViewerInput::resetBindings()      {          mKeyBindings[i].clear();          mMouseBindings[i].clear(); +        mLMouseDefaultHandling[i] = false;      }  } @@ -1355,13 +1413,14 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)      if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))      { +        // pass mouse left button press to script          if (key_down && !repeat)          { -            res = agen_control_lbutton_handle(KEYSTATE_DOWN); +            res = agent_control_lbutton_handle(KEYSTATE_DOWN);          }          if (key_up)          { -            res = agen_control_lbutton_handle(KEYSTATE_UP); +            res = agent_control_lbutton_handle(KEYSTATE_UP);          }      }      return res; @@ -1481,24 +1540,28 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const      S32 mode = getMode();      MASK mask = gKeyboard->currentMask(TRUE);      res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, 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)) +    // This will pass AGENT_CONTROL_LBUTTON_DOWN to server, no idea why it doesn't do mouselook variant _ML_ +    // but it was set this way forever (moved as is from LLTool::handleMouseDown) so lots of scripts probably +    // rely on this. +    if (!res && mLMouseDefaultHandling[mode] && agent_control_lbutton.canHandle(click, KEY_NONE, mask))      {          switch (state)          {          case MOUSE_STATE_DOWN: -            agen_control_lbutton_handle(KEYSTATE_DOWN); +            agent_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); +            agent_control_lbutton_handle(KEYSTATE_DOWN); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          case MOUSE_STATE_UP: -            agen_control_lbutton_handle(KEYSTATE_UP); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          default: diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index 281a209896..32dd3c0e28 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -31,6 +31,7 @@  #include "llinitparam.h"  const S32 MAX_KEY_BINDINGS = 128; // was 60 +const std::string script_mouse_handler_name = "sript_trigger_lbutton";  class LLNamedFunction  { @@ -124,7 +125,8 @@ public:      BOOL            handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);      void            scanMouse(); -    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON); +    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode); +    bool            isLMouseHandlingDefault(const S32 mode) { return mLMouseDefaultHandling[mode]; }  private:      bool            scanKey(const std::vector<LLKeyboardBinding> &binding, @@ -163,6 +165,7 @@ private:      // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)      std::vector<LLKeyboardBinding>	mKeyBindings[MODE_COUNT];      std::vector<LLMouseBinding>		mMouseBindings[MODE_COUNT]; +    bool							mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority  	typedef std::map<U32, U32> key_remap_t;  	key_remap_t		mRemapKeys[MODE_COUNT]; diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml index ce5d3556b6..a97c45dd6f 100644 --- a/indra/newview/skins/default/xui/en/control_table_contents_media.xml +++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml @@ -73,4 +73,14 @@           name="lst_action"           value="Start Gesture" />      </rows> +    <rows +     name="sript_trigger_lbutton" +     value="sript_trigger_lbutton"> +        <columns +         column="lst_action" +         font="SansSerif" +         halign="left" +         name="lst_action" +         value="Interact (Script LMB)" /> +    </rows>  </contents> | 
