diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2019-09-27 19:53:33 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-06-23 14:48:04 +0300 | 
| commit | 0b8021870335ff9b9684fb193c6e0fe2f02b4091 (patch) | |
| tree | 418c417b7ee2f7602d78d6a2b084e0f78b77914c | |
| parent | b12cf6696348520556cf70f96e0562776479fe70 (diff) | |
SL-6109 Cleanup, run commands, and preparation for tooltip support
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 369 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.h | 4 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.cpp | 426 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.h | 117 | ||||
| -rw-r--r-- | indra/newview/llviewerinput.cpp | 76 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_controls.xml | 55 | 
7 files changed, 510 insertions, 539 deletions
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 4852a9d93e..f94a52a232 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -185,18 +185,53 @@ public:  	static void onCancel(void* user_data);  	static void onBlank(void* user_data);  	static void onDefault(void* user_data); +	static void onClickTimeout(void* user_data, MASK mask); + +	class Updater;  private: +	void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore);  	LLPanelPreferenceControls* pParent;  	LLCheckBoxCtrl* pCheckBox; -	U32 mKeyMask; +	U32 mKeyFilterMask; +	Updater *pUpdater; +}; + +class LLSetKeyBindDialog::Updater : public LLEventTimer +{ +public: + +    typedef boost::function<void(MASK)> callback_t; + +    Updater(callback_t cb, F32 period, MASK mask) +        :LLEventTimer(period), +        mMask(mask), +        mCallback(cb) +    { +        mEventTimer.start(); +    } + +    virtual ~Updater(){} + +protected: +    BOOL tick() +    { +        mCallback(mMask); +        // Deletes itseft after execution +        return TRUE; +    } + +private: +    MASK mMask; +    callback_t mCallback;  };  LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)    : LLModalDialog(key),  	pParent(NULL), -	mKeyMask(DEFAULT_KEY_FILTER) +	mKeyFilterMask(DEFAULT_KEY_FILTER), +	pUpdater(NULL)  {  } @@ -227,13 +262,19 @@ void LLSetKeyBindDialog::onClose(bool app_quiting)          pParent->onCancelKeyBind();          pParent = NULL;      } +    if (pUpdater) +    { +        // Doubleclick timer has't fired, delete it +        delete pUpdater; +        pUpdater = NULL; +    }      LLModalDialog::onClose(app_quiting);  }  void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_mask)  {      pParent = parent; -    mKeyMask = key_mask; +    mKeyFilterMask = key_mask;      LLTextBase *text_ctrl = getChild<LLTextBase>("descritption"); @@ -259,24 +300,18 @@ void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_ma  BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask)  { -	BOOL result = TRUE; -      if ((key == 'Q' && mask == MASK_CONTROL)          || key == KEY_ESCAPE)      {          closeFloater(); -        return true; +        return TRUE;      }      if (key == KEY_DELETE)      { -        if (pParent) -        { -            pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); -            pParent = NULL; -        } +        setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);          closeFloater(); -        return true; +        return FALSE;      }      // forbidden keys @@ -284,40 +319,41 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask)          || key == KEY_RETURN          || key == KEY_BACKSPACE)      { -        return false; +        return FALSE;      } -    if ((mKeyMask & ALLOW_MASKS) == 0 +    if ((mKeyFilterMask & ALLOW_MASKS) == 0          && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT))      {          // mask by themself are not allowed -        return false; +        return FALSE;      } -    else if ((mKeyMask & ALLOW_KEYS) == 0) +    else if ((mKeyFilterMask & ALLOW_KEYS) == 0)      {          // basic keys not allowed -        return false; +        return FALSE;      } -    else if ((mKeyMask & ALLOW_MASK_KEYS) == 0 && mask != 0) +    else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0)      {          // masked keys not allowed -        return false; +        return FALSE;      } -	if (pParent) -	{ -        pParent->onSetKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); -        pParent = NULL; -	} -	closeFloater(); -	return result; +    setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); +    closeFloater(); +    return TRUE;  }  BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)  {      BOOL result = FALSE; - -    if (clicktype == CLICK_LEFT) +    if (!pParent) +    { +        // we already processed 'down' event, this is 'up', consume +        closeFloater(); +        result = TRUE; +    } +    if (!result && clicktype == CLICK_LEFT)      {          // try handling buttons first          if (down) @@ -328,25 +364,38 @@ BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClic          {              result = LLView::handleMouseUp(x, y, mask);          } +        if (result) +        { +            setFocus(TRUE); +            gFocusMgr.setKeystrokesOnly(TRUE); +        } +        // ignore selection related combinations +        else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0) +        { +            // this can be a double click, wait a bit; +            if (!pUpdater) +            { +                // Note: default doubleclick time is 500ms, but can stretch up to 5s +                pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask); +                result = TRUE; +            } +        }      }      if (!result -        && ((mKeyMask & ALLOW_MOUSE) != 0) +        && (clicktype != CLICK_LEFT) // subcases were handled above +        && ((mKeyFilterMask & ALLOW_MOUSE) != 0)          && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported -        && ((mKeyMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) +        && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection      { -        if (pParent) +        setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); +        result = TRUE; +        if (!down)          { -            pParent->onSetKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); -            pParent = NULL; +            // wait for 'up' event before closing +            // alternative: set pUpdater +            closeFloater();          } -        result = TRUE; -        closeFloater(); -    } -     -    if (!result) -    { -        result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);      }      return result; @@ -356,7 +405,7 @@ BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClic  void LLSetKeyBindDialog::onCancel(void* user_data)  {      LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; -	self->closeFloater(); +    self->closeFloater();  }  //static @@ -364,11 +413,7 @@ void LLSetKeyBindDialog::onBlank(void* user_data)  {      LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;      // tmp needs 'no key' button -    if (self->pParent) -    { -        self->pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); -        self->pParent = NULL; -    } +    self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);      self->closeFloater();  } @@ -376,7 +421,6 @@ void LLSetKeyBindDialog::onBlank(void* user_data)  void LLSetKeyBindDialog::onDefault(void* user_data)  {      LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; -    // tmp needs 'no key' button      if (self->pParent)      {          self->pParent->onDefaultKeyBind(); @@ -385,6 +429,27 @@ void LLSetKeyBindDialog::onDefault(void* user_data)      self->closeFloater();  } +//static +void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask) +{ +    LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; + +    // timer will delete itself after timeout +    self->pUpdater = NULL; + +    self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean()); +    self->closeFloater(); +} + +void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore) +{ +    if (pParent) +    { +        pParent->onSetKeyBind(click, key, mask, ignore); +        pParent = NULL; +    } +} +  // global functions  @@ -2921,9 +2986,72 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()  //------------------------LLPanelPreferenceControls--------------------------------  static LLPanelInjector<LLPanelPreferenceControls> t_pref_contrls("panel_preference_controls"); +//name of control and name of icon if it is a group, likely 'TEMP' until xml gets properly populated +typedef std::vector<std::pair<std::string, std::string> > controls_to_icon_t; +static const controls_to_icon_t commands_and_headers = +{ +    //{ "control_view_actions", "Search_Icon" }, +    //{ "control_interactions", "Command_Gestures_Icon" }, +    { "control_movements", "Move_Walk_Off" }, +    { "walk_to", "" }, +    { "teleport_to", "" }, +    { "push_forward", "" }, +    { "push_backward", "" }, +    { "turn_left", "" }, +    { "turn_right", "" }, +    { "slide_left", "" }, +    { "slide_right", "" }, +    { "jump", "" }, +    { "push_down", "" }, +    { "run_forward", "" }, +    { "run_backward", "" }, +    { "run_left", "" }, +    { "run_right", "" }, +    { "toggle_run", "" }, +    { "toggle_fly", "" }, +    { "toggle_sit", "" }, +    { "stop_moving", "" }, +    { "control_camera", "Cam_FreeCam_Off" }, +    { "look_up", "" }, +    { "look_down", "" }, +    { "move_forward", "" }, +    { "move_backward", "" }, +    { "move_forward_fast", "" }, +    { "move_backward_fast", "" }, +    { "move_forward_sitting", "" }, +    { "move_backward_sitting", "" }, +    { "spin_over", "" }, +    { "spin_under", "" }, +    { "spin_over_sitting", "" }, +    { "spin_under_sitting", "" }, +    { "pan_up", "" }, +    { "pan_down", "" }, +    { "pan_left", "" }, +    { "pan_right", "" }, +    { "pan_in", "" }, +    { "pan_out", "" }, +    { "spin_around_ccw", "" }, +    { "spin_around_cw", "" }, +    { "spin_around_ccw_sitting", "" }, +    { "spin_around_cw_sitting", "" }, +    { "control_edit_title", "Tool_Dozer" }, +    { "edit_avatar_spin_ccw", "" }, +    { "edit_avatar_spin_cw", "" }, +    { "edit_avatar_spin_over", "" }, +    { "edit_avatar_spin_under", "" }, +    { "edit_avatar_move_forward", "" }, +    { "edit_avatar_move_backward", "" }, +    { "control_mediacontent", "Audio_Press" }, +    { "toggle_pause_media", "" }, +    { "toggle_enable_media", "" }, +    { "voice_follow_key", "" }, +    { "toggle_voice", "" }, +    { "start_chat", "" }, +    { "start_gesture", "" }, +}; +  LLPanelPreferenceControls::LLPanelPreferenceControls()      :LLPanelPreference(), -    mEditingIndex(-1),      mEditingColumn(-1),      mEditingMode(0),      mShowKeyDialog(false), @@ -2962,8 +3090,8 @@ BOOL LLPanelPreferenceControls::handleHover(S32 x, S32 y, MASK mask)      if (mShowKeyDialog)      {          mShowKeyDialog = false; -        if (mEditingIndex > 0 -            && mConflictHandler[mEditingMode].canAssignControl((LLKeyConflictHandler::EControlTypes)mEditingIndex)) +        if (!mEditingControl.empty() +            && mConflictHandler[mEditingMode].canAssignControl(mEditingControl))          {              LLScrollListItem* item = pControlsTable->getFirstSelected(); // don't use pControlsTable->hitItem(x, y) dur to drift;              if (item) @@ -2991,10 +3119,10 @@ BOOL LLPanelPreferenceControls::handleHover(S32 x, S32 y, MASK mask)      return LLPanelPreference::handleHover(x, y, mask);  } -void LLPanelPreferenceControls::addGroupRow(const std::string &icon, S32 index) +void LLPanelPreferenceControls::addGroupRow(const std::string &control_name, const std::string &icon)  {      LLScrollListItem::Params item_params; -    item_params.value = LLSD::Integer(-1); +    item_params.value = "";      LLScrollListCell::Params icon_cell_params;      icon_cell_params.font = LLFontGL::getFontSansSerif(); @@ -3006,7 +3134,6 @@ void LLPanelPreferenceControls::addGroupRow(const std::string &icon, S32 index)      cell_params.font = LLFontGL::getFontSansSerif();      cell_params.font_halign = LLFontGL::LEFT; -    std::string control_name = LLKeyConflictHandler::getControlName((LLKeyConflictHandler::EControlTypes)index);      std::string label;      if (hasString(control_name))      { @@ -3059,76 +3186,48 @@ void LLPanelPreferenceControls::populateControlTable()      cell_params.column = "";      cell_params.value = label; -    S32 start = mEditingMode == LLKeyConflictHandler::MODE_GENERAL ? LLKeyConflictHandler::CONTROL_VIEW_ACTIONS : LLKeyConflictHandler::CONTROL_MOVEMENTS; -    S32 end = mEditingMode == LLKeyConflictHandler::MODE_GENERAL ? LLKeyConflictHandler::CONTROL_NUM_INDICES : LLKeyConflictHandler::CONTROL_RESERVED; -    for (S32 i = start; i < end; i++) +    controls_to_icon_t::const_iterator iter = commands_and_headers.begin(); +    controls_to_icon_t::const_iterator end = commands_and_headers.end(); +    for (; iter != end; ++iter)      { -        LLKeyConflictHandler::EControlTypes type = (LLKeyConflictHandler::EControlTypes)i; -        switch (type) +        if (iter->second.empty())          { -        case LLKeyConflictHandler::CONTROL_VIEW_ACTIONS: -            addSeparator(); -            addGroupRow("Search_Icon", i); -            break; -        case LLKeyConflictHandler::CONTROL_INTERACTIONS: -            addSeparator(); -            addGroupRow("Command_Gestures_Icon", i); -            break; -        case LLKeyConflictHandler::CONTROL_MOVEMENTS: -            addSeparator(); -            addGroupRow("Move_Walk_Off", i); -            break; -        case LLKeyConflictHandler::CONTROL_MEDIACONTENT: -            addSeparator(); -            addGroupRow("Audio_Press", i); -            break; -        case LLKeyConflictHandler::CONTROL_CAMERA: -            addSeparator(); -            addGroupRow("Cam_FreeCam_Off", i); -            break; -        case LLKeyConflictHandler::CONTROL_EDIT_TITLE: -            addSeparator(); -            addGroupRow("Tool_Dozer", i); -            break; -        case LLKeyConflictHandler::CONTROL_RESERVED: -            addSeparator(); -            addGroupRow("Info_Small", i); -            break; -        default: +            // general control +            LLScrollListItem::Params item_params; +            item_params.value = LLSD(iter->first); + +            cell_params.column = "lst_action"; +            bool enabled = mConflictHandler[mEditingMode].canAssignControl(iter->first); +            if (hasString(iter->first))              { -                //default insert -                LLScrollListItem::Params item_params; -                item_params.value = LLSD::Integer(i); - -                cell_params.column = "lst_action"; -                bool enabled = mConflictHandler[mEditingMode].canAssignControl(type); -                control_name = LLKeyConflictHandler::getControlName(type); -                if (hasString(control_name)) -                { -                    label = getString(control_name); -                } -                else -                { -                    label = control_name; -                } -                cell_params.value = label; -                item_params.columns.add(cell_params); -                cell_params.column = "lst_ctrl1"; -                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 0); -                cell_params.enabled = enabled; -                item_params.columns.add(cell_params); -                cell_params.column = "lst_ctrl2"; -                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 1); -                cell_params.enabled = enabled; -                item_params.columns.add(cell_params); -                cell_params.column = "lst_ctrl3"; -                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 2); -                cell_params.enabled = enabled; -                item_params.columns.add(cell_params); - -                pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM); -                break; +                label = getString(iter->first);              } +            else +            { +                label = iter->first; +            } +            cell_params.value = label; +            item_params.columns.add(cell_params); +            cell_params.column = "lst_ctrl1"; +            cell_params.value = mConflictHandler[mEditingMode].getControlString(iter->first, 0); +            cell_params.enabled = enabled; +            item_params.columns.add(cell_params); +            cell_params.column = "lst_ctrl2"; +            cell_params.value = mConflictHandler[mEditingMode].getControlString(iter->first, 1); +            cell_params.enabled = enabled; +            item_params.columns.add(cell_params); +            cell_params.column = "lst_ctrl3"; +            cell_params.value = mConflictHandler[mEditingMode].getControlString(iter->first, 2); +            cell_params.enabled = enabled; +            item_params.columns.add(cell_params); + +            pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM); +        } +        else +        { +            // header +            addSeparator(); +            addGroupRow(iter->first, iter->second);          }      }  } @@ -3144,13 +3243,13 @@ void LLPanelPreferenceControls::addSeparator()  void LLPanelPreferenceControls::updateTable()  { +    mEditingControl.clear();      std::vector<LLScrollListItem*> list = pControlsTable->getAllData();      for (S32 i = 0; i < list.size(); ++i)      { -        S32 value = list[i]->getValue().asInteger(); -        if (value > 0) +        std::string control = list[i]->getValue(); +        if (!control.empty())          { -            LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)value;              LLScrollListCell* cell = list[i]->getColumn(1);              cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0));              cell = list[i]->getColumn(2); @@ -3207,6 +3306,7 @@ void LLPanelPreferenceControls::saveSettings()          if (mConflictHandler[i].hasUnsavedChanges())          {              mConflictHandler[i].saveToSettings(); +            mConflictHandler[i].clear();          }      } @@ -3229,20 +3329,21 @@ void LLPanelPreferenceControls::resetDirtyChilds()  void LLPanelPreferenceControls::onListCommit()  { +    mShowKeyDialog = false;      LLScrollListItem* item = pControlsTable->getFirstSelected();      if (item == NULL)      {          return;      } -    S32 control = item->getValue().asInteger(); +    std::string control = item->getValue(); -    if (control <= 0) +    if (control.empty())      {          return;      } -    if (!mConflictHandler[mEditingMode].canAssignControl((LLKeyConflictHandler::EControlTypes)control)) +    if (!mConflictHandler[mEditingMode].canAssignControl(control))      {          return;      } @@ -3251,7 +3352,7 @@ void LLPanelPreferenceControls::onListCommit()      // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,      // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,      // use coordinates from hover to calculate cell -    mEditingIndex = control; +    mEditingControl = control;      mShowKeyDialog = true;      if (mHighlightedCell) @@ -3269,18 +3370,16 @@ void LLPanelPreferenceControls::onModeCommit()  // todo: copy onSetKeyBind to interface and inherit from interface  void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask)  { -    LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)mEditingIndex; - -    if (!mConflictHandler[mEditingMode].canAssignControl(control)) +    if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))      {          return;      }      pControlsTable->deselectAllItems(); -    pControlsTable->selectByValue(mEditingIndex); +    pControlsTable->selectByValue(mEditingControl);      if ( mEditingColumn > 0)      { -        mConflictHandler[mEditingMode].registerControl(control, mEditingColumn - 1, click, key, mask, ignore_mask); +        mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, ignore_mask);      }      updateTable(); @@ -3296,19 +3395,17 @@ void LLPanelPreferenceControls::onRestoreDefaults()  void LLPanelPreferenceControls::onDefaultKeyBind()  { -    LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)mEditingIndex; - -    if (!mConflictHandler[mEditingMode].canAssignControl(control)) +    if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))      {          return;      }      pControlsTable->deselectAllItems(); -    pControlsTable->selectByValue(mEditingIndex); +    pControlsTable->selectByValue(mEditingControl);      if (mEditingColumn > 0)      { -        mConflictHandler[mEditingMode].resetToDefault(control, mEditingColumn - 1); +        mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);      }      updateTable();  } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 9178927e74..e07ead7e18 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -318,7 +318,7 @@ public:  	void onCancelKeyBind();  private: -	void addGroupRow(const std::string &icon, S32 index); +	void addGroupRow(const std::string &control_name, const std::string &icon);  	void regenerateControls();  	void populateControlTable();  	void addSeparator(); @@ -328,7 +328,7 @@ private:  	LLComboBox *pKeyModeBox;  	LLScrollListCell *mHighlightedCell;  	LLKeyConflictHandler mConflictHandler[LLKeyConflictHandler::MODE_COUNT]; -	S32 mEditingIndex; +	std::string mEditingControl;  	S32 mEditingColumn;  	S32 mEditingMode;  	bool mShowKeyDialog; diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index e81d121e3b..c74eea6e47 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -41,135 +41,7 @@  #include "llxuiparser.h"  //#include "llstring.h" -static const std::string typetostring[LLKeyConflictHandler::CONTROL_NUM_INDICES] = { -    "control_view_actions", -    "control_about", -    "control_orbit", -    "control_pan", -    "control_world_map", -    "control_zoom", -    "control_interactions", -    "control_build", -    //"control_drag", -    "control_edit", -    //"control_menu", -    "control_open", -    "control_touch", -    "control_wear", -    "control_movements", -    "walk_to", -    "teleport_to", -    "push_forward", -    "push_backward", -    "turn_left", -    "turn_right", -    "slide_left", -    "slide_right", -    "jump", -    "push_down", -    //"control_run", -    "toggle_run", -    "toggle_fly", -    "toggle_sit", -    "stop_moving", -    "control_camera", -    "look_up", -    "look_down", -    "move_forward", -    "move_backward", -    "move_forward_fast", -    "move_backward_fast", -    "move_forward_sitting", -    "move_backward_sitting", -    "spin_over", -    "spin_under", -    "spin_over_sitting", -    "spin_under_sitting", -    "pan_up", -    "pan_down", -    "pan_left", -    "pan_right", -    "pan_in", -    "pan_out", -    "spin_around_ccw", -    "spin_around_cw", -    "spin_around_ccw_sitting", -    "spin_around_cw_sitting", -    "control_edit_title", -    "edit_avatar_spin_ccw", -    "edit_avatar_spin_cw", -    "edit_avatar_spin_over", -    "edit_avatar_spin_under", -    "edit_avatar_move_forward", -    "edit_avatar_move_backward", -    "control_mediacontent", -    "toggle_pause_media", -    "toggle_enable_media", -    "voice_follow_key", -    "toggle_voice", -    "start_chat", -    "start_gesture", -    "control_reserved", -    "control_delete", -    "control_menu", -    "control_reserved_select", -    "control_shift_select", -    "control_cntrl_select" -}; - -// note, a solution is needed that will keep this up to date with llviewerinput -typedef std::map<std::string, LLKeyConflictHandler::EControlTypes> control_enum_t; -static const control_enum_t command_to_key = -{ -    { "jump", LLKeyConflictHandler::CONTROL_JUMP }, -    { "push_down", LLKeyConflictHandler::CONTROL_DOWN }, -    { "push_forward", LLKeyConflictHandler::CONTROL_FORWARD }, -    { "push_backward", LLKeyConflictHandler::CONTROL_BACKWARD }, -    { "look_up", LLKeyConflictHandler::CONTROL_LOOK_UP }, -    { "look_down", LLKeyConflictHandler::CONTROL_LOOK_DOWN }, -    { "toggle_fly", LLKeyConflictHandler::CONTROL_TOGGLE_FLY }, -    { "turn_left", LLKeyConflictHandler::CONTROL_LEFT }, -    { "turn_right", LLKeyConflictHandler::CONTROL_RIGHT }, -    { "slide_left", LLKeyConflictHandler::CONTROL_LSTRAFE }, -    { "slide_right", LLKeyConflictHandler::CONTROL_RSTRAFE }, -    { "spin_around_ccw", LLKeyConflictHandler::CONTROL_CAMERA_SPIN_CCW }, // todo, no idea what these spins are -    { "spin_around_cw", LLKeyConflictHandler::CONTROL_CAMERA_SPIN_CW }, -    { "spin_around_ccw_sitting", LLKeyConflictHandler::CONTROL_CAMERA_SPIN_CCW_SITTING }, -    { "spin_around_cw_sitting", LLKeyConflictHandler::CONTROL_CAMERA_SPIN_CCW_SITTING }, -    { "spin_over", LLKeyConflictHandler::CONTROL_CAMERA_SOVER }, -    { "spin_under", LLKeyConflictHandler::CONTROL_CAMERA_SUNDER }, -    { "spin_over_sitting", LLKeyConflictHandler::CONTROL_CAMERA_SOVER_SITTING }, -    { "spin_under_sitting", LLKeyConflictHandler::CONTROL_CAMERA_SUNDER_SITTING }, -    { "move_forward", LLKeyConflictHandler::CONTROL_CAMERA_FORWARD }, -    { "move_backward", LLKeyConflictHandler::CONTROL_CAMERA_BACKWARD }, -    { "move_forward_sitting", LLKeyConflictHandler::CONTROL_CAMERA_FSITTING }, -    { "move_backward_sitting", LLKeyConflictHandler::CONTROL_CAMERA_BSITTING }, -    { "pan_up", LLKeyConflictHandler::CONTROL_CAMERA_PANUP }, -    { "pan_down", LLKeyConflictHandler::CONTROL_CAMERA_PANDOWN }, -    { "pan_left", LLKeyConflictHandler::CONTROL_CAMERA_PANLEFT }, -    { "pan_right", LLKeyConflictHandler::CONTROL_CAMERA_PANRIGHT }, -    { "pan_in", LLKeyConflictHandler::CONTROL_CAMERA_PANIN }, -    { "pan_out", LLKeyConflictHandler::CONTROL_CAMERA_PANOUT }, -    { "move_forward_fast", LLKeyConflictHandler::CONTROL_CAMERA_FFORWARD }, -    { "move_backward_fast", LLKeyConflictHandler::CONTROL_CAMERA_FBACKWARD }, -    { "edit_avatar_spin_ccw", LLKeyConflictHandler::CONTROL_EDIT_AV_SPIN_CCW }, -    { "edit_avatar_spin_cw", LLKeyConflictHandler::CONTROL_EDIT_AV_SPIN_CW }, -    { "edit_avatar_spin_over", LLKeyConflictHandler::CONTROL_EDIT_AV_SPIN_OVER }, -    { "edit_avatar_spin_under", LLKeyConflictHandler::CONTROL_EDIT_AV_SPIN_UNDER }, -    { "edit_avatar_move_forward", LLKeyConflictHandler::CONTROL_EDIT_AV_MV_FORWARD }, -    { "edit_avatar_move_backward", LLKeyConflictHandler::CONTROL_EDIT_AV_MV_BACKWARD }, -    { "stop_moving", LLKeyConflictHandler::CONTROL_STOP }, -    { "start_chat", LLKeyConflictHandler::CONTROL_START_CHAT }, -    { "start_gesture", LLKeyConflictHandler::CONTROL_START_GESTURE }, -    { "toggle_run", LLKeyConflictHandler::CONTROL_TOGGLE_RUN }, -    { "toggle_sit", LLKeyConflictHandler::CONTROL_SIT }, -    { "toggle_parcel_media", LLKeyConflictHandler::CONTROL_PAUSE_MEDIA }, -    { "toggle_enable_media", LLKeyConflictHandler::CONTROL_ENABLE_MEDIA }, -    { "walk_to", LLKeyConflictHandler::CONTROL_MOVETO }, -    { "teleport_to", LLKeyConflictHandler::CONTROL_TELEPORTTO }, -    { "toggle_voice", LLKeyConflictHandler::CONTROL_TOGGLE_VOICE }, -    { "voice_follow_key", LLKeyConflictHandler::CONTROL_VOICE }, -}; +static const std::string saved_settings_key_controls[] = { "placeholder" };  // LLKeyboard::stringFromMask is meant for UI and is OS dependent, @@ -267,29 +139,29 @@ LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode)      loadFromSettings(mode);  } -bool LLKeyConflictHandler::canHandleControl(LLKeyConflictHandler::EControlTypes control_type, EMouseClickType mouse_ind, KEY key, MASK mask) +bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask)  { -    return mControlsMap[control_type].canHandle(mouse_ind, key, mask); +    return mControlsMap[control_name].canHandle(mouse_ind, key, mask);  } -bool LLKeyConflictHandler::canHandleKey(EControlTypes control_type, KEY key, MASK mask) +bool LLKeyConflictHandler::canHandleKey(const std::string &control_name, KEY key, MASK mask)  { -    return canHandleControl(control_type, CLICK_NONE, key, mask); +    return canHandleControl(control_name, CLICK_NONE, key, mask);  } -bool LLKeyConflictHandler::canHandleMouse(LLKeyConflictHandler::EControlTypes control_type, EMouseClickType mouse_ind, MASK mask) +bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask)  { -    return canHandleControl(control_type, mouse_ind, KEY_NONE, mask); +    return canHandleControl(control_name, mouse_ind, KEY_NONE, mask);  } -bool LLKeyConflictHandler::canHandleMouse(EControlTypes control_type, S32 mouse_ind, MASK mask) +bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask)  { -    return canHandleControl(control_type, (EMouseClickType)mouse_ind, KEY_NONE, mask); +    return canHandleControl(control_name, (EMouseClickType)mouse_ind, KEY_NONE, mask);  } -bool LLKeyConflictHandler::canAssignControl(EControlTypes control_type) +bool LLKeyConflictHandler::canAssignControl(const std::string &control_name)  { -    std::map<EControlTypes, LLKeyConflict>::iterator iter = mControlsMap.find(control_type); +    control_map_t::iterator iter = mControlsMap.find(control_name);      if (iter != mControlsMap.end())      {          return iter->second.mAssignable; @@ -297,9 +169,13 @@ bool LLKeyConflictHandler::canAssignControl(EControlTypes control_type)      return false;  } -bool LLKeyConflictHandler::registerControl(EControlTypes control_type, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) +bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)  { -    LLKeyConflict &type_data = mControlsMap[control_type]; +    if (control_name.empty()) +    { +        return false; +    } +    LLKeyConflict &type_data = mControlsMap[control_name];      if (!type_data.mAssignable)      {          LL_ERRS() << "Error in code, user or system should not be able to change certain controls" << LL_ENDL; @@ -319,9 +195,13 @@ bool LLKeyConflictHandler::registerControl(EControlTypes control_type, U32 index      return false;  } -LLKeyData LLKeyConflictHandler::getControl(EControlTypes control_type, U32 index) +LLKeyData LLKeyConflictHandler::getControl(const std::string &control_name, U32 index)  { -    return mControlsMap[control_type].getKeyData(index); +    if (control_name.empty()) +    { +        return LLKeyData(); +    } +    return mControlsMap[control_name].getKeyData(index);  }  // static @@ -341,24 +221,37 @@ std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata)      {          result = LLKeyboard::stringFromAccelerator(keydata.mMask);      } +    else if (keydata.mIgnoreMasks) +    { +        result = "acc+"; +    }      result += string_from_mouse(keydata.mMouse);      return result;  } -// static -std::string LLKeyConflictHandler::getControlName(EControlTypes control_type) +std::string LLKeyConflictHandler::getControlString(const std::string &control_name, U32 index)  { -    return typetostring[control_type]; +    if (control_name.empty()) +    { +        return ""; +    } +    return getStringFromKeyData(mControlsMap[control_name].getKeyData(index));  } -std::string LLKeyConflictHandler::getControlString(EControlTypes control_type, U32 index) +void LLKeyConflictHandler::loadFromControlSettings(const std::string &name)  { -    return getStringFromKeyData(mControlsMap[control_type].getKeyData(index)); +    LLControlVariablePtr var = gSavedSettings.getControl(name); +    if (var) +    { +        LLKeyBind bind(var->getValue()); +        LLKeyConflict key(bind, true, 0); +        mControlsMap[name] = key; +    }  } -void  LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination) +void LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination)  {      for (LLInitParam::ParamIterator<LLViewerInput::KeyBinding>::const_iterator it = keymode.bindings.begin(),          end_it = keymode.bindings.end(); @@ -378,28 +271,23 @@ void  LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymo              LLKeyboard::keyFromString(it->key, &key);          }          LLKeyboard::maskFromString(it->mask, &mask); -        std::string command_name = it->command; -        // it->command -        // It might be better to have <string,bind> map, but at the moment enum is easier to iterate through. -        // Besides keys.xml might not contain all commands -        control_enum_t::const_iterator iter = command_to_key.find(command_name); -        if (iter != command_to_key.end()) -        { -            LLKeyConflict &type_data = (*destination)[iter->second]; -            type_data.mAssignable = true; -            // Don't care about conflict level, all movement and view commands already account for it -            type_data.mKeyBind.addKeyData(mouse, key, mask, ignore); -        } +        // Note: it->command is also the name of UI element, howhever xml we are loading from +        // might not know all the commands, so UI will have to know what to fill by its own +        LLKeyConflict &type_data = (*destination)[it->command]; +        type_data.mAssignable = true; +        type_data.mKeyBind.addKeyData(mouse, key, mask, ignore);      }  } -void LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination) +bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination)  {      if (filename.empty())      { -        return; +        return false;      } +    bool res = false; +      LLViewerInput::Keys keys;      LLSimpleXUIParser parser; @@ -412,39 +300,45 @@ void LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const              if (keys.first_person.isProvided())              {                  loadFromSettings(keys.first_person, destination); +                res = true;              }              break;          case MODE_THIRD_PERSON:              if (keys.third_person.isProvided())              {                  loadFromSettings(keys.third_person, destination); +                res = true;              }              break;          case MODE_EDIT:              if (keys.edit.isProvided())              {                  loadFromSettings(keys.edit, destination); +                res = true;              }              break;          case MODE_EDIT_AVATAR:              if (keys.edit_avatar.isProvided())              {                  loadFromSettings(keys.edit_avatar, destination); +                res = true;              }              break;          case MODE_SITTING:              if (keys.sitting.isProvided())              {                  loadFromSettings(keys.sitting, destination); +                res = true;              }              break;          default:              break;          }      } +    return res;  } -void  LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode) +void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)  {      mControlsMap.clear();      mDefaultsMap.clear(); @@ -454,48 +348,26 @@ void  LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)      if (load_mode == MODE_GENERAL)      { -        for (U32 i = 0; i < CONTROL_NUM_INDICES; i++) +        // load settings clss knows about, but it also possible to load settings by name separately +        const S32 size = std::extent<decltype(saved_settings_key_controls)>::value; +        for (U32 i = 0; i < size; i++)          { -            EControlTypes type = (EControlTypes)i; -            switch (type) -            { -            case LLKeyConflictHandler::CONTROL_VIEW_ACTIONS: -            case LLKeyConflictHandler::CONTROL_INTERACTIONS: -            case LLKeyConflictHandler::CONTROL_MOVEMENTS: -            case LLKeyConflictHandler::CONTROL_MEDIACONTENT: -            case LLKeyConflictHandler::CONTROL_CAMERA: -            case LLKeyConflictHandler::CONTROL_EDIT_TITLE: -            case LLKeyConflictHandler::CONTROL_RESERVED: -                // ignore 'headers', they are for representation and organization purposes -                break; -            default: -                { -                    std::string name = getControlName(type); -                    LLControlVariablePtr var = gSavedSettings.getControl(name); -                    if (var) -                    { -                        LLKeyBind bind(var->getValue()); -                        LLKeyConflict key(bind, true, 0); -                        mControlsMap[type] = key; -                    } -                    break; -                } -            } +            loadFromControlSettings(saved_settings_key_controls[i]);          }      }      else      {          // load defaults          std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "keys.xml"); -        loadFromSettings(load_mode, filename, &mDefaultsMap); +        if (!loadFromSettings(load_mode, filename, &mDefaultsMap)) +        { +            LL_WARNS() << "Failed to load default settings, aborting" << LL_ENDL; +            return; +        }          // load user's          filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "keys.xml"); -        if (gDirUtilp->fileExists(filename)) -        { -            loadFromSettings(load_mode, filename, &mControlsMap); -        } -        else +        if (!gDirUtilp->fileExists(filename) || loadFromSettings(load_mode, filename, &mControlsMap))          {              // mind placeholders              mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); @@ -504,7 +376,7 @@ void  LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)      mLoadMode = load_mode;  } -void  LLKeyConflictHandler::saveToSettings() +void LLKeyConflictHandler::saveToSettings()  {      if (mControlsMap.empty())      { @@ -513,39 +385,33 @@ void  LLKeyConflictHandler::saveToSettings()      if (mLoadMode == MODE_GENERAL)      { -        for (U32 i = 0; i < CONTROL_NUM_INDICES; i++) +        control_map_t::iterator iter = mControlsMap.begin(); +        control_map_t::iterator end = mControlsMap.end(); + +        for (; iter != end; ++iter)          { -            EControlTypes type = (EControlTypes)i; -            switch (type) +            if (iter->first.empty())              { -            case LLKeyConflictHandler::CONTROL_VIEW_ACTIONS: -            case LLKeyConflictHandler::CONTROL_INTERACTIONS: -            case LLKeyConflictHandler::CONTROL_MOVEMENTS: -            case LLKeyConflictHandler::CONTROL_MEDIACONTENT: -            case LLKeyConflictHandler::CONTROL_CAMERA: -            case LLKeyConflictHandler::CONTROL_EDIT_TITLE: -            case LLKeyConflictHandler::CONTROL_RESERVED: -                // ignore 'headers', they are for representation and organization purposes -                break; -            default: +                continue; +            } + +            LLKeyConflict &key = iter->second; +            key.mKeyBind.trimEmpty(); +            if (!key.mAssignable)              { -                if (mControlsMap[type].mAssignable) -                { -                    std::string name = getControlName(type); -                    if (gSavedSettings.controlExists(name)) -                    { -                        gSavedSettings.setLLSD(name, mControlsMap[type].mKeyBind.asLLSD()); -                    } -                    else if (!mControlsMap[type].mKeyBind.empty()) -                    { -                        // shouldn't happen user side since all settings are supposed to be declared already, but handy when creating new ones -                        // (just don't forget to change comment and to copy them from user's folder) -                        LL_INFOS() << "Creating new keybinding " << name << LL_ENDL; -                        gSavedSettings.declareLLSD(name, mControlsMap[type].mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS); -                    } -                } -                break; +                continue; +            } + +            if (gSavedSettings.controlExists(iter->first)) +            { +                gSavedSettings.setLLSD(iter->first, key.mKeyBind.asLLSD());              } +            else if (!key.mKeyBind.empty()) +            { +                // Note: this is currently not in use, might be better for load mechanics to ask for and retain control group +                // otherwise settings loaded from other control groups will end in this one +                LL_INFOS() << "Creating new keybinding " << iter->first << LL_ENDL; +                gSavedSettings.declareLLSD(iter->first, key.mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS);              }          }      } @@ -564,8 +430,8 @@ void  LLKeyConflictHandler::saveToSettings()          {              // replace category we edited -            // todo: fix this -            // workaround to avoid doing own param container  +            // mode is a HACK to correctly reset bindings without reparsing whole file and avoid doing +            // own param container (which will face issues with inasseesible members of LLInitParam)              LLViewerInput::KeyMode mode;              LLViewerInput::KeyBinding binding; @@ -581,8 +447,20 @@ void  LLKeyConflictHandler::saveToSettings()                  U32 size = iter->second.mKeyBind.getDataCount();                  for (U32 i = 0; i < size; ++i)                  { -                    // Still write empty keys to make sure we will maintain UI position -                    LLKeyData data = iter->second.mKeyBind.getKeyData(i); +                    if (iter->first.empty()) +                    { +                        continue; +                    } + +                    LLKeyConflict &key = iter->second; +                    key.mKeyBind.trimEmpty(); +                    if (key.mKeyBind.empty() || !key.mAssignable) +                    { +                        continue; +                    } + +                    LLKeyData data = key.mKeyBind.getKeyData(i); +                    // Still write empty LLKeyData to make sure we will maintain UI position                      if (data.mKey == KEY_NONE)                      {                          binding.key = ""; @@ -595,7 +473,7 @@ void  LLKeyConflictHandler::saveToSettings()                      binding.mask = string_from_mask(data.mMask);                      binding.mouse.set(string_from_mouse(data.mMouse), true); //set() because 'optional', for compatibility purposes                      binding.ignore.set(data.mIgnoreMasks, true); -                    binding.command = getControlName(iter->first); +                    binding.command = iter->first;                      mode.bindings.add(binding);                  }              } @@ -664,12 +542,15 @@ void  LLKeyConflictHandler::saveToSettings()      mHasUnsavedChanges = false;  } -LLKeyData LLKeyConflictHandler::getDefaultControl(EControlTypes control_type, U32 index) +LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index)  { +    if (control_name.empty()) +    { +        return LLKeyData(); +    }      if (mLoadMode == MODE_GENERAL)      { -        std::string name = getControlName(control_type); -        LLControlVariablePtr var = gSavedSettings.getControl(name); +        LLControlVariablePtr var = gSavedSettings.getControl(control_name);          if (var)          {              return LLKeyBind(var->getDefault()).getKeyData(index); @@ -678,7 +559,7 @@ LLKeyData LLKeyConflictHandler::getDefaultControl(EControlTypes control_type, U3      }      else      { -        control_map_t::iterator iter = mDefaultsMap.find(control_type); +        control_map_t::iterator iter = mDefaultsMap.find(control_name);          if (iter != mDefaultsMap.end())          {              return iter->second.mKeyBind.getKeyData(index); @@ -687,24 +568,31 @@ LLKeyData LLKeyConflictHandler::getDefaultControl(EControlTypes control_type, U3      }  } -void LLKeyConflictHandler::resetToDefault(EControlTypes control_type, U32 index) +void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 index)  { -    LLKeyData data = getDefaultControl(control_type, index); +    if (control_name.empty()) +    { +        return; +    } +    LLKeyData data = getDefaultControl(control_name, index); -    if (data != mControlsMap[control_type].getKeyData(index)) +    if (data != mControlsMap[control_name].getKeyData(index))      {          // reset controls that might have been switched to our current control -        removeConflicts(data, mControlsMap[control_type].mConflictMask); -        mControlsMap[control_type].setKeyData(data, index); +        removeConflicts(data, mControlsMap[control_name].mConflictMask); +        mControlsMap[control_name].setKeyData(data, index);      }  } -void LLKeyConflictHandler::resetToDefaultAndResolve(EControlTypes control_type, bool ignore_conflicts) +void LLKeyConflictHandler::resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts)  { +    if (control_name.empty()) +    { +        return; +    }      if (mLoadMode == MODE_GENERAL)      { -        std::string name = getControlName(control_type); -        LLControlVariablePtr var = gSavedSettings.getControl(name); +        LLControlVariablePtr var = gSavedSettings.getControl(control_name);          if (var)          {              LLKeyBind bind(var->getDefault()); @@ -712,67 +600,53 @@ void LLKeyConflictHandler::resetToDefaultAndResolve(EControlTypes control_type,              {                  for (S32 i = 0; i < bind.getDataCount(); ++i)                  { -                    removeConflicts(bind.getKeyData(i), mControlsMap[control_type].mConflictMask); +                    removeConflicts(bind.getKeyData(i), mControlsMap[control_name].mConflictMask);                  }              } -            mControlsMap[control_type].mKeyBind = bind; +            mControlsMap[control_name].mKeyBind = bind;          }          else          { -            mControlsMap[control_type].mKeyBind.clear(); +            mControlsMap[control_name].mKeyBind.clear();          }      }      else      { -        control_map_t::iterator iter = mDefaultsMap.find(control_type); +        control_map_t::iterator iter = mDefaultsMap.find(control_name);          if (iter != mDefaultsMap.end())          {              if (!ignore_conflicts)              {                  for (S32 i = 0; i < iter->second.mKeyBind.getDataCount(); ++i)                  { -                    removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_type].mConflictMask); +                    removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_name].mConflictMask);                  }              } -            mControlsMap[control_type].mKeyBind = iter->second.mKeyBind; +            mControlsMap[control_name].mKeyBind = iter->second.mKeyBind;          }          else          { -            mControlsMap[control_type].mKeyBind.clear(); +            mControlsMap[control_name].mKeyBind.clear();          }      }  } -void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) +void LLKeyConflictHandler::resetToDefault(const std::string &control_name)  {      // reset specific binding without ignoring conflicts -    resetToDefaultAndResolve(control_type, false); +    resetToDefaultAndResolve(control_name, false);  }  void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)  {      if (mode == MODE_GENERAL)      { -        for (U32 i = 0; i < CONTROL_NUM_INDICES; i++) +        control_map_t::iterator iter = mControlsMap.begin(); +        control_map_t::iterator end = mControlsMap.end(); + +        for (; iter != end; ++iter)          { -            EControlTypes type = (EControlTypes)i; -            switch (type) -            { -            case LLKeyConflictHandler::CONTROL_VIEW_ACTIONS: -            case LLKeyConflictHandler::CONTROL_INTERACTIONS: -            case LLKeyConflictHandler::CONTROL_MOVEMENTS: -            case LLKeyConflictHandler::CONTROL_MEDIACONTENT: -            case LLKeyConflictHandler::CONTROL_CAMERA: -            case LLKeyConflictHandler::CONTROL_EDIT_TITLE: -            case LLKeyConflictHandler::CONTROL_RESERVED: -                // ignore 'headers', they are for representation and organization purposes -                break; -            default: -            { -                resetToDefaultAndResolve(type, true); -                break; -            } -            } +            resetToDefaultAndResolve(iter->first, true);          }      }      else @@ -834,7 +708,7 @@ bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &con          // Can't conflict          return true;      } -    std::map<EControlTypes, S32> conflict_list; +    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) @@ -859,8 +733,8 @@ bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &con          }      } -    std::map<EControlTypes, S32>::iterator cnflct_iter = conflict_list.begin(); -    std::map<EControlTypes, S32>::iterator cnflct_end = conflict_list.end(); +    std::map<std::string, S32>::iterator cnflct_iter = conflict_list.begin(); +    std::map<std::string, S32>::iterator cnflct_end = conflict_list.end();      for (; cnflct_iter != cnflct_end; ++cnflct_iter)      {          mControlsMap[cnflct_iter->first].mKeyBind.resetKeyData(cnflct_iter->second); @@ -868,9 +742,9 @@ bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &con      return true;  } -void LLKeyConflictHandler::registerTemporaryControl(EControlTypes control_type, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask) +void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask)  { -    LLKeyConflict *type_data = &mControlsMap[control_type]; +    LLKeyConflict *type_data = &mControlsMap[control_name];      type_data->mAssignable = false;      type_data->mConflictMask = conflict_mask;      type_data->mKeyBind.addKeyData(mouse, key, mask, false); diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index e4a6da30d0..a0886bedce 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -70,114 +70,35 @@ public:      // at the moment this just means that key will conflict with everything that is identical      const U32 CONFLICT_ANY = U32_MAX; -    // todo, unfortunately will have to remove this and use map/array of strings -    enum EControlTypes -    { -        CONTROL_VIEW_ACTIONS = 0, // Group control, for visual representation in view, not for use -        CONTROL_ABOUT, -        CONTROL_ORBIT, -        CONTROL_PAN, -        CONTROL_WORLD_MAP, -        CONTROL_ZOOM, -        CONTROL_INTERACTIONS, // Group control, for visual representation -        CONTROL_BUILD, -        //CONTROL_DRAG, -        CONTROL_EDIT, -        //CONTROL_MENU, -        CONTROL_OPEN, -        CONTROL_TOUCH, -        CONTROL_WEAR, -        CONTROL_MOVEMENTS, // Group control, for visual representation -        CONTROL_MOVETO, -        CONTROL_TELEPORTTO, -        CONTROL_FORWARD, -        CONTROL_BACKWARD, -        CONTROL_LEFT, // Check and sinc name with real movement names -        CONTROL_RIGHT, -        CONTROL_LSTRAFE, -        CONTROL_RSTRAFE, -        CONTROL_JUMP, -        CONTROL_DOWN, -        //CONTROL_RUN, -        CONTROL_TOGGLE_RUN, -        CONTROL_TOGGLE_FLY, -        CONTROL_SIT, -        CONTROL_STOP, -        CONTROL_CAMERA, // Group control, for visual representation -        CONTROL_LOOK_UP, -        CONTROL_LOOK_DOWN, -        CONTROL_CAMERA_FORWARD, -        CONTROL_CAMERA_BACKWARD, -        CONTROL_CAMERA_FFORWARD, -        CONTROL_CAMERA_FBACKWARD, -        CONTROL_CAMERA_FSITTING, -        CONTROL_CAMERA_BSITTING, -        CONTROL_CAMERA_SOVER, -        CONTROL_CAMERA_SUNDER, -        CONTROL_CAMERA_SOVER_SITTING, -        CONTROL_CAMERA_SUNDER_SITTING, -        CONTROL_CAMERA_PANUP, -        CONTROL_CAMERA_PANDOWN, -        CONTROL_CAMERA_PANLEFT, -        CONTROL_CAMERA_PANRIGHT, -        CONTROL_CAMERA_PANIN, -        CONTROL_CAMERA_PANOUT, -        CONTROL_CAMERA_SPIN_CCW, -        CONTROL_CAMERA_SPIN_CW, -        CONTROL_CAMERA_SPIN_CCW_SITTING, -        CONTROL_CAMERA_SPIN_CW_SITTING, -        CONTROL_EDIT_TITLE, // Group control, for visual representation -        CONTROL_EDIT_AV_SPIN_CCW, -        CONTROL_EDIT_AV_SPIN_CW, -        CONTROL_EDIT_AV_SPIN_OVER, -        CONTROL_EDIT_AV_SPIN_UNDER, -        CONTROL_EDIT_AV_MV_FORWARD, -        CONTROL_EDIT_AV_MV_BACKWARD, -        CONTROL_MEDIACONTENT, // Group control, for visual representation -        CONTROL_PAUSE_MEDIA, // Play pause -        CONTROL_ENABLE_MEDIA, // Play stop -        CONTROL_VOICE, // Keep pressing for voice to be ON -        CONTROL_TOGGLE_VOICE, // Press once to ON/OFF -        CONTROL_START_CHAT, // Press once to ON/OFF -        CONTROL_START_GESTURE, // Press once to ON/OFF -        CONTROL_RESERVED, // Special group control, controls that are disabled by default and not meant to be changed -        CONTROL_DELETE, -        CONTROL_RESERVED_MENU, -        CONTROL_RESERVED_SELECT, -        CONTROL_SHIFT_SELECT, -        CONTROL_CNTRL_SELECT, -        CONTROL_NUM_INDICES // Size, always should be last -    }; -      // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel)      LLKeyConflictHandler();      LLKeyConflictHandler(ESourceMode mode); -    bool canHandleControl(EControlTypes control_type, EMouseClickType mouse_ind, KEY key, MASK mask); -    bool canHandleKey(EControlTypes control_type, KEY key, MASK mask); -    bool canHandleMouse(EControlTypes control_type, EMouseClickType mouse_ind, MASK mask); -    bool canHandleMouse(EControlTypes control_type, S32 mouse_ind, MASK mask); //Just for convinience -    bool canAssignControl(EControlTypes control_type); -    bool registerControl(EControlTypes control_type, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts? - -    LLKeyData getControl(EControlTypes control_type, U32 data_index); +    bool canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask); +    bool canHandleKey(const std::string &control_name, KEY key, MASK mask); +    bool canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask); +    bool canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask); //Just for convinience +    bool canAssignControl(const std::string &control_name); +    bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts? -    static std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata); -    static std::string getControlName(EControlTypes control_type); -    std::string getControlString(EControlTypes control_type, U32 data_index); +    LLKeyData getControl(const std::string &control_name, U32 data_index); +    static std::string getStringFromKeyData(const LLKeyData& keydata); +    std::string getControlString(const std::string &control_name, U32 data_index); +    // Load single control, overrides existing one if names match +    void loadFromControlSettings(const std::string &name);      // Drops any changes loads controls with ones from 'saved settings' or from xml      void loadFromSettings(ESourceMode load_mode);      // Saves settings to 'saved settings' or to xml      void saveToSettings(); -    LLKeyData getDefaultControl(EControlTypes control_type, U32 data_index); +    LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);      // Resets keybinding to default variant from 'saved settings' or xml -    void resetToDefault(EControlTypes control_type, U32 index); -    void resetToDefault(EControlTypes control_type); -    // resets current mode to defaults,  +    void resetToDefault(const std::string &control_name, U32 index); +    void resetToDefault(const std::string &control_name); +    // resets current mode to defaults      void resetToDefaults();      bool empty() { return mControlsMap.empty(); } @@ -188,15 +109,15 @@ public:      ESourceMode getLoadMode() { return mLoadMode; }  private: -    void resetToDefaultAndResolve(EControlTypes control_type, bool ignore_conflicts); +    void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts);      void resetToDefaults(ESourceMode mode);      // at the moment these kind of control is not savable, but takes part will take part in conflict resolution -    void registerTemporaryControl(EControlTypes control_type, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); +    void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); -    typedef std::map<EControlTypes, LLKeyConflict> control_map_t; +    typedef std::map<std::string, LLKeyConflict> control_map_t;      void loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination); -    void loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination); +    bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);      void resetKeyboardBindings();      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 diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index fb405fd225..4a06a2012f 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -650,6 +650,78 @@ bool start_gesture( EKeystate s )  	return true;  } +bool run_forward(EKeystate s) +{ +    if (KEYSTATE_DOWN == s) +    { +        gAgent.setAlwaysRun(); +        gAgent.setRunning(); +        gAgent.sendWalkRun(true); +    } +    else if(KEYSTATE_UP == s) +    { +        gAgent.clearAlwaysRun(); +        gAgent.clearRunning(); +        gAgent.sendWalkRun(false); +    } +    agent_push_forward(s); +    return true; +} + +bool run_backward(EKeystate s) +{ +    if (KEYSTATE_DOWN == s) +    { +        gAgent.setAlwaysRun(); +        gAgent.setRunning(); +        gAgent.sendWalkRun(true); +    } +    else if (KEYSTATE_UP == s) +    { +        gAgent.clearAlwaysRun(); +        gAgent.clearRunning(); +        gAgent.sendWalkRun(false); +    } +    agent_push_backward(s); +    return true; +} + +bool run_left(EKeystate s) +{ +    if (KEYSTATE_DOWN == s) +    { +        gAgent.setAlwaysRun(); +        gAgent.setRunning(); +        gAgent.sendWalkRun(true); +    } +    else if (KEYSTATE_UP == s) +    { +        gAgent.clearAlwaysRun(); +        gAgent.clearRunning(); +        gAgent.sendWalkRun(false); +    } +    agent_slide_left(s); +    return true; +} + +bool run_right(EKeystate s) +{ +    if (KEYSTATE_DOWN == s) +    { +        gAgent.setAlwaysRun(); +        gAgent.setRunning(); +        gAgent.sendWalkRun(true); +    } +    else if (KEYSTATE_UP == s) +    { +        gAgent.clearAlwaysRun(); +        gAgent.clearRunning(); +        gAgent.sendWalkRun(false); +    } +    agent_slide_right(s); +    return true; +} +  bool toggle_run(EKeystate s)  {      if (KEYSTATE_DOWN != s) return true; @@ -791,6 +863,10 @@ 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("run_forward", run_forward); +REGISTER_KEYBOARD_ACTION("run_backward", run_backward); +REGISTER_KEYBOARD_ACTION("run_left", run_left); +REGISTER_KEYBOARD_ACTION("run_right", run_right);  REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run);  REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit);  REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 28adc2b7ab..091fc720c1 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -971,6 +971,8 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m  		case CLICK_BUTTON5:  			buttonname = "Button 5";  			break; +		default: +			break; // COUNT and NONE  		}  		LLView::sMouseHandlerMessage.clear(); diff --git a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml index 62267dce8a..385d4796a0 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml @@ -10,6 +10,10 @@   top="1"   width="517">    <panel.string +   name="walk_to"> +    Walk to +  </panel.string> +  <panel.string     name="control_view_actions">      View Actions    </panel.string> @@ -70,8 +74,8 @@      Move Actions    </panel.string>    <panel.string -   name="control_moveto"> -    Move To +   name="teleport_to"> +    Teleport to    </panel.string>    <panel.string     name="toggle_sit"> @@ -119,6 +123,22 @@      Run    </panel.string>    <panel.string +   name="run_forward"> +    Run Forward +  </panel.string> +  <panel.string +   name="run_backward"> +    Run Backward +  </panel.string> +  <panel.string +   name="run_left"> +    Run Left +  </panel.string> +  <panel.string +   name="run_right"> +    Run Right +  </panel.string> +  <panel.string     name="toggle_run">      Toggle Run    </panel.string> @@ -127,6 +147,10 @@      Fly/Stop flying    </panel.string>    <panel.string +   name="stop_moving"> +    Stop Moving +  </panel.string> +  <panel.string     name="control_camera">      Camera    </panel.string> @@ -215,36 +239,13 @@      Play/Stop All Media    </panel.string>    <panel.string -   name="control_voice"> +   name="voice_follow_key">      Voice    </panel.string>    <panel.string -   name="control_toggle_voice"> +   name="toggle_voice">      Toggle Voice    </panel.string> -  <panel.string -   name="control_reserved"> -    Reserved Controls -  </panel.string> -  <panel.string -   name="control_delete"> -    Delete -  </panel.string> -  <!-- -   name="control_menu" not needed -   --> -  <panel.string -   name="control_reserved_select"> -    Select -  </panel.string> -  <panel.string -   name="control_shift_select"> -    Multi-Select -  </panel.string> -  <panel.string -   name="control_cntrl_select"> -    Add to Selection -  </panel.string>    <combo_box     follows="top|left"  | 
