diff options
| -rw-r--r-- | indra/newview/llchiclet.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llimfloater.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llimfloater.h | 2 | ||||
| -rw-r--r-- | indra/newview/lltransientdockablefloater.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/lltransientdockablefloater.h | 4 | ||||
| -rw-r--r-- | indra/newview/lltransientfloatermgr.cpp | 69 | ||||
| -rw-r--r-- | indra/newview/lltransientfloatermgr.h | 37 | 
7 files changed, 90 insertions, 33 deletions
| diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 8da207f887..f1de4e2982 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1272,6 +1272,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)  		chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));  		arrange(); +		LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet);  		return true;  	} @@ -1299,6 +1300,7 @@ void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)  	mChicletList.erase(it);  	arrange(); +	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet);  	chiclet->die();  } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index e06e0c94ec..73597e7de3 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -110,6 +110,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)  		}  	}  	setOverlapsScreenChannel(true); + +	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);  }  void LLIMFloater::onFocusLost() @@ -228,6 +230,7 @@ void LLIMFloater::sendMsg()  LLIMFloater::~LLIMFloater()  { +	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);  }  //virtual @@ -513,14 +516,14 @@ bool LLIMFloater::toggle(const LLUUID& session_id)  	if(!isChatMultiTab())  	{  		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -		if (floater && floater->getVisible()) +		if (floater && floater->getVisible() && floater->hasFocus())  		{  			// clicking on chiclet to close floater just hides it to maintain existing  			// scroll/text entry state  			floater->setVisible(false);  			return false;  		} -		else if(floater && !floater->isDocked()) +		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))  		{  			floater->setVisible(TRUE);  			floater->setFocus(TRUE); diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index d9db385d06..0ca0325451 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -116,6 +116,8 @@ public:  	static void onIMChicletCreated(const LLUUID& session_id); +	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } +  private:  	// process focus events to set a currently active session  	/* virtual */ void onFocusLost(); diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp index 7e4d4988d1..b830498cb0 100644 --- a/indra/newview/lltransientdockablefloater.cpp +++ b/indra/newview/lltransientdockablefloater.cpp @@ -39,7 +39,7 @@  LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockControl, bool uniqueDocking,  		const LLSD& key, const Params& params) : -		LLDockableFloater(dockControl, uniqueDocking, key, params) +		LLDockableFloater(dockControl, uniqueDocking, key, params), LLTransientFloater(this)  {  	LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);  } diff --git a/indra/newview/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h index 6e8a3afd22..e0541d6597 100644 --- a/indra/newview/lltransientdockablefloater.h +++ b/indra/newview/lltransientdockablefloater.h @@ -37,12 +37,13 @@  #include "llfloater.h"  #include "lldockcontrol.h"  #include "lldockablefloater.h" +#include "lltransientfloatermgr.h"  /**   * Represents floater that can dock and managed by transient floater manager.   * Transient floaters should be hidden if user click anywhere except defined view list.   */ -class LLTransientDockableFloater : public LLDockableFloater +class LLTransientDockableFloater : public LLDockableFloater, LLTransientFloater  {  public:  	LOG_CLASS(LLTransientDockableFloater); @@ -52,6 +53,7 @@ public:  	/*virtual*/ void setVisible(BOOL visible);  	/* virtual */void setDocked(bool docked, bool pop_on_undock = true); +	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }  };  #endif /* LL_TRANSIENTDOCKABLEFLOATER_H */ diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp index 347399f239..f474f47eb7 100644 --- a/indra/newview/lltransientfloatermgr.cpp +++ b/indra/newview/lltransientfloatermgr.cpp @@ -44,57 +44,68 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()  {  	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(  			&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3)); + +	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>())); +	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));  } -void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater)  {  	mTransSet.insert(floater);  } -void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* floater)  {  	mTransSet.erase(floater);  } +void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view) +{ +	mGroupControls.find(group)->second.insert(view); +} + +void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view) +{ +	mGroupControls.find(group)->second.erase(view); +} +  void LLTransientFloaterMgr::addControlView(LLView* view)  { -	mControlsSet.insert(view); +	addControlView(GLOBAL, view);  }  void LLTransientFloaterMgr::removeControlView(LLView* view)  {  	// we will still get focus lost callbacks on this view, but that's ok  	// since we run sanity checking logic every time -	mControlsSet.erase(view); +	removeControlView(GLOBAL, view);  } -void LLTransientFloaterMgr::hideTransientFloaters() +void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)  { -	for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it +	for (std::set<LLTransientFloater*>::iterator it = mTransSet.begin(); it  			!= mTransSet.end(); it++)  	{ -		LLFloater* floater = *it; -		if (floater->isDocked()) +		LLTransientFloater* floater = *it; +		if (floater->isTransientDocked())  		{ -			floater->setVisible(FALSE); +			ETransientGroup group = floater->getGroup(); + +			bool hide = isControlClicked(mGroupControls.find(group)->second, x, y); +			if (hide) +			{ +				floater->setTransientVisible(FALSE); +			}  		}  	}  } -void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, -		MASK mask) +bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y)  { -	bool hide = true; -	for (controls_set_t::iterator it = mControlsSet.begin(); it -			!= mControlsSet.end(); it++) +	bool res = true; +	for (controls_set_t::iterator it = set.begin(); it +			!= set.end(); it++)  	{ -		// don't hide transient floater if any context menu opened -		if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) -		{ -			hide = false; -			break; -		} -  		LLView* control_view = *it;  		if (!control_view->getVisible())  		{ @@ -105,14 +116,26 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,  		// if click inside view rect  		if (rect.pointInRect(x, y))  		{ -			hide = false; +			res = false;  			break;  		}  	} +	return res; +} + +void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, +		MASK mask) +{ +	// don't hide transient floater if any context menu opened +	if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) +	{ +		return; +	} +	bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);  	if (hide)  	{ -		hideTransientFloaters(); +		hideTransientFloaters(x, y);  	}  } diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index cef6e1fe45..95eba666a0 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -37,6 +37,7 @@  #include "llsingleton.h"  #include "llfloater.h" +class LLTransientFloater;  /**   * Provides functionality to hide transient floaters. @@ -44,20 +45,44 @@  class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>  {  public: +	enum ETransientGroup +	{ +		GLOBAL, IM +	}; +  	LLTransientFloaterMgr(); -	void registerTransientFloater(LLFloater* floater); -	void unregisterTransientFloater(LLFloater* floater); +	void registerTransientFloater(LLTransientFloater* floater); +	void unregisterTransientFloater(LLTransientFloater* floater); +	void addControlView(ETransientGroup group, LLView* view); +	void removeControlView(ETransientGroup group, LLView* view);  	void addControlView(LLView* view);  	void removeControlView(LLView* view);  private: -	void hideTransientFloaters(); +	void hideTransientFloaters(S32 x, S32 y);  	void leftMouseClickCallback(S32 x, S32 y, MASK mask); - +	bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y);  private: -	std::set<LLFloater*> mTransSet; +	std::set<LLTransientFloater*> mTransSet; +  	typedef std::set<LLView*> controls_set_t; -	controls_set_t mControlsSet; +	typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t; +	group_controls_t mGroupControls; +}; + +/** + * An abstract class declares transient floater interfaces. + */ +class LLTransientFloater +{ +public: +	LLTransientFloater(LLFloater* floater) : mFloater(floater) {} +	virtual LLTransientFloaterMgr::ETransientGroup getGroup() = 0; +	bool isTransientDocked() { return mFloater->isDocked(); }; +	void setTransientVisible(BOOL visible) {mFloater->setVisible(visible); } + +private: +	LLFloater* mFloater;  };  #endif  // LL_LLTRANSIENTFLOATERMGR_H | 
