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 +++++--------- 3 files changed, 15 insertions(+), 26 deletions(-) (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; -- cgit v1.2.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 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 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 -- cgit v1.2.3 From c4cfd1df44c1a6784f7780b03267203400804c48 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 28 Sep 2010 14:21:54 -0700 Subject: don't show empty context menus --- indra/llui/llmenugl.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index b1f4b362d5..87f01cf44f 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3803,6 +3803,11 @@ void LLContextMenu::setVisible(BOOL visible) // Takes cursor position in screen space? void LLContextMenu::show(S32 x, S32 y) { + if (getChildList()->empty()) + { + // nothing to show, so abort + return; + } // Save click point for detecting cursor moves before mouse-up. // Must be in local coords to compare with mouseUp events. // If the mouse doesn't move, the menu will stay open ala the Mac. -- cgit v1.2.3 From abc18951c6b639bcbacae2dd83a13ef8e02de85d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 28 Sep 2010 14:23:32 -0700 Subject: fix for crash when background image not specified for line editor --- indra/llui/lllineeditor.cpp | 2 ++ indra/llui/llui.cpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index a1fc977ce1..16e86a8eac 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1491,6 +1491,8 @@ void LLLineEditor::drawBackground() { image = mBgImage; } + + if (!image) return; F32 alpha = getDrawContext().mAlpha; // optionally draw programmatic border diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index ff9af21e54..1f86855a1e 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1596,23 +1596,25 @@ void LLUI::initClass(const settings_map_t& settings, sWindow = NULL; // set later in startup LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow"); + LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar(); + // Callbacks for associating controls with floater visibilty: - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2)); + reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2)); + reg.add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2)); + reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2)); + reg.add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2)); // Button initialization callback for toggle buttons - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); + reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); // Button initialization callback for toggle buttons on dockale floaters - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2)); + reg.add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2)); // Display the help topic for the current context - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); + reg.add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); // Currently unused, but kept for reference: - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2)); + reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2)); // Used by menus along with Floater.Toggle to display visibility as a checkmark LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::floaterInstanceVisible, _2)); -- cgit v1.2.3 From ff071bbdce6478f8cd666ecf75658ca6e24f1140 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Tue, 28 Sep 2010 16:49:22 -0700 Subject: Added a mechanism for preventing classes of notifications from being displayed, controlled by the notification_visibility.xml file in the viewer skin. Reviewed by Richard. --- indra/llui/CMakeLists.txt | 1 + indra/llui/llnotifications.cpp | 75 +++++++++++++++++++++++++++++- indra/llui/llnotifications.h | 17 ++++++- indra/llui/llnotificationvisibilityrule.h | 76 +++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 indra/llui/llnotificationvisibilityrule.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index e98201ea63..864f3f699e 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -159,6 +159,7 @@ set(llui_HEADER_FILES llnotificationslistener.h llnotificationsutil.h llnotificationtemplate.h + llnotificationvisibilityrule.h llpanel.h llprogressbar.h llradiogroup.h diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 9a3933093c..46af9323e1 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -28,6 +28,7 @@ #include "llnotifications.h" #include "llnotificationtemplate.h" +#include "llnotificationvisibilityrule.h" #include "llinstantmessage.h" #include "llxmlnode.h" @@ -414,6 +415,13 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form)); } +LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Params &p) +: mVisible(p.visible), + mType(p.type), + mTag(p.tag) +{ +} + LLNotification::LLNotification(const LLNotification::Params& p) : mTimestamp(p.time_stamp), mSubstitutions(p.substitutions), @@ -1188,6 +1196,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN void LLNotifications::initSingleton() { loadTemplates(); + loadVisibilityRules(); createDefaultChannels(); } @@ -1205,7 +1214,9 @@ void LLNotifications::createDefaultChannels() boost::bind(&LLNotifications::uniqueFilter, this, _1)); LLNotificationChannel::buildChannel("Ignore", "Unique", filterIgnoredNotifications); - LLNotificationChannel::buildChannel("Visible", "Ignore", + LLNotificationChannel::buildChannel("VisibilityRules", "Ignore", + boost::bind(&LLNotifications::isVisibleByRules, this, _1)); + LLNotificationChannel::buildChannel("Visible", "VisibilityRules", &LLNotificationFilters::includeEverything); // create special persistent notification channel @@ -1226,6 +1237,8 @@ void LLNotifications::createDefaultChannels() // connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); LLNotifications::instance().getChannel("Ignore")-> connectFailedFilter(&handleIgnoredNotification); + LLNotifications::instance().getChannel("VisibilityRules")-> + connectFailedFilter(&handleIgnoredNotification); } bool LLNotifications::addTemplate(const std::string &name, @@ -1404,6 +1417,36 @@ bool LLNotifications::loadTemplates() return true; } +bool LLNotifications::loadVisibilityRules() +{ + const std::string xml_filename = "notification_visibility.xml"; + std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); + + LLXMLNodePtr root; + BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + + if (!success || root.isNull() || !root->hasName( "notification_visibility" )) + { + llerrs << "Problem reading UI Notification Visibility Rules file: " << full_filename << llendl; + return false; + } + + LLNotificationVisibilityRule::Rules params; + LLXUIParser parser; + parser.readXUI(root, params, full_filename); + + mVisibilityRules.clear(); + + for(LLInitParam::ParamIterator::iterator it = params.rules.begin(), end_it = params.rules.end(); + it != end_it; + ++it) + { + mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it))); + } + + return true; +} + // Add a simple notification (from XUI) void LLNotifications::addFromCallback(const LLSD& name) { @@ -1553,6 +1596,36 @@ bool LLNotifications::getIgnoreAllNotifications() { return mIgnoreAllNotifications; } + +bool LLNotifications::isVisibleByRules(LLNotificationPtr n) +{ + VisibilityRuleList::iterator it; + + for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++) + { + // An empty type or tag string will match any notification, so only do the comparison when the string is non-empty in the rule. + + if(!(*it)->mType.empty()) + { + if((*it)->mType != n->getType()) + { + // Type doesn't match, so skip this rule. + continue; + } + } + + if(!(*it)->mTag.empty()) + { + // TODO: check this notification's tag(s) against it->mTag and continue if no match is found. + } + + // If we got here, the rule matches. Don't evaluate subsequent rules. + return (*it)->mVisible; + } + + // Default for cases with no rules or incomplete rules is to show all notifications. + return true; +} // --- // END OF LLNotifications implementation diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 4fe1687f0e..75c67151ca 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -268,6 +268,11 @@ struct LLNotificationTemplate; // with smart pointers typedef boost::shared_ptr LLNotificationTemplatePtr; + +struct LLNotificationVisibilityRule; + +typedef boost::shared_ptr LLNotificationVisibilityRulePtr; + /** * @class LLNotification * @brief The object that expresses the details of a notification @@ -856,6 +861,10 @@ public: // load notification descriptions from file; // OK to call more than once because it will reload bool loadTemplates(); + + // load visibility rules from file; + // OK to call more than once because it will reload + bool loadVisibilityRules(); // Add a simple notification (from XUI) void addFromCallback(const LLSD& name); @@ -902,6 +911,8 @@ public: // test for existence bool templateExists(const std::string& name); + typedef std::list VisibilityRuleList; + void forceResponse(const LLNotification::Params& params, S32 option); void createDefaultChannels(); @@ -916,7 +927,9 @@ public: void setIgnoreAllNotifications(bool ignore); bool getIgnoreAllNotifications(); - + + bool isVisibleByRules(LLNotificationPtr pNotification); + private: // we're a singleton, so we don't have a public constructor LLNotifications(); @@ -935,6 +948,8 @@ private: // put your template in bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate); TemplateMap mTemplates; + + VisibilityRuleList mVisibilityRules; std::string mFileName; diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h new file mode 100644 index 0000000000..a98591c9d6 --- /dev/null +++ b/indra/llui/llnotificationvisibilityrule.h @@ -0,0 +1,76 @@ +/** +* @file llnotificationvisibility.h +* @brief Rules for +* @author Monroe +* +* $LicenseInfo:firstyear=2010&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_LLNOTIFICATION_VISIBILITY_RULE_H +#define LL_LLNOTIFICATION_VISIBILITY_RULE_H + +#include "llinitparam.h" +//#include "llnotifications.h" + + + +// This is the class of object read from the XML file (notification_visibility.xml, +// from the appropriate local language directory). +struct LLNotificationVisibilityRule +{ + struct Params : public LLInitParam::Block + { + Mandatory visible; + Optional type; + Optional tag; + + Params() + : visible("visible"), + type("type"), + tag("tag") + {} + }; + + + struct Rules : public LLInitParam::Block + { + Multiple rules; + + Rules() + : rules("rule") + {} + }; + + LLNotificationVisibilityRule(const Params& p); + + // If true, this rule makes matching notifications visible. Otherwise, it makes them invisible. + bool mVisible; + + // String to match against the notification's "type". An empty string matches all notifications. + std::string mType; + + // String to match against the notification's tag(s). An empty string matches all notifications. + std::string mTag; +}; + +#endif //LL_LLNOTIFICATION_VISIBILITY_RULE_H + -- cgit v1.2.3 From b2ebf4c245fa4b5024c6c2bee46c426ad58cb14c Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Tue, 28 Sep 2010 17:10:40 -0700 Subject: Add XML validation in LLNotifications when loading notifications.xml and notification_visibility.xml. Reviewed by Richard. --- indra/llui/llnotifications.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 46af9323e1..6e1f574935 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1367,6 +1367,12 @@ bool LLNotifications::loadTemplates() LLNotificationTemplate::Notifications params; LLXUIParser parser; parser.readXUI(root, params, full_filename); + + if(!params.validateBlock()) + { + llerrs << "Problem reading UI Notifications file: " << full_filename << llendl; + return false; + } mTemplates.clear(); @@ -1435,6 +1441,12 @@ bool LLNotifications::loadVisibilityRules() LLXUIParser parser; parser.readXUI(root, params, full_filename); + if(!params.validateBlock()) + { + llerrs << "Problem reading UI Notification Visibility Rules file: " << full_filename << llendl; + return false; + } + mVisibilityRules.clear(); for(LLInitParam::ParamIterator::iterator it = params.rules.begin(), end_it = params.rules.end(); -- cgit v1.2.3 From ee50f389fd5d1b4cd07a33a3f769a0a88e45ed2b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 28 Sep 2010 17:11:27 -0700 Subject: made menus work with empty contents --- indra/llui/llmenugl.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 87f01cf44f..67993988fe 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2596,6 +2596,7 @@ LLMenuItemGL* LLMenuGL::getHighlightedItem() LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disabled) { + if (mItems.empty()) return NULL; // highlighting first item on a torn off menu is the // same as giving focus to it if (!cur_item && getTornOff()) @@ -2674,6 +2675,8 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disabled) { + if (mItems.empty()) return NULL; + // highlighting first item on a torn off menu is the // same as giving focus to it if (!cur_item && getTornOff()) @@ -2986,6 +2989,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size const S32 CURSOR_WIDTH = 12; + if(menu->getChildList()->empty()) + { + return; + } + // Save click point for detecting cursor moves before mouse-up. // Must be in local coords to compare with mouseUp events. // If the mouse doesn't move, the menu will stay open ala the Mac. -- cgit v1.2.3 From 67be46c78a28864360a0ca5ba66d6044a1b9b38d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 28 Sep 2010 17:12:50 -0700 Subject: made mIsFocusRoot a XUI param --- indra/llui/llpanel.cpp | 2 +- indra/llui/llview.cpp | 3 ++- indra/llui/llview.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index c8e56630f1..d0aba2733f 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -434,7 +434,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p) //and LLView::initFromParams will use them to set visible and enabled setVisible(p.visible); setEnabled(p.enabled); - + setFocusRoot(p.focus_root); setSoundFlags(p.sound_flags); // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 6ac009956d..267640a226 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -102,6 +102,7 @@ LLView::Params::Params() left_pad("left_pad"), left_delta("left_delta", S32_MAX), from_xui("from_xui", false), + focus_root("focus_root", false), needs_translate("translate"), xmlns("xmlns"), xmlns_xsi("xmlns:xsi"), @@ -117,7 +118,7 @@ LLView::LLView(const LLView::Params& p) mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), mFromXUI(p.from_xui), - mIsFocusRoot(FALSE), + mIsFocusRoot(p.focus_root), mLastVisible(FALSE), mNextInsertionOrdinal(0), mHoverCursor(getCursorFromString(p.hover_cursor)), diff --git a/indra/llui/llview.h b/indra/llui/llview.h index e6e0a41962..654e99563e 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -116,7 +116,8 @@ public: visible, mouse_opaque, use_bounding_rect, - from_xui; + from_xui, + focus_root; Optional tab_group, default_tab_group; -- cgit v1.2.3 From 3bab3fc66183f124d173b4ec192c03a9205788d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 Sep 2010 15:02:32 -0700 Subject: fix for crash on exit also made handle subtyping work --- indra/llui/llhandle.h | 2 +- indra/llui/lllineeditor.h | 2 +- indra/llui/llmenugl.cpp | 24 +++++++++++------------- indra/llui/llmenugl.h | 7 +++++-- 4 files changed, 18 insertions(+), 17 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index a43f095d67..a198a26c22 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -99,9 +99,9 @@ public: { return lhs.mTombStone > rhs.mTombStone; } -protected: protected: + template friend class LLHandle; LLPointer > mTombStone; private: diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 76d0187712..66fe8304e2 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -326,7 +326,7 @@ protected: std::vector mPreeditPositions; LLPreeditor::standouts_t mPreeditStandouts; - LLHandle mContextMenuHandle; + LLHandle mContextMenuHandle; private: // Instances that by default point to the statics but can be overidden in XML. diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 67993988fe..64f84bae7c 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3694,9 +3694,7 @@ public: LLContextMenuBranch(const Params&); virtual ~LLContextMenuBranch() - { - delete mBranch; - } + {} // called to rebuild the draw label virtual void buildDrawLabel( void ); @@ -3704,21 +3702,21 @@ public: // onCommit() - do the primary funcationality of the menu item. virtual void onCommit( void ); - LLContextMenu* getBranch() { return mBranch; } + LLContextMenu* getBranch() { return mBranch.get(); } void setHighlight( BOOL highlight ); protected: void showSubMenu(); - LLContextMenu* mBranch; + LLHandle mBranch; }; LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) : LLMenuItemGL(p), - mBranch( p.branch ) + mBranch( p.branch()->getHandle() ) { - mBranch->hide(); - mBranch->setParentMenuItem(this); + mBranch.get()->hide(); + mBranch.get()->setParentMenuItem(this); } // called to rebuild the draw label @@ -3727,12 +3725,12 @@ void LLContextMenuBranch::buildDrawLabel( void ) { // default enablement is this -- if any of the subitems are // enabled, this item is enabled. JC - U32 sub_count = mBranch->getItemCount(); + U32 sub_count = mBranch.get()->getItemCount(); U32 i; BOOL any_enabled = FALSE; for (i = 0; i < sub_count; i++) { - LLMenuItemGL* item = mBranch->getItem(i); + LLMenuItemGL* item = mBranch.get()->getItem(i); item->buildDrawLabel(); if (item->getEnabled() && !item->getDrawTextDisabled() ) { @@ -3754,13 +3752,13 @@ void LLContextMenuBranch::buildDrawLabel( void ) void LLContextMenuBranch::showSubMenu() { - LLMenuItemGL* menu_item = mBranch->getParentMenuItem(); + LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem(); if (menu_item != NULL && menu_item->getVisible()) { S32 center_x; S32 center_y; localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - mBranch->show(center_x, center_y); + mBranch.get()->show(center_x, center_y); } } @@ -3780,7 +3778,7 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) } else { - mBranch->hide(); + mBranch.get()->hide(); } } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 19b738312e..bb17bf4102 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -670,9 +670,12 @@ public: BOOL appendContextSubMenu(LLContextMenu *menu); + LLHandle getHandle() { mHandle.bind(this); return mHandle; } + protected: - BOOL mHoveredAnyItem; - LLMenuItemGL* mHoverItem; + BOOL mHoveredAnyItem; + LLMenuItemGL* mHoverItem; + LLRootHandle mHandle; }; -- cgit v1.2.3 From 68b4d9164ccf2b3bb643f153be4d3b2821c4d9d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 Sep 2010 15:50:12 -0700 Subject: removed unworkable subclassing support from LLHandle --- indra/llui/llhandle.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index a198a26c22..8c000eee48 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -61,13 +61,6 @@ public: return *this; } - template - LLHandle& operator =(const LLHandle& other) - { - mTombStone = other.mTombStone; - return *this; - } - bool isDead() const { return mTombStone->getTarget() == NULL; @@ -101,7 +94,6 @@ public: } protected: - template friend class LLHandle; LLPointer > mTombStone; private: -- cgit v1.2.3 From 27f6b2ea7d9339f9ecfd3f7bbbde356cfe007848 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Wed, 29 Sep 2010 16:51:21 -0700 Subject: Change non-visible notifications to return empty response instead of default. This is part of EXP-111. Reviewed by Richard. --- indra/llui/llnotifications.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 6e1f574935..98718e4de7 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -182,6 +182,20 @@ bool defaultResponse(const LLSD& payload) return false; } +bool emptyResponse(const LLSD& payload) +{ + if (payload["sigtype"].asString() == "add") + { + LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID()); + if (pNotif) + { + // supply empty response + pNotif->respond(pNotif->getResponseTemplate(LLNotification::WITHOUT_DEFAULT_BUTTON)); + } + } + return false; +} + namespace LLNotificationFilters { // a sample filter @@ -1238,7 +1252,7 @@ void LLNotifications::createDefaultChannels() LLNotifications::instance().getChannel("Ignore")-> connectFailedFilter(&handleIgnoredNotification); LLNotifications::instance().getChannel("VisibilityRules")-> - connectFailedFilter(&handleIgnoredNotification); + connectFailedFilter(&emptyResponse); } bool LLNotifications::addTemplate(const std::string &name, -- cgit v1.2.3 From cd2b9b45faa6dfd7a4c4e72fbe5395de8ad8f98d Mon Sep 17 00:00:00 2001 From: Monroe Williams Date: Thu, 30 Sep 2010 12:18:49 -0700 Subject: Cancel hidden notifications instead of using empty responses. This is more work on EXP-111. Reviewed by Richard. --- indra/llui/llnotifications.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 98718e4de7..dd56f03237 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -196,6 +196,17 @@ bool emptyResponse(const LLSD& payload) return false; } +bool cancelNotification(const LLSD& payload) +{ + if (payload["sigtype"].asString() == "add") + { + // cancel this notification + LLNotifications::instance().cancel(LLNotifications::instance().find(payload["id"].asUUID())); + } + return false; +} + + namespace LLNotificationFilters { // a sample filter @@ -1252,7 +1263,7 @@ void LLNotifications::createDefaultChannels() LLNotifications::instance().getChannel("Ignore")-> connectFailedFilter(&handleIgnoredNotification); LLNotifications::instance().getChannel("VisibilityRules")-> - connectFailedFilter(&emptyResponse); + connectFailedFilter(&cancelNotification); } bool LLNotifications::addTemplate(const std::string &name, -- cgit v1.2.3 From 2b6d3b851fc6210e7cf6272ac0bc9f8645ca5644 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 30 Sep 2010 14:48:36 -0700 Subject: Adding tags mechanism to notification visibility rules. Also started adding the tag 'fail' to entries in notifications.xml that are failures the user should always be told about. Reviewed by Richard. --- indra/llui/llnotifications.cpp | 34 +++++++++++++++++++++++++++++++++- indra/llui/llnotifications.h | 2 ++ indra/llui/llnotificationtemplate.h | 12 ++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index dd56f03237..289020fa3f 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -437,6 +437,14 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mUniqueContext.push_back(it->key); } + for(LLInitParam::ParamIterator::const_iterator it = p.tags.begin(), + end_it = p.tags.end(); + it != end_it; + ++it) + { + mTags.push_back(it->value); + } + mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form)); } @@ -716,6 +724,25 @@ bool LLNotification::hasUniquenessConstraints() const return (mTemplatep ? mTemplatep->mUnique : false); } +bool LLNotification::matchesTag(const std::string& tag) +{ + bool result = false; + + if(mTemplatep) + { + std::list::iterator it; + for(it = mTemplatep->mTags.begin(); it != mTemplatep->mTags.end(); it++) + { + if((*it) == tag) + { + result = true; + break; + } + } + } + + return result; +} void LLNotification::setIgnored(bool ignore) { @@ -1653,7 +1680,12 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n) if(!(*it)->mTag.empty()) { - // TODO: check this notification's tag(s) against it->mTag and continue if no match is found. + // check this notification's tag(s) against it->mTag and continue if no match is found. + if(!n->matchesTag((*it)->mTag)) + { + // This rule's non-empty tag didn't match one of the notification's tags. Skip this rule. + continue; + } } // If we got here, the rule matches. Don't evaluate subsequent rules. diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 75c67151ca..98ff035170 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -580,6 +580,8 @@ public: std::string summarize() const; bool hasUniquenessConstraints() const; + + bool matchesTag(const std::string& tag); virtual ~LLNotification() {} }; diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index 6bc0d2aaff..dfc2b10eb5 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -156,6 +156,15 @@ struct LLNotificationTemplate {} }; + struct Tag : public LLInitParam::Block + { + Mandatory value; + + Tag() + : value("value") + {} + }; + struct Params : public LLInitParam::Block { Mandatory name; @@ -173,6 +182,7 @@ struct LLNotificationTemplate Optional form_ref; Optional priority; + Multiple tags; Params() @@ -276,6 +286,8 @@ struct LLNotificationTemplate // this is loaded as a name, but looked up to get the UUID upon template load. // If null, it wasn't specified. LLUUID mSoundEffect; + // List of tags that rules can match against. + std::list mTags; }; #endif //LL_LLNOTIFICATION_TEMPLATE_H -- cgit v1.2.3 From a82a270b80a6bb9ed1a6bd1f70a42f4234197c36 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Fri, 1 Oct 2010 17:43:27 -0700 Subject: More precise control of notifications using notification_visibility.xml. Added a "name" property that lets a rule match a specific notification. Added a "response" property that lets a rule specify a response when it matches. Reviewed by Richard. --- indra/llui/llnotifications.cpp | 84 +++++++++++++++++++++---------- indra/llui/llnotificationvisibilityrule.h | 13 ++++- 2 files changed, 70 insertions(+), 27 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 289020fa3f..5b2e7590b1 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -182,28 +182,11 @@ bool defaultResponse(const LLSD& payload) return false; } -bool emptyResponse(const LLSD& payload) +bool visibilityRuleMached(const LLSD& payload) { - if (payload["sigtype"].asString() == "add") - { - LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID()); - if (pNotif) - { - // supply empty response - pNotif->respond(pNotif->getResponseTemplate(LLNotification::WITHOUT_DEFAULT_BUTTON)); - } - } - return false; -} - -bool cancelNotification(const LLSD& payload) -{ - if (payload["sigtype"].asString() == "add") - { - // cancel this notification - LLNotifications::instance().cancel(LLNotifications::instance().find(payload["id"].asUUID())); - } - return false; + // This is needed because LLNotifications::isVisibleByRules may have cancelled the notification. + // Returning true here makes LLNotificationChannelBase::updateItem do an early out, which prevents things from happening in the wrong order. + return true; } @@ -450,8 +433,10 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Params &p) : mVisible(p.visible), + mResponse(p.response), mType(p.type), - mTag(p.tag) + mTag(p.tag), + mName(p.name) { } @@ -1290,7 +1275,7 @@ void LLNotifications::createDefaultChannels() LLNotifications::instance().getChannel("Ignore")-> connectFailedFilter(&handleIgnoredNotification); LLNotifications::instance().getChannel("VisibilityRules")-> - connectFailedFilter(&cancelNotification); + connectFailedFilter(&visibilityRuleMached); } bool LLNotifications::addTemplate(const std::string &name, @@ -1663,6 +1648,12 @@ bool LLNotifications::getIgnoreAllNotifications() bool LLNotifications::isVisibleByRules(LLNotificationPtr n) { + if(n->isRespondedTo()) + { + // This avoids infinite recursion in the case where the filter calls respond() + return true; + } + VisibilityRuleList::iterator it; for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++) @@ -1687,15 +1678,56 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n) continue; } } + + if(!(*it)->mName.empty()) + { + lldebugs << "rule name = " << (*it)->mName << ", notification name = " << n->getName() << llendl; + + // check this notification's name against the notification's name and continue if no match is found. + if((*it)->mName != n->getName()) + { + // This rule's non-empty name didn't match the notification. Skip this rule. + continue; + } + } // If we got here, the rule matches. Don't evaluate subsequent rules. - return (*it)->mVisible; + if(!(*it)->mVisible) + { + // This notification is being hidden. + + if((*it)->mResponse.empty()) + { + // Response property is empty. Cancel this notification. + lldebugs << "cancelling notification " << n->getName() << llendl; + + n->cancel(); + } + else + { + // Response property is not empty. Return the specified response. + LLSD response = n->getResponseTemplate(LLNotification::WITHOUT_DEFAULT_BUTTON); + // TODO: verify that the response template has an item with the correct name + response[(*it)->mResponse] = true; + + lldebugs << "responding to notification " << n->getName() << " with response = " << response << llendl; + + n->respond(response); + } + + return false; + } + + // If we got here, exit the loop and return true. + break; } - // Default for cases with no rules or incomplete rules is to show all notifications. + lldebugs << "allowing notification " << n->getName() << llendl; + return true; } - + + // --- // END OF LLNotifications implementation // ========================================================= diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h index a98591c9d6..58a7eb6176 100644 --- a/indra/llui/llnotificationvisibilityrule.h +++ b/indra/llui/llnotificationvisibilityrule.h @@ -40,13 +40,17 @@ struct LLNotificationVisibilityRule struct Params : public LLInitParam::Block { Mandatory visible; + Optional response; Optional type; Optional tag; + Optional name; Params() : visible("visible"), + response("response"), type("type"), - tag("tag") + tag("tag"), + name("name") {} }; @@ -65,11 +69,18 @@ struct LLNotificationVisibilityRule // If true, this rule makes matching notifications visible. Otherwise, it makes them invisible. bool mVisible; + // Which response to give when making a notification invisible. An empty string means the notification should be cancelled instead of responded to. + std::string mResponse; + // String to match against the notification's "type". An empty string matches all notifications. std::string mType; // String to match against the notification's tag(s). An empty string matches all notifications. std::string mTag; + + // String to match against the notification's name. An empty string matches all notifications. + std::string mName; + }; #endif //LL_LLNOTIFICATION_VISIBILITY_RULE_H -- cgit v1.2.3 From 69215ae757452fd0f7cdc399e2104104bd06f8cf Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Mon, 4 Oct 2010 18:21:08 -0700 Subject: Fix for EXP-140 -- After logging into Skylight Viewer - User is required to click on Viewer window before using movement keys / flying In LLMenuHolderGL::handleKey(), in the highlightNextItem() case, don't return true if highlightNextItem() did nothing. Reviewed by Richard. --- indra/llui/llmenugl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 64f84bae7c..7db8b97180 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3460,8 +3460,10 @@ BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) else { //highlight first enabled one - pMenu->highlightNextItem(NULL); - handled = true; + if(pMenu->highlightNextItem(NULL)) + { + handled = true; + } } } } -- cgit v1.2.3 From ff81c6c529ce2c7216ee2cd5aa60b7a232792fec Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 5 Oct 2010 14:31:07 -0700 Subject: changed format of notification_visibility rules to be cleaner --- indra/llui/llnotifications.cpp | 45 ++++++++++++++++++------------- indra/llui/llnotificationvisibilityrule.h | 45 +++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 32 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 92fa6ada54..c41c19216c 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -431,13 +431,30 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form)); } -LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Params &p) -: mVisible(p.visible), - mResponse(p.response), - mType(p.type), - mTag(p.tag), - mName(p.name) +LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Rule &p) { + if (p.show.isChosen()) + { + mType = p.show.type; + mTag = p.show.tag; + mName = p.show.name; + mVisible = true; + } + else if (p.hide.isChosen()) + { + mType = p.hide.type; + mTag = p.hide.tag; + mName = p.hide.name; + mVisible = false; + } + else if (p.respond.isChosen()) + { + mType = p.respond.type; + mTag = p.respond.tag; + mName = p.respond.name; + mVisible = false; + mResponse = p.respond.response; + } } LLNotification::LLNotification(const LLNotification::Params& p) : @@ -1465,18 +1482,9 @@ bool LLNotifications::loadVisibilityRules() const std::string xml_filename = "notification_visibility.xml"; std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); - LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); - - if (!success || root.isNull() || !root->hasName( "notification_visibility" )) - { - llerrs << "Problem reading UI Notification Visibility Rules file: " << full_filename << llendl; - return false; - } - LLNotificationVisibilityRule::Rules params; - LLXUIParser parser; - parser.readXUI(root, params, full_filename); + LLSimpleXUIParser parser; + parser.readXUI(full_filename, params); if(!params.validateBlock()) { @@ -1486,7 +1494,8 @@ bool LLNotifications::loadVisibilityRules() mVisibilityRules.clear(); - for(LLInitParam::ParamIterator::iterator it = params.rules.begin(), end_it = params.rules.end(); + for(LLInitParam::ParamIterator::iterator it = params.rules.begin(), + end_it = params.rules.end(); it != end_it; ++it) { diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h index 58a7eb6176..78bdec2a8f 100644 --- a/indra/llui/llnotificationvisibilityrule.h +++ b/indra/llui/llnotificationvisibilityrule.h @@ -37,34 +37,51 @@ // from the appropriate local language directory). struct LLNotificationVisibilityRule { - struct Params : public LLInitParam::Block + struct Filter : public LLInitParam::Block { - Mandatory visible; - Optional response; - Optional type; - Optional tag; - Optional name; - - Params() - : visible("visible"), - response("response"), - type("type"), + Optional type, + tag, + name; + + Filter() + : type("type"), tag("tag"), name("name") {} }; + struct Respond : public LLInitParam::Block + { + Mandatory response; + + Respond() + : response("response") + {} + }; + + struct Rule : public LLInitParam::Choice + { + Alternative show; + Alternative hide; + Alternative respond; + + Rule() + : show("show"), + hide("hide"), + respond("respond") + {} + }; struct Rules : public LLInitParam::Block { - Multiple rules; + Multiple rules; Rules() - : rules("rule") + : rules("") {} }; - LLNotificationVisibilityRule(const Params& p); + LLNotificationVisibilityRule(const Rule& p); // If true, this rule makes matching notifications visible. Otherwise, it makes them invisible. bool mVisible; -- cgit v1.2.3 From f5b3fc596d029d3ac2f953ee94ea3ae131d00940 Mon Sep 17 00:00:00 2001 From: callum Date: Wed, 6 Oct 2010 15:34:32 -0700 Subject: Add support for debug setting to disable link highlight & follow in URLs that appear in XUI widgets --- indra/llui/llurlentry.cpp | 10 ++++++++++ indra/llui/llurlentry.h | 2 +- indra/llui/tests/llurlentry_test.cpp | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 5680ab8bd4..13c729ace9 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llurlentry.h" +#include "lluictrl.h" #include "lluri.h" #include "llurlmatch.h" #include "llurlregistry.h" @@ -146,6 +147,15 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab } } +/// is this a match for a URL that should not be hyperlinked? +bool LLUrlEntryBase::isLinkDisabled() const +{ + // this allows us to have a global setting to turn off text hyperlink highlighting/action + bool globally_disabled = LLUI::sSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions"); + + return mDisabledLink || globally_disabled; +} + static std::string getStringAfterToken(const std::string str, const std::string token) { size_t pos = str.find(token); diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index e25eaa7555..623856c320 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -86,7 +86,7 @@ public: virtual std::string getLocation(const std::string &url) const { return ""; } /// is this a match for a URL that should not be hyperlinked? - bool isLinkDisabled() const { return mDisabledLink; } + bool isLinkDisabled() const; /// Should this link text be underlined only when mouse is hovered over it? virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 95affe4460..4c2b3a8d59 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -27,12 +27,21 @@ #include "linden_common.h" #include "../llurlentry.h" +#include "../lluictrl.h" #include "llurlentry_stub.cpp" #include "lltut.h" #include "../lluicolortable.h" #include +typedef std::map settings_map_t; +settings_map_t LLUI::sSettingGroups; + +BOOL LLControlGroup::getBOOL(const std::string& name) +{ + return false; +} + LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const { return LLUIColor(); -- cgit v1.2.3 From 5647e745989d6c3e4387ec990a35c4308dd6b929 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Wed, 6 Oct 2010 16:56:38 -0700 Subject: added param block support for empty/undefined elements in XML/LLSD respectively. This way or LLSD["foo"]; both define a default constructed value for the parameter named foo, useful in the Multiple case --- indra/llui/llsdparam.cpp | 27 +++++++++++++++++++++++++++ indra/llui/llsdparam.h | 2 ++ 2 files changed, 29 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index f97f80ab6c..fae20a473e 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -45,6 +45,7 @@ LLParamSDParser::LLParamSDParser() if (sReadFuncs.empty()) { + registerParserFuncs(readNoValue, &LLParamSDParser::writeNoValue); registerParserFuncs(readS32, &LLParamSDParser::writeTypedValue); registerParserFuncs(readU32, &LLParamSDParser::writeU32Param); registerParserFuncs(readF32, &LLParamSDParser::writeTypedValue); @@ -71,6 +72,18 @@ bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const voi return true; } +bool LLParamSDParser::writeNoValue(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack) +{ + LLParamSDParser& sdparser = static_cast(parser); + if (!sdparser.mWriteRootSD) return false; + + LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); + if (!sd_to_write) return false; + + return true; +} + + void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent) { mCurReadSD = NULL; @@ -87,6 +100,8 @@ void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) block.serializeBlock(*this); } +const LLSD NO_VALUE_MARKER; + void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block) { if (sd.isMap()) @@ -110,6 +125,11 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block readSDValues(*it, block); } } + else if (sd.isUndefined()) + { + mCurReadSD = &NO_VALUE_MARKER; + block.submitValue(mNameStack, *this); + } else { mCurReadSD = &sd; @@ -206,6 +226,13 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack) return sd_to_write; } +bool LLParamSDParser::readNoValue(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast(parser); + return self.mCurReadSD == &NO_VALUE_MARKER; +} + + bool LLParamSDParser::readS32(Parser& parser, void* val_ptr) { LLParamSDParser& self = static_cast(parser); diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h index 97e8b58e49..69dab2b411 100644 --- a/indra/llui/llsdparam.h +++ b/indra/llui/llsdparam.h @@ -63,7 +63,9 @@ private: LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack); static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack); + static bool writeNoValue(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack); + static bool readNoValue(Parser& parser, void* val_ptr); static bool readS32(Parser& parser, void* val_ptr); static bool readU32(Parser& parser, void* val_ptr); static bool readF32(Parser& parser, void* val_ptr); -- cgit v1.2.3 From 1ae67f66d1d0203069cec62421d1d71d67a3334f Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 7 Oct 2010 15:44:35 -0700 Subject: Fixed a problem that prevented notification tags from being parsed. Added some lldebugs to the LLNotificationTemplate constructor and LLNotifications::isVisibleByRules() that may be useful in debugging notification issues in the future. --- indra/llui/llnotifications.cpp | 17 +++++++++++++---- indra/llui/llnotificationtemplate.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index c41c19216c..916ca24d13 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -419,12 +419,15 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par { mUniqueContext.push_back(it->key); } - + + lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl; + for(LLInitParam::ParamIterator::const_iterator it = p.tags.begin(), end_it = p.tags.end(); it != end_it; ++it) { + lldebugs << " tag \"" << std::string(it->value) << "\"" << llendl; mTags.push_back(it->value); } @@ -1667,7 +1670,15 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n) for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++) { - // An empty type or tag string will match any notification, so only do the comparison when the string is non-empty in the rule. + // An empty type/tag/name string will match any notification, so only do the comparison when the string is non-empty in the rule. + + lldebugs + << "notification \"" << n->getName() << "\" " + << "testing against " << ((*it)->mVisible?"show":"hide") << " rule, " + << "name = \"" << (*it)->mName << "\" " + << "tag = \"" << (*it)->mTag << "\" " + << "type = \"" << (*it)->mType << "\" " + << llendl; if(!(*it)->mType.empty()) { @@ -1690,8 +1701,6 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n) if(!(*it)->mName.empty()) { - lldebugs << "rule name = " << (*it)->mName << ", notification name = " << n->getName() << llendl; - // check this notification's name against the notification's name and continue if no match is found. if((*it)->mName != n->getName()) { diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index dfc2b10eb5..5a6ab40a2e 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -199,7 +199,8 @@ struct LLNotificationTemplate expire_option("expireOption", -1), url("url"), unique("unique"), - form_ref("") + form_ref(""), + tags("tag") {} }; -- cgit v1.2.3 From 6c0e9432d027dfb363baf4eaff79a835e3e75b37 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 8 Oct 2010 12:18:16 -0700 Subject: potential fix for linux build --- indra/llui/llsdparam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index fae20a473e..9ad13054cb 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -45,7 +45,7 @@ LLParamSDParser::LLParamSDParser() if (sReadFuncs.empty()) { - registerParserFuncs(readNoValue, &LLParamSDParser::writeNoValue); + registerParserFuncs(readNoValue, &LLParamSDParser::writeNoValue); registerParserFuncs(readS32, &LLParamSDParser::writeTypedValue); registerParserFuncs(readU32, &LLParamSDParser::writeU32Param); registerParserFuncs(readF32, &LLParamSDParser::writeTypedValue); -- cgit v1.2.3 From 688c2a73cdf982a4fe5ee0bfea0a52135fc461ef Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 8 Oct 2010 15:56:34 -0700 Subject: made progressbar derive from lluictrl and take percentage as llsd value --- indra/llui/llprogressbar.cpp | 6 +++--- indra/llui/llprogressbar.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index aaa328754d..ead22686bc 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -50,7 +50,7 @@ LLProgressBar::Params::Params() LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) -: LLView(p), +: LLUICtrl(p), mImageBar(p.image_bar), mImageFill(p.image_fill), mColorBackground(p.color_bg()), @@ -80,7 +80,7 @@ void LLProgressBar::draw() mImageFill->draw(progress_rect, bar_color); } -void LLProgressBar::setPercent(const F32 percent) +void LLProgressBar::setValue(const LLSD& value) { - mPercentDone = llclamp(percent, 0.f, 100.f); + mPercentDone = llclamp((F32)value.asReal(), 0.f, 100.f); } diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 13297f7493..3f308e7496 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -27,14 +27,14 @@ #ifndef LL_LLPROGRESSBAR_H #define LL_LLPROGRESSBAR_H -#include "llview.h" +#include "lluictrl.h" #include "llframetimer.h" class LLProgressBar - : public LLView + : public LLUICtrl { public: - struct Params : public LLInitParam::Block + struct Params : public LLInitParam::Block { Optional image_bar, image_fill; @@ -47,7 +47,7 @@ public: LLProgressBar(const Params&); virtual ~LLProgressBar(); - void setPercent(const F32 percent); + void setValue(const LLSD& value); /*virtual*/ void draw(); -- cgit v1.2.3 From b10744dbee7ffa64180f5558cac874e126045fc8 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 11 Oct 2010 16:33:23 -0700 Subject: fix for default notification form valus not appearing --- indra/llui/llnotifications.cpp | 3 ++- indra/llui/llnotifications.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 916ca24d13..133d12ff22 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -80,7 +80,8 @@ LLNotificationForm::FormButton::FormButton() LLNotificationForm::FormInput::FormInput() : type("type"), - width("width", 0) + width("width", 0), + value("value") {} LLNotificationForm::FormElement::FormElement() diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 5298549b58..3b50d0b2b6 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -194,6 +194,7 @@ public: { Mandatory type; Optional width; + Optional value; FormInput(); }; -- cgit v1.2.3 From 98563df257729ce36dff363134136f0b549f8313 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 15 Oct 2010 14:11:24 -0700 Subject: switch ui string args to auto_ptr to do automatic cleanup --- indra/llui/lluistring.cpp | 4 ++-- indra/llui/lluistring.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index ac69d3bf85..d805e37c09 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -129,7 +129,7 @@ void LLUIString::updateResult() const mResult = mOrig; // get the defailt args + local args - if (!mArgs || mArgs->empty()) + if (!mArgs.get() || mArgs->empty()) { LLStringUtil::format(mResult, LLTrans::getDefaultArgs()); } @@ -150,7 +150,7 @@ void LLUIString::updateWResult() const LLStringUtil::format_map_t& LLUIString::getArgs() { - if (!mArgs) + if (!mArgs.get()) { mArgs = new LLStringUtil::format_map_t; } diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index eff2467bf0..d7be3b1800 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -80,7 +80,7 @@ public: S32 length() const { return getUpdatedWResult().size(); } void clear(); - void clearArgs() { if (mArgs) mArgs->clear(); } + void clearArgs() { if (mArgs.get()) mArgs->clear(); } // These utility functions are included for text editing. // They do not affect mOrig and do not perform argument substitution @@ -104,7 +104,7 @@ private: std::string mOrig; mutable std::string mResult; mutable LLWString mWResult; // for displaying - LLStringUtil::format_map_t* mArgs; + std::auto_ptr mArgs; // controls lazy evaluation mutable bool mNeedsResult; -- cgit v1.2.3 From c4ec141cc0e2de055d6eff10727fd33ae6767d98 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 15 Oct 2010 14:33:10 -0700 Subject: fixed build --- indra/llui/llscrolllistctrl.cpp | 42 +++++++++++++++++++++-------------------- indra/llui/llscrolllistctrl.h | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 7df7c13dc0..40e66b7add 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -322,6 +322,7 @@ LLScrollListCtrl::~LLScrollListCtrl() delete mSortCallback; std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); } @@ -2370,10 +2371,10 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar ) void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) { - std::map::iterator itor = mColumns.find(name); + column_map_t::iterator itor = mColumns.find(name); if (itor != mColumns.end()) { - sortByColumnIndex((*itor).second.mIndex, ascending); + sortByColumnIndex((*itor).second->mIndex, ascending); } } @@ -2419,11 +2420,11 @@ void LLScrollListCtrl::dirtyColumns() // just in case someone indexes into it immediately mColumnsIndexed.resize(mColumns.size()); - std::map::iterator column_itor; + column_map_t::iterator column_itor; for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) { - LLScrollListColumn *column = &column_itor->second; - mColumnsIndexed[column_itor->second.mIndex] = column; + LLScrollListColumn *column = column_itor->second; + mColumnsIndexed[column_itor->second->mIndex] = column; } } @@ -2581,8 +2582,8 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params if (mColumns.find(name) == mColumns.end()) { // Add column - mColumns[name] = LLScrollListColumn(column_params, this); - LLScrollListColumn* new_column = &mColumns[name]; + mColumns[name] = new LLScrollListColumn(column_params, this); + LLScrollListColumn* new_column = mColumns[name]; new_column->mIndex = mColumns.size()-1; // Add button @@ -2604,14 +2605,14 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params S32 top = mItemListRect.mTop; S32 left = mItemListRect.mLeft; - for (std::map::iterator itor = mColumns.begin(); + for (column_map_t::iterator itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - if (itor->second.mIndex < new_column->mIndex && - itor->second.getWidth() > 0) + if (itor->second->mIndex < new_column->mIndex && + itor->second->getWidth() > 0) { - left += itor->second.getWidth() + mColumnPadding; + left += itor->second->getWidth() + mColumnPadding; } } @@ -2667,8 +2668,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata) if (column->mSortingColumn != column->mName && parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) { - LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn]; - column_index = info_redir.mIndex; + LLScrollListColumn* info_redir = parent->mColumns[column->mSortingColumn]; + column_index = info_redir->mIndex; } // if this column is the primary sort key, reverse the direction @@ -2701,16 +2702,17 @@ BOOL LLScrollListCtrl::hasSortOrder() const void LLScrollListCtrl::clearColumns() { - std::map::iterator itor; + column_map_t::iterator itor; for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - LLScrollColumnHeader *header = itor->second.mHeader; + LLScrollColumnHeader *header = itor->second->mHeader; if (header) { removeChild(header); delete header; } } + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); mColumns.clear(); mSortColumns.clear(); mTotalStaticColumnWidth = 0; @@ -2744,7 +2746,7 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name) column_map_t::iterator column_itor = mColumns.find(name); if (column_itor != mColumns.end()) { - return &column_itor->second; + return column_itor->second; } return NULL; } @@ -2805,7 +2807,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS new_column.width.pixel_width = cell_p.width; } addColumn(new_column); - columnp = &mColumns[column]; + columnp = mColumns[column]; new_item->setNumColumns(mColumns.size()); } @@ -2842,7 +2844,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS LLScrollListCell* cell = LLScrollListCell::create(LLScrollListCell::Params().value(item_p.value)); if (cell) { - LLScrollListColumn* columnp = &(mColumns.begin()->second); + LLScrollListColumn* columnp = mColumns.begin()->second; new_item->setColumn(0, cell); if (columnp->mHeader @@ -2857,10 +2859,10 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS // add dummy cells for missing columns for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) { - S32 column_idx = column_it->second.mIndex; + S32 column_idx = column_it->second->mIndex; if (new_item->getColumn(column_idx) == NULL) { - LLScrollListColumn* column_ptr = &column_it->second; + LLScrollListColumn* column_ptr = column_it->second; LLScrollListCell::Params cell_p; cell_p.width = column_ptr->getWidth(); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8a2f893ba2..09ab89960d 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -491,7 +491,7 @@ private: mutable bool mSorted; - typedef std::map column_map_t; + typedef std::map column_map_t; column_map_t mColumns; BOOL mDirty; -- cgit v1.2.3 From 6357806dd0d4f70822ba6aa453efbe3a54dc32af Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 15 Oct 2010 14:37:00 -0700 Subject: another attempt at lluistring cleanup --- indra/llui/lluistring.cpp | 4 ++-- indra/llui/lluistring.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index d805e37c09..ac69d3bf85 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -129,7 +129,7 @@ void LLUIString::updateResult() const mResult = mOrig; // get the defailt args + local args - if (!mArgs.get() || mArgs->empty()) + if (!mArgs || mArgs->empty()) { LLStringUtil::format(mResult, LLTrans::getDefaultArgs()); } @@ -150,7 +150,7 @@ void LLUIString::updateWResult() const LLStringUtil::format_map_t& LLUIString::getArgs() { - if (!mArgs.get()) + if (!mArgs) { mArgs = new LLStringUtil::format_map_t; } diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index d7be3b1800..86457a8b25 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -61,6 +61,7 @@ public: LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {} LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args); LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); } + ~LLUIString() { delete mArgs; } void assign(const std::string& instring); LLUIString& operator=(const std::string& s) { assign(s); return *this; } @@ -80,7 +81,7 @@ public: S32 length() const { return getUpdatedWResult().size(); } void clear(); - void clearArgs() { if (mArgs.get()) mArgs->clear(); } + void clearArgs() { if (mArgs) mArgs->clear(); } // These utility functions are included for text editing. // They do not affect mOrig and do not perform argument substitution @@ -104,7 +105,7 @@ private: std::string mOrig; mutable std::string mResult; mutable LLWString mWResult; // for displaying - std::auto_ptr mArgs; + LLStringUtil::format_map_t* mArgs; // controls lazy evaluation mutable bool mNeedsResult; -- cgit v1.2.3 From 5080a19afae4cc04196c643f755f35431d37e3a0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 18 Oct 2010 16:55:20 -0700 Subject: EXP-230 FIX "elp" text flashes on and off in upper left corner of skylight viewe --- indra/llui/llmenugl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 7db8b97180..8e142aed41 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1462,7 +1462,7 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) { BOOL branch_visible = getBranch()->getVisible(); BOOL handled = getBranch()->handleAcceleratorKey(key, mask); - if (handled && !branch_visible && getVisible()) + if (handled && !branch_visible && isInVisibleChain()) { // flash this menu entry because we triggered an invisible menu item LLMenuHolderGL::setActivatedItem(this); -- cgit v1.2.3 From f241e2327c3e28ed0692ec4f3a1a11ebf563b8bf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 21 Oct 2010 17:13:09 -0700 Subject: made layout stack open/close time configurable --- indra/llui/lllayoutstack.cpp | 17 +++++++++-------- indra/llui/lllayoutstack.h | 4 ++++ 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 940c7e7e18..ac30fce392 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -97,6 +97,8 @@ LLLayoutStack::Params::Params() : orientation("orientation"), animate("animate", true), clip("clip", true), + open_time_constant("open_time_constant", 0.02f), + close_time_constant("close_time_constant", 0.03f), border_size("border_size", LLCachedControl(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) { name="stack"; @@ -110,7 +112,9 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL), mAnimate(p.animate), mAnimatedThisFrame(false), - mClip(p.clip) + mClip(p.clip), + mOpenTimeConstant(p.open_time_constant), + mCloseTimeConstant(p.close_time_constant) {} LLLayoutStack::~LLLayoutStack() @@ -303,9 +307,6 @@ void LLLayoutStack::updateLayout(BOOL force_resize) S32 total_width = 0; S32 total_height = 0; - const F32 ANIM_OPEN_TIME = 0.02f; - const F32 ANIM_CLOSE_TIME = 0.03f; - e_panel_list_t::iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { @@ -316,7 +317,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { if (!mAnimatedThisFrame) { - (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME)); + (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant)); if ((*panel_it)->mVisibleAmt > 0.99f) { (*panel_it)->mVisibleAmt = 1.f; @@ -334,7 +335,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { if (!mAnimatedThisFrame) { - (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME)); + (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); if ((*panel_it)->mVisibleAmt < 0.001f) { (*panel_it)->mVisibleAmt = 0.f; @@ -349,11 +350,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if ((*panel_it)->mCollapsed) { - (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME)); + (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } else { - (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME)); + (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } if (mOrientation == HORIZONTAL) diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index e19ef403ef..2fc6164d7a 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -46,6 +46,8 @@ public: Optional border_size; Optional animate, clip; + Optional open_time_constant, + close_time_constant; Params(); }; @@ -137,6 +139,8 @@ private: bool mAnimatedThisFrame; bool mAnimate; bool mClip; + F32 mOpenTimeConstant; + F32 mCloseTimeConstant; }; // end class LLLayoutStack class LLLayoutPanel : public LLPanel -- cgit v1.2.3 From 20e9dbf40b0c3e4ef9674adbaca255723a412959 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 22 Oct 2010 18:37:40 -0700 Subject: EXP-273 FIXED Add button/tray for avatar picker made "toggleable" radio group --- indra/llui/llcheckboxctrl.cpp | 57 +++++++++++++++---------------------------- indra/llui/llradiogroup.cpp | 44 ++++++++++++++++----------------- indra/llui/llradiogroup.h | 12 ++++----- 3 files changed, 47 insertions(+), 66 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index bbd8db2645..58ace3c548 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -88,27 +88,19 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) tbparams.font(p.font); } mLabel = LLUICtrlFactory::create (tbparams); + mLabel->reshapeToFitText(); addChild(mLabel); - S32 text_width = mLabel->getTextBoundingRect().getWidth(); - S32 text_height = llround(mFont->getLineHeight()); - LLRect label_rect; - label_rect.setOriginAndSize( - llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, - llcheckboxctrl_vpad + 1, // padding to get better alignment - text_width + llcheckboxctrl_hpad, - text_height ); - mLabel->setShape(label_rect); - + LLRect label_rect = mLabel->getRect(); // Button // Note: button cover the label by extending all the way to the right. - LLRect btn_rect; + LLRect btn_rect = p.check_button.rect(); btn_rect.setOriginAndSize( - llcheckboxctrl_hpad, - llcheckboxctrl_vpad, - llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width + llcheckboxctrl_hpad, - llmax( text_height, llcheckboxctrl_btn_size() ) + llcheckboxctrl_vpad); + btn_rect.mLeft, + btn_rect.mBottom, + llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft), + llmax( label_rect.getHeight(), btn_rect.mTop)); std::string active_true_id, active_false_id; std::string inactive_true_id, inactive_false_id; @@ -174,31 +166,20 @@ void LLCheckBoxCtrl::clear() void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) { - //stretch or shrink bounding rectangle of label when rebuilding UI at new scale - static LLUICachedControl llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0); - static LLUICachedControl llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0); - static LLUICachedControl llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0); - static LLUICachedControl llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); - S32 text_width = mLabel->getTextBoundingRect().getWidth(); - S32 text_height = llround(mFont->getLineHeight()); - LLRect label_rect; - label_rect.setOriginAndSize( - llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, - llcheckboxctrl_vpad, - text_width, - text_height ); - mLabel->setShape(label_rect); - - LLRect btn_rect; + mLabel->reshapeToFitText(); + + LLRect label_rect = mLabel->getRect(); + + // Button + // Note: button cover the label by extending all the way to the right. + LLRect btn_rect = mButton->getRect(); btn_rect.setOriginAndSize( - llcheckboxctrl_hpad, - llcheckboxctrl_vpad, - llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width, - llmax( text_height, llcheckboxctrl_btn_size() ) ); - mButton->setShape( btn_rect ); - - LLUICtrl::reshape(width, height, called_from_parent); + btn_rect.mLeft, + btn_rect.mBottom, + llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft), + llmax( label_rect.getHeight(), btn_rect.mTop)); + mButton->setShape(btn_rect); } //virtual diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index cc348fdc63..6e9586369f 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -69,7 +69,7 @@ protected: static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); LLRadioGroup::Params::Params() -: has_border("draw_border"), +: allow_deselect("allow_deselect"), items("item") { addSynonym(items, "radio_item"); @@ -85,18 +85,8 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p) : LLUICtrl(p), mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()), mSelectedIndex(-1), - mHasBorder(p.has_border) -{ - if (mHasBorder) - { - LLViewBorder::Params params; - params.name("radio group border"); - params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0)); - params.bevel_style(LLViewBorder::BEVEL_NONE); - LLViewBorder * vb = LLUICtrlFactory::create (params); - addChild (vb); - } -} + mAllowDeselect(p.allow_deselect) +{} void LLRadioGroup::initFromParams(const Params& p) { @@ -184,7 +174,7 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) { - if (index < 0 || (S32)mRadioButtons.size() <= index ) + if ((S32)mRadioButtons.size() <= index ) { return FALSE; } @@ -202,13 +192,16 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) mSelectedIndex = index; - LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex]; - radio_item->setTabStop(true); - radio_item->setValue( TRUE ); - - if (hasFocus()) + if (mSelectedIndex >= 0) { - mRadioButtons[mSelectedIndex]->focusFirstItem(FALSE, FALSE); + LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex]; + radio_item->setTabStop(true); + radio_item->setValue( TRUE ); + + if (hasFocus()) + { + radio_item->focusFirstItem(FALSE, FALSE); + } } if (!from_event) @@ -307,8 +300,15 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl) LLRadioCtrl* radio = *iter; if (radio == clicked_radio) { - // llinfos << "clicked button " << index << llendl; - setSelectedIndex(index); + if (index == mSelectedIndex && mAllowDeselect) + { + // don't select anything + setSelectedIndex(-1); + } + else + { + setSelectedIndex(index); + } // BUG: Calls click callback even if button didn't actually change onCommit(); diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 0588900600..8bd5698538 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -49,7 +49,7 @@ public: struct Params : public LLInitParam::Block { - Optional has_border; + Optional allow_deselect; Multiple > items; Params(); }; @@ -73,7 +73,6 @@ public: void setIndexEnabled(S32 index, BOOL enabled); // return the index value of the selected item S32 getSelectedIndex() const { return mSelectedIndex; } - // set the index value programatically BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); @@ -103,12 +102,13 @@ public: /*virtual*/ BOOL operateOnAll(EOperation op); private: - const LLFontGL* mFont; - S32 mSelectedIndex; + const LLFontGL* mFont; + S32 mSelectedIndex; + typedef std::vector button_list_t; - button_list_t mRadioButtons; + button_list_t mRadioButtons; - BOOL mHasBorder; + bool mAllowDeselect; // user can click on an already selected option to deselect it }; #endif -- cgit v1.2.3 From 7a975354a28fa700486759cea3fd5a9445ac46b7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 25 Oct 2010 12:35:40 -0700 Subject: EXP-297 FIX Gray Bar shown on top of Skylight Viewer login screen during login on Gaikai --- indra/llui/lluicolortable.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 0641f6d175..9455d09cc0 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -215,6 +215,12 @@ bool LLUIColorTable::loadFromSettings() result |= loadFromFilename(current_filename, mLoadedColors); } + current_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + if(current_filename != default_filename) + { + result |= loadFromFilename(current_filename, mLoadedColors); + } + std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml"); loadFromFilename(user_filename, mUserSetColors); -- cgit v1.2.3 From ff6147d6bdb3559e4dd36ccc0961ea4c46f6cd76 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 26 Oct 2010 10:23:20 -0700 Subject: fixed checkboxes growing larger over time --- indra/llui/llcheckboxctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 58ace3c548..4fe444c1a4 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -177,8 +177,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) btn_rect.setOriginAndSize( btn_rect.mLeft, btn_rect.mBottom, - llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft), - llmax( label_rect.getHeight(), btn_rect.mTop)); + llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft), + llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight())); mButton->setShape(btn_rect); } -- cgit v1.2.3