summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/app_settings/settings.xml11
-rwxr-xr-xindra/newview/llfloaterpreference.cpp166
-rw-r--r--indra/newview/llfloaterpreference.h27
-rw-r--r--indra/newview/lltoolpie.cpp157
-rw-r--r--indra/newview/lltoolpie.h8
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_move.xml148
6 files changed, 384 insertions, 133 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8804c40aff..5ffbbc6163 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13564,6 +13564,17 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ClickToTeleport</key>
+ <map>
+ <key>Comment</key>
+ <string>Click in world to teleport to location</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
<integer>0</integer>
</map>
<key>ShowOfferedInventory</key>
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index d65928e385..5dd1cc3b97 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -304,7 +304,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mOriginalIMViaEmail(false),
mLanguageChanged(false),
mAvatarDataInitialized(false),
- mDoubleClickActionDirty(false)
+ mClickActionDirty(false)
{
//Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
@@ -348,8 +348,10 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
sSkin = gSavedSettings.getString("SkinCurrent");
- mCommitCallbackRegistrar.add("Pref.CommitDoubleClickChekbox", boost::bind(&LLFloaterPreference::onDoubleClickCheckBox, this, _1));
- mCommitCallbackRegistrar.add("Pref.CommitRadioDoubleClick", boost::bind(&LLFloaterPreference::onDoubleClickRadio, this));
+ mCommitCallbackRegistrar.add("Pref.CommitClickToWalkCheckbox", boost::bind(&LLFloaterPreference::onWalkCheckboxCommit, this));
+ mCommitCallbackRegistrar.add("Pref.CommitClickToTeleportCheckbox", boost::bind(&LLFloaterPreference::onTeleportCheckboxCommit, this));
+ mCommitCallbackRegistrar.add("Pref.CommitWalkTriggerRadio", boost::bind(&LLFloaterPreference::onWalkTriggerRadioCommit, this));
+ mCommitCallbackRegistrar.add("Pref.CommitTeleportTriggerRadio", boost::bind(&LLFloaterPreference::onTeleportTriggerRadioCommit, this));
gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
@@ -439,8 +441,6 @@ BOOL LLFloaterPreference::postBuild()
if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
tabcontainer->selectFirstTab();
- updateDoubleClickControls();
-
getChild<LLUICtrl>("cache_location")->setEnabled(FALSE); // make it read-only but selectable (STORM-227)
std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
setCacheLocation(cache_location);
@@ -581,10 +581,10 @@ void LLFloaterPreference::apply()
saveAvatarProperties();
- if (mDoubleClickActionDirty)
+ if (mClickActionDirty)
{
- updateDoubleClickSettings();
- mDoubleClickActionDirty = false;
+ updateClickActionSettings();
+ mClickActionDirty = false;
}
}
@@ -613,11 +613,12 @@ void LLFloaterPreference::cancel()
// reverts any changes to current skin
gSavedSettings.setString("SkinCurrent", sSkin);
- if (mDoubleClickActionDirty)
+ if (mClickActionDirty)
{
- updateDoubleClickControls();
- mDoubleClickActionDirty = false;
+ updateClickActionControls();
+ mClickActionDirty = false;
}
+
LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
if (advanced_proxy_settings)
{
@@ -681,6 +682,9 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// Display selected maturity icons.
onChangeMaturity();
+
+ // Load (double-)click to walk/teleport settings.
+ updateClickActionControls();
// Enabled/disabled popups, might have been changed by user actions
// while preferences floater was closed.
@@ -1503,72 +1507,116 @@ void LLFloaterPreference::onClickBlockList()
}
}
-void LLFloaterPreference::onDoubleClickCheckBox(LLUICtrl* ctrl)
+void LLFloaterPreference::onClickProxySettings()
{
- if (!ctrl) return;
- mDoubleClickActionDirty = true;
- LLRadioGroup* radio_double_click_action = getChild<LLRadioGroup>("double_click_action");
- if (!radio_double_click_action) return;
- // select default value("teleport") in radio-group.
- radio_double_click_action->setSelectedIndex(0);
- // set radio-group enabled depending on state of checkbox
- radio_double_click_action->setEnabled(ctrl->getValue());
+ LLFloaterReg::showInstance("prefs_proxy");
}
-void LLFloaterPreference::onDoubleClickRadio()
+void LLFloaterPreference::onWalkCheckboxCommit()
{
- mDoubleClickActionDirty = true;
+ LLCheckBoxCtrl* walk_trigger_cb = getChild<LLCheckBoxCtrl>("walk_to_chkbox");
+ LLRadioGroup* walk_trigger_radio = getChild<LLRadioGroup>("walk_trigger_radio");
+ const bool checked = walk_trigger_cb->getValue().asBoolean();
+
+ mClickActionDirty = true;
+ walk_trigger_radio->setEnabled(checked);
+ if (checked)
+ {
+ fixWalkRadioValue(); // don't allow two actions on click or double click
+ }
}
-void LLFloaterPreference::updateDoubleClickSettings()
+void LLFloaterPreference::onTeleportCheckboxCommit()
{
- LLCheckBoxCtrl* double_click_action_cb = getChild<LLCheckBoxCtrl>("double_click_chkbox");
- if (!double_click_action_cb) return;
- bool enable = double_click_action_cb->getValue().asBoolean();
+ LLCheckBoxCtrl* teleport_trigger_cb = getChild<LLCheckBoxCtrl>("teleport_to_chkbox");
+ LLRadioGroup* teleport_trigger_radio = getChild<LLRadioGroup>("teleport_trigger_radio");
+ const bool checked = teleport_trigger_cb->getValue().asBoolean();
- LLRadioGroup* radio_double_click_action = getChild<LLRadioGroup>("double_click_action");
- if (!radio_double_click_action) return;
-
- // enable double click radio-group depending on state of checkbox
- radio_double_click_action->setEnabled(enable);
-
- if (!enable)
+ mClickActionDirty = true;
+ teleport_trigger_radio->setEnabled(checked);
+ if (checked)
{
- // set double click action settings values to false if checkbox was unchecked
- gSavedSettings.setBOOL("DoubleClickAutoPilot", false);
- gSavedSettings.setBOOL("DoubleClickTeleport", false);
- }
- else
- {
- std::string selected = radio_double_click_action->getValue().asString();
- bool teleport_selected = selected == "radio_teleport";
- // set double click action settings values depending on chosen radio-button
- gSavedSettings.setBOOL( "DoubleClickTeleport", teleport_selected );
- gSavedSettings.setBOOL( "DoubleClickAutoPilot", !teleport_selected );
+ fixTeleportRadioValue(); // don't allow two actions on click or double click
}
}
-void LLFloaterPreference::onClickProxySettings()
+void LLFloaterPreference::onWalkTriggerRadioCommit()
{
- LLFloaterReg::showInstance("prefs_proxy");
+ mClickActionDirty = true;
+ fixTeleportRadioValue();
+}
+
+void LLFloaterPreference::onTeleportTriggerRadioCommit()
+{
+ mClickActionDirty = true;
+ fixWalkRadioValue();
+}
+
+void LLFloaterPreference::fixWalkRadioValue()
+{
+ LLRadioGroup* walk_trigger_radio = getChild<LLRadioGroup>("walk_trigger_radio");
+ LLRadioGroup* teleport_trigger_radio = getChild<LLRadioGroup>("teleport_trigger_radio");
+
+ walk_trigger_radio->setSelectedIndex(!teleport_trigger_radio->getSelectedIndex());
+}
+
+
+void LLFloaterPreference::fixTeleportRadioValue()
+{
+ LLRadioGroup* walk_trigger_radio = getChild<LLRadioGroup>("walk_trigger_radio");
+ LLRadioGroup* teleport_trigger_radio = getChild<LLRadioGroup>("teleport_trigger_radio");
+
+ teleport_trigger_radio->setSelectedIndex(!walk_trigger_radio->getSelectedIndex());
+}
+
+void LLFloaterPreference::updateClickActionSettings()
+{
+ const bool walk_trigger_enabled = getChild<LLCheckBoxCtrl>("walk_to_chkbox")->getValue().asBoolean();
+ const bool teleport_trigger_enabled = getChild<LLCheckBoxCtrl>("teleport_to_chkbox")->getValue().asBoolean();
+
+ const bool walk_on_dbl_click = (bool) getChild<LLRadioGroup>("walk_trigger_radio")->getSelectedIndex();
+ const bool teleport_on_dbl_click = (bool) getChild<LLRadioGroup>("teleport_trigger_radio")->getSelectedIndex();
+
+ gSavedSettings.setBOOL("ClickToWalk", walk_trigger_enabled && !walk_on_dbl_click);
+ gSavedSettings.setBOOL("ClickToTeleport", teleport_trigger_enabled && !teleport_on_dbl_click);
+ gSavedSettings.setBOOL("DoubleClickAutoPilot", walk_trigger_enabled && walk_on_dbl_click);
+ gSavedSettings.setBOOL("DoubleClickTeleport", teleport_trigger_enabled && teleport_on_dbl_click);
}
-void LLFloaterPreference::updateDoubleClickControls()
+void LLFloaterPreference::updateClickActionControls()
{
- // check is one of double-click actions settings enabled
- bool double_click_action_enabled = gSavedSettings.getBOOL("DoubleClickAutoPilot") || gSavedSettings.getBOOL("DoubleClickTeleport");
- LLCheckBoxCtrl* double_click_action_cb = getChild<LLCheckBoxCtrl>("double_click_chkbox");
- if (double_click_action_cb)
+ LLCheckBoxCtrl* walk_trigger_cb = getChild<LLCheckBoxCtrl>("walk_to_chkbox");
+ LLCheckBoxCtrl* teleport_trigger_cb = getChild<LLCheckBoxCtrl>("teleport_to_chkbox");
+
+ LLRadioGroup* walk_trigger_radio = getChild<LLRadioGroup>("walk_trigger_radio");
+ LLRadioGroup* teleport_trigger_radio = getChild<LLRadioGroup>("teleport_trigger_radio");
+
+ const bool click_to_walk = gSavedSettings.getBOOL("ClickToWalk");
+ const bool click_to_teleport = gSavedSettings.getBOOL("ClickToTeleport");
+ const bool dbl_click_to_walk = gSavedSettings.getBOOL("DoubleClickAutoPilot");
+ const bool dbl_click_to_teleport = gSavedSettings.getBOOL("DoubleClickTeleport");
+
+ const bool walk_trigger_enabled = click_to_walk || dbl_click_to_walk;
+ const bool teleport_trigger_enabled = click_to_teleport || dbl_click_to_teleport;
+
+ walk_trigger_cb->setValue(walk_trigger_enabled);
+ teleport_trigger_cb->setValue(teleport_trigger_enabled);
+
+ walk_trigger_radio->setEnabled(walk_trigger_enabled);
+ walk_trigger_radio->setSelectedIndex(dbl_click_to_walk);
+
+ teleport_trigger_radio->setEnabled(teleport_trigger_enabled);
+ teleport_trigger_radio->setSelectedIndex(dbl_click_to_teleport);
+
+ // Make sure it doesn't look like there is more than one action per trigger.
+ if (teleport_trigger_enabled)
+ {
+ fixWalkRadioValue();
+ }
+ else
{
- // check checkbox if one of double-click actions settings enabled, uncheck otherwise
- double_click_action_cb->setValue(double_click_action_enabled);
+ fixTeleportRadioValue();
}
- LLRadioGroup* double_click_action_radio = getChild<LLRadioGroup>("double_click_action");
- if (!double_click_action_radio) return;
- // set radio-group enabled if one of double-click actions settings enabled
- double_click_action_radio->setEnabled(double_click_action_enabled);
- // select button in radio-group depending on setting
- double_click_action_radio->setSelectedIndex(gSavedSettings.getBOOL("DoubleClickAutoPilot"));
}
void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ef9bc2dd53..b7263f0ac3 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -104,14 +104,23 @@ protected:
void setHardwareDefaults();
// callback for when client turns on shaders
void onVertexShaderEnable();
- // callback for changing double click action checkbox
- void onDoubleClickCheckBox(LLUICtrl* ctrl);
- // callback for selecting double click action radio-button
- void onDoubleClickRadio();
- // updates double-click action settings depending on controls from preferences
- void updateDoubleClickSettings();
- // updates double-click action controls depending on values from settings.xml
- void updateDoubleClickControls();
+
+ // callback for clicking the "Walk to Click Point" checkbox
+ void onWalkCheckboxCommit();
+ // callback for clicking the "Teleport to Click Point" checkbox
+ void onTeleportCheckboxCommit();
+ // callback for selecting trigger for "Walk to Click Point"
+ void onWalkTriggerRadioCommit();
+ // callback for selecting trigger for "Teleport to Click Point"
+ void onTeleportTriggerRadioCommit();
+ // make sure the radio buttons have mutually exclusive values
+ void fixWalkRadioValue();
+ // make sure the radio buttons have mutually exclusive values
+ void fixTeleportRadioValue();
+ // updates click/double-click action settings depending on controls values
+ void updateClickActionSettings();
+ // updates click/double-click action controls depending on values from settings.xml
+ void updateClickActionControls();
// This function squirrels away the current values of the controls so that
// cancel() can restore them.
@@ -166,7 +175,7 @@ private:
static std::string sSkin;
// set true if state of double-click action checkbox or radio-group was changed by user
// (reset back to false on apply or cancel)
- bool mDoubleClickActionDirty;
+ bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
bool mGotPersonalInfo;
bool mOriginalIMViaEmail;
bool mLanguageChanged;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index c38c8bad80..e614fe23d0 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -35,7 +35,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llavatarnamecache.h"
-#include "llviewercontrol.h"
+#include "lleventtimer.h"
#include "llfocusmgr.h"
#include "llfirstuse.h"
#include "llfloaterland.h"
@@ -57,6 +57,7 @@
#include "lltrans.h"
#include "llviewercamera.h"
#include "llviewerparcelmedia.h"
+#include "llviewercontrol.h"
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerobject.h"
@@ -76,6 +77,41 @@ static void handle_click_action_play();
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
static ECursorType cursor_from_parcel_media(U8 click_action);
+/**
+ * Schedule teleport to the specified location when user clicks in world.
+ *
+ * Deferring teleport is needed for double-click-to-walk to work.
+ * If double click in the world view occurs, teleport gets canceled.
+ */
+class LLClickToTeleportTimer : public LLEventTimer
+{
+ LOG_CLASS(LLClickToTeleportTimer);
+public:
+ LLClickToTeleportTimer(const LLVector3d& pos);
+ ~LLClickToTeleportTimer();
+ /*virtual*/ BOOL tick();
+
+private:
+ LLVector3d mTeleportPos;
+};
+
+LLClickToTeleportTimer::LLClickToTeleportTimer(const LLVector3d& pos)
+: LLEventTimer(0.33) // should be greater than double click interval
+, mTeleportPos(pos)
+{
+};
+
+LLClickToTeleportTimer::~LLClickToTeleportTimer()
+{
+ LLToolPie::instance().mClickToTeleportTimer = NULL;
+}
+
+BOOL LLClickToTeleportTimer::tick()
+{
+ lldebugs << "Teleporting to " << mTeleportPos << llendl;
+ gAgent.teleportViaLocationLookAt(mTeleportPos);
+ return TRUE; // destroy the timer
+}
LLToolPie::LLToolPie()
: LLTool(std::string("Pie")),
@@ -84,6 +120,8 @@ LLToolPie::LLToolPie()
mMouseSteerX(-1),
mMouseSteerY(-1),
mBlockClickToWalk(false),
+ mBlockClickToTeleport(false),
+ mClickToTeleportTimer(NULL),
mClickAction(0),
mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") )
@@ -479,6 +517,18 @@ void LLToolPie::resetSelection()
mClickAction = 0;
}
+void LLToolPie::walkToClickedLocation()
+{
+ if(mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
+ mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
+ mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
+ mAutoPilotDestination->setPixelSize(5);
+ mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
+ mAutoPilotDestination->setDuration(3.f);
+
+ handle_go_to();
+}
+
// When we get object properties after left-clicking on an object
// with left-click = buy, if it's the same object, do the buy.
@@ -637,44 +687,64 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
mMouseButtonDown = false;
if (click_action == CLICK_ACTION_NONE // not doing 1-click action
- && gSavedSettings.getBOOL("ClickToWalk") // click to walk enabled
&& !gAgent.getFlying() // don't auto-navigate while flying until that works
&& gAgentAvatarp
&& !gAgentAvatarp->isSitting()
- && !mBlockClickToWalk // another behavior hasn't cancelled click to walk
&& !mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
&& (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land
|| mPick.mObjectID.notNull())) // or on an object
{
- // handle special cases of steering picks
- LLViewerObject* avatar_object = mPick.getObject();
-
- // get pointer to avatar
- while (avatar_object && !avatar_object->isAvatar())
+ if (gSavedSettings.getBOOL("ClickToWalk")
+ && !mBlockClickToWalk) // another behavior hasn't cancelled click to walk
{
- avatar_object = (LLViewerObject*)avatar_object->getParent();
- }
+ // handle special cases of steering picks
+ LLViewerObject* avatar_object = mPick.getObject();
- if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
- {
- const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
- // pretend we picked some point a bit in front of avatar
- mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
+ // get pointer to avatar
+ while (avatar_object && !avatar_object->isAvatar())
+ {
+ avatar_object = (LLViewerObject*)avatar_object->getParent();
+ }
+
+ if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
+ {
+ const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
+ // pretend we picked some point a bit in front of avatar
+ mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
+ }
+ gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
+ walkToClickedLocation();
+ LLFirstUse::notMoving(false);
+
+ return TRUE;
}
- gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
- if(mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
- mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
- mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
- mAutoPilotDestination->setPixelSize(5);
- mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
- mAutoPilotDestination->setDuration(3.f);
+ else if (gSavedSettings.getBOOL("ClickToTeleport") && !mBlockClickToTeleport)
+ {
+ LLViewerObject* objp = mPick.getObject();
+ LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
- handle_go_to();
- LLFirstUse::notMoving(false);
+ bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
+ bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND;
+ bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
+ bool has_click_action = final_click_action(objp);
- mBlockClickToWalk = false;
+ if (is_land || (is_in_world && !has_touch_handler && !has_click_action))
+ {
+ LLVector3d pos = mPick.mPosGlobal;
+ pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
- return TRUE;
+ if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
+ {
+ // defer for more than the double click interval.
+ scheduleTeleport(pos);
+ }
+ else
+ {
+ gAgent.teleportViaLocationLookAt(pos);
+ }
+ return TRUE;
+ }
+ }
}
gViewerWindow->setCursor(UI_CURSOR_ARROW);
if (hasMouseCapture())
@@ -686,6 +756,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
mBlockClickToWalk = false;
+ mBlockClickToTeleport = false;
return LLTool::handleMouseUp(x, y, mask);
}
@@ -706,18 +777,17 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
llinfos << "LLToolPie handleDoubleClick (becoming mouseDown)" << llendl;
}
+ cancelScheduledTeleport();
+
if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
{
- if (mPick.mPickType == LLPickInfo::PICK_LAND
- && !mPick.mPosGlobal.isExactlyZero())
- {
- handle_go_to();
- return TRUE;
- }
- else if (mPick.mObjectID.notNull()
- && !mPick.mPosGlobal.isExactlyZero())
+ // Avoid teleporting for the second time when user releases mouse button after double click.
+ mBlockClickToTeleport = true;
+
+ if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
+ (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()))
{
- handle_go_to();
+ walkToClickedLocation();
return TRUE;
}
}
@@ -1373,6 +1443,23 @@ bool LLToolPie::inCameraSteerMode()
return mMouseButtonDown && mMouseOutsideSlop && gSavedSettings.getBOOL("ClickToWalk");
}
+void LLToolPie::scheduleTeleport(const LLVector3d& pos)
+{
+ // cancel previously scheduled teleport (if any)
+ cancelScheduledTeleport();
+
+ // and schedule new one
+ mClickToTeleportTimer = new LLClickToTeleportTimer(pos);
+}
+
+void LLToolPie::cancelScheduledTeleport()
+{
+ if (mClickToTeleportTimer)
+ {
+ delete mClickToTeleportTimer;
+ }
+}
+
// true if x,y outside small box around start_x,start_y
BOOL LLToolPie::outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y)
{
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index d7c79ee223..7e84170549 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -32,6 +32,7 @@
#include "llviewerwindow.h" // for LLPickInfo
#include "llhudeffectblob.h" // for LLPointer<LLHudEffectBlob>, apparently
+class LLClickToTeleportTimer;
class LLViewerObject;
class LLObjectSelection;
@@ -66,6 +67,7 @@ public:
LLViewerObject* getClickActionObject() { return mClickActionObject; }
LLObjectSelection* getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; }
void resetSelection();
+ void walkToClickedLocation();
void blockClickToWalk() { mBlockClickToWalk = true; }
void stopClickToWalk();
@@ -96,8 +98,12 @@ private:
void startCameraSteering();
void stopCameraSteering();
bool inCameraSteerMode();
+ void scheduleTeleport(const LLVector3d& pos);
+ void cancelScheduledTeleport();
private:
+ friend class LLClickToTeleportTimer;
+
bool mMouseButtonDown;
bool mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
S32 mMouseDownX;
@@ -108,6 +114,8 @@ private:
LLPointer<LLHUDEffectBlob> mMouseSteerGrabPoint;
bool mClockwise;
bool mBlockClickToWalk;
+ bool mBlockClickToTeleport;
+ LLClickToTeleportTimer* mClickToTeleportTimer;
LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;
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 1a8aae7f91..5a70acddeb 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -105,16 +105,61 @@
mouse_opaque="false"
visible="true"
width="18"
- top_pad="2"
+ top_pad="10"
left="30" />
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="78"
+ name="keyboard_lbl"
+ width="270"
+ top_delta="2">
+ Keyboard:
+ </text>
+ <check_box
+ control_name="ArrowKeysAlwaysMove"
+ follows="left|top"
+ height="20"
+ label="Arrow keys always move me"
+ layout="topleft"
+ left_delta="5"
+ name="arrow_keys_move_avatar_check"
+ width="237"
+ top_pad="5"/>
+ <check_box
+ control_name="AllowTapTapHoldRun"
+ follows="left|top"
+ height="20"
+ label="Tap-tap-hold to run"
+ layout="topleft"
+ left_delta="0"
+ name="tap_tap_hold_to_run"
+ width="237"
+ top_pad="0"/>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="78"
+ name="mouse_lbl"
+ width="270"
+ top_pad="15">
+ Mouse:
+ </text>
<check_box
control_name="FirstPersonAvatarVisible"
follows="left|top"
height="20"
label="Show me in Mouselook"
layout="topleft"
- left_pad="30"
+ left_delta="5"
name="first_person_avatar_visible"
+ top_pad="5"
width="256" />
<text
type="string"
@@ -136,7 +181,7 @@
initial_value="2"
layout="topleft"
show_text="false"
- left_pad="5"
+ left_pad="0"
max_val="15"
name="mouse_sensitivity"
top_delta="-1"
@@ -150,62 +195,105 @@
name="invert_mouse"
top_delta="0"
width="128" />
- <check_box
- control_name="ArrowKeysAlwaysMove"
+ <text
follows="left|top"
- height="20"
- label="Arrow keys always move me"
+ type="string"
+ length="1"
+ height="10"
layout="topleft"
- left="78"
- name="arrow_keys_move_avatar_check"
- width="237"
- top_pad="10"/>
+ left="259"
+ name="single_click_lbl"
+ width="100"
+ top_pad="10">
+ Single-Click
+ </text>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="368"
+ name="double_click_lbl"
+ width="100"
+ top_delta="0">
+ Double-Click
+ </text>
<check_box
- control_name="AllowTapTapHoldRun"
follows="left|top"
height="20"
- label="Tap-tap-hold to run"
+ label="Walk to Click Point:"
layout="topleft"
- left_delta="0"
- name="tap_tap_hold_to_run"
+ left="83"
+ name="walk_to_chkbox"
width="237"
- top_pad="0"/>
+ top_pad="7">
+ <check_box.commit_callback
+ function="Pref.CommitClickToWalkCheckbox"/>
+ </check_box>
+ <radio_group
+ height="20"
+ layout="topleft"
+ left="280"
+ top_delta="3"
+ name="walk_trigger_radio"
+ width="200">
+ <radio_item
+ height="16"
+ label=""
+ layout="topleft"
+ left="0"
+ name="walk_single_click"
+ top_delta="20"
+ width="110" />
+ <radio_item
+ height="16"
+ label=""
+ left_pad="0"
+ layout="topleft"
+ name="walk_double_click"
+ top_delta="0"
+ width="75" />
+ <radio_group.commit_callback
+ function="Pref.CommitWalkTriggerRadio"/>
+ </radio_group>
<check_box
follows="left|top"
height="20"
- label="Double-Click to:"
+ label="Teleport to Click Point:"
layout="topleft"
- left_delta="0"
- name="double_click_chkbox"
+ left="83"
+ name="teleport_to_chkbox"
width="237"
top_pad="0">
<check_box.commit_callback
- function="Pref.CommitDoubleClickChekbox"/>
+ function="Pref.CommitClickToTeleportCheckbox"/>
</check_box>
<radio_group
- height="20"
- layout="topleft"
- left_delta="17"
- top_pad="2"
- name="double_click_action">
+ height="20"
+ layout="topleft"
+ left="280"
+ top_delta="3"
+ name="teleport_trigger_radio"
+ width="200">
<radio_item
height="16"
- label="Teleport"
+ label=""
layout="topleft"
left="0"
- name="radio_teleport"
+ name="teleport_single_click"
top_delta="20"
width="110" />
<radio_item
height="16"
- label="Auto-pilot"
+ label=""
left_pad="0"
layout="topleft"
- name="radio_autopilot"
+ name="teleport_double_click"
top_delta="0"
width="75" />
<radio_group.commit_callback
- function="Pref.CommitRadioDoubleClick"/>
+ function="Pref.CommitTeleportTriggerRadio"/>
</radio_group>
<button
height="23"