From 5a6a792920bb0dee35bcd711bd786d907bda556a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 24 Aug 2010 09:41:35 -0700 Subject: fix for sim console not staying scrolled to bottom --- indra/llui/lltextbase.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 17e41d9e24..3ba9bd4d1b 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1569,7 +1569,10 @@ void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& // appendText modifies mCursorPos... appendText(text, false, input_params); // ...so move cursor to top after appending text - startOfDoc(); + if (!mTrackEnd) + { + startOfDoc(); + } onValueChange(0, getLength()); } -- cgit v1.3 From 4b9abaaab9448df7e0773cdbaf1a5202a1f9e6c7 Mon Sep 17 00:00:00 2001 From: "Matthew Breindel (Falcon)" Date: Thu, 26 Aug 2010 17:09:15 -0700 Subject: Cleaned up the debug console a bit. Gave it a command history and proper scrolling to the bottom of the returned data. --- indra/llui/lllineeditor.cpp | 6 +-- indra/newview/llfloaterregiondebugconsole.cpp | 48 ++++++++++++++++------ .../xui/en/floater_region_debug_console.xml | 10 +++-- 3 files changed, 45 insertions(+), 19 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index c93ca1af88..69b4c73e48 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1272,7 +1272,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) // handle ctrl-uparrow if we have a history enabled line editor. case KEY_UP: - if( mHaveHistory && ( MASK_CONTROL == mask ) ) + if( mHaveHistory && ((mIgnoreArrowKeys == false) || ( MASK_CONTROL == mask )) ) { if( mCurrentHistoryLine > mLineHistory.begin() ) { @@ -1287,9 +1287,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) } break; - // handle ctrl-downarrow if we have a history enabled line editor + // handle [ctrl]-downarrow if we have a history enabled line editor case KEY_DOWN: - if( mHaveHistory && ( MASK_CONTROL == mask ) ) + if( mHaveHistory && ((mIgnoreArrowKeys == false) || ( MASK_CONTROL == mask )) ) { if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 ) { diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index 058f894800..159dee7631 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -55,11 +55,8 @@ public: /*virtual*/ void result(const LLSD& content) { - std::string text = mOutput->getText(); - text += '\n'; - text += content.asString(); - text += '\n'; - mOutput->setText(text); + std::string text = content.asString() + "\n\n> "; + mOutput->appendText(text, false); }; LLTextEditor * mOutput; @@ -72,22 +69,47 @@ LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(LLSD const & key) BOOL LLFloaterRegionDebugConsole::postBuild() { - getChild("region_debug_console_input")->setCommitCallback(boost::bind(&LLFloaterRegionDebugConsole::onInput, this, _1, _2)); + LLLineEditor* input = getChild("region_debug_console_input"); + input->setEnableLineHistory(true); + input->setCommitCallback(boost::bind(&LLFloaterRegionDebugConsole::onInput, this, _1, _2)); + input->setFocus(true); + input->setCommitOnFocusLost(false); + mOutput = getChild("region_debug_console_output"); + + std::string url = gAgent.getRegion()->getCapability("SimConsole"); + if ( url.size() == 0 ) + { + mOutput->appendText("This region does not support the simulator console.\n\n> ", false); + } + else + { + mOutput->appendText("> ", false); + } + + return TRUE; } void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param) { - LLLineEditor * input = static_cast(ctrl); - std::string text = mOutput->getText(); - text += "\n\POST: "; - text += input->getText(); - mOutput->setText(text); + LLLineEditor* input = static_cast(ctrl); + std::string text = input->getText() + "\n"; + std::string url = gAgent.getRegion()->getCapability("SimConsole"); - LLHTTPClient::post(url, LLSD(input->getText()), new ::Responder(mOutput)); - input->setText(std::string("")); + if ( url.size() > 0 ) + { + LLHTTPClient::post(url, LLSD(input->getText()), new ::Responder(mOutput)); + } + else + { + text += "\nError: No console available for this region/simulator.\n\n> "; + } + + mOutput->appendText(text, false); + + input->clear(); } diff --git a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml index 591d77340a..cf95257b0a 100644 --- a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml +++ b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml @@ -6,7 +6,8 @@ min_height="300" min_width="300" height="400" - width="600"> + width="600" + default_tab_group="1"> + word_wrap="true" + track_end="true" + read_only="true"> + width="576" /> -- cgit v1.3 From f8a17515f592a1d759ca2c79f80b2ed032af2ebe Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 22 Sep 2010 12:27:26 -0700 Subject: EXP-109 WIP strip down main_view.xml made menu keyboard access only work when menus are visible dummy widgets are now added with a parent view that is invisible popupview can now be default-built --- indra/llui/llmenugl.cpp | 5 ++++- indra/llui/llview.cpp | 22 ++++++------------- indra/llui/llview.h | 14 +++++------- indra/newview/llpopupview.cpp | 3 ++- indra/newview/llpopupview.h | 2 +- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/skins/minimal/xui/en/main_view.xml | 27 ++++++++++++++++++++++++ 7 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 indra/newview/skins/minimal/xui/en/main_view.xml (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 900a814238..e179f63ee5 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3066,7 +3066,10 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask) mAltKeyTrigger = FALSE; } - if(!result && (key == KEY_F10 && mask == MASK_CONTROL) && !gKeyboard->getKeyRepeated(key)) + if(!result + && (key == KEY_F10 && mask == MASK_CONTROL) + && !gKeyboard->getKeyRepeated(key) + && isInVisibleChain()) { if (getHighlightedItem()) { diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 3fa86bf0ca..6ac009956d 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -163,8 +163,6 @@ LLView::~LLView() if (mDefaultWidgets) { - std::for_each(mDefaultWidgets->begin(), mDefaultWidgets->end(), - DeletePairedPointer()); delete mDefaultWidgets; mDefaultWidgets = NULL; } @@ -1682,18 +1680,7 @@ BOOL LLView::hasChild(const std::string& childname, BOOL recurse) const //----------------------------------------------------------------------------- LLView* LLView::getChildView(const std::string& name, BOOL recurse) const { - LLView* child = findChildView(name, recurse); - if (!child) - { - child = getDefaultWidget(name); - if (!child) - { - LLView::Params view_params; - view_params.name = name; - child = LLUICtrlFactory::create(view_params); - } - } - return child; + return getChild(name, recurse); } static LLFastTimer::DeclareTimer FTM_FIND_VIEWS("Find Widgets"); @@ -2804,11 +2791,14 @@ LLView::root_to_view_iterator_t LLView::endRootToView() // only create maps on demand, as they incur heap allocation/deallocation cost // when a view is constructed/deconstructed -LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const +LLView& LLView::getDefaultWidgetContainer() const { if (!mDefaultWidgets) { - mDefaultWidgets = new default_widget_map_t(); + LLView::Params p; + p.name = "default widget container"; + p.visible = false; // ensures default widgets can't steal focus, etc. + mDefaultWidgets = new LLView(p); } return *mDefaultWidgets; } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 6bcee98f26..e6e0a41962 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -461,12 +461,8 @@ public: template T* getDefaultWidget(const std::string& name) const { - default_widget_map_t::const_iterator found_it = getDefaultWidgetMap().find(name); - if (found_it == getDefaultWidgetMap().end()) - { - return NULL; - } - return dynamic_cast(found_it->second); + LLView* widgetp = getDefaultWidgetContainer().findChildView(name); + return dynamic_cast(widgetp); } ////////////////////////////////////////////// @@ -580,9 +576,9 @@ private: typedef std::map default_widget_map_t; // allocate this map no demand, as it is rarely needed - mutable default_widget_map_t* mDefaultWidgets; + mutable LLView* mDefaultWidgets; - default_widget_map_t& getDefaultWidgetMap() const; + LLView& getDefaultWidgetContainer() const; public: // Depth in view hierarchy during rendering @@ -649,7 +645,7 @@ template T* LLView::getChild(const std::string& name, BOOL recurse) co return NULL; } - getDefaultWidgetMap()[name] = result; + getDefaultWidgetContainer().addChild(result); } } return result; diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 499b6a8f5f..18035c42f4 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -40,7 +40,8 @@ bool view_visible(LLView* viewp) } -LLPopupView::LLPopupView() +LLPopupView::LLPopupView(const LLPopupView::Params& p) +: LLPanel(p) { // register ourself as handler of UI popups LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this)); diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h index fec4afd79c..b378f61984 100644 --- a/indra/newview/llpopupview.h +++ b/indra/newview/llpopupview.h @@ -32,7 +32,7 @@ class LLPopupView : public LLPanel { public: - LLPopupView(); + LLPopupView(const Params& p = LLPanel::Params()); ~LLPopupView(); /*virtual*/ void draw(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 7f8b7fba9f..19f51b2bbe 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1524,7 +1524,7 @@ void LLViewerWindow::initBase() mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle(); mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle(); - mPopupView = main_view->findChild("popup_holder"); + mPopupView = main_view->getChild("popup_holder"); mHintHolder = main_view->getChild("hint_holder")->getHandle(); // Constrain floaters to inside the menu and status bar regions. diff --git a/indra/newview/skins/minimal/xui/en/main_view.xml b/indra/newview/skins/minimal/xui/en/main_view.xml new file mode 100644 index 0000000000..c793b1b813 --- /dev/null +++ b/indra/newview/skins/minimal/xui/en/main_view.xml @@ -0,0 +1,27 @@ + + + + + -- cgit v1.3 From 636c86782b9c8a37996aaf01868f713214c54584 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 22 Sep 2010 16:12:04 -0700 Subject: cleaned up notifications.xml and made global notifications toggle not use or modify saved responses --- indra/llui/llnotifications.cpp | 28 ++++++++++---- indra/newview/app_settings/cmd_line.xml | 2 +- .../newview/skins/default/xui/en/notifications.xml | 44 +++++----------------- 3 files changed, 30 insertions(+), 44 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index ab9bd12b85..d86b0183fc 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -133,12 +133,6 @@ private: bool filterIgnoredNotifications(LLNotificationPtr notification) { - // filter everything if we are to ignore ALL - if(LLNotifications::instance().getIgnoreAllNotifications()) - { - return false; - } - LLNotificationFormPtr form = notification->getForm(); // Check to see if the user wants to ignore this alert return !notification->getForm()->getIgnored(); @@ -173,6 +167,20 @@ bool handleIgnoredNotification(const LLSD& payload) return false; } +bool defaultResponse(const LLSD& payload) +{ + if (payload["sigtype"].asString() == "add") + { + LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID()); + if (pNotif) + { + // supply default response + pNotif->respond(pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON)); + } + } + return false; +} + namespace LLNotificationFilters { // a sample filter @@ -1187,9 +1195,11 @@ void LLNotifications::createDefaultChannels() { // now construct the various channels AFTER loading the notifications, // because the history channel is going to rewrite the stored notifications file - LLNotificationChannel::buildChannel("Expiration", "", + LLNotificationChannel::buildChannel("Enabled", "", + !boost::bind(&LLNotifications::getIgnoreAllNotifications, this)); + LLNotificationChannel::buildChannel("Expiration", "Enabled", boost::bind(&LLNotifications::expirationFilter, this, _1)); - LLNotificationChannel::buildChannel("Unexpired", "", + LLNotificationChannel::buildChannel("Unexpired", "Enabled", !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind LLNotificationChannel::buildChannel("Unique", "Unexpired", boost::bind(&LLNotifications::uniqueFilter, this, _1)); @@ -1203,6 +1213,8 @@ void LLNotifications::createDefaultChannels() new LLPersistentNotificationChannel(); // connect action methods to these channels + LLNotifications::instance().getChannel("Enabled")-> + connectFailedFilter(&defaultResponse); LLNotifications::instance().getChannel("Expiration")-> connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1)); // uniqueHandler slot should be added as first slot of the signal due to diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 00d69f805e..962c4e9d36 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -149,7 +149,7 @@ nonotifications desc - User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs. + User will not get any notifications. map-to IgnoreAllNotifications diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index e1aecda151..5966db9d51 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2069,7 +2069,7 @@ Would you be my friend? -- cgit v1.3 From 3c4cf5a309612d2a999453b282cad0aab7764083 Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Wed, 1 Dec 2010 15:46:57 +0200 Subject: STORM-677 ADDITIONAL_FIX Force textures inside texture picker to be 100% opaque while the control is in a focused floater. Besides, made LLFloater handle opacity more like other controls do. --- indra/llui/llfloater.cpp | 33 +++++++++++++++++---------------- indra/llui/llfloater.h | 5 ++--- indra/newview/llnearbychat.cpp | 13 +++++++++++++ indra/newview/llnearbychat.h | 1 + indra/newview/llsidetray.cpp | 2 +- indra/newview/lltexturectrl.cpp | 6 ++++-- 6 files changed, 38 insertions(+), 22 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index da5dad6b82..7727e154da 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1189,7 +1189,7 @@ void LLFloater::setFocus( BOOL b ) last_focus->setFocus(TRUE); } } - updateChildrenTransparency(this, b ? TT_ACTIVE : TT_INACTIVE); + updateTransparency(this, b ? TT_ACTIVE : TT_INACTIVE); } // virtual @@ -1649,7 +1649,7 @@ void LLFloater::onClickCloseBtn() // virtual void LLFloater::draw() { - mCurrentTransparency = hasFocus() ? sActiveControlTransparency : sInactiveControlTransparency; + const F32 alpha = getCurrentTransparency(); // draw background if( isBackgroundVisible() ) @@ -1681,12 +1681,12 @@ void LLFloater::draw() if (image) { // We're using images for this floater's backgrounds - image->draw(getLocalRect(), overlay_color % mCurrentTransparency); + image->draw(getLocalRect(), overlay_color % alpha); } else { // We're not using images, use old-school flat colors - gl_rect_2d( left, top, right, bottom, color % mCurrentTransparency ); + gl_rect_2d( left, top, right, bottom, color % alpha ); // draw highlight on title bar to indicate focus. RDW if(hasFocus() @@ -1698,7 +1698,7 @@ void LLFloater::draw() const LLFontGL* font = LLFontGL::getFontSansSerif(); LLRect r = getRect(); gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1, - titlebar_focus_color % mCurrentTransparency, 0, TRUE); + titlebar_focus_color % alpha, 0, TRUE); } } } @@ -1764,29 +1764,30 @@ void LLFloater::drawShadow(LLPanel* panel) shadow_color.mV[VALPHA] *= 0.5f; } gl_drop_shadow(left, top, right, bottom, - shadow_color % mCurrentTransparency, + shadow_color % getCurrentTransparency(), llround(shadow_offset)); } -void LLFloater::updateChildrenTransparency(LLView* ctrl, ETypeTransparency transparency_type) +void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type) { - child_list_t children = *ctrl->getChildList(); + child_list_t children = *view->getChildList(); child_list_t::iterator it = children.begin(); + LLUICtrl* ctrl = dynamic_cast(view); + if (ctrl) + { + ctrl->setTransparencyType(transparency_type); + } + for(; it != children.end(); ++it) { - LLUICtrl* ui_ctrl = dynamic_cast(*it); - if (ui_ctrl) - { - ui_ctrl->setTransparencyType(transparency_type); - } - updateChildrenTransparency(*it, transparency_type); + updateTransparency(*it, transparency_type); } } -void LLFloater::updateChildrenTransparency(ETypeTransparency transparency_type) +void LLFloater::updateTransparency(ETypeTransparency transparency_type) { - updateChildrenTransparency(this, transparency_type); + updateTransparency(this, transparency_type); } void LLFloater::setCanMinimize(BOOL can_minimize) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 2ec233f454..bb96272d02 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -285,7 +285,7 @@ public: static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } static LLMultiFloater* getFloaterHost() {return sHostp; } - void updateChildrenTransparency(ETypeTransparency transparency_type); + void updateTransparency(ETypeTransparency transparency_type); protected: @@ -345,7 +345,7 @@ private: static void updateActiveFloaterTransparency(); static void updateInactiveFloaterTransparency(); - void updateChildrenTransparency(LLView* ctrl, ETypeTransparency transparency_type); + void updateTransparency(LLView* view, ETypeTransparency transparency_type); public: // Called when floater is opened, passes mKey @@ -363,7 +363,6 @@ protected: std::string mVisibilityControl; std::string mDocStateControl; LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg - F32 mCurrentTransparency; LLDragHandle* mDragHandle; LLResizeBar* mResizeBar[4]; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 180695e40b..572eeb8fc7 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -365,3 +365,16 @@ BOOL LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask) mChatHistory->setFocus(TRUE); return LLDockableFloater::handleMouseDown(x, y, mask); } + +void LLNearbyChat::draw() +{ + // *HACK: Update transparency type depending on whether our children have focus. + // This is needed because this floater is chrome and thus cannot accept focus, so + // the transparency type setting code from LLFloater::setFocus() isn't reached. + if (getTransparencyType() != TT_DEFAULT) + { + setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE); + } + + LLDockableFloater::draw(); +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 1e62910385..2ea79797f8 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -48,6 +48,7 @@ public: bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual void draw(); // focus overrides /*virtual*/ void onFocusLost(); diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 526f3d1e77..3f8aeaf400 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -277,7 +277,7 @@ void LLSideTrayTab::dock(LLFloater* floater_tab) if (!side_tray) return; // Before docking the tab, reset its (and its children's) transparency to default (STORM-688). - floater_tab->updateChildrenTransparency(TT_DEFAULT); + floater_tab->updateTransparency(TT_DEFAULT); if (!side_tray->addTab(this)) { diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 759f68b321..56e9739350 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -564,7 +564,8 @@ void LLFloaterTexturePicker::draw() LLRect interior = border; interior.stretch( -1 ); - const F32 alpha = mCurrentTransparency; // mCurrentTransparency gets updated in LLFloater::draw() + // If the floater is focused, don't apply its alpha to the texture (STORM-677). + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); if( mTexturep ) { if( mTexturep->getComponents() == 4 ) @@ -1264,7 +1265,8 @@ void LLTextureCtrl::draw() LLRect interior = border; interior.stretch( -1 ); - const F32 alpha = getCurrentTransparency(); + // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677). + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); if( mTexturep ) { if( mTexturep->getComponents() == 4 ) -- cgit v1.3 From 3cf5ee8a2f547af245140f058288a093a2ff0ed0 Mon Sep 17 00:00:00 2001 From: Kent Quirk Date: Wed, 1 Dec 2010 15:34:44 -0500 Subject: Fix STORM-716 by re-fixing STORM-530 in a different way. --- indra/llui/llcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index a268ee5d75..70014fe4f5 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -769,7 +769,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask) return FALSE; } // if selection has changed, pop open list - else + else if ((mList->getLastSelectedItem() != last_selected_item) || (key == KEY_DOWN) || (key == KEY_UP)) { showList(); } -- cgit v1.3 From 7ed0938226d377e4945e9eea65ef4e4856716fbd Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Fri, 3 Dec 2010 20:45:53 +0200 Subject: STORM-579 FIXED SLURLs color for residents and objects names in plain text chat match the user setting for "URLs" in the Color tab in Prefs. Avatar names SLURLs now use the user color setting for "URLs" everywhere across the viewer. --- indra/llui/llurlentry.cpp | 4 ++-- indra/newview/llchathistory.cpp | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 6cc72bad82..f25be55665 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -456,8 +456,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa LLStyle::Params LLUrlEntryAgent::getStyle() const { LLStyle::Params style_params = LLUrlEntryBase::getStyle(); - style_params.color = LLUIColorTable::instance().getColor("AgentLinkColor"); - style_params.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor"); + style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); return style_params; } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 271ee0c4a4..6e778de2d8 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -789,24 +789,22 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // set the link for the object name to be the objectim SLapp // (don't let object names with hyperlinks override our objectim Url) LLStyle::Params link_params(style_params); - link_params.color.control = "HTMLLinkColor"; + LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + link_params.color = link_color; + link_params.readonly_color = link_color; link_params.is_link = true; link_params.link_href = url; + mEditor->appendText(chat.mFromName + delimiter, false, link_params); } else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) { LLStyle::Params link_params(style_params); - - // Setting is_link = true for agent SLURL to avoid applying default style to it. - // See LLTextBase::appendTextImpl(). - link_params.is_link = true; - link_params.link_href = LLSLURL("agent", chat.mFromID, "inspect").getSLURLString(); + link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); // Add link to avatar's inspector and delimiter to message. - mEditor->appendText(chat.mFromName, false, link_params); - mEditor->appendText(delimiter, false, style_params); + mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params); } else { -- cgit v1.3 From b9fa0e9bbe0db5ecdfb5fbdd88474e0d3bb8eed2 Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Sat, 4 Dec 2010 13:07:51 +0200 Subject: STORM-717 FIXED Made nearby chat toasts respect transparency settings: * Normally toasts are as opaque as specified by "inactive floater opacity" setting. * When mouse is hovering a toast, the toast uses "active floater opacity" setting. * Fading toasts have 1/2 of "inactive floater opacity". --- indra/llui/lluictrl.cpp | 4 ++++ indra/llui/lluictrl.h | 5 +++-- indra/newview/llnearbychathandler.cpp | 39 +++++++++++++++++++++++++++++++++++ indra/newview/lltoast.h | 8 ++++--- 4 files changed, 51 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 7e4cb78d80..afd60cbb3e 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -944,6 +944,10 @@ F32 LLUICtrl::getCurrentTransparency() case TT_INACTIVE: alpha = sInactiveControlTransparency; break; + + case TT_FADING: + alpha = sInactiveControlTransparency / 2; + break; } return alpha; diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index a78f98ac76..b37e9f6b1b 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -123,8 +123,9 @@ public: enum ETypeTransparency { TT_DEFAULT, - TT_ACTIVE, - TT_INACTIVE + TT_ACTIVE, // focused floater + TT_INACTIVE, // other floaters + TT_FADING, // fading toast }; /*virtual*/ ~LLUICtrl(); diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index d2ad78f140..dfbbaa0941 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -165,11 +165,20 @@ public: : LLToast(p), mNearbyChatScreenChannelp(nc_channelp) { + updateTransparency(); + setMouseEnterCallback(boost::bind(&LLNearbyChatToast::updateTransparency, this)); + setMouseLeaveCallback(boost::bind(&LLNearbyChatToast::updateTransparency, this)); } /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void setBackgroundOpaque(BOOL b); + +protected: + /*virtual*/ void setTransparentState(bool transparent); private: + void updateTransparency(); + LLNearbyChatScreenChannel* mNearbyChatScreenChannelp; }; @@ -597,4 +606,34 @@ void LLNearbyChatToast::onClose(bool app_quitting) mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting); } +// virtual +void LLNearbyChatToast::setBackgroundOpaque(BOOL b) +{ + // We don't want background changes: transparency is handled differently. + LLToast::setBackgroundOpaque(TRUE); +} + +// virtual +void LLNearbyChatToast::setTransparentState(bool transparent) +{ + LLToast::setTransparentState(transparent); + updateTransparency(); +} + +void LLNearbyChatToast::updateTransparency() +{ + ETypeTransparency transparency_type; + + if (isHovered()) + { + transparency_type = TT_ACTIVE; + } + else + { + transparency_type = getTransparentState() ? TT_FADING : TT_INACTIVE; + } + + LLFloater::updateTransparency(transparency_type); +} + // EOF diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index f88c628631..d23e858c5c 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -141,7 +141,7 @@ public: // virtual void setVisible(BOOL show); - /*virtual*/ void setBackgroundOpaque(BOOL b); + virtual void setBackgroundOpaque(BOOL b); // virtual void hide(); @@ -198,6 +198,10 @@ public: LLHandle getHandle() { mHandle.bind(this); return mHandle; } + bool getTransparentState() const { return mIsTransparent; } + virtual void setTransparentState(bool transparent); + + private: void onToastMouseEnter(); @@ -206,8 +210,6 @@ private: void expire(); - void setTransparentState(bool transparent); - LLUUID mNotificationID; LLUUID mSessionID; LLNotificationPtr mNotification; -- cgit v1.3 From 81313cb3047b215df8f6e4c053a2a656274a8983 Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Tue, 7 Dec 2010 12:06:35 +0200 Subject: STORM-732 FIXED Voice Morphing floater was opaque on first open. --- indra/llui/llfloater.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 7727e154da..e79e280b20 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1462,6 +1462,9 @@ void LLFloater::setFrontmost(BOOL take_focus) // there are more than one floater view // so we need to query our parent directly ((LLFloaterView*)getParent())->bringToFront(this, take_focus); + + // Make sure we use the active floater transparency settings (STORM-732). + updateTransparency(TT_ACTIVE); } } -- cgit v1.3 From 2b70e8e0017846b174baaaea0ca1ca63e871eaba Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Tue, 7 Dec 2010 13:45:29 +0200 Subject: STORM-733 FIXED Build Tools floater now has inactive floater transparency when opened (because it's not focused by default). --- indra/llui/llfloater.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e79e280b20..1265733bf5 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1,4 +1,5 @@ /** + * @file llfloater.cpp * @brief LLFloater base class * @@ -1189,7 +1190,7 @@ void LLFloater::setFocus( BOOL b ) last_focus->setFocus(TRUE); } } - updateTransparency(this, b ? TT_ACTIVE : TT_INACTIVE); + updateTransparency(b ? TT_ACTIVE : TT_INACTIVE); } // virtual @@ -1463,8 +1464,8 @@ void LLFloater::setFrontmost(BOOL take_focus) // so we need to query our parent directly ((LLFloaterView*)getParent())->bringToFront(this, take_focus); - // Make sure we use the active floater transparency settings (STORM-732). - updateTransparency(TT_ACTIVE); + // Make sure to set the appropriate transparency type (STORM-732). + updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); } } -- cgit v1.3 From 91480065ca8bc1f023e41f5afbbc3c12b8463c3b Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Tue, 7 Dec 2010 16:05:12 +0200 Subject: STORM-710 FIXED Don't show search history dropdown if the history is empty. --- indra/llui/llcombobox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 70014fe4f5..6b06040b8a 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -769,7 +769,8 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask) return FALSE; } // if selection has changed, pop open list - else if ((mList->getLastSelectedItem() != last_selected_item) || (key == KEY_DOWN) || (key == KEY_UP)) + else if (mList->getLastSelectedItem() != last_selected_item || + (key == KEY_DOWN || key == KEY_UP) && !mList->isEmpty()) { showList(); } -- cgit v1.3 From 32750132db47eb335c56f6c880902cf7195e1825 Mon Sep 17 00:00:00 2001 From: Andrew Productengine Date: Thu, 9 Dec 2010 19:54:40 +0200 Subject: STORM-34 ADDITIONAL_FIX Implemented storing of multi-user favorites and showing them on login screen. - Changed the way SLURLs are cached a little, because previous one introduced problems with theit order. - Also allowed saving of favorites to disk even if not all of them received SLURL info - this is done to avoid favorites not saving when there is at least one "dead" landmark among them. - "Username" field on login screen is now not a lineeditor, but combobox (to enable autocompletion), but without button (Esbee asked for this in ticket for security reasons, and perhaps for visual consistency). - Elements of this combobox are names of users whose favorites we have saved in file. - Contents of "Start at:" combobox are changed depending on changes in "Username"- if username is present in favorites file, favorites for this user are added there. - New callback was added to LLCombobox and used in this fix, because present ones weren't enough to easily track changes in text entry. --- indra/llui/llcombobox.cpp | 9 +++ indra/llui/llcombobox.h | 5 +- indra/newview/llfavoritesbar.cpp | 3 +- indra/newview/llpanellogin.cpp | 68 ++++++++++++++++------ indra/newview/llpanellogin.h | 2 +- indra/newview/llviewerinventory.cpp | 22 ++++--- indra/newview/llviewerinventory.h | 1 + indra/newview/skins/default/xui/en/panel_login.xml | 21 ++++--- 8 files changed, 93 insertions(+), 38 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 70014fe4f5..9f32ade280 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -94,6 +94,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mMaxChars(p.max_chars), mPrearrangeCallback(p.prearrange_callback()), mTextEntryCallback(p.text_entry_callback()), + mTextChangedCallback(p.text_changed_callback()), mListPosition(p.list_position), mLastSelectedIndex(-1), mLabel(p.label) @@ -833,6 +834,10 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor) mList->deselectAllItems(); mLastSelectedIndex = -1; } + if (mTextChangedCallback != NULL) + { + (mTextChangedCallback)(line_editor, LLSD()); + } return; } @@ -877,6 +882,10 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor) // RN: presumably text entry updateSelection(); } + if (mTextChangedCallback != NULL) + { + (mTextChangedCallback)(line_editor, LLSD()); + } } void LLComboBox::updateSelection() diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 5f0e4a6843..74d64269bd 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -73,7 +73,8 @@ public: allow_new_values; Optional max_chars; Optional prearrange_callback, - text_entry_callback; + text_entry_callback, + text_changed_callback; Optional list_position; @@ -190,6 +191,7 @@ public: void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; } void setTextEntryCallback( commit_callback_t cb ) { mTextEntryCallback = cb; } + void setTextChangedCallback( commit_callback_t cb ) { mTextChangedCallback = cb; } void setButtonVisible(BOOL visible); @@ -220,6 +222,7 @@ private: BOOL mTextEntryTentative; commit_callback_t mPrearrangeCallback; commit_callback_t mTextEntryCallback; + commit_callback_t mTextChangedCallback; commit_callback_t mSelectionCallback; boost::signals2::connection mTopLostSignalConnection; S32 mLastSelectedIndex; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 4f87221065..9f1d3a2a7d 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -611,10 +611,9 @@ void LLFavoritesBarCtrl::changed(U32 mask) LLIsType is_type(LLAssetType::AT_LANDMARK); gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); - S32 sortField = 0; for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) { - (*i)->setSortField(++sortField); + (*i)->getSLURL(); } updateButtons(); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 16ea303c77..c50e8c48b5 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -266,26 +266,51 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // Show last logged in user favorites in "Start at" combo if corresponding option is enabled. if (gSavedSettings.getBOOL("ShowFavoritesOnLogin")) { - addFavoritesToStartLocation(); + addUsersWithFavoritesToUsername(); + getChild("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); } updateLocationCombo(false); } -void LLPanelLogin::addFavoritesToStartLocation() +void LLPanelLogin::addUsersWithFavoritesToUsername() { + LLComboBox* combo = getChild("username_combo"); + if (!combo) return; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); LLSD fav_llsd; llifstream file; file.open(filename); if (!file.is_open()) return; + LLSDSerialize::fromXML(fav_llsd, file); + for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); + iter != fav_llsd.endMap(); ++iter) + { + combo->add(iter->first); + } +} + +void LLPanelLogin::addFavoritesToStartLocation() +{ LLComboBox* combo = getChild("start_location_combo"); - combo->addSeparator(); + if (!combo) return; + int num_items = combo->getItemCount(); + for (int i = num_items - 1; i > 2; i--) + { + combo->remove(i); + } + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + LLSD fav_llsd; + llifstream file; + file.open(filename); + if (!file.is_open()) return; LLSDSerialize::fromXML(fav_llsd, file); for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); iter != fav_llsd.endMap(); ++iter) { + if(iter->first != getChild("username_combo")->getSimple()) continue; + combo->addSeparator(); LLSD user_llsd = iter->second; for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); iter1 != user_llsd.endArray(); ++iter1) @@ -297,7 +322,7 @@ void LLPanelLogin::addFavoritesToStartLocation() combo->add(label, value); } } - + break; } } @@ -461,13 +486,14 @@ void LLPanelLogin::giveFocus() if( sInstance ) { // Grab focus and move cursor to first blank input field - std::string username = sInstance->getChild("username_edit")->getValue().asString(); + std::string username = sInstance->getChild("username_combo")->getValue().asString(); std::string pass = sInstance->getChild("password_edit")->getValue().asString(); BOOL have_username = !username.empty(); BOOL have_pass = !pass.empty(); LLLineEditor* edit = NULL; + LLComboBox* combo = NULL; if (have_username && !have_pass) { // User saved his name but not his password. Move @@ -477,7 +503,7 @@ void LLPanelLogin::giveFocus() else { // User doesn't have a name, so start there. - edit = sInstance->getChild("username_edit"); + combo = sInstance->getChild("username_combo"); } if (edit) @@ -485,6 +511,10 @@ void LLPanelLogin::giveFocus() edit->setFocus(TRUE); edit->selectAll(); } + else if (combo) + { + combo->setFocus(TRUE); + } } #endif } @@ -498,8 +528,8 @@ void LLPanelLogin::showLoginWidgets() // *TODO: Append all the usual login parameters, like first_login=Y etc. std::string splash_screen_url = sInstance->getString("real_url"); web_browser->navigateTo( splash_screen_url, "text/html" ); - LLUICtrl* username_edit = sInstance->getChild("username_edit"); - username_edit->setFocus(TRUE); + LLUICtrl* username_combo = sInstance->getChild("username_combo"); + username_combo->setFocus(TRUE); } // static @@ -543,15 +573,19 @@ void LLPanelLogin::setFields(LLPointer credential, login_id += " "; login_id += lastname; } - sInstance->getChild("username_edit")->setValue(login_id); + sInstance->getChild("username_combo")->setLabel(login_id); } else if((std::string)identifier["type"] == "account") { - sInstance->getChild("username_edit")->setValue((std::string)identifier["account_name"]); + sInstance->getChild("username_combo")->setLabel((std::string)identifier["account_name"]); } else { - sInstance->getChild("username_edit")->setValue(std::string()); + sInstance->getChild("username_combo")->setLabel(std::string()); + } + if (gSavedSettings.getBOOL("ShowFavoritesOnLogin")) + { + sInstance->addFavoritesToStartLocation(); } // if the password exists in the credential, set the password field with // a filler to get some stars @@ -600,7 +634,7 @@ void LLPanelLogin::getFields(LLPointer& credential, authenticator = credential->getAuthenticator(); } - std::string username = sInstance->getChild("username_edit")->getValue().asString(); + std::string username = sInstance->getChild("username_combo")->getValue().asString(); LLStringUtil::trim(username); std::string password = sInstance->getChild("password_edit")->getValue().asString(); @@ -692,15 +726,15 @@ BOOL LLPanelLogin::areCredentialFieldsDirty() } else { - std::string username = sInstance->getChild("username_edit")->getValue().asString(); + std::string username = sInstance->getChild("username_combo")->getValue().asString(); LLStringUtil::trim(username); std::string password = sInstance->getChild("password_edit")->getValue().asString(); - LLLineEditor* ctrl = sInstance->getChild("username_edit"); - if(ctrl && ctrl->isDirty()) + LLComboBox* combo = sInstance->getChild("username_combo"); + if(combo && combo->isDirty()) { return true; } - ctrl = sInstance->getChild("password_edit"); + LLLineEditor* ctrl = sInstance->getChild("password_edit"); if(ctrl && ctrl->isDirty()) { return true; @@ -1007,7 +1041,7 @@ void LLPanelLogin::onClickConnect(void *) return; } updateStartSLURL(); - std::string username = sInstance->getChild("username_edit")->getValue().asString(); + std::string username = sInstance->getChild("username_combo")->getValue().asString(); if(username.empty()) diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 8a8888a053..1ef6539ecc 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -85,8 +85,8 @@ public: private: friend class LLPanelLoginListener; void reshapeBrowser(); - // adds favorites of last logged in user from file to "Start at" combobox. void addFavoritesToStartLocation(); + void addUsersWithFavoritesToUsername(); static void onClickConnect(void*); static void onClickNewAccount(void*); // static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 941e81d36f..4fa79b1855 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1562,6 +1562,13 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs() if (user_dir.empty()) return; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + llifstream in_file; + in_file.open(filename); + LLSD fav_llsd; + if (in_file.is_open()) + { + LLSDSerialize::fromXML(fav_llsd, in_file); + } const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); LLInventoryModel::cat_array_t cats; @@ -1579,18 +1586,10 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs() if (slurl_iter != mSLURLs.end()) { value["slurl"] = slurl_iter->second; + user_llsd[(*it)->getSortField()] = value; } - else - { - llwarns << "Fetching SLURLs for \"Favorites\" is not complete!" << llendl; - return; - } - - user_llsd[(*it)->getSortField()] = value; } - LLSD fav_llsd; - // this level in LLSD is not needed now and is just a stub, but will be needed later when implementing save of multiple users favorites in one file. LLAvatarName av_name; LLAvatarNameCache::get( gAgentID, &av_name ); fav_llsd[av_name.getLegacyName()] = user_llsd; @@ -1680,6 +1679,11 @@ S32 LLViewerInventoryItem::getSortField() const void LLViewerInventoryItem::setSortField(S32 sortField) { LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField); + getSLURL(); +} + +void LLViewerInventoryItem::getSLURL() +{ LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 1af06a1be8..41542a4e0f 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -62,6 +62,7 @@ public: virtual const std::string& getName() const; virtual S32 getSortField() const; virtual void setSortField(S32 sortField); + virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here. virtual const LLPermissions& getPermissions() const; virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied virtual const LLUUID& getCreatorUUID() const; diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index b181ca3bba..5ad8d1fd40 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -64,23 +64,28 @@ left="20" width="150"> Username: - +name="username_combo" +width="178"> + + + @@ -127,7 +132,7 @@ top="20" Date: Fri, 10 Dec 2010 10:11:03 -0800 Subject: WIP XUI HTTP Auth dialog refactored LLWindowShade into seperate file improved layout of dialog improved dialog resizing logic Tab and Enter keys now work as expected in windowshade form added "modal" capability to window shade added HTTP Auth notifications to MOAP --- indra/llui/CMakeLists.txt | 2 + indra/llui/lllayoutstack.h | 3 + indra/llui/lluictrl.cpp | 2 +- indra/llui/llview.h | 9 +- indra/llui/llwindowshade.cpp | 328 ++++++++++++++++++++++ indra/llui/llwindowshade.h | 69 +++++ indra/newview/llbrowsernotification.cpp | 12 +- indra/newview/llmediactrl.cpp | 280 +----------------- indra/newview/llmediactrl.h | 1 - indra/newview/llpanelprimmediacontrols.cpp | 60 +++- indra/newview/llpanelprimmediacontrols.h | 8 + indra/newview/llviewermedia.cpp | 43 ++- indra/newview/llviewermedia.h | 12 +- indra/newview/llviewermediafocus.cpp | 2 +- indra/newview/skins/default/xui/en/menu_login.xml | 1 - 15 files changed, 546 insertions(+), 286 deletions(-) create mode 100644 indra/llui/llwindowshade.cpp create mode 100644 indra/llui/llwindowshade.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index e98201ea63..063e3906c7 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -111,6 +111,7 @@ set(llui_SOURCE_FILES llviewmodel.cpp llview.cpp llviewquery.cpp + llwindowshade.cpp ) set(llui_HEADER_FILES @@ -209,6 +210,7 @@ set(llui_HEADER_FILES llviewmodel.h llview.h llviewquery.h + llwindowshade.h ) set_source_files_properties(${llui_HEADER_FILES} diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 9e8539c716..e43669d893 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -173,6 +173,9 @@ public: ~LLLayoutPanel(); void initFromParams(const Params& p); + void setMinDim(S32 value) { mMinDim = value; } + void setMaxDim(S32 value) { mMaxDim = value; } + protected: LLLayoutPanel(const Params& p) ; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 3ac3bf8c41..d81f425cce 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -823,7 +823,7 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot() { LLUICtrl* focus_root = NULL; LLUICtrl* next_view = this; - while(next_view) + while(next_view && next_view->hasTabStop()) { if (next_view->isFocusRoot()) { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 33d345beff..cd2f215c2d 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -412,14 +412,9 @@ public: LLControlVariable *findControl(const std::string& name); - // Moved setValue(), getValue(), setControlValue(), setControlName(), - // controlListener() to LLUICtrl because an LLView is NOT assumed to - // contain a value. If that's what you want, use LLUICtrl instead. -// virtual bool handleEvent(LLPointer event, const LLSD& userdata); - const child_list_t* getChildList() const { return &mChildList; } - const child_list_const_iter_t beginChild() { return mChildList.begin(); } - const child_list_const_iter_t endChild() { return mChildList.end(); } + child_list_const_iter_t beginChild() const { return mChildList.begin(); } + child_list_const_iter_t endChild() const { return mChildList.end(); } // LLMouseHandler functions // Default behavior is to pass events to children diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp new file mode 100644 index 0000000000..77e94385d4 --- /dev/null +++ b/indra/llui/llwindowshade.cpp @@ -0,0 +1,328 @@ +/** + * @file LLWindowShade.cpp + * @brief Notification dialog that slides down and optionally disabled a piece of UI + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llwindowshade.h" + +#include "lllayoutstack.h" +#include "lltextbox.h" +#include "lliconctrl.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "lllineeditor.h" + +const S32 MIN_NOTIFICATION_AREA_HEIGHT = 30; +const S32 MAX_NOTIFICATION_AREA_HEIGHT = 100; + +LLWindowShade::Params::Params() +: bg_image("bg_image"), + modal("modal", false), + text_color("text_color"), + can_close("can_close", true) +{ + mouse_opaque = false; +} + +LLWindowShade::LLWindowShade(const LLWindowShade::Params& params) +: LLUICtrl(params), + mNotification(params.notification), + mModal(params.modal), + mFormHeight(0), + mTextColor(params.text_color) +{ + setFocusRoot(true); +} + +void LLWindowShade::initFromParams(const LLWindowShade::Params& params) +{ + LLUICtrl::initFromParams(params); + + LLLayoutStack::Params layout_p; + layout_p.name = "notification_stack"; + layout_p.rect = params.rect; + layout_p.follows.flags = FOLLOWS_ALL; + layout_p.mouse_opaque = false; + layout_p.orientation = LLLayoutStack::VERTICAL; + layout_p.border_size = 0; + + LLLayoutStack* stackp = LLUICtrlFactory::create(layout_p); + addChild(stackp); + + LLLayoutPanel::Params panel_p; + panel_p.rect = LLRect(0, 30, 800, 0); + panel_p.name = "notification_area"; + panel_p.visible = false; + panel_p.user_resize = false; + panel_p.background_visible = true; + panel_p.bg_alpha_image = params.bg_image; + panel_p.auto_resize = false; + LLLayoutPanel* notification_panel = LLUICtrlFactory::create(panel_p); + stackp->addChild(notification_panel); + + panel_p = LLUICtrlFactory::getDefaultParams(); + panel_p.auto_resize = true; + panel_p.user_resize = false; + panel_p.rect = params.rect; + panel_p.name = "background_area"; + panel_p.mouse_opaque = false; + panel_p.background_visible = false; + panel_p.bg_alpha_color = LLColor4(0.f, 0.f, 0.f, 0.2f); + LLLayoutPanel* dummy_panel = LLUICtrlFactory::create(panel_p); + stackp->addChild(dummy_panel); + + layout_p = LLUICtrlFactory::getDefaultParams(); + layout_p.rect = LLRect(0, 30, 800, 0); + layout_p.follows.flags = FOLLOWS_ALL; + layout_p.orientation = LLLayoutStack::HORIZONTAL; + stackp = LLUICtrlFactory::create(layout_p); + notification_panel->addChild(stackp); + + panel_p = LLUICtrlFactory::getDefaultParams(); + panel_p.rect.height = 30; + LLLayoutPanel* panel = LLUICtrlFactory::create(panel_p); + stackp->addChild(panel); + + LLIconCtrl::Params icon_p; + icon_p.name = "notification_icon"; + icon_p.rect = LLRect(5, 23, 21, 8); + panel->addChild(LLUICtrlFactory::create(icon_p)); + + LLTextBox::Params text_p; + text_p.rect = LLRect(31, 20, panel->getRect().getWidth() - 5, 0); + text_p.follows.flags = FOLLOWS_ALL; + text_p.text_color = mTextColor; + text_p.font = LLFontGL::getFontSansSerifSmall(); + text_p.font.style = "BOLD"; + text_p.name = "notification_text"; + text_p.use_ellipses = true; + text_p.wrap = true; + panel->addChild(LLUICtrlFactory::create(text_p)); + + panel_p = LLUICtrlFactory::getDefaultParams(); + panel_p.auto_resize = false; + panel_p.user_resize = false; + panel_p.name="form_elements"; + panel_p.rect = LLRect(0, 30, 130, 0); + LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create(panel_p); + stackp->addChild(form_elements_panel); + + if (params.can_close) + { + panel_p = LLUICtrlFactory::getDefaultParams(); + panel_p.auto_resize = false; + panel_p.user_resize = false; + panel_p.rect = LLRect(0, 30, 25, 0); + LLLayoutPanel* close_panel = LLUICtrlFactory::create(panel_p); + stackp->addChild(close_panel); + + LLButton::Params button_p; + button_p.name = "close_notification"; + button_p.rect = LLRect(5, 23, 21, 7); + button_p.image_color.control="DkGray_66"; + button_p.image_unselected.name="Icon_Close_Foreground"; + button_p.image_selected.name="Icon_Close_Press"; + button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this); + + close_panel->addChild(LLUICtrlFactory::create(button_p)); + } + + LLSD payload = mNotification->getPayload(); + + LLNotificationFormPtr formp = mNotification->getForm(); + LLLayoutPanel& notification_area = getChildRef("notification_area"); + notification_area.getChild("notification_icon")->setValue(mNotification->getIcon()); + notification_area.getChild("notification_text")->setValue(mNotification->getMessage()); + notification_area.getChild("notification_text")->setToolTip(mNotification->getMessage()); + + LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); + LLLayoutPanel& form_elements = notification_area.getChildRef("form_elements"); + form_elements.deleteAllChildren(); + + const S32 FORM_PADDING_HORIZONTAL = 10; + const S32 FORM_PADDING_VERTICAL = 3; + const S32 WIDGET_HEIGHT = 24; + const S32 LINE_EDITOR_WIDTH = 120; + S32 cur_x = FORM_PADDING_HORIZONTAL; + S32 cur_y = FORM_PADDING_VERTICAL + WIDGET_HEIGHT; + S32 form_width = cur_x; + + if (ignore_type != LLNotificationForm::IGNORE_NO) + { + LLCheckBoxCtrl::Params checkbox_p; + checkbox_p.name = "ignore_check"; + checkbox_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT); + checkbox_p.label = formp->getIgnoreMessage(); + checkbox_p.label_text.text_color = LLColor4::black; + checkbox_p.commit_callback.function = boost::bind(&LLWindowShade::onClickIgnore, this, _1); + checkbox_p.initial_value = formp->getIgnored(); + + LLCheckBoxCtrl* check = LLUICtrlFactory::create(checkbox_p); + check->setRect(check->getBoundingRect()); + form_elements.addChild(check); + cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL; + form_width = llmax(form_width, cur_x); + } + + for (S32 i = 0; i < formp->getNumElements(); i++) + { + LLSD form_element = formp->getElement(i); + std::string type = form_element["type"].asString(); + if (type == "button") + { + LLButton::Params button_p; + button_p.name = form_element["name"]; + button_p.label = form_element["text"]; + button_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT); + button_p.click_callback.function = boost::bind(&LLWindowShade::onClickNotificationButton, this, form_element["name"].asString()); + button_p.auto_resize = true; + + LLButton* button = LLUICtrlFactory::create(button_p); + button->autoResize(); + form_elements.addChild(button); + + if (form_element["default"].asBoolean()) + { + form_elements.setDefaultBtn(button); + } + + cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL; + form_width = llmax(form_width, cur_x); + } + else if (type == "text" || type == "password") + { + // if not at beginning of line... + if (cur_x != FORM_PADDING_HORIZONTAL) + { + // start new line + cur_x = FORM_PADDING_HORIZONTAL; + cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL; + } + LLTextBox::Params label_p; + label_p.name = form_element["name"].asString() + "_label"; + label_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT); + label_p.initial_value = form_element["text"]; + label_p.text_color = mTextColor; + label_p.font_valign = LLFontGL::VCENTER; + label_p.v_pad = 5; + LLTextBox* textbox = LLUICtrlFactory::create(label_p); + textbox->reshapeToFitText(); + textbox->reshape(textbox->getRect().getWidth(), form_elements.getRect().getHeight() - 2 * FORM_PADDING_VERTICAL); + form_elements.addChild(textbox); + cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL; + + LLLineEditor::Params line_p; + line_p.name = form_element["name"]; + line_p.keystroke_callback = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString()); + line_p.is_password = type == "password"; + line_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT); + + LLLineEditor* line_editor = LLUICtrlFactory::create(line_p); + form_elements.addChild(line_editor); + form_width = llmax(form_width, cur_x + LINE_EDITOR_WIDTH + FORM_PADDING_HORIZONTAL); + + // reset to start of next line + cur_x = FORM_PADDING_HORIZONTAL; + cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL; + } + } + + mFormHeight = form_elements.getRect().getHeight() - (cur_y - FORM_PADDING_VERTICAL) + WIDGET_HEIGHT; + form_elements.reshape(form_width, mFormHeight); + form_elements.setMinDim(form_width); + + // move all form elements back onto form surface + S32 delta_y = WIDGET_HEIGHT + FORM_PADDING_VERTICAL - cur_y; + for (child_list_const_iter_t it = form_elements.getChildList()->begin(), end_it = form_elements.getChildList()->end(); + it != end_it; + ++it) + { + (*it)->translate(0, delta_y); + } +} + +void LLWindowShade::show() +{ + getChildRef("notification_area").setVisible(true); + getChildRef("background_area").setBackgroundVisible(mModal); + + setMouseOpaque(mModal); +} + +void LLWindowShade::draw() +{ + LLRect message_rect = getChild("notification_text")->getTextBoundingRect(); + + LLLayoutPanel* notification_area = getChild("notification_area"); + + notification_area->reshape(notification_area->getRect().getWidth(), + llclamp(message_rect.getHeight() + 10, + llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT), + MAX_NOTIFICATION_AREA_HEIGHT)); + + LLUICtrl::draw(); + if (mNotification && !mNotification->isActive()) + { + hide(); + } +} + +void LLWindowShade::hide() +{ + getChildRef("notification_area").setVisible(false); + getChildRef("background_area").setBackgroundVisible(false); + + setMouseOpaque(false); +} + +void LLWindowShade::onCloseNotification() +{ + LLNotifications::instance().cancel(mNotification); +} + +void LLWindowShade::onClickIgnore(LLUICtrl* ctrl) +{ + bool check = ctrl->getValue().asBoolean(); + if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) + { + // question was "show again" so invert value to get "ignore" + check = !check; + } + mNotification->setIgnored(check); +} + +void LLWindowShade::onClickNotificationButton(const std::string& name) +{ + if (!mNotification) return; + + mNotificationResponse[name] = true; + + mNotification->respond(mNotificationResponse); +} + +void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name) +{ + mNotificationResponse[name] = ctrl->getValue().asString(); +} diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h new file mode 100644 index 0000000000..0047195929 --- /dev/null +++ b/indra/llui/llwindowshade.h @@ -0,0 +1,69 @@ +/** + * @file llwindowshade.h + * @brief Notification dialog that slides down and optionally disabled a piece of UI + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWINDOWSHADE_H +#define LL_LLWINDOWSHADE_H + +#include "lluictrl.h" +#include "llnotifications.h" + +class LLWindowShade : public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block + { + Mandatory notification; + Optional bg_image; + Optional text_color; + Optional modal, + can_close; + + Params(); + }; + + void show(); + /*virtual*/ void draw(); + void hide(); + +private: + friend class LLUICtrlFactory; + + LLWindowShade(const Params& p); + void initFromParams(const Params& params); + + void onCloseNotification(); + void onClickNotificationButton(const std::string& name); + void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name); + void onClickIgnore(LLUICtrl* ctrl); + + LLNotificationPtr mNotification; + LLSD mNotificationResponse; + bool mModal; + S32 mFormHeight; + LLUIColor mTextColor; +}; + +#endif // LL_LLWINDOWSHADE_H diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 633ef4f1ce..6e77d1e336 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -31,6 +31,7 @@ #include "llnotifications.h" #include "llmediactrl.h" #include "llviewermedia.h" +#include "llviewermediafocus.h" using namespace LLNotificationsUI; @@ -39,10 +40,19 @@ bool LLBrowserNotification::processNotification(const LLSD& notify) LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); if (!notification) return false; - LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID()); + LLUUID media_id = notification->getPayload()["media_id"].asUUID(); + LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id); if (media_instance) { media_instance->showNotification(notification); } + else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id) + { + LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(media_id); + if (impl) + { + impl->showNotification(notification); + } + } return false; } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index eaa2a60938..6ae95a9039 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -57,264 +57,12 @@ #include "lllineeditor.h" #include "llfloatermediabrowser.h" #include "llfloaterwebcontent.h" +#include "llwindowshade.h" extern BOOL gRestoreGL; static LLDefaultChildRegistry::Register r("web_browser"); -class LLWindowShade : public LLView -{ -public: - struct Params : public LLInitParam::Block - { - Mandatory notification; - Optional bg_image; - - Params() - : bg_image("bg_image") - { - mouse_opaque = false; - } - }; - - void show(); - /*virtual*/ void draw(); - void hide(); - -private: - friend class LLUICtrlFactory; - - LLWindowShade(const Params& p); - void initFromParams(const Params& params); - - void onCloseNotification(); - void onClickNotificationButton(const std::string& name); - void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name); - void onClickIgnore(LLUICtrl* ctrl); - - LLNotificationPtr mNotification; - LLSD mNotificationResponse; -}; - -LLWindowShade::LLWindowShade(const LLWindowShade::Params& params) -: LLView(params), - mNotification(params.notification) -{ -} - -void LLWindowShade::initFromParams(const LLWindowShade::Params& params) -{ - LLView::initFromParams(params); - - LLLayoutStack::Params layout_p; - layout_p.name = "notification_stack"; - layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30); - layout_p.follows.flags = FOLLOWS_ALL; - layout_p.mouse_opaque = false; - layout_p.orientation = LLLayoutStack::VERTICAL; - - LLLayoutStack* stackp = LLUICtrlFactory::create(layout_p); - addChild(stackp); - - LLLayoutPanel::Params panel_p; - panel_p.rect = LLRect(0, 30, 800, 0); - panel_p.min_height = 30; - panel_p.name = "notification_area"; - panel_p.visible = false; - panel_p.user_resize = false; - panel_p.background_visible = true; - panel_p.bg_alpha_image = params.bg_image; - panel_p.auto_resize = false; - LLLayoutPanel* notification_panel = LLUICtrlFactory::create(panel_p); - stackp->addChild(notification_panel); - - panel_p = LLUICtrlFactory::getDefaultParams(); - panel_p.auto_resize = true; - panel_p.mouse_opaque = false; - LLLayoutPanel* dummy_panel = LLUICtrlFactory::create(panel_p); - stackp->addChild(dummy_panel); - - layout_p = LLUICtrlFactory::getDefaultParams(); - layout_p.rect = LLRect(0, 30, 800, 0); - layout_p.follows.flags = FOLLOWS_ALL; - layout_p.orientation = LLLayoutStack::HORIZONTAL; - stackp = LLUICtrlFactory::create(layout_p); - notification_panel->addChild(stackp); - - panel_p = LLUICtrlFactory::getDefaultParams(); - panel_p.rect.height = 30; - LLLayoutPanel* panel = LLUICtrlFactory::create(panel_p); - stackp->addChild(panel); - - LLIconCtrl::Params icon_p; - icon_p.name = "notification_icon"; - icon_p.rect = LLRect(5, 23, 21, 8); - panel->addChild(LLUICtrlFactory::create(icon_p)); - - LLTextBox::Params text_p; - text_p.rect = LLRect(31, 20, 430, 0); - text_p.text_color = LLColor4::black; - text_p.font = LLFontGL::getFontSansSerif(); - text_p.font.style = "BOLD"; - text_p.name = "notification_text"; - text_p.use_ellipses = true; - panel->addChild(LLUICtrlFactory::create(text_p)); - - panel_p = LLUICtrlFactory::getDefaultParams(); - panel_p.auto_resize = false; - panel_p.user_resize = false; - panel_p.name="form_elements"; - panel_p.rect = LLRect(0, 30, 130, 0); - LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create(panel_p); - stackp->addChild(form_elements_panel); - - panel_p = LLUICtrlFactory::getDefaultParams(); - panel_p.auto_resize = false; - panel_p.user_resize = false; - panel_p.rect = LLRect(0, 30, 25, 0); - LLLayoutPanel* close_panel = LLUICtrlFactory::create(panel_p); - stackp->addChild(close_panel); - - LLButton::Params button_p; - button_p.name = "close_notification"; - button_p.rect = LLRect(5, 23, 21, 7); - button_p.image_color=LLUIColorTable::instance().getColor("DkGray_66"); - button_p.image_unselected.name="Icon_Close_Foreground"; - button_p.image_selected.name="Icon_Close_Press"; - button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this); - - close_panel->addChild(LLUICtrlFactory::create(button_p)); - - LLSD payload = mNotification->getPayload(); - - LLNotificationFormPtr formp = mNotification->getForm(); - LLLayoutPanel& notification_area = getChildRef("notification_area"); - notification_area.getChild("notification_icon")->setValue(mNotification->getIcon()); - notification_area.getChild("notification_text")->setValue(mNotification->getMessage()); - notification_area.getChild("notification_text")->setToolTip(mNotification->getMessage()); - LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); - LLLayoutPanel& form_elements = notification_area.getChildRef("form_elements"); - form_elements.deleteAllChildren(); - - const S32 FORM_PADDING_HORIZONTAL = 10; - const S32 FORM_PADDING_VERTICAL = 3; - S32 cur_x = FORM_PADDING_HORIZONTAL; - - if (ignore_type != LLNotificationForm::IGNORE_NO) - { - LLCheckBoxCtrl::Params checkbox_p; - checkbox_p.name = "ignore_check"; - checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); - checkbox_p.label = formp->getIgnoreMessage(); - checkbox_p.label_text.text_color = LLColor4::black; - checkbox_p.commit_callback.function = boost::bind(&LLWindowShade::onClickIgnore, this, _1); - checkbox_p.initial_value = formp->getIgnored(); - - LLCheckBoxCtrl* check = LLUICtrlFactory::create(checkbox_p); - check->setRect(check->getBoundingRect()); - form_elements.addChild(check); - cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL; - } - - for (S32 i = 0; i < formp->getNumElements(); i++) - { - LLSD form_element = formp->getElement(i); - std::string type = form_element["type"].asString(); - if (type == "button") - { - LLButton::Params button_p; - button_p.name = form_element["name"]; - button_p.label = form_element["text"]; - button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); - button_p.click_callback.function = boost::bind(&LLWindowShade::onClickNotificationButton, this, form_element["name"].asString()); - button_p.auto_resize = true; - - LLButton* button = LLUICtrlFactory::create(button_p); - button->autoResize(); - form_elements.addChild(button); - - cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL; - } - else if (type == "text" || type == "password") - { - LLTextBox::Params label_p; - label_p.name = form_element["name"].asString() + "_label"; - label_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL); - label_p.initial_value = form_element["text"]; - label_p.text_color = LLColor4::black; - LLTextBox* textbox = LLUICtrlFactory::create(label_p); - textbox->reshapeToFitText(); - form_elements.addChild(textbox); - cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL; - - LLLineEditor::Params line_p; - line_p.name = form_element["name"]; - line_p.commit_callback.function = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString()); - line_p.commit_on_focus_lost = true; - line_p.is_password = type == "password"; - line_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL); - - LLLineEditor* line_editor = LLUICtrlFactory::create(line_p); - form_elements.addChild(line_editor); - cur_x = line_editor->getRect().mRight + FORM_PADDING_HORIZONTAL; - } - } - - form_elements.reshape(cur_x, form_elements.getRect().getHeight()); -} - -void LLWindowShade::show() -{ - LLLayoutPanel& panel = getChildRef("notification_area"); - panel.setVisible(true); -} - -void LLWindowShade::draw() -{ - LLView::draw(); - if (mNotification && !mNotification->isActive()) - { - hide(); - } -} - -void LLWindowShade::hide() -{ - LLLayoutPanel& panel = getChildRef("notification_area"); - panel.setVisible(false); -} - -void LLWindowShade::onCloseNotification() -{ - LLNotifications::instance().cancel(mNotification); -} - -void LLWindowShade::onClickIgnore(LLUICtrl* ctrl) -{ - bool check = ctrl->getValue().asBoolean(); - if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) - { - // question was "show again" so invert value to get "ignore" - check = !check; - } - mNotification->setIgnored(check); -} - -void LLWindowShade::onClickNotificationButton(const std::string& name) -{ - if (!mNotification) return; - - mNotificationResponse[name] = true; - - mNotification->respond(mNotificationResponse); -} - -void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name) -{ - mNotificationResponse[name] = ctrl->getValue().asString(); -} - - LLMediaCtrl::Params::Params() : start_url("start_url"), border_visible("border_visible", true), @@ -1305,7 +1053,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) LLNotification::Params auth_request_params; auth_request_params.name = "AuthRequest"; auth_request_params.payload = LLSD().with("media_id", mMediaTextureID); - auth_request_params.functor.function = boost::bind(&LLMediaCtrl::onAuthSubmit, this, _1, _2); + auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, mMediaSource->getMediaPlugin()); LLNotifications::instance().add(auth_request_params); }; break; @@ -1351,31 +1099,27 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response) } } -void LLMediaCtrl::onAuthSubmit(const LLSD& notification, const LLSD& response) -{ - if (response["ok"]) - { - mMediaSource->getMediaPlugin()->sendAuthResponse(true, response["username"], response["password"]); - } - else - { - mMediaSource->getMediaPlugin()->sendAuthResponse(false, "", ""); - } -} - - void LLMediaCtrl::showNotification(LLNotificationPtr notify) { delete mWindowShade; LLWindowShade::Params params; + params.name = "notification_shade"; params.rect = getLocalRect(); params.follows.flags = FOLLOWS_ALL; params.notification = notify; + params.modal = true; //HACK: don't hardcode this - if (notify->getName() == "PopupAttempt") + if (notify->getIcon() == "Popup_Caution") { params.bg_image.name = "Yellow_Gradient"; + params.text_color = LLColor4::black; + } + else + { + //HACK: make this a property of the notification itself, "cancellable" + params.can_close = false; + params.text_color.control = "LabelTextColor"; } mWindowShade = LLUICtrlFactory::create(params); diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 0c369840bf..48e4c48376 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -167,7 +167,6 @@ public: private: void onVisibilityChange ( const LLSD& new_visibility ); void onPopup(const LLSD& notification, const LLSD& response); - void onAuthSubmit(const LLSD& notification, const LLSD& response); const S32 mTextureDepthBytes; LLUUID mMediaTextureID; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index b04971f980..87465ad2be 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -59,6 +59,7 @@ #include "llvovolume.h" #include "llweb.h" #include "llwindow.h" +#include "llwindowshade.h" #include "llfloatertools.h" // to enable hide if build tools are up // Functions pulled from pipeline.cpp @@ -90,7 +91,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mTargetObjectNormal(LLVector3::zero), mZoomObjectID(LLUUID::null), mZoomObjectFace(0), - mVolumeSliderVisible(0) + mVolumeSliderVisible(0), + mWindowShade(NULL) { mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this)); mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this)); @@ -205,6 +207,9 @@ BOOL LLPanelPrimMediaControls::postBuild() mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this )); + LLWindowShade::Params window_shade_params; + window_shade_params.name = "window_shade"; + mCurrentZoom = ZOOM_NONE; // clicks on buttons do not remove keyboard focus from media setIsChrome(TRUE); @@ -698,6 +703,24 @@ void LLPanelPrimMediaControls::updateShape() /*virtual*/ void LLPanelPrimMediaControls::draw() { + LLViewerMediaImpl* impl = getTargetMediaImpl(); + if (impl) + { + LLNotificationPtr notification = impl->getCurrentNotification(); + if (notification != mActiveNotification) + { + mActiveNotification = notification; + if (notification) + { + showNotification(notification); + } + else + { + hideNotification(); + } + } + } + F32 alpha = getDrawContext().mAlpha; if(mFadeTimer.getStarted()) { @@ -1295,3 +1318,38 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible() { return mVolumeSliderVisible > 0; } + +void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify) +{ + delete mWindowShade; + LLWindowShade::Params params; + params.rect = mMediaRegion->getLocalRect(); + params.follows.flags = FOLLOWS_ALL; + params.notification = notify; + + //HACK: don't hardcode this + if (notify->getIcon() == "Popup_Caution") + { + params.bg_image.name = "Yellow_Gradient"; + params.text_color = LLColor4::black; + } + else + { + //HACK: make this a property of the notification itself, "cancellable" + params.can_close = false; + params.text_color.control = "LabelTextColor"; + } + + mWindowShade = LLUICtrlFactory::create(params); + + mMediaRegion->addChild(mWindowShade); + mWindowShade->show(); +} + +void LLPanelPrimMediaControls::hideNotification() +{ + if (mWindowShade) + { + mWindowShade->hide(); + } +} diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 3ec24f0e24..0b9664359c 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -29,6 +29,7 @@ #include "llpanel.h" #include "llviewermedia.h" +#include "llnotificationptr.h" class LLButton; class LLCoordWindow; @@ -37,6 +38,7 @@ class LLLayoutStack; class LLProgressBar; class LLSliderCtrl; class LLViewerMediaImpl; +class LLWindowShade; class LLPanelPrimMediaControls : public LLPanel { @@ -54,6 +56,9 @@ public: void updateShape(); bool isMouseOver(); + void showNotification(LLNotificationPtr notify); + void hideNotification(); + enum EZoomLevel { ZOOM_NONE = 0, @@ -162,6 +167,7 @@ private: LLUICtrl *mRightBookend; LLUIImage* mBackgroundImage; LLUIImage* mVolumeSliderBackgroundImage; + LLWindowShade* mWindowShade; F32 mSkipStep; S32 mMinWidth; S32 mMinHeight; @@ -204,6 +210,8 @@ private: S32 mZoomObjectFace; S32 mVolumeSliderVisible; + + LLNotificationPtr mActiveNotification; }; #endif // LL_PANELPRIMMEDIACONTROLS_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index be4e23728a..4a50b1717e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -52,6 +52,7 @@ #include "llviewerregion.h" #include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! #include "llfilepicker.h" +#include "llnotifications.h" #include "llevent.h" // LLSimpleListener #include "llnotificationsutil.h" @@ -1044,6 +1045,18 @@ bool LLViewerMedia::isParcelAudioPlaying() return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying()); } +void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media) +{ + if (response["ok"]) + { + media->sendAuthResponse(true, response["username"], response["password"]); + } + else + { + media->sendAuthResponse(false, "", ""); + } +} + ///////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerMedia::clearAllCookies() @@ -1912,6 +1925,18 @@ void LLViewerMediaImpl::setSize(int width, int height) } } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::showNotification(LLNotificationPtr notify) +{ + mNotification = notify; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::hideNotification() +{ + mNotification.reset(); +} + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::play() { @@ -2976,6 +3001,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL; + hideNotification(); if(getNavState() == MEDIANAVSTATE_SERVER_SENT) { @@ -3067,13 +3093,17 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla } break; + case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST: { - llinfos << "MEDIA_EVENT_AUTH_REQUEST, url " << plugin->getAuthURL() << ", realm " << plugin->getAuthRealm() << LL_ENDL; - //plugin->sendAuthResponse(false, "", ""); - } + LLNotification::Params auth_request_params; + auth_request_params.name = "AuthRequest"; + auth_request_params.payload = LLSD().with("media_id", mTextureId); + auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, plugin); + LLNotifications::instance().add(auth_request_params); + }; break; - + case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST: { std::string uuid = plugin->getClickUUID(); @@ -3591,6 +3621,11 @@ bool LLViewerMediaImpl::isInAgentParcel() const return result; } +LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const +{ + return mNotification; +} + ////////////////////////////////////////////////////////////////////////////////////////// // // static diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 6f8d12e676..83fe790839 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -37,6 +37,7 @@ #include "llpluginclassmedia.h" #include "v4color.h" +#include "llnotificationptr.h" #include "llurl.h" @@ -130,6 +131,8 @@ public: static bool isParcelMediaPlaying(); static bool isParcelAudioPlaying(); + static void onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media); + // Clear all cookies for all plugins static void clearAllCookies(); @@ -199,6 +202,9 @@ public: LLPluginClassMedia* getMediaPlugin() { return mMediaSource; } void setSize(int width, int height); + void showNotification(LLNotificationPtr notify); + void hideNotification(); + void play(); void stop(); void pause(); @@ -391,6 +397,9 @@ public: // Is this media in the agent's parcel? bool isInAgentParcel() const; + // get currently active notification associated with this media instance + LLNotificationPtr getCurrentNotification() const; + private: bool isAutoPlayable() const; bool shouldShowBasedOnClass() const; @@ -448,7 +457,8 @@ private: bool mNavigateSuspendedDeferred; bool mTrustedBrowser; std::string mTarget; - + LLNotificationPtr mNotification; + private: BOOL mIsUpdated ; std::list< LLVOVolume* > mObjectList ; diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index de52aa17d1..72a494201d 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -592,4 +592,4 @@ LLUUID LLViewerMediaFocus::getControlsMediaID() } return LLUUID::null; -} +} \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 271b688be5..0d4a095e14 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -189,7 +189,6 @@ function="Advanced.WebContentTest" parameter="http://www.google.com"/> - Date: Mon, 13 Dec 2010 13:17:48 +0200 Subject: STORM-229 FIXED Fixed long loading times and stalling of Viewer while loading big scripts or pasting a lot of text into script. The bug was fixed by Satomi Ahn. Here is the description of what causes the problem from her comment in ticket: "Disabling the loading of syntax keywords in LLScriptEdCore::postBuild() removes the freeze (and with it: syntax highlighting). So it obviously comes from the parsing of the text. I also noticed something else: by adding a llwarn in LLTextEditor::updateSegments(), I saw that this function was called a lot of times when loading a script, roughly once for each line in the script (naively I would have thought only necessary to update when finished... or to only update the new line). My llwarn was in the "if (mReflowIndex < S32_MAX && mKeywords.isLoaded())", which means that, at each call, the text is actually parsed for all keywords... so the parsing of the script becomes quadratic instead of linear!!!" - To fix this, Satomi added a flag depending on which parsing is disabled when it is not necessary. --- doc/contributions.txt | 1 + indra/llui/lltexteditor.cpp | 10 ++++++++-- indra/llui/lltexteditor.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/doc/contributions.txt b/doc/contributions.txt index 4c33834a46..67683204e2 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -607,6 +607,7 @@ Sammy Frederix VWR-6186 Satomi Ahn STORM-501 + STORM-229 Scrippy Scofield VWR-3748 Seg Baphomet diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 94bf716e7d..5a46c7c98e 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -277,6 +277,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mHPad += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; updateRects(); } + + mParseOnTheFly = TRUE; } void LLTextEditor::initFromParams( const LLTextEditor::Params& p) @@ -324,8 +326,10 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str, const LLStyle::Param blockUndo(); deselect(); - + + mParseOnTheFly = FALSE; LLTextBase::setText(utf8str, input_params); + mParseOnTheFly = TRUE; resetDirty(); } @@ -1367,6 +1371,7 @@ void LLTextEditor::pastePrimary() // paste from primary (itsprimary==true) or clipboard (itsprimary==false) void LLTextEditor::pasteHelper(bool is_primary) { + mParseOnTheFly = FALSE; bool can_paste_it; if (is_primary) { @@ -1450,6 +1455,7 @@ void LLTextEditor::pasteHelper(bool is_primary) deselect(); onKeyStroke(); + mParseOnTheFly = TRUE; } @@ -2385,7 +2391,7 @@ void LLTextEditor::loadKeywords(const std::string& filename, void LLTextEditor::updateSegments() { - if (mReflowIndex < S32_MAX && mKeywords.isLoaded()) + if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) { LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING); // HACK: No non-ascii keywords for now diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 58ecefdccb..9e4b95003b 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -315,6 +315,7 @@ private: BOOL mAllowEmbeddedItems; bool mShowContextMenu; + bool mParseOnTheFly; LLUUID mSourceID; -- cgit v1.3 From abda07fb77de69b294eafb65cb1cfb265855365f Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Thu, 16 Dec 2010 20:22:32 +0200 Subject: STORM-796 FIXED Implemented rendering /app/region/ SLapps into human-readable strings. Example: secondlife:///app/region/Ahern/10/20/30/ is displayed as "Ahern (10,20,30)". --- indra/llui/llurlentry.cpp | 63 +++++++++++++++ indra/llui/llurlentry.h | 12 +++ indra/llui/llurlregistry.cpp | 1 + indra/llui/tests/llurlentry_test.cpp | 149 +++++++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e51f28e2e9..4f7b4be526 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -805,6 +805,69 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const return ::getStringAfterToken(url, "://"); } +// +// LLUrlEntryRegion Describes secondlife:///app/region/REGION_NAME/X/Y/Z URLs, e.g. +// secondlife:///app/region/Ahern/128/128/0 +// +LLUrlEntryRegion::LLUrlEntryRegion() +{ + mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?", + boost::regex::perl|boost::regex::icase); + mMenuName = "menu_url_slurl.xml"; + mTooltip = LLTrans::getString("TooltipSLURL"); +} + +std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + // + // we handle SLURLs in the following formats: + // - secondlife:///app/region/Place/X/Y/Z + // - secondlife:///app/region/Place/X/Y + // - secondlife:///app/region/Place/X + // - secondlife:///app/region/Place + // + + LLSD path_array = LLURI(url).pathArray(); + S32 path_parts = path_array.size(); + + if (path_parts < 3) // no region name + { + llwarns << "Failed to parse url [" << url << "]" << llendl; + return url; + } + + std::string label = unescapeUrl(path_array[2]); // region name + + if (path_parts > 3) // secondlife:///app/region/Place/X + { + std::string x = path_array[3]; + label += " (" + x; + + if (path_parts > 4) // secondlife:///app/region/Place/X/Y + { + std::string y = path_array[4]; + label += "," + y; + + if (path_parts > 5) // secondlife:///app/region/Place/X/Y/Z + { + std::string z = path_array[5]; + label = label + "," + z; + } + } + + label += ")"; + } + + return label; +} + +std::string LLUrlEntryRegion::getLocation(const std::string &url) const +{ + LLSD path_array = LLURI(url).pathArray(); + std::string region_name = unescapeUrl(path_array[2]); + return region_name; +} + // // LLUrlEntryTeleport Describes a Second Life teleport Url, e.g., // secondlife:///app/teleport/Ahern/50/50/50/ diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 43a667c390..1791739061 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -301,6 +301,18 @@ public: /*virtual*/ std::string getLocation(const std::string &url) const; }; +/// +/// LLUrlEntryRegion Describes a Second Life location Url, e.g., +/// secondlife:///app/region/Ahern/128/128/0 +/// +class LLUrlEntryRegion : public LLUrlEntryBase +{ +public: + LLUrlEntryRegion(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getLocation(const std::string &url) const; +}; + /// /// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g., /// secondlife:///app/teleport/Ahern/50/50/50/ diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 478b412d5e..523ee5d78c 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -54,6 +54,7 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); + registerUrl(new LLUrlEntryRegion()); registerUrl(new LLUrlEntryWorldMap()); registerUrl(new LLUrlEntryObjectIM()); registerUrl(new LLUrlEntryPlace()); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 59c0826ad7..d0b2030d12 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -103,6 +103,45 @@ namespace tut ensure_equals(testname, url, expected); } + void dummyCallback(const std::string &url, const std::string &label, const std::string& icon) + { + } + + void testLabel(const std::string &testname, LLUrlEntryBase &entry, + const char *text, const std::string &expected) + { + boost::regex regex = entry.getPattern(); + std::string label = ""; + boost::cmatch result; + bool found = boost::regex_search(text, result, regex); + if (found) + { + S32 start = static_cast(result[0].first - text); + S32 end = static_cast(result[0].second - text); + std::string url = std::string(text+start, end-start); + label = entry.getLabel(url, dummyCallback); + } + ensure_equals(testname, label, expected); + } + + void testLocation(const std::string &testname, LLUrlEntryBase &entry, + const char *text, const std::string &expected) + { + boost::regex regex = entry.getPattern(); + std::string location = ""; + boost::cmatch result; + bool found = boost::regex_search(text, result, regex); + if (found) + { + S32 start = static_cast(result[0].first - text); + S32 end = static_cast(result[0].second - text); + std::string url = std::string(text+start, end-start); + location = entry.getLocation(url); + } + ensure_equals(testname, location, expected); + } + + template<> template<> void object::test<1>() { @@ -697,4 +736,114 @@ namespace tut "My Object", "My Object"); } + + template<> template<> + void object::test<13>() + { + // + // test LLUrlEntryRegion - secondlife:///app/region/ URLs + // + LLUrlEntryRegion url; + + // Regex tests. + testRegex("no valid region", url, + "secondlife:///app/region/", + ""); + + testRegex("invalid coords", url, + "secondlife:///app/region/Korea2/a/b/c", + "secondlife:///app/region/Korea2/"); // don't count invalid coords + + testRegex("Ahern (50,50,50) [1]", url, + "secondlife:///app/region/Ahern/50/50/50/", + "secondlife:///app/region/Ahern/50/50/50/"); + + testRegex("Ahern (50,50,50) [2]", url, + "XXX secondlife:///app/region/Ahern/50/50/50/ XXX", + "secondlife:///app/region/Ahern/50/50/50/"); + + testRegex("Ahern (50,50,50) [3]", url, + "XXX secondlife:///app/region/Ahern/50/50/50 XXX", + "secondlife:///app/region/Ahern/50/50/50"); + + testRegex("Ahern (50,50,50) multicase", url, + "XXX secondlife:///app/region/Ahern/50/50/50/ XXX", + "secondlife:///app/region/Ahern/50/50/50/"); + + testRegex("Ahern (50,50) [1]", url, + "XXX secondlife:///app/region/Ahern/50/50/ XXX", + "secondlife:///app/region/Ahern/50/50/"); + + testRegex("Ahern (50,50) [2]", url, + "XXX secondlife:///app/region/Ahern/50/50 XXX", + "secondlife:///app/region/Ahern/50/50"); + + // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat + testRegex("Region with brackets", url, + "XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX", + "secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30"); + + // DEV-35459: SLURLs and teleport Links not parsed properly + testRegex("Region with quote", url, + "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX", + "secondlife:///app/region/A%27ksha%20Oasis/41/166/701"); + + // Rendering tests. + testLabel("Render /app/region/Ahern/50/50/50/", url, + "secondlife:///app/region/Ahern/50/50/50/", + "Ahern (50,50,50)"); + + testLabel("Render /app/region/Ahern/50/50/50", url, + "secondlife:///app/region/Ahern/50/50/50", + "Ahern (50,50,50)"); + + testLabel("Render /app/region/Ahern/50/50/", url, + "secondlife:///app/region/Ahern/50/50/", + "Ahern (50,50)"); + + testLabel("Render /app/region/Ahern/50/50", url, + "secondlife:///app/region/Ahern/50/50", + "Ahern (50,50)"); + + testLabel("Render /app/region/Ahern/50/", url, + "secondlife:///app/region/Ahern/50/", + "Ahern (50)"); + + testLabel("Render /app/region/Ahern/50", url, + "secondlife:///app/region/Ahern/50", + "Ahern (50)"); + + testLabel("Render /app/region/Ahern/", url, + "secondlife:///app/region/Ahern/", + "Ahern"); + + testLabel("Render /app/region/Ahern/ within context", url, + "XXX secondlife:///app/region/Ahern/ XXX", + "Ahern"); + + testLabel("Render /app/region/Ahern", url, + "secondlife:///app/region/Ahern", + "Ahern"); + + testLabel("Render /app/region/Ahern within context", url, + "XXX secondlife:///app/region/Ahern XXX", + "Ahern"); + + testLabel("Render /app/region/Product%20Engine/", url, + "secondlife:///app/region/Product%20Engine/", + "Product Engine"); + + testLabel("Render /app/region/Product%20Engine", url, + "secondlife:///app/region/Product%20Engine", + "Product Engine"); + + // Location parsing texts. + testLocation("Location /app/region/Ahern/50/50/50/", url, + "secondlife:///app/region/Ahern/50/50/50/", + "Ahern"); + + testLocation("Location /app/region/Product%20Engine", url, + "secondlife:///app/region/Product%20Engine", + "Product Engine"); + } } -- cgit v1.3 From 3b97a200b80949398cc349cac9788f7c60c8dc63 Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Sat, 18 Dec 2010 18:35:32 +0200 Subject: STORM-796 ADDITIONAL_FIX Fixed Mac build. --- indra/llui/tests/llurlentry_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index d0b2030d12..8f0a48018f 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -119,7 +119,7 @@ namespace tut S32 start = static_cast(result[0].first - text); S32 end = static_cast(result[0].second - text); std::string url = std::string(text+start, end-start); - label = entry.getLabel(url, dummyCallback); + label = entry.getLabel(url, boost::bind(dummyCallback, _1, _2, _3)); } ensure_equals(testname, label, expected); } -- cgit v1.3 From 2b44c8919f7e0ed58c7ae1ee782d8ff419382c03 Mon Sep 17 00:00:00 2001 From: Andrew Productengine Date: Thu, 30 Dec 2010 20:18:00 +0200 Subject: STORM-823 FIXED Fixed Tab Key not working properly in floaters. Bug was caused by not fiding focus root in LLUICtrl::findRootMostFocusRoot() when tab was pressed in floaters. When it was not found, LLPanel::handleKeyHere() didn't move focus to the next control. Floaters had erroneous behaviour because of focus_root xml param: though value of focus root was set with setFocusRoot() in floater's constructor , later it was overwritten in LLFloater::initFloaterXML() with value from xml again. This problem was introduced in af49c237b0f9 - there focus root was moved to xml. - To fix the problem, setFocusRoot() call was added after initFromParams() in LLFloater::initFloaterXML() to set proper value of focus root after overwriting it from xml. The drawback of the fix is that focus_root param is ignored by floaters and its value is determined depending on chrome, as it did before but the only other way to fix this problem would be to set the param in xml manually for each existing floater, and do it for each new floater added to viewer. --- indra/llui/llfloater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 1265733bf5..d30697e178 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2910,7 +2910,9 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str params.from_xui = true; applyXUILayout(params, parent); initFromParams(params); - + // chrome floaters don't take focus at all + setFocusRoot(!getIsChrome()); + initFloater(params); LLMultiFloater* last_host = LLFloater::getFloaterHost(); -- cgit v1.3