summaryrefslogtreecommitdiff
path: root/indra/llui/llfloaterreg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llfloaterreg.cpp')
-rw-r--r--indra/llui/llfloaterreg.cpp730
1 files changed, 365 insertions, 365 deletions
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index f888d7ff68..989ce12d09 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfloaterreg.cpp
* @brief LLFloaterReg Floater Registration Class
*
* $LicenseInfo:firstyear=2002&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$
*/
@@ -28,7 +28,7 @@
#include "llfloaterreg.h"
-//#include "llagent.h"
+//#include "llagent.h"
#include "llfloater.h"
#include "llmultifloater.h"
#include "llfloaterreglistener.h"
@@ -51,10 +51,10 @@ static LLFloaterRegListener sFloaterRegListener;
//static
void LLFloaterReg::add(const std::string& name, const std::string& filename, const LLFloaterBuildFunc& func, const std::string& groupname)
{
- sBuildMap[name].mFunc = func;
- sBuildMap[name].mFile = filename;
- sGroupMap[name] = groupname.empty() ? name : groupname;
- sGroupMap[groupname] = groupname; // for referencing directly by group name
+ sBuildMap[name].mFunc = func;
+ sBuildMap[name].mFile = filename;
+ sGroupMap[name] = groupname.empty() ? name : groupname;
+ sGroupMap[groupname] = groupname; // for referencing directly by group name
}
//static
@@ -66,468 +66,468 @@ bool LLFloaterReg::isRegistered(const std::string& name)
//static
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
{
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
- {
- instance_list_t& list = sInstanceMap[groupname];
- if (!list.empty())
- {
- for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
- {
- LLFloater* inst = *iter;
-
- if (inst->getVisible() && !inst->isMinimized())
- {
- return inst;
- }
- }
- }
- }
- return NULL;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ if (!list.empty())
+ {
+ for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
+ {
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible() && !inst->isMinimized())
+ {
+ return inst;
+ }
+ }
+ }
+ }
+ return NULL;
}
LLFloater* LLFloaterReg::getLastFloaterCascading()
{
- LLRect candidate_rect;
- candidate_rect.mTop = 100000;
- LLFloater* candidate_floater = NULL;
-
- std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
- for( ; it != it_end; ++it)
- {
- const std::string& group_name = it->second;
-
- instance_list_t& instances = sInstanceMap[group_name];
-
- for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
- {
- LLFloater* inst = *iter;
-
- if (inst->getVisible()
- && (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING)
- || inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))
- {
- if (candidate_rect.mTop > inst->getRect().mTop)
- {
- candidate_floater = inst;
- candidate_rect = inst->getRect();
- }
- }
- }
- }
-
- return candidate_floater;
+ LLRect candidate_rect;
+ candidate_rect.mTop = 100000;
+ LLFloater* candidate_floater = NULL;
+
+ std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
+ for( ; it != it_end; ++it)
+ {
+ const std::string& group_name = it->second;
+
+ instance_list_t& instances = sInstanceMap[group_name];
+
+ for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible()
+ && (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING)
+ || inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))
+ {
+ if (candidate_rect.mTop > inst->getRect().mTop)
+ {
+ candidate_floater = inst;
+ candidate_rect = inst->getRect();
+ }
+ }
+ }
+ }
+
+ return candidate_floater;
}
//static
LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
{
- LLFloater* res = NULL;
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
- {
- instance_list_t& list = sInstanceMap[groupname];
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- LLFloater* inst = *iter;
- if (inst->matchesKey(key))
- {
- res = inst;
- break;
- }
- }
- }
- return res;
+ LLFloater* res = NULL;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ break;
+ }
+ }
+ }
+ return res;
}
//static
-LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
+LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
{
- LLFloater* res = findInstance(name, key);
- if (!res)
- {
- const LLFloaterBuildFunc& build_func = sBuildMap[name].mFunc;
- const std::string& xui_file = sBuildMap[name].mFile;
- if (build_func)
- {
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
- {
- instance_list_t& list = sInstanceMap[groupname];
-
- res = build_func(key);
- if (!res)
- {
- LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
- return NULL;
- }
- bool success = res->buildFromFile(xui_file);
- if (!success)
- {
- LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
- return NULL;
- }
-
- // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
- if (res->mKey.isUndefined())
- {
- res->mKey = key;
- }
- res->setInstanceName(name);
-
- LLFloater *last_floater = (list.empty() ? NULL : list.back());
-
- res->applyControlsAndPosition(last_floater);
-
- gFloaterView->adjustToFitScreen(res, false);
-
- list.push_back(res);
- }
- }
- if (!res)
- {
- LL_WARNS() << "Floater type: '" << name << "' not registered." << LL_ENDL;
- }
- }
- return res;
+ LLFloater* res = findInstance(name, key);
+ if (!res)
+ {
+ const LLFloaterBuildFunc& build_func = sBuildMap[name].mFunc;
+ const std::string& xui_file = sBuildMap[name].mFile;
+ if (build_func)
+ {
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+
+ res = build_func(key);
+ if (!res)
+ {
+ LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
+ return NULL;
+ }
+ bool success = res->buildFromFile(xui_file);
+ if (!success)
+ {
+ LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
+ return NULL;
+ }
+
+ // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
+ if (res->mKey.isUndefined())
+ {
+ res->mKey = key;
+ }
+ res->setInstanceName(name);
+
+ LLFloater *last_floater = (list.empty() ? NULL : list.back());
+
+ res->applyControlsAndPosition(last_floater);
+
+ gFloaterView->adjustToFitScreen(res, false);
+
+ list.push_back(res);
+ }
+ }
+ if (!res)
+ {
+ LL_WARNS() << "Floater type: '" << name << "' not registered." << LL_ENDL;
+ }
+ }
+ return res;
}
//static
LLFloater* LLFloaterReg::removeInstance(const std::string& name, const LLSD& key)
{
- LLFloater* res = NULL;
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
- {
- instance_list_t& list = sInstanceMap[groupname];
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- LLFloater* inst = *iter;
- if (inst->matchesKey(key))
- {
- res = inst;
- list.erase(iter);
- break;
- }
- }
- }
- return res;
+ LLFloater* res = NULL;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ list.erase(iter);
+ break;
+ }
+ }
+ }
+ return res;
}
//static
// returns true if the instance existed
bool LLFloaterReg::destroyInstance(const std::string& name, const LLSD& key)
{
- LLFloater* inst = removeInstance(name, key);
- if (inst)
- {
- delete inst;
- return true;
- }
- else
- {
- return false;
- }
+ LLFloater* inst = removeInstance(name, key);
+ if (inst)
+ {
+ delete inst;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
// Iterators
//static
LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::string& name)
{
- instance_map_t::iterator iter = sInstanceMap.find(name);
- if (iter != sInstanceMap.end())
- {
- return iter->second;
- }
- else
- {
- return sNullInstanceList;
- }
+ instance_map_t::iterator iter = sInstanceMap.find(name);
+ if (iter != sInstanceMap.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return sNullInstanceList;
+ }
}
// Visibility Management
//static
-LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
+LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
{
- if( sBlockShowFloaters
- // see EXT-7090
- && sAlwaysShowableList.find(name) == sAlwaysShowableList.end())
- return 0;//
- LLFloater* instance = getInstance(name, key);
- if (instance)
- {
- instance->openFloater(key);
- if (focus)
- instance->setFocus(TRUE);
- }
- return instance;
+ if( sBlockShowFloaters
+ // see EXT-7090
+ && sAlwaysShowableList.find(name) == sAlwaysShowableList.end())
+ return 0;//
+ LLFloater* instance = getInstance(name, key);
+ if (instance)
+ {
+ instance->openFloater(key);
+ if (focus)
+ instance->setFocus(TRUE);
+ }
+ return instance;
}
//static
// returns true if the instance exists
-bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
-{
- LLFloater* instance = findInstance(name, key);
- if (instance)
- {
- instance->closeHostedFloater();
- }
- return (instance != NULL);
+bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* instance = findInstance(name, key);
+ if (instance)
+ {
+ instance->closeHostedFloater();
+ }
+ return (instance != NULL);
}
//static
// returns true if the instance is visible when completed
bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
{
- LLFloater* instance = findInstance(name, key);
- if (LLFloater::isShown(instance))
- {
- instance->closeHostedFloater();
- return false;
- }
- else
- {
- return showInstance(name, key, TRUE) ? true : false;
- }
+ LLFloater* instance = findInstance(name, key);
+ if (LLFloater::isShown(instance))
+ {
+ instance->closeHostedFloater();
+ return false;
+ }
+ else
+ {
+ return showInstance(name, key, TRUE) ? true : false;
+ }
}
//static
// returns true if the instance exists and is visible (doesnt matter minimized or not)
bool LLFloaterReg::instanceVisible(const std::string& name, const LLSD& key)
{
- LLFloater* instance = findInstance(name, key);
- return LLFloater::isVisible(instance);
+ LLFloater* instance = findInstance(name, key);
+ return LLFloater::isVisible(instance);
}
//static
-void LLFloaterReg::showInitialVisibleInstances()
+void LLFloaterReg::showInitialVisibleInstances()
{
- // Iterate through alll registered instance names and show any with a save visible state
- for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
- {
- const std::string& name = iter->first;
- std::string controlname = getVisibilityControlName(name);
- if (LLFloater::getControlGroup()->controlExists(controlname))
- {
- BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname);
- if (isvis)
- {
- showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
- }
- }
- }
+ // Iterate through alll registered instance names and show any with a save visible state
+ for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ std::string controlname = getVisibilityControlName(name);
+ if (LLFloater::getControlGroup()->controlExists(controlname))
+ {
+ BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname);
+ if (isvis)
+ {
+ showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
+ }
+ }
+ }
}
//static
void LLFloaterReg::hideVisibleInstances(const std::set<std::string>& exceptions)
{
- // Iterate through alll active instances and hide them
- for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
- {
- const std::string& name = iter->first;
- if (exceptions.find(name) != exceptions.end())
- continue;
- instance_list_t& list = iter->second;
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- LLFloater* floater = *iter;
- floater->pushVisible(FALSE);
- }
- }
+ // Iterate through alll active instances and hide them
+ for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ if (exceptions.find(name) != exceptions.end())
+ continue;
+ instance_list_t& list = iter->second;
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* floater = *iter;
+ floater->pushVisible(FALSE);
+ }
+ }
}
//static
void LLFloaterReg::restoreVisibleInstances()
{
- // Iterate through all active instances and restore visibility
- for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
- {
- instance_list_t& list = iter->second;
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- LLFloater* floater = *iter;
- floater->popVisible();
- }
- }
+ // Iterate through all active instances and restore visibility
+ for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
+ {
+ instance_list_t& list = iter->second;
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* floater = *iter;
+ floater->popVisible();
+ }
+ }
}
//static
std::string LLFloaterReg::getRectControlName(const std::string& name)
{
- return std::string("floater_rect_") + getBaseControlName(name);
+ return std::string("floater_rect_") + getBaseControlName(name);
}
//static
std::string LLFloaterReg::declareRectControl(const std::string& name)
{
- std::string controlname = getRectControlName(name);
- LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
- llformat("Window Size for %s", name.c_str()),
- LLControlVariable::PERSIST_NONDFT);
- return controlname;
+ std::string controlname = getRectControlName(name);
+ LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
+ llformat("Window Size for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
+ return controlname;
}
std::string LLFloaterReg::declarePosXControl(const std::string& name)
{
- std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_x";
- LLFloater::getControlGroup()->declareF32(controlname,
- 10.f,
- llformat("Window X Position for %s", name.c_str()),
- LLControlVariable::PERSIST_NONDFT);
- return controlname;
+ std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_x";
+ LLFloater::getControlGroup()->declareF32(controlname,
+ 10.f,
+ llformat("Window X Position for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
+ return controlname;
}
std::string LLFloaterReg::declarePosYControl(const std::string& name)
{
- std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_y";
- LLFloater::getControlGroup()->declareF32(controlname,
- 10.f,
- llformat("Window Y Position for %s", name.c_str()),
- LLControlVariable::PERSIST_NONDFT);
+ std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_y";
+ LLFloater::getControlGroup()->declareF32(controlname,
+ 10.f,
+ llformat("Window Y Position for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
- return controlname;
+ return controlname;
}
//static
std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
{
- return std::string("floater_vis_") + getBaseControlName(name);
+ return std::string("floater_vis_") + getBaseControlName(name);
}
-//static
+//static
std::string LLFloaterReg::getBaseControlName(const std::string& name)
{
- std::string res(name);
- LLStringUtil::replaceChar( res, ' ', '_' );
- return res;
+ std::string res(name);
+ LLStringUtil::replaceChar( res, ' ', '_' );
+ return res;
}
//static
std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
{
- std::string controlname = getVisibilityControlName(name);
- LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
- llformat("Window Visibility for %s", name.c_str()),
- LLControlVariable::PERSIST_NONDFT);
- return controlname;
+ std::string controlname = getVisibilityControlName(name);
+ LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
+ llformat("Window Visibility for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
+ return controlname;
}
//static
std::string LLFloaterReg::declareDockStateControl(const std::string& name)
{
- std::string controlname = getDockStateControlName(name);
- LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
- llformat("Window Docking state for %s", name.c_str()),
- LLControlVariable::PERSIST_NONDFT);
- return controlname;
+ std::string controlname = getDockStateControlName(name);
+ LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
+ llformat("Window Docking state for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
+ return controlname;
}
//static
std::string LLFloaterReg::getDockStateControlName(const std::string& name)
{
- std::string res = std::string("floater_dock_") + name;
- LLStringUtil::replaceChar( res, ' ', '_' );
- return res;
+ std::string res = std::string("floater_dock_") + name;
+ LLStringUtil::replaceChar( res, ' ', '_' );
+ return res;
}
//static
void LLFloaterReg::registerControlVariables()
{
- // Iterate through alll registered instance names and register rect and visibility control variables
- for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
- {
- const std::string& name = iter->first;
- if (LLFloater::getControlGroup()->controlExists(getRectControlName(name)))
- {
- declareRectControl(name);
- }
- if (LLFloater::getControlGroup()->controlExists(getVisibilityControlName(name)))
- {
- declareVisibilityControl(name);
- }
- }
-
- const LLSD& exclude_list = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("always_showable_floaters");
- for (LLSD::array_const_iterator iter = exclude_list.beginArray();
- iter != exclude_list.endArray();
- iter++)
- {
- sAlwaysShowableList.insert(iter->asString());
- }
+ // Iterate through alll registered instance names and register rect and visibility control variables
+ for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ if (LLFloater::getControlGroup()->controlExists(getRectControlName(name)))
+ {
+ declareRectControl(name);
+ }
+ if (LLFloater::getControlGroup()->controlExists(getVisibilityControlName(name)))
+ {
+ declareVisibilityControl(name);
+ }
+ }
+
+ const LLSD& exclude_list = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("always_showable_floaters");
+ for (LLSD::array_const_iterator iter = exclude_list.beginArray();
+ iter != exclude_list.endArray();
+ iter++)
+ {
+ sAlwaysShowableList.insert(iter->asString());
+ }
}
//static
void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key)
{
- //
- // Floaters controlled by the toolbar behave a bit differently from others.
- // Namely they have 3-4 states as defined in the design wiki page here:
- // https://wiki.lindenlab.com/wiki/FUI_Button_states
- //
- // The basic idea is this:
- // * If the target floater is minimized, this button press will un-minimize it.
- // * Else if the target floater is closed open it.
- // * Else if the target floater does not have focus, give it focus.
- // * Also, if it is not on top, bring it forward when focus is given.
- // * Else the target floater is open, close it.
- //
- std::string name = sdname.asString();
- LLFloater* instance = getInstance(name, key);
-
- if (!instance)
- {
- LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;
- return;
- }
-
- // If hosted, we need to take that into account
- LLFloater* host = instance->getHost();
-
- if (host)
- {
- if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
- {
- host->setMinimized(FALSE);
- instance->openFloater(key);
- instance->setVisibleAndFrontmost(true, key);
- }
- else if (!instance->getVisible())
- {
- instance->openFloater(key);
- instance->setVisibleAndFrontmost(true, key);
- instance->setFocus(TRUE);
- }
- else
- {
- instance->closeHostedFloater();
- }
- }
- else
- {
- if (instance->isMinimized())
- {
- instance->setMinimized(FALSE);
- instance->setVisibleAndFrontmost(true, key);
- }
- else if (!instance->isShown())
- {
- instance->openFloater(key);
- instance->setVisibleAndFrontmost(true, key);
- }
- else if (!instance->isFrontmost())
- {
- instance->setVisibleAndFrontmost(true, key);
- }
- else
- {
- instance->closeHostedFloater();
- }
- }
+ //
+ // Floaters controlled by the toolbar behave a bit differently from others.
+ // Namely they have 3-4 states as defined in the design wiki page here:
+ // https://wiki.lindenlab.com/wiki/FUI_Button_states
+ //
+ // The basic idea is this:
+ // * If the target floater is minimized, this button press will un-minimize it.
+ // * Else if the target floater is closed open it.
+ // * Else if the target floater does not have focus, give it focus.
+ // * Also, if it is not on top, bring it forward when focus is given.
+ // * Else the target floater is open, close it.
+ //
+ std::string name = sdname.asString();
+ LLFloater* instance = getInstance(name, key);
+
+ if (!instance)
+ {
+ LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;
+ return;
+ }
+
+ // If hosted, we need to take that into account
+ LLFloater* host = instance->getHost();
+
+ if (host)
+ {
+ if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+ {
+ host->setMinimized(FALSE);
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->getVisible())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ instance->setFocus(TRUE);
+ }
+ else
+ {
+ instance->closeHostedFloater();
+ }
+ }
+ else
+ {
+ if (instance->isMinimized())
+ {
+ instance->setMinimized(FALSE);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isShown())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isFrontmost())
+ {
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else
+ {
+ instance->closeHostedFloater();
+ }
+ }
}
// static
@@ -585,25 +585,25 @@ void LLFloaterReg::showInstanceOrBringToFront(const LLSD& sdname, const LLSD& ke
// static
U32 LLFloaterReg::getVisibleFloaterInstanceCount()
{
- U32 count = 0;
+ U32 count = 0;
- std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
- for( ; it != it_end; ++it)
- {
- const std::string& group_name = it->second;
+ std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
+ for( ; it != it_end; ++it)
+ {
+ const std::string& group_name = it->second;
- instance_list_t& instances = sInstanceMap[group_name];
+ instance_list_t& instances = sInstanceMap[group_name];
- for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
- {
- LLFloater* inst = *iter;
+ for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
- if (inst->getVisible() && !inst->isMinimized())
- {
- count++;
- }
- }
- }
+ if (inst->getVisible() && !inst->isMinimized())
+ {
+ count++;
+ }
+ }
+ }
- return count;
+ return count;
}