diff options
Diffstat (limited to 'indra/newview')
59 files changed, 435 insertions, 273 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f0e28d4ae3..04045585a0 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3210,14 +3210,14 @@ <map> <key>Comment</key> <string>Specifies that you have not logged in with the viewer since you performed a clean install</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstSelectedDisabledPopups</key> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FirstSelectedDisabledPopups</key> <map> <key>Comment</key> <string>Return false if there is not disabled popup selected in the list of floater preferences popups</string> @@ -12597,5 +12597,27 @@ <key>Value</key> <integer>1</integer> </map> + <key>GenericErrorPageURL</key> + <map> + <key>Comment</key> + <string>URL to set as a property on LLMediaControl to navigate to if the a page completes with a 400-499 HTTP status code</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/agni/404.html</string> + </map> + <key>DestinationsAndAvatarsVisibility</key> + <map> + <key>Comment</key> + <string>Whether destination panel or avatar picker are open (0=destination guide, 1=avatar picker, default=nothing)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml index 03656f2a53..490da2c9d4 100644 --- a/indra/newview/app_settings/settings_minimal.xml +++ b/indra/newview/app_settings/settings_minimal.xml @@ -61,7 +61,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/damballah/howto/index.html?topic=[TOPIC]</string> + <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/agni/howto/index.html?topic=[TOPIC]</string> </map> <key>PreferredMaturity</key> <map> @@ -345,7 +345,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/damballah/guide.html</string> + <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/agni/guide.html</string> </map> <key>AvatarPickerURL</key> <map> @@ -356,7 +356,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/damballah/avatars.html</string> + <string>http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/agni/avatars.html</string> </map> <key>LogInventoryDecline</key> <map> diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index d520debc31..e6f1c04675 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -64,7 +64,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const params.append(event_data["x"]); params.append(event_data["y"]); params.append(event_data["z"]); - LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true); + LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true); // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" // should we just compose LLCommandHandler and LLDispatchListener? } @@ -74,7 +74,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const LLVector3(event_data["x"].asReal(), event_data["y"].asReal(), event_data["z"].asReal())).getSLURLString(); - LLURLDispatcher::dispatch(url, NULL, false); + LLURLDispatcher::dispatch(url, "clicked", NULL, false); } } diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 898cc1c0ba..523c2e3adf 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -233,7 +233,7 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ std::string url = slurl; LLMediaCtrl* web = NULL; const bool trusted_browser = false; - if (LLURLDispatcher::dispatch(url, web, trusted_browser)) + if (LLURLDispatcher::dispatch(url, "", web, trusted_browser)) { // bring window to foreground, as it has just been "launched" from a URL // todo: hmm, how to get there from here? diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 1cd80986d8..c2916717bd 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -500,7 +500,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) LLMediaCtrl* web = NULL; const bool trusted_browser = false; - LLURLDispatcher::dispatch(url, web, trusted_browser); + LLURLDispatcher::dispatch(url, "", web, trusted_browser); } return(result); diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp index 5744d055a9..586f45fd8f 100644 --- a/indra/newview/llcommanddispatcherlistener.cpp +++ b/indra/newview/llcommanddispatcherlistener.cpp @@ -65,7 +65,7 @@ void LLCommandDispatcherListener::dispatch(const LLSD& params) const trusted_browser = params["trusted"].asBoolean(); } LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL, - trusted_browser); + "clicked", trusted_browser); } void LLCommandDispatcherListener::enumerate(const LLSD& params) const diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 1b6ba02aac..bb1fb41fae 100755 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -35,7 +35,7 @@ // system includes #include <boost/tokenizer.hpp> -#define THROTTLE_PERIOD 5 // required secs between throttled commands +#define THROTTLE_PERIOD 20 // required secs between throttled commands static LLCommandDispatcherListener sCommandDispatcherListener; @@ -59,6 +59,7 @@ public: const LLSD& params, const LLSD& query_map, LLMediaCtrl* web, + const std::string& nav_type, bool trusted_browser); private: @@ -91,6 +92,7 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, LLMediaCtrl* web, + const std::string& nav_type, bool trusted_browser) { static bool slurl_blocked = false; @@ -120,6 +122,14 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, return true; case LLCommandHandler::UNTRUSTED_THROTTLE: + // if users actually click on a link, we don't need to throttle it + // (throttling mechanism is used to prevent an avalanche of clicks via + // javascript + if ( nav_type == "clicked" ) + { + break; + } + cur_time = LLTimer::getElapsedSeconds(); if (cur_time < last_throttle_time + THROTTLE_PERIOD) { @@ -166,10 +176,11 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, LLMediaCtrl* web, + const std::string& nav_type, bool trusted_browser) { return LLCommandHandlerRegistry::instance().dispatch( - cmd, params, query_map, web, trusted_browser); + cmd, params, query_map, web, nav_type, trusted_browser); } static std::string lookup(LLCommandHandler::EUntrustedAccess value); diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 1e65b6de23..1e0895565a 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -95,6 +95,7 @@ public: const LLSD& params, const LLSD& query_map, LLMediaCtrl* web, + const std::string& nav_type, bool trusted_browser); // Execute a command registered via the above mechanism, // passing string parameters. diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index e319418def..1c15360b09 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -115,7 +115,11 @@ void LLFirstUse::notMoving(bool enable) { // fire off 2 notifications and rely on filtering to select the relevant one firstUseNotification("FirstNotMoving", enable, "HintMove", LLSD(), LLSD().with("target", "move_btn").with("direction", "top")); - firstUseNotification("FirstNotMoving", enable, "HintMoveArrows", LLSD(), LLSD().with("target", "bottom_tray").with("direction", "top").with("hint_image", "arrow_keys.png").with("down_arrow", "")); + firstUseNotification("FirstNotMoving", enable, "HintMoveClick", LLSD(), LLSD() + .with("target", "nav_bar") + .with("direction", "bottom") + .with("hint_image", "click_to_move.png") + .with("up_arrow", "")); } // static diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index a650886d89..627defd006 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -50,6 +50,7 @@ BOOL LLFloaterHelpBrowser::postBuild() { mBrowser = getChild<LLMediaCtrl>("browser"); mBrowser->addObserver(this); + mBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); childSetAction("open_browser", onClickOpenWebBrowser, this); diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp index c4dcaf11f9..97f0e36a0c 100644 --- a/indra/newview/llhints.cpp +++ b/indra/newview/llhints.cpp @@ -191,6 +191,8 @@ BOOL LLHintPopup::postBuild() LLRect text_bounds = hint_text.getTextBoundingRect(); S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight(); reshape(getRect().getWidth(), getRect().getHeight() + delta_height); + hint_text.reshape(hint_text.getRect().getWidth(), hint_text.getRect().getHeight() + delta_height); + hint_text.translate(0, -delta_height); return TRUE; } @@ -211,6 +213,18 @@ void LLHintPopup::draw() alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f); } + LLIconCtrl& hint_icon = getChildRef<LLIconCtrl>("hint_image"); + + LLUIImagePtr hint_image = hint_icon.getImage(); + S32 image_height = hint_image.isNull() ? 0 : hint_image->getHeight(); + S32 image_width = hint_image.isNull() ? 0 : hint_image->getWidth(); + + S32 delta_height = image_height - hint_icon.getRect().getHeight(); + hint_icon.getParent()->reshape(image_width, image_height); + + LLRect hint_rect = getLocalRect(); + reshape(hint_rect.getWidth(), hint_rect.getHeight() + delta_height); + { LLViewDrawContext context(alpha); if (mTarget.empty()) diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 9493fddf50..5007f1c17a 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -44,6 +44,7 @@ #include "llslurl.h" #include "lluictrlfactory.h" // LLDefaultChildRegistry #include "llkeyboard.h" +#include "llviewermenu.h" // linden library includes #include "llfocusmgr.h" @@ -73,6 +74,7 @@ LLMediaCtrl::Params::Params() texture_height("texture_height", 1024), caret_color("caret_color"), initial_mime_type("initial_mime_type"), + error_page_url("error_page_url"), media_id("media_id"), trusted_content("trusted_content", false), focus_on_click("focus_on_click", true) @@ -102,9 +104,11 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mTextureHeight ( 1024 ), mClearCache(false), mHomePageMimeType(p.initial_mime_type), + mErrorPageURL(p.error_page_url), mTrusted(p.trusted_content), mWindowShade(NULL), - mHoverTextChanged(false) + mHoverTextChanged(false), + mContextMenu(NULL) { { LLColor4 color = p.caret_color().get(); @@ -149,7 +153,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : LLMediaCtrl::~LLMediaCtrl() { - if (mMediaSource) { mMediaSource->remObserver( this ); @@ -304,10 +307,12 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask ) BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) { if (LLPanel::handleRightMouseDown(x, y, mask)) return TRUE; - convertInputCoords(x, y); + + S32 media_x = x, media_y = y; + convertInputCoords(media_x, media_y); if (mMediaSource) - mMediaSource->mouseDown(x, y, mask, 1); + mMediaSource->mouseDown(media_x, media_y, mask, 1); gFocusMgr.setMouseCapture( this ); @@ -316,6 +321,12 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) setFocus( TRUE ); } + if (mContextMenu) + { + mContextMenu->show(x, y); + LLMenuGL::showPopup(this, mContextMenu, x, y); + } + return TRUE; } @@ -378,6 +389,8 @@ void LLMediaCtrl::onFocusLost() // BOOL LLMediaCtrl::postBuild () { + mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( + "menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2)); return TRUE; } @@ -503,22 +516,6 @@ bool LLMediaCtrl::canNavigateForward() //////////////////////////////////////////////////////////////////////////////// // -void LLMediaCtrl::set404RedirectUrl( std::string redirect_url ) -{ - if(mMediaSource && mMediaSource->hasMedia()) - mMediaSource->getMediaPlugin()->set_status_redirect( 404, redirect_url ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::clr404RedirectUrl() -{ - if(mMediaSource && mMediaSource->hasMedia()) - mMediaSource->getMediaPlugin()->set_status_redirect(404, ""); -} - -//////////////////////////////////////////////////////////////////////////////// -// void LLMediaCtrl::clearCache() { if(mMediaSource) @@ -626,6 +623,16 @@ void LLMediaCtrl::setTarget(const std::string& target) } } +void LLMediaCtrl::setErrorPageURL(const std::string& url) +{ + mErrorPageURL = url; +} + +const std::string& LLMediaCtrl::getErrorPageURL() +{ + return mErrorPageURL; +} + //////////////////////////////////////////////////////////////////////////////// // bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) @@ -976,6 +983,16 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) }; break; + case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; + if ( mErrorPageURL.length() > 0 ) + { + navigateTo(mErrorPageURL, "text/html"); + }; + }; + break; + case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 38a74f90d3..28666e620f 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -34,6 +34,7 @@ class LLViewBorder; class LLUICtrlFactory; +class LLContextMenu; //////////////////////////////////////////////////////////////////////////////// // @@ -63,6 +64,7 @@ public: Optional<std::string> initial_mime_type; Optional<std::string> media_id; + Optional<std::string> error_page_url; Params(); }; @@ -113,10 +115,9 @@ public: void setTarget(const std::string& target); - // set/clear URL to visit when a 404 page is reached - void set404RedirectUrl( std::string redirect_url ); - void clr404RedirectUrl(); - + void setErrorPageURL(const std::string& url); + const std::string& getErrorPageURL(); + // Clear the browser cache when the instance gets loaded void clearCache(); @@ -179,6 +180,7 @@ public: std::string mHomePageUrl; std::string mHomePageMimeType; std::string mCurrentNavUrl; + std::string mErrorPageURL; std::string mTarget; bool mIgnoreUIScale; bool mAlwaysRefresh; @@ -194,6 +196,7 @@ public: bool mClearCache; class LLWindowShade* mWindowShade; bool mHoverTextChanged; + LLContextMenu* mContextMenu; }; #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 3b160ddc8e..b8832dfd8e 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -57,6 +57,7 @@ #include "llviewercontrol.h" #include "llfloatermediabrowser.h" #include "llweb.h" +#include "llhints.h" #include "llinventorymodel.h" #include "lllandmarkactions.h" @@ -324,6 +325,8 @@ BOOL LLNavigationBar::postBuild() LLTeleportHistory::getInstance()->setHistoryChangedCallback( boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this)); + LLHints::registerHintTarget("nav_bar", LLView::getHandle()); + return TRUE; } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 903cf4780d..7820ac3ecd 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -214,7 +214,9 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, } updateLocationCombo(false); - gSavedSettings.getControl("SessionSettingsFile")->getSignal()->connect(boost::bind(&onModeChange)); + LLUICtrl& mode_combo = getChildRef<LLUICtrl>("mode_combo"); + mode_combo.setValue(gSavedSettings.getString("SessionSettingsFile")); + mode_combo.setCommitCallback(boost::bind(&LLPanelLogin::onModeChange, this, getChild<LLUICtrl>("mode_combo")->getValue(), _2)); LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo"); server_choice_combo->setCommitCallback(onSelectServer, NULL); @@ -1159,23 +1161,26 @@ void LLPanelLogin::updateLoginPanelLinks() sInstance->getChildView("forgot_password_text")->setVisible( system_grid); } -//static -void LLPanelLogin::onModeChange() +void LLPanelLogin::onModeChange(const LLSD& original_value, const LLSD& new_value) { - LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&onModeChangeConfirm, _1, _2)); + if (original_value.asString() != new_value.asString()) + { + LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&LLPanelLogin::onModeChangeConfirm, this, original_value, new_value, _1, _2)); + } } -//static -void LLPanelLogin::onModeChangeConfirm(const LLSD& notification, const LLSD& response) +void LLPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch (option) { case 0: - LLAppViewer::instance()->requestQuit(); + gSavedSettings.getControl("SessionSettingsFile")->set(new_value); + LLAppViewer::instance()->forceQuit(); break; case 1: - // do nothing + // revert to original value + getChild<LLUICtrl>("mode_combo")->setValue(original_value); break; default: break; diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 1430bec832..9cc5e3456a 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -98,8 +98,8 @@ private: static void onServerComboLostFocus(LLFocusableElement*); static void updateServerCombo(); static void updateStartSLURL(); - static void onModeChange(); - static void onModeChangeConfirm(const LLSD& notification, const LLSD& response); + void onModeChange(const LLSD& original_value, const LLSD& new_value); + void onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response); static void updateLoginPanelLinks(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8fccb35886..bfa8cf09fd 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2717,7 +2717,7 @@ bool LLStartUp::dispatchURL() || (dx*dx > SLOP*SLOP) || (dy*dy > SLOP*SLOP) ) { - LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(), + LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(), "clicked", NULL, false); } return true; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 9549f180df..95bd210ae3 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -37,7 +37,7 @@ #include "llavatarnamecache.h" #include "llviewercontrol.h" #include "llfocusmgr.h" -//#include "llfirstuse.h" +#include "llfirstuse.h" #include "llfloaterland.h" #include "llfloaterreg.h" #include "llfloaterscriptdebug.h" @@ -528,42 +528,17 @@ void LLToolPie::selectionPropertiesReceived() BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) { - if (!mMouseOutsideSlop - && mMouseButtonDown - && gSavedSettings.getBOOL("ClickToWalk")) - { - S32 delta_x = x - mMouseDownX; - S32 delta_y = y - mMouseDownY; - S32 threshold = gSavedSettings.getS32("DragAndDropDistanceThreshold"); - if (delta_x * delta_x + delta_y * delta_y > threshold * threshold) - { - startCameraSteering(); - } - } - mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE); - - if (inCameraSteerMode()) - { - steerCameraWithMouse(x, y); - gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); - return TRUE; - } - - // perform a separate pick that detects transparent objects since they respond to 1-click actions - LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE); - - // Show screen-space highlight glow effect - bool show_highlight = false; LLViewerObject *parent = NULL; LLViewerObject *object = mHoverPick.getObject(); - if (object) { parent = object->getRootEdit(); } - LLViewerObject* click_action_object = click_action_pick.getObject(); + // Show screen-space highlight glow effect + bool show_highlight = false; + if (handleMediaHover(mHoverPick)) { // *NOTE: If you think the hover glow conflicts with the media outline, you @@ -572,39 +547,70 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) // cursor set by media object lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } - else if (click_action_object && useClickAction(mask, click_action_object, click_action_object->getRootEdit())) + else if (!mMouseOutsideSlop + && mMouseButtonDown + && gSavedSettings.getBOOL("ClickToWalk")) { - show_highlight = true; - ECursorType cursor = cursorFromObject(click_action_object); - gViewerWindow->setCursor(cursor); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + S32 delta_x = x - mMouseDownX; + S32 delta_y = y - mMouseDownY; + S32 threshold = gSavedSettings.getS32("DragAndDropDistanceThreshold"); + if (delta_x * delta_x + delta_y * delta_y > threshold * threshold) + { + startCameraSteering(); + steerCameraWithMouse(x, y); + gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); + } + else + { + gViewerWindow->setCursor(UI_CURSOR_ARROW); + } } - - else if ((object && !object->isAvatar() && object->usePhysics()) - || (parent && !parent->isAvatar() && parent->usePhysics())) + else if (inCameraSteerMode()) { - show_highlight = true; + steerCameraWithMouse(x, y); gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; - } - else if ( (object && object->flagHandleTouch()) - || (parent && parent->flagHandleTouch())) - { - show_highlight = true; - gViewerWindow->setCursor(UI_CURSOR_HAND); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } else { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + // perform a separate pick that detects transparent objects since they respond to 1-click actions + LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE); + + LLViewerObject* click_action_object = click_action_pick.getObject(); - if(!object) + if (click_action_object && useClickAction(mask, click_action_object, click_action_object->getRootEdit())) + { + show_highlight = true; + ECursorType cursor = cursorFromObject(click_action_object); + gViewerWindow->setCursor(cursor); + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + } + + else if ((object && !object->isAvatar() && object->usePhysics()) + || (parent && !parent->isAvatar() && parent->usePhysics())) + { + show_highlight = true; + gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + } + else if ( (object && object->flagHandleTouch()) + || (parent && parent->flagHandleTouch())) + { + show_highlight = true; + gViewerWindow->setCursor(UI_CURSOR_HAND); + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + } + else { - LLViewerMediaFocus::getInstance()->clearHover(); + gViewerWindow->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } } + if(!object) + { + LLViewerMediaFocus::getInstance()->clearHover(); + } + static LLCachedControl<bool> enable_highlight( gSavedSettings, "RenderHoverGlowEnable", false); LLDrawable* drawable = NULL; @@ -662,6 +668,8 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) mAutoPilotDestination->setDuration(3.f); handle_go_to(); + LLFirstUse::notMoving(false); + mBlockClickToWalk = false; return TRUE; @@ -1430,6 +1438,7 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { // Make sure keyboard focus is set to the media focus object. gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); mMediaMouseCaptureID = mep->getMediaID(); @@ -1709,8 +1718,13 @@ void LLToolPie::showVisualContextMenuEffect() effectp->setDuration(0.25f); } +typedef enum e_near_far +{ + NEAR_INTERSECTION, + FAR_INTERSECTION +} ENearFar; -bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius, LLVector3& intersection_pt) +bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius, e_near_far near_far, LLVector3& intersection_pt) { // do ray/sphere intersection by solving quadratic equation LLVector3 sphere_to_ray_start_vec = ray_pt - sphere_center; @@ -1718,10 +1732,11 @@ bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_di F32 C = sphere_to_ray_start_vec.lengthSquared() - (sphere_radius * sphere_radius); F32 discriminant = B*B - 4.f*C; - if (discriminant > 0.f) + if (discriminant >= 0.f) { // intersection detected, now find closest one F32 t0 = (-B - sqrtf(discriminant)) / 2.f; - if (t0 > 0.f) + + if (t0 > 0.f && near_far == NEAR_INTERSECTION) { intersection_pt = ray_pt + ray_dir * t0; } @@ -1732,12 +1747,15 @@ bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_di } return true; } - - return false; + else + { // no intersection + return false; + } } void LLToolPie::startCameraSteering() { + LLFirstUse::notMoving(false); mMouseOutsideSlop = true; mBlockClickToWalk = true; @@ -1786,64 +1804,80 @@ void LLToolPie::startCameraSteering() void LLToolPie::steerCameraWithMouse(S32 x, S32 y) { - const F32 MIN_ROTATION_RADIUS_FRACTION = 0.2f; - + const LLViewerCamera& camera = LLViewerCamera::instance(); + const LLCoordFrame& rotation_frame = gAgent.getFrameAgent(); const LLVector3 pick_pos = gAgent.getPosAgentFromGlobal(mSteerPick.mPosGlobal); - const LLVector3 rotation_center = gAgent.getFrameAgent().getOrigin(); - // FIXME: get this to work with camera tilt (i.e. sitting on a rotating object) - const LLVector3 rotation_up_axis(LLVector3::z_axis); - - LLVector3 object_rotation_center = rotation_center + parallel_component(pick_pos - rotation_center, rotation_up_axis); - F32 min_rotation_radius = MIN_ROTATION_RADIUS_FRACTION * dist_vec(rotation_center, LLViewerCamera::instance().getOrigin());; - F32 pick_distance_from_rotation_center = llclamp(dist_vec(pick_pos, object_rotation_center), min_rotation_radius, F32_MAX); + const LLVector3 pick_rotation_center = rotation_frame.getOrigin() + parallel_component(pick_pos - rotation_frame.getOrigin(), rotation_frame.getUpAxis()); + const F32 MIN_ROTATION_RADIUS_FRACTION = 0.2f; + const F32 min_rotation_radius = MIN_ROTATION_RADIUS_FRACTION * dist_vec(pick_rotation_center, camera.getOrigin());; + const F32 pick_distance_from_rotation_center = llclamp(dist_vec(pick_pos, pick_rotation_center), min_rotation_radius, F32_MAX); + const LLVector3 camera_to_rotation_center = pick_rotation_center - camera.getOrigin(); + const LLVector3 adjusted_camera_pos = LLViewerCamera::instance().getOrigin() + projected_vec(camera_to_rotation_center, rotation_frame.getUpAxis()); + const F32 camera_distance_from_rotation_center = dist_vec(adjusted_camera_pos, pick_rotation_center); - LLVector3 mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(x, y), rotation_up_axis); + LLVector3 mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(x, y), rotation_frame.getUpAxis()); mouse_ray.normalize(); - LLVector3 old_mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(mMouseSteerX, mMouseSteerY), rotation_up_axis); + LLVector3 old_mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(mMouseSteerX, mMouseSteerY), rotation_frame.getUpAxis()); old_mouse_ray.normalize(); - LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent(); - LLVector3 camera_to_rotation_center = object_rotation_center - camera_pos; - LLVector3 adjusted_camera_pos = camera_pos + projected_vec(camera_to_rotation_center, rotation_up_axis); - LLVector3 rotation_fwd_axis = LLViewerCamera::instance().getAtAxis() - projected_vec(LLViewerCamera::instance().getAtAxis(), rotation_up_axis); - rotation_fwd_axis.normalize(); - F32 pick_dist = dist_vec(pick_pos, adjusted_camera_pos); - + F32 yaw_angle; + F32 old_yaw_angle; LLVector3 mouse_on_sphere; - bool mouse_hit_sphere = intersect_ray_with_sphere(adjusted_camera_pos + (mouse_ray * pick_dist * 1.1f), - -1.f * mouse_ray, - object_rotation_center, - pick_distance_from_rotation_center, - mouse_on_sphere); - LLVector3 old_mouse_on_sphere; - intersect_ray_with_sphere(adjusted_camera_pos + (old_mouse_ray * pick_dist * 1.1f), - -1.f * old_mouse_ray, - object_rotation_center, - pick_distance_from_rotation_center, - old_mouse_on_sphere); - if (mouse_hit_sphere) + if (intersect_ray_with_sphere( + adjusted_camera_pos, + mouse_ray, + pick_rotation_center, + pick_distance_from_rotation_center, + FAR_INTERSECTION, + mouse_on_sphere)) { - // calculate rotation frame in screen space - LLVector3 screen_rotation_up_axis = orthogonal_component(rotation_up_axis, LLViewerCamera::instance().getAtAxis()); - screen_rotation_up_axis.normalize(); - - LLVector3 screen_rotation_left_axis = screen_rotation_up_axis % LLViewerCamera::instance().getAtAxis(); + LLVector3 mouse_sphere_offset = mouse_on_sphere - pick_rotation_center; + yaw_angle = atan2f(mouse_sphere_offset * rotation_frame.getLeftAxis(), mouse_sphere_offset * rotation_frame.getAtAxis()); + } + else + { + yaw_angle = F_PI_BY_TWO + asinf(pick_distance_from_rotation_center / camera_distance_from_rotation_center); + if (mouse_ray * rotation_frame.getLeftAxis() < 0.f) + { + yaw_angle *= -1.f; + } + } - LLVector3 rotation_furthest_pt = object_rotation_center + pick_distance_from_rotation_center * rotation_fwd_axis; - F32 mouse_lateral_distance = llclamp(((mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f); - F32 old_mouse_lateral_distance = llclamp(((old_mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f); + if (intersect_ray_with_sphere( + adjusted_camera_pos, + old_mouse_ray, + pick_rotation_center, + pick_distance_from_rotation_center, + FAR_INTERSECTION, + old_mouse_on_sphere)) + { + LLVector3 mouse_sphere_offset = old_mouse_on_sphere - pick_rotation_center; + old_yaw_angle = atan2f(mouse_sphere_offset * rotation_frame.getLeftAxis(), mouse_sphere_offset * rotation_frame.getAtAxis()); + } + else + { + old_yaw_angle = F_PI_BY_TWO + asinf(pick_distance_from_rotation_center / camera_distance_from_rotation_center); - F32 yaw_angle = asinf(mouse_lateral_distance); - F32 old_yaw_angle = asinf(old_mouse_lateral_distance); + if (mouse_ray * rotation_frame.getLeftAxis() < 0.f) + { + old_yaw_angle *= -1.f; + } + } - F32 delta_angle = yaw_angle - old_yaw_angle; - if (!mClockwise) delta_angle *= -1.f; + const F32 delta_angle = yaw_angle - old_yaw_angle; + if (mClockwise) + { gAgent.yaw(delta_angle); - mMouseSteerX = x; - mMouseSteerY = y; } + else + { + gAgent.yaw(-delta_angle); + } + + mMouseSteerX = x; + mMouseSteerY = y; } diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index ebbb045f0a..ed4d278e90 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -53,6 +53,7 @@ class LLURLDispatcherImpl { public: static bool dispatch(const LLSLURL& slurl, + const std::string& nav_type, LLMediaCtrl* web, bool trusted_browser); // returns true if handled or explicitly blocked. @@ -61,6 +62,7 @@ public: private: static bool dispatchCore(const LLSLURL& slurl, + const std::string& nav_type, bool right_mouse, LLMediaCtrl* web, bool trusted_browser); @@ -71,6 +73,7 @@ private: // Returns true if handled. static bool dispatchApp(const LLSLURL& slurl, + const std::string& nav_type, bool right_mouse, LLMediaCtrl* web, bool trusted_browser); @@ -78,7 +81,7 @@ private: // by showing panel in Search floater. // Returns true if handled or explicitly blocked. - static bool dispatchRegion(const LLSLURL& slurl, bool right_mouse); + static bool dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse); // handles secondlife://Ahern/123/45/67/ // Returns true if handled. @@ -97,6 +100,7 @@ private: // static bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl, + const std::string& nav_type, bool right_mouse, LLMediaCtrl* web, bool trusted_browser) @@ -105,9 +109,9 @@ bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl, switch(slurl.getType()) { case LLSLURL::APP: - return dispatchApp(slurl, right_mouse, web, trusted_browser); + return dispatchApp(slurl, nav_type, right_mouse, web, trusted_browser); case LLSLURL::LOCATION: - return dispatchRegion(slurl, right_mouse); + return dispatchRegion(slurl, nav_type, right_mouse); default: return false; } @@ -122,11 +126,12 @@ bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl, // static bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl, + const std::string& nav_type, LLMediaCtrl* web, bool trusted_browser) { const bool right_click = false; - return dispatchCore(slurl, right_click, web, trusted_browser); + return dispatchCore(slurl, nav_type, right_click, web, trusted_browser); } // static @@ -135,11 +140,12 @@ bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl) const bool right_click = true; LLMediaCtrl* web = NULL; const bool trusted_browser = false; - return dispatchCore(slurl, right_click, web, trusted_browser); + return dispatchCore(slurl, "clicked", right_click, web, trusted_browser); } // static bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, + const std::string& nav_type, bool right_mouse, LLMediaCtrl* web, bool trusted_browser) @@ -147,7 +153,7 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl; const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery()); bool handled = LLCommandDispatcher::dispatch( - slurl.getAppCmd(), slurl.getAppPath(), query_map, web, trusted_browser); + slurl.getAppCmd(), slurl.getAppPath(), query_map, web, nav_type, trusted_browser); // alert if we didn't handle this secondlife:///app/ SLURL // (but still return true because it is a valid app SLURL) @@ -159,7 +165,7 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, } // static -bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, bool right_mouse) +bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse) { if(slurl.getType() != LLSLURL::LOCATION) { @@ -287,10 +293,11 @@ LLTeleportHandler gTeleportHandler; // static bool LLURLDispatcher::dispatch(const std::string& slurl, + const std::string& nav_type, LLMediaCtrl* web, bool trusted_browser) { - return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser); + return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), nav_type, web, trusted_browser); } // static @@ -310,7 +317,7 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl) // *TODO: Make this trust model more refined. JC const bool trusted_browser = true; LLMediaCtrl* web = NULL; - return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser); + return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser); } diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h index b07db4da3f..6309a97af5 100644 --- a/indra/newview/llurldispatcher.h +++ b/indra/newview/llurldispatcher.h @@ -33,6 +33,7 @@ class LLURLDispatcher public: static bool dispatch(const std::string& slurl, + const std::string& nav_type, LLMediaCtrl* web, bool trusted_browser); // At startup time and on clicks in internal web browsers, @@ -41,6 +42,8 @@ public: // secondlife://RegionName/123/45/67/ // secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show // sl://app/foo/bar + // @param nav_type + // type of navigation type (see LLQtWebKit::LLWebPage::acceptNavigationRequest) // @param web // Pointer to LLMediaCtrl sending URL, can be NULL // @param trusted_browser diff --git a/indra/newview/llurldispatcherlistener.cpp b/indra/newview/llurldispatcherlistener.cpp index d0441d7bfa..c7b9afafef 100644 --- a/indra/newview/llurldispatcherlistener.cpp +++ b/indra/newview/llurldispatcherlistener.cpp @@ -61,7 +61,7 @@ void LLURLDispatcherListener::dispatch(const LLSD& params) const // But for testing, allow a caller to specify untrusted. trusted_browser = params["trusted"].asBoolean(); } - LLURLDispatcher::dispatch(params["url"], NULL, trusted_browser); + LLURLDispatcher::dispatch(params["url"], "clicked", NULL, trusted_browser); } void LLURLDispatcherListener::dispatchRightClick(const LLSD& params) const diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 41b7c13826..2f8f842ce7 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1066,8 +1066,8 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); mat.set_translate( - glh::vec3f(clamp_rescale((F32)screen_region.getCenterX(), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), - clamp_rescale((F32)screen_region.getCenterY(), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), + glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), + clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), 0.f)); proj *= mat; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 499165135a..037e22584f 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -2543,23 +2543,7 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask) // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it... if( MASK_CONTROL & mask ) { - if( 'C' == key ) - { - mMediaSource->copy(); - result = true; - } - else - if( 'V' == key ) - { - mMediaSource->paste(); - result = true; - } - else - if( 'X' == key ) - { - mMediaSource->cut(); - result = true; - } + result = true; } if(!result) @@ -3000,7 +2984,8 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; std::string url = plugin->getClickURL(); - LLURLDispatcher::dispatch(url, NULL, mTrustedBrowser); + std::string nav_type = plugin->getClickNavType(); + LLURLDispatcher::dispatch(url, nav_type, NULL, mTrustedBrowser); } break; case MEDIA_EVENT_CLICK_LINK_HREF: diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index de52aa17d1..4543a1ba9a 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -113,6 +113,11 @@ void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 fac media_impl->focus(true); gFocusMgr.setKeyboardFocus(this); + LLViewerMediaImpl* impl = getFocusedMediaImpl(); + if (impl) + { + LLEditMenuHandler::gEditMenuHandler = impl; + } // We must do this before processing the media HUD zoom, or it may zoom to the wrong face. update(); @@ -139,6 +144,13 @@ void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 fac { gFocusMgr.setKeyboardFocus(NULL); } + + LLViewerMediaImpl* impl = getFocusedMediaImpl(); + if (LLEditMenuHandler::gEditMenuHandler == impl) + { + LLEditMenuHandler::gEditMenuHandler = NULL; + } + mFocusedImplID = LLUUID::null; if (objectp.notNull()) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ec72df79d1..0883d1edf7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -856,40 +856,36 @@ void toggle_destination_and_avatar_picker(const LLSD& show) LLButton* avatar_btn = gViewerWindow->getRootView()->getChildView("bottom_tray")->getChild<LLButton>("avatar_btn"); LLButton* destination_btn = gViewerWindow->getRootView()->getChildView("bottom_tray")->getChild<LLButton>("destination_btn"); - switch(panel_idx) - { - case 0: - if (!destinations->getVisible()) - { - container->setVisible(true); - destinations->setVisible(true); - avatar_picker->setVisible(false); - LLFirstUse::notUsingDestinationGuide(false); - avatar_btn->setToggleState(false); - destination_btn->setToggleState(true); - return; - } - break; - case 1: - if (!avatar_picker->getVisible()) - { - container->setVisible(true); - destinations->setVisible(false); - avatar_picker->setVisible(true); - avatar_btn->setToggleState(true); - destination_btn->setToggleState(false); - return; - } - break; - default: - break; + if (panel_idx == 0 + && !destinations->getVisible()) + { // opening destinations guide + container->setVisible(true); + destinations->setVisible(true); + avatar_picker->setVisible(false); + LLFirstUse::notUsingDestinationGuide(false); + avatar_btn->setToggleState(false); + destination_btn->setToggleState(true); + gSavedSettings.setS32("DestinationsAndAvatarsVisibility", 0); + } + else if (panel_idx == 1 + && !avatar_picker->getVisible()) + { // opening avatar picker + container->setVisible(true); + destinations->setVisible(false); + avatar_picker->setVisible(true); + avatar_btn->setToggleState(true); + destination_btn->setToggleState(false); + gSavedSettings.setS32("DestinationsAndAvatarsVisibility", 1); + } + else + { // toggling off dest guide or avatar picker + container->setVisible(false); + destinations->setVisible(false); + avatar_picker->setVisible(false); + avatar_btn->setToggleState(false); + destination_btn->setToggleState(false); + gSavedSettings.setS32("DestinationsAndAvatarsVisibility", -1); } - - container->setVisible(false); - destinations->setVisible(false); - avatar_picker->setVisible(false); - avatar_btn->setToggleState(false); - destination_btn->setToggleState(false); }; diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 40f0b43313..dfa35edef4 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -539,6 +539,12 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent }; break; + case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; + }; + break; + case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e1d3e8a0b3..6ae143d299 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -111,7 +111,7 @@ public: } // Process the SLapp as if it was a secondlife://{PLACE} SLurl - LLURLDispatcher::dispatch(url, web, true); + LLURLDispatcher::dispatch(url, "clicked", web, true); return true; } }; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index aa83bcb68b..cd19d0c5cd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -915,7 +915,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi { if (drop) { - LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), NULL, true ); + LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), "clicked", NULL, true ); return LLWindowCallbacks::DND_MOVE; } return LLWindowCallbacks::DND_COPY; @@ -1306,7 +1306,7 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data) std::string url = (const char*)data; LLMediaCtrl* web = NULL; const bool trusted_browser = false; - if (LLURLDispatcher::dispatch(url, web, trusted_browser)) + if (LLURLDispatcher::dispatch(url, "clicked", web, trusted_browser)) { // bring window to foreground, as it has just been "launched" from a URL mWindow->bringToFront(); @@ -1791,19 +1791,18 @@ void LLViewerWindow::initWorldUI() LLMediaCtrl* avatar_picker = avatar_picker_destination_guide_container->findChild<LLMediaCtrl>("avatar_picker_contents"); if (destinations) { + destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); destinations->navigateTo(gSavedSettings.getString("DestinationGuideURL"), "text/html"); } if (avatar_picker) { + avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); avatar_picker->navigateTo(gSavedSettings.getString("AvatarPickerURL"), "text/html"); } - if (gSavedSettings.getBOOL("FirstLoginThisInstall")) - { - toggle_destination_and_avatar_picker(0); - gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE); - } + // show destinations by default + toggle_destination_and_avatar_picker(gSavedSettings.getS32("DestinationsAndAvatarsVisibility")); } // Destroy the UI diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 8ef3a3b839..8cdb615686 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -1745,7 +1745,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) // Invoke the event details floater if someone is clicking on an event. LLSD params(LLSD::emptyArray()); params.append(event_id); - LLCommandDispatcher::dispatch("event", params, LLSD(), NULL, true); + LLCommandDispatcher::dispatch("event", params, LLSD(), NULL, "clicked", true); break; } case MAP_ITEM_LAND_FOR_SALE: diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 8eee8f44b5..ef670bdd52 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -96,7 +96,7 @@ filename="panel_preferences_colors.xml" label="Colors" layout="topleft" - help_topic="preferences_im_tab" + help_topic="preferences_colors_tab" name="colors" /> <panel class="panel_preference" diff --git a/indra/newview/skins/default/xui/en/menu_media_ctrl.xml b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml new file mode 100644 index 0000000000..c39c26f25f --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + name="media ctrl context menu"> + <menu_item_call + label="Cut" + layout="topleft" + name="Cut"> + <menu_item_call.on_click + function="Edit.Cut" /> + <menu_item_call.on_enable + function="Edit.EnableCut" /> + </menu_item_call> + <menu_item_call + label="Copy" + layout="topleft" + name="Copy"> + <menu_item_call.on_click + function="Edit.Copy" /> + <menu_item_call.on_enable + function="Edit.EnableCopy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="Paste"> + <menu_item_call.on_click + function="Edit.Paste" /> + <menu_item_call.on_enable + function="Edit.EnablePaste" /> + </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_text_editor.xml b/indra/newview/skins/default/xui/en/menu_text_editor.xml index ecd96088e7..fe8489166b 100644 --- a/indra/newview/skins/default/xui/en/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/en/menu_text_editor.xml @@ -4,8 +4,7 @@ <menu_item_call label="Cut" layout="topleft" - name="Cut" - shortcut="control|X"> + name="Cut"> <menu_item_call.on_click function="Edit.Cut" /> <menu_item_call.on_enable @@ -14,8 +13,7 @@ <menu_item_call label="Copy" layout="topleft" - name="Copy" - shortcut="control|C"> + name="Copy"> <menu_item_call.on_click function="Edit.Copy" /> <menu_item_call.on_enable @@ -24,8 +22,7 @@ <menu_item_call label="Paste" layout="topleft" - name="Paste" - shortcut="control|V"> + name="Paste"> <menu_item_call.on_click function="Edit.Paste" /> <menu_item_call.on_enable @@ -34,8 +31,7 @@ <menu_item_call label="Delete" layout="topleft" - name="Delete" - shortcut="Del"> + name="Delete"> <menu_item_call.on_click function="Edit.Delete" /> <menu_item_call.on_enable @@ -44,8 +40,7 @@ <menu_item_call label="Select All" layout="topleft" - name="Select All" - shortcut="control|A"> + name="Select All"> <menu_item_call.on_click function="Edit.SelectAll" /> <menu_item_call.on_enable diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ba13479860..67bce2412d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7018,11 +7018,15 @@ Mute everyone? </notification> <notification - name="HintMoveArrows" + name="HintMoveClick" label="Move" type="hint" unique="true"> - To walk, use the directional keys on your keyboard. You can run by pressing the Up arrow twice. +Click to Walk +Click anywhere on the ground to walk to that spot. + +Click and Drag to Rotate View +Click and drag anywhere on the world to rotate your view <tag>custom_skin</tag> </notification> diff --git a/indra/newview/skins/default/xui/en/panel_hint.xml b/indra/newview/skins/default/xui/en/panel_hint.xml index e2e9d0aef0..c883fd8a1d 100644 --- a/indra/newview/skins/default/xui/en/panel_hint.xml +++ b/indra/newview/skins/default/xui/en/panel_hint.xml @@ -16,7 +16,7 @@ right="197" top="26" bottom="92" - follows="all" + follows="left|right|bottom" text_color="Black" wrap="true"/> <button right="197" diff --git a/indra/newview/skins/default/xui/en/panel_hint_image.xml b/indra/newview/skins/default/xui/en/panel_hint_image.xml index 00b6e42497..30dd1836f1 100644 --- a/indra/newview/skins/default/xui/en/panel_hint_image.xml +++ b/indra/newview/skins/default/xui/en/panel_hint_image.xml @@ -1,33 +1,43 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - width="205" + width="305" height="140" layout="topleft"> <text name="hint_title" font="SansSerifMedium" left="8" - right="180" + right="290" top="8" bottom="20" follows="left|right|top" text_color="Black" wrap="false"/> - <icon name="hint_image" - left="42" - top="25" - width="115" - height="86" - image_name="arrow_keys.png" - /> + <layout_stack left="0" + top="25" + width="305" + height="0" + follows="all" + orientation="horizontal"> + <layout_panel auto_resize="true" width="100"/> + <layout_panel auto_resize="true" width="0"> + <icon name="hint_image" + top="0" + left="0" + height="0" + width="0" + follows="all"/> + </layout_panel> + <layout_panel auto_resize="true" width="100"/> + </layout_stack> <text name="hint_text" left="8" - right="197" + right="297" top_pad="5" bottom="120" - follows="all" + follows="left|right|bottom" text_color="Black" wrap="true"/> - <button right="197" + <button right="297" top="8" width="16" height="16" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 4c2faddfe4..8d0f1437e6 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -133,7 +133,6 @@ label="Remember password" max_chars="128" tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features." top_pad="0" - control_name="SessionSettingsFile" name="mode_combo" width="110"> <combo_box.item diff --git a/indra/newview/skins/minimal/textures/click_to_move.png b/indra/newview/skins/minimal/textures/click_to_move.png Binary files differnew file mode 100644 index 0000000000..74e3faa8ff --- /dev/null +++ b/indra/newview/skins/minimal/textures/click_to_move.png diff --git a/indra/newview/skins/minimal/textures/textures.xml b/indra/newview/skins/minimal/textures/textures.xml index 3e2f5cd397..b4848a0619 100644 --- a/indra/newview/skins/minimal/textures/textures.xml +++ b/indra/newview/skins/minimal/textures/textures.xml @@ -2,6 +2,7 @@ <textures version="101"> <texture name="Button_Separator" file_name="bottomtray/button_separator.png" preload="true" /> <texture name="arrow_keys.png"/> + <texture name="click_to_move" file_name="click_to_move.png"/> <texture name="bottomtray_close_off" file_name="bottomtray/close_off.png" preload="true" /> <texture name="bottomtray_close_over" file_name="bottomtray/close_over.png" preload="true" /> <texture name="bottomtray_close_press" file_name="bottomtray/close_press.png" preload="true" /> diff --git a/indra/newview/skins/minimal/xui/en/menu_avatar_icon.xml b/indra/newview/skins/minimal/xui/en/menu_avatar_icon.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/minimal/xui/en/menu_avatar_icon.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_bottomtray.xml b/indra/newview/skins/minimal/xui/en/menu_bottomtray.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_bottomtray.xml +++ b/indra/newview/skins/minimal/xui/en/menu_bottomtray.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_favorites.xml b/indra/newview/skins/minimal/xui/en/menu_favorites.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_favorites.xml +++ b/indra/newview/skins/minimal/xui/en/menu_favorites.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_group_plus.xml b/indra/newview/skins/minimal/xui/en/menu_group_plus.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_group_plus.xml +++ b/indra/newview/skins/minimal/xui/en/menu_group_plus.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_hide_navbar.xml b/indra/newview/skins/minimal/xui/en/menu_hide_navbar.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_hide_navbar.xml +++ b/indra/newview/skins/minimal/xui/en/menu_hide_navbar.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_imchiclet_adhoc.xml b/indra/newview/skins/minimal/xui/en/menu_imchiclet_adhoc.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_imchiclet_adhoc.xml +++ b/indra/newview/skins/minimal/xui/en/menu_imchiclet_adhoc.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/minimal/xui/en/menu_imchiclet_group.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_imchiclet_group.xml +++ b/indra/newview/skins/minimal/xui/en/menu_imchiclet_group.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/minimal/xui/en/menu_imchiclet_p2p.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_imchiclet_p2p.xml +++ b/indra/newview/skins/minimal/xui/en/menu_imchiclet_p2p.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_inv_offer_chiclet.xml b/indra/newview/skins/minimal/xui/en/menu_inv_offer_chiclet.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_inv_offer_chiclet.xml +++ b/indra/newview/skins/minimal/xui/en/menu_inv_offer_chiclet.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_inventory.xml b/indra/newview/skins/minimal/xui/en/menu_inventory.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_inventory.xml +++ b/indra/newview/skins/minimal/xui/en/menu_inventory.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_inventory_add.xml b/indra/newview/skins/minimal/xui/en/menu_inventory_add.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/minimal/xui/en/menu_inventory_add.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_mini_map.xml b/indra/newview/skins/minimal/xui/en/menu_mini_map.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/minimal/xui/en/menu_mini_map.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_navbar.xml b/indra/newview/skins/minimal/xui/en/menu_navbar.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_navbar.xml +++ b/indra/newview/skins/minimal/xui/en/menu_navbar.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_nearby_chat.xml b/indra/newview/skins/minimal/xui/en/menu_nearby_chat.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_nearby_chat.xml +++ b/indra/newview/skins/minimal/xui/en/menu_nearby_chat.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_object_icon.xml b/indra/newview/skins/minimal/xui/en/menu_object_icon.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_object_icon.xml +++ b/indra/newview/skins/minimal/xui/en/menu_object_icon.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_people_groups.xml b/indra/newview/skins/minimal/xui/en/menu_people_groups.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_people_groups.xml +++ b/indra/newview/skins/minimal/xui/en/menu_people_groups.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_place_add_button.xml b/indra/newview/skins/minimal/xui/en/menu_place_add_button.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_place_add_button.xml +++ b/indra/newview/skins/minimal/xui/en/menu_place_add_button.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_script_chiclet.xml b/indra/newview/skins/minimal/xui/en/menu_script_chiclet.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_script_chiclet.xml +++ b/indra/newview/skins/minimal/xui/en/menu_script_chiclet.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_slurl.xml b/indra/newview/skins/minimal/xui/en/menu_slurl.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_slurl.xml +++ b/indra/newview/skins/minimal/xui/en/menu_slurl.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/menu_topinfobar.xml b/indra/newview/skins/minimal/xui/en/menu_topinfobar.xml index 9ebab9ef98..d3d9e2ef8a 100644 --- a/indra/newview/skins/minimal/xui/en/menu_topinfobar.xml +++ b/indra/newview/skins/minimal/xui/en/menu_topinfobar.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu/> +<menu visible="false"/> diff --git a/indra/newview/skins/minimal/xui/en/panel_login.xml b/indra/newview/skins/minimal/xui/en/panel_login.xml index ef058e5567..3903658e71 100644 --- a/indra/newview/skins/minimal/xui/en/panel_login.xml +++ b/indra/newview/skins/minimal/xui/en/panel_login.xml @@ -134,7 +134,6 @@ top="20" max_chars="128" top_pad="0" tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features." - control_name="SessionSettingsFile" name="mode_combo" width="120"> <combo_box.item |