From 47cbaeed23b121cfc61e291d1bfda40efc7668b4 Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Wed, 30 Jan 2013 14:07:59 -0500 Subject: [PATCH] XML-Driven floater feature (and documentation) Changes: Adds LLUICtrlFactory::getBuiltFloater() to return LLFloater* when a floater has been built. In llviewermenu.cpp's LLShowFloater::handleEvent(): Return early if the floater_name is empty, otherwise if no anticipated floater is found, build one, unless one of the same name is already built, then bring it to focus. Documentation: In order to add simple codeless floaters, a general understanding of our XMLs is necessary... A simple codeless floater can be a few things, perhaps not limited to: media browsers, settings controls, and holders for inventory_panels. So how do you make them conform to the codeless standard? For the purpose of these examples, my floater file will always be floater_name.xml Let's start with a shortened xml menu entry: Alright, that wasn't so hard, just remember the key in this is ShowFloater is the function and userdata is the filename. The next part is the actual floater, which isn't so different from making a complex floater.. There are two ways to do this, depending upon desired behavior: The first behavior is to have only one of the floater open at a time, the following short xml exemplifies this: Having a floater with this behavior will cause the menu entry to bring it into focus. The other behavior is to allow more than one of the floater open at a time: In this case, the menu entry will spawn a new version of the floater with every click, regardless of previous ones existing. Granted, these short 's probably aren't but examples and will not likely stand alone. --- indra/llui/lluictrlfactory.cpp | 14 ++++++++++++++ indra/llui/lluictrlfactory.h | 2 ++ indra/newview/llviewermenu.cpp | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index eb86f1e96..c1da6e8e5 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -293,6 +293,20 @@ void LLUICtrlFactory::buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &ro mBuiltFloaters[handle] = filename; } +//----------------------------------------------------------------------------- +// getBuiltFloater() +//----------------------------------------------------------------------------- +LLFloater* LLUICtrlFactory::getBuiltFloater(const std::string name) const +{ + for (built_floater_t::const_iterator i = mBuiltFloaters.begin(); i != mBuiltFloaters.end(); ++i) + { + LLFloater* floater = i->first.get(); + if (floater && floater->getName() == name) + return floater; + } + return NULL; +} + //----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 4dd0cdd73..345d25cad 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -61,6 +61,8 @@ public: BOOL buildPanelFromBuffer(LLPanel *panelp, const std::string &buffer, const LLCallbackMap::map_t* factory_map = NULL); + LLFloater* getBuiltFloater(const std::string name) const; + void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); } void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ac0ece092..32526bd1c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6517,6 +6517,7 @@ class LLShowFloater : public view_listener_t bool handleEvent(LLPointer event, const LLSD& userdata) { std::string floater_name = userdata.asString(); + if (floater_name.empty()) return false; if (floater_name == "gestures") { LLFloaterGesture::toggleVisibility(); @@ -6688,6 +6689,14 @@ class LLShowFloater : public view_listener_t { LLFloaterOutbox::toggleInstance(LLSD()); } + else // Simple codeless floater + { + LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name); + if (floater) + gFloaterView->bringToFront(floater); + else + LLUICtrlFactory::getInstance()->buildFloater(new LLFloater(), floater_name); + } return true; } };