summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-06-15 20:35:58 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-06-23 14:51:30 +0300
commite578491be761fefa34e4041458e2cf5badc81873 (patch)
tree46402c1ee9af1d11352a3277a3f094394821a9cb
parent6092e2ffab9ec76bdd8821e188db9cb785456eee (diff)
SL-13418 Restored previously removed 'click on land' controls from 'move & view'
According to UX UI engineer. Also adapted it to new system, but it needs a better solution.
-rw-r--r--indra/newview/llfloaterpreference.cpp212
-rw-r--r--indra/newview/llfloaterpreference.h22
-rw-r--r--indra/newview/llkeyconflict.cpp16
-rw-r--r--indra/newview/llkeyconflict.h5
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_move.xml64
5 files changed, 312 insertions, 7 deletions
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 604f054aa5..ac2b0172c7 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -311,6 +311,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
sSkin = gSavedSettings.getString("SkinCurrent");
+ mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
+
gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
@@ -609,6 +611,8 @@ void LLFloaterPreference::cancel()
// reverts any changes to current skin
gSavedSettings.setString("SkinCurrent", sSkin);
+ updateClickActionViews();
+
LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
if (advanced_proxy_settings)
{
@@ -690,6 +694,9 @@ void LLFloaterPreference::onOpen(const LLSD& key)
onChangeTextureFolder();
onChangeSoundFolder();
onChangeAnimationFolder();
+
+ // Load (double-)click to walk/teleport settings.
+ updateClickActionViews();
// Enabled/disabled popups, might have been changed by user actions
// while preferences floater was closed.
@@ -1486,6 +1493,7 @@ void LLFloaterPreference::refresh()
{
advanced->refresh();
}
+ updateClickActionViews();
}
void LLFloaterPreferenceGraphicsAdvanced::refresh()
@@ -1995,6 +2003,11 @@ void LLFloaterPreference::onClickAdvanced()
}
}
+void LLFloaterPreference::onClickActionChange()
+{
+ updateClickActionControls();
+}
+
void LLFloaterPreference::onClickPermsDefault()
{
LLFloaterReg::showInstance("perms_default");
@@ -2032,6 +2045,86 @@ void LLFloaterPreference::onLogChatHistorySaved()
}
}
+void LLFloaterPreference::updateClickActionControls()
+{
+ const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
+ const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ // Potential option: make constructor of LLKeyConflictHandler private
+ // but add a getter that will return shared pointer for specific
+ // mode, pointer should only exist so long as there are external users.
+ // In such case we won't need to do this 'dynamic_cast' nightmare.
+ // updateTable() can also be avoided
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE,
+ single_clk_action == 1);
+
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 1);
+
+ panel->setKeyBind("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 2);
+
+ panel->updateTable();
+ }
+ }
+}
+
+void LLFloaterPreference::updateClickActionViews()
+{
+ bool click_to_walk = false;
+ bool dbl_click_to_walk = false;
+ bool dbl_click_to_teleport = false;
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_teleport = panel->canKeyBindHandle("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+ }
+ }
+
+ getChild<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
+ getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
+}
+
void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
{
LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
@@ -2856,7 +2949,7 @@ void LLPanelPreferenceControls::saveSettings()
}
S32 mode = pKeyModeBox->getValue().asInteger();
- if (mConflictHandler[mode].empty())
+ if (mConflictHandler[mode].empty() || pControlsTable->isEmpty())
{
regenerateControls();
}
@@ -2951,6 +3044,13 @@ void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notificati
mConflictHandler[i].resetToDefaults();
// Apply changes to viewer as 'temporary'
mConflictHandler[i].saveToSettings(true);
+
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
}
updateTable();
@@ -2960,6 +3060,16 @@ void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notificati
// Apply changes to viewer as 'temporary'
mConflictHandler[mEditingMode].saveToSettings(true);
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
updateTable();
break;
case 2: // Cancel
@@ -2969,7 +3079,80 @@ void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notificati
}
}
-// todo: copy onSetKeyBind to interface and inherit from interface
+// Bypass to let Move & view read values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+bool LLPanelPreferenceControls::canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ return mConflictHandler[mode].canHandleControl(control, click, key, mask);
+}
+
+// Bypass to let Move & view modify values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+void LLPanelPreferenceControls::setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ if (!mConflictHandler[mode].canAssignControl(mEditingControl))
+ {
+ return;
+ }
+
+ bool already_recorded = mConflictHandler[mode].canHandleControl(control, click, key, mask);
+ if (set)
+ {
+ if (already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find free spot to add data, if no free spot, assign to first
+ S32 index = 0;
+ for (S32 i = 0; i < 3; i++)
+ {
+ if (mConflictHandler[mode].getControl(control, i).isEmpty())
+ {
+ index = i;
+ break;
+ }
+ }
+ mConflictHandler[mode].registerControl(control, index, click, key, mask, true);
+ }
+ else if (!set)
+ {
+ if (!already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find specific control and reset it
+ for (S32 i = 0; i < 3; i++)
+ {
+ LLKeyData data = mConflictHandler[mode].getControl(control, i);
+ if (data.mMouse == click && data.mKey == key && data.mMask == mask)
+ {
+ mConflictHandler[mode].clearControl(control, i);
+ }
+ }
+ }
+}
+
+// from LLSetKeybindDialog's interface
bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
{
if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
@@ -3001,6 +3184,21 @@ bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MAS
}
updateTable();
+
+ if ((mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ && (mEditingControl == "walk_to"
+ || mEditingControl == "teleport_to"
+ || click == CLICK_LEFT
+ || click == CLICK_DOUBLELEFT))
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
return true;
}
@@ -3034,6 +3232,16 @@ void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes)
}
}
updateTable();
+
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
}
void LLPanelPreferenceControls::onCancelKeyBind()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ea6e1070cd..066deb97ee 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -106,6 +106,8 @@ public:
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
+ // updates click/double-click action controls depending on values from settings.xml
+ void updateClickActionViews();
protected:
void onBtnOK(const LLSD& userdata);
@@ -131,6 +133,11 @@ protected:
// callback for when client turns on impostors
void onAvatarImpostorsEnable();
+ // callback for commit in the "Single click on land" and "Double click on land" comboboxes.
+ void onClickActionChange();
+ // updates click/double-click action keybindngs depending on view values
+ void updateClickActionControls();
+
public:
// This function squirrels away the current values of the controls so that
// cancel() can restore them.
@@ -304,9 +311,20 @@ public:
void onModeCommit();
void onRestoreDefaultsBtn();
void onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response);
+
+ // Bypass to let Move & view read values without need to create own key binding handler
+ // Todo: consider a better way to share access to keybindings
+ bool canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask);
+ // Bypasses to let Move & view modify values without need to create own key binding handler
+ void setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set /*set or reset*/ );
+
+ // from interface
/*virtual*/ bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes);
/*virtual*/ void onDefaultKeyBind(bool all_modes);
- /*virtual*/ void onCancelKeyBind();
+ /*virtual*/ void onCancelKeyBind();
+
+ // Updates keybindings from storage to table
+ void updateTable();
private:
// reloads settings, discards current changes, updates table
@@ -319,8 +337,6 @@ private:
// Cleans content and then adds content from xml files according to current mEditingMode
void populateControlTable();
- // Updates keybindings from storage to table
- void updateTable();
LLScrollListCtrl* pControlsTable;
LLComboBox *pKeyModeBox;
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index 5f966624ca..b426dc14fc 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -217,6 +217,22 @@ bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32
return false;
}
+bool LLKeyConflictHandler::clearControl(const std::string &control_name, U32 data_index)
+{
+ if (control_name.empty())
+ {
+ return false;
+ }
+ LLKeyConflict &type_data = mControlsMap[control_name];
+ if (!type_data.mAssignable)
+ {
+ // Example: user tried to assign camera spin to all modes, but first person mode doesn't support it
+ return false;
+ }
+ type_data.mKeyBind.resetKeyData(data_index);
+ return true;
+}
+
LLKeyData LLKeyConflictHandler::getControl(const std::string &control_name, U32 index)
{
if (control_name.empty())
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
index 5451c16ae2..7566303cdd 100644
--- a/indra/newview/llkeyconflict.h
+++ b/indra/newview/llkeyconflict.h
@@ -86,8 +86,8 @@ public:
// @control_name - see REGISTER_KEYBOARD_ACTION in llviewerinput for avaliable options,
// usually this is just name of the function
// @data_index - single control (function) can have multiple key combinations trigering
- // it, this index indicates combination function will change/add note that preferences
- // floater can only display up to 3 options, but data_index can be bigger then that
+ // it, this index indicates combination function will change/add; Note that preferences
+ // floater can only display up to 3 options, but data_index can be bigger than that
// @mouse_ind - mouse action (middle click, MB5 etc)
// @key - keyboard key action
// @mask - shift/ctrl/alt flags
@@ -95,6 +95,7 @@ public:
// is active) or ignore not expected masks as long as expected mask is present
// (ctrl+K will be triggered if ctrl+shift+K is active)
bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts?
+ bool clearControl(const std::string &control_name, U32 data_index);
LLKeyData getControl(const std::string &control_name, U32 data_index);
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
index d106456b31..8794e3bf95 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -195,6 +195,70 @@
name="invert_mouse"
top_delta="0"
width="128" />
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="single_click_action_lbl"
+ width="150"
+ top_pad="20">
+ Single click on land:
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="single_click_action_combo"
+ width="200">
+ <combo_box.item
+ label="No action"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Move to clicked point"
+ name="1"
+ value="1"/>
+ <combo_box.commit_callback
+ function="Pref.ClickActionChange"/>
+ </combo_box>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="double_click_action_lbl"
+ width="150"
+ top_pad="12">
+ Double click on land:
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="double_click_action_combo"
+ width="200">
+ <combo_box.item
+ label="No action"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Move to clicked point"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Teleport to clicked point"
+ name="2"
+ value="2"/>
+ <combo_box.commit_callback
+ function="Pref.ClickActionChange"/>
+ </combo_box>
<button
height="23"
label="Other Devices"