diff options
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rwxr-xr-x | indra/newview/llfloaterpreference.cpp | 166 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.h | 27 | ||||
-rw-r--r-- | indra/newview/lltoolpie.cpp | 157 | ||||
-rw-r--r-- | indra/newview/lltoolpie.h | 8 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_move.xml | 148 |
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" |