diff options
| -rw-r--r-- | indra/llui/llfloater.cpp | 38 | ||||
| -rw-r--r-- | indra/llui/llfloater.h | 4 | ||||
| -rw-r--r-- | indra/newview/llsidetray.cpp | 176 | ||||
| -rw-r--r-- | indra/newview/llsidetray.h | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_side_bar_tab.xml | 1 | 
5 files changed, 165 insertions, 55 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 0c4c857022..ff90806271 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -519,6 +519,36 @@ void LLFloater::storeDockStateControl()  	}  } +LLRect LLFloater::getSavedRect() const +{ +	LLRect rect; + +	if (mRectControl.size() > 1) +	{ +		rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl); +	} + +	return rect; +} + +bool LLFloater::hasSavedRect() const +{ +	return !getSavedRect().isEmpty(); +} + +// static +std::string LLFloater::getControlName(const std::string& name, const LLSD& key) +{ +	std::string ctrl_name = name; + +	// Add the key to the control name if appropriate. +	if (key.isString() && !key.asString().empty()) +	{ +		ctrl_name += "_" + key.asString(); +	} + +	return ctrl_name; +}  void LLFloater::setVisible( BOOL visible )  { @@ -2664,13 +2694,7 @@ void LLFloater::setInstanceName(const std::string& name)  	mInstanceName = name;  	if (!mInstanceName.empty())  	{ -		std::string ctrl_name = mInstanceName; - -		// Add the key to the control name if appropriate. -		if (mKey.isString() && !mKey.asString().empty()) -		{ -			ctrl_name += "_" + mKey.asString(); -		} +		std::string ctrl_name = getControlName(mInstanceName, mKey);  		// save_rect and save_visibility only apply to registered floaters  		if (!mRectControl.empty()) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 5e482cbac3..ed1f0715af 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -203,6 +203,10 @@ public:  	BOOL			isResizable() const				{ return mResizable; }  	void			setResizeLimits( S32 min_width, S32 min_height );  	void			getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; } +	LLRect			getSavedRect() const; +	bool			hasSavedRect() const; + +	static std::string	getControlName(const std::string& name, const LLSD& key);  	bool			isMinimizeable() const{ return mCanMinimize; }  	bool			isCloseable() const{ return mCanClose; } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 9e989ed052..a143318763 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -111,7 +111,11 @@ public:  	};  protected:  	LLSideTrayTab(const Params& params); -	 + +	void			dock(); +	void			undock(LLFloater* floater_tab); + +	LLSideTray*		getSideTray();  public:  	virtual ~LLSideTrayTab(); @@ -211,6 +215,28 @@ void	LLSideTrayTab::onOpen		(const LLSD& key)  		panel->onOpen(key);  } +// Attempts to get the existing side tray instance. +// Needed to avoid recursive calls of LLSideTray::getInstance(). +LLSideTray* LLSideTrayTab::getSideTray() +{ +	// First, check if the side tray is our parent (i.e. we're attached). +	LLSideTray* side_tray = dynamic_cast<LLSideTray*>(getParent()); +	if (!side_tray) +	{ +		// Detached? Ok, check if the instance exists at all/ +		if (LLSideTray::instanceCreated()) +		{ +			side_tray = LLSideTray::getInstance(); +		} +		else +		{ +			llerrs << "No safe way to get the side tray instance" << llendl; +		} +	} + +	return side_tray; +} +  void LLSideTrayTab::toggleTabDocked()  {  	std::string tab_name = getName(); @@ -220,70 +246,99 @@ void LLSideTrayTab::toggleTabDocked()  	LLFloaterReg::toggleInstance("side_bar_tab", tab_name); -	LLSideTray* side_tray = LLSideTray::getInstance(); - -	bool is_tab_undocked = LLFloater::isShown(floater_tab); +	bool docking = !LLFloater::isShown(floater_tab);  	// Hide the "Tear Off" button when a tab gets undocked  	// and show "Dock" button instead. -	getChild<LLButton>("undock")->setVisible(!is_tab_undocked); -	getChild<LLButton>("dock")->setVisible(is_tab_undocked); +	getChild<LLButton>("undock")->setVisible(docking); +	getChild<LLButton>("dock")->setVisible(!docking); -	if (is_tab_undocked) +	if (docking)  	{ -		// Remove the tab from Side Tray's tabs list. -		// We have to do it despite removing the tab from Side Tray's child view tree -		// by addChild(). Otherwise the tab could be accessed by the pointer in LLSideTray::mTabs. -		if (!side_tray->removeTab(this)) -		{ -			llwarns << "Failed to remove tab " << getName() << " from side tray" << llendl; -			return; -		} +		dock(); +	} +	else +	{ +		undock(floater_tab); +	} +} -		setVisible(true); // *HACK: restore visibility after being hidden by LLSideTray::selectTabByName(). -		floater_tab->addChild(this); -		floater_tab->setTitle(mTabTitle); +void LLSideTrayTab::dock() +{ +	LLSideTray* side_tray = getSideTray(); +	if (!side_tray) return; -		LLRect rect = side_tray->getLocalRect(); -		floater_tab->reshape(rect.getWidth(), rect.getHeight()); +	if (!side_tray->addTab(this)) +	{ +		llwarns << "Failed to add tab " << getName() << " to side tray" << llendl; +		return; +	} -		rect.mTop -= floater_tab->getHeaderHeight(); -		setRect(rect); -		reshape(rect.getWidth(), rect.getHeight()); +	setRect(side_tray->getLocalRect()); +	reshape(getRect().getWidth(), getRect().getHeight()); -		// Set FOLLOWS_ALL flag for the tab to follow floater dimensions upon resizing. -		setFollowsAll(); +	// Select the re-docked tab. +	side_tray->selectTabByName(getName()); -		if (!side_tray->getCollapsed()) -		{ -			side_tray->collapseSideBar(); -		} +	if (side_tray->getCollapsed()) +	{ +		side_tray->expandSideBar(); +	} +} -		if (side_tray->getActiveTab() != this) -		{ -			// When a tab other then current active tab is detached from Side Tray -			// onOpen() should be called as tab visibility is changed. -			onOpen(LLSD()); -		} +void LLSideTrayTab::undock(LLFloater* floater_tab) +{ +	LLSideTray* side_tray = getSideTray(); +	if (!side_tray) return; + +	// Remove the tab from Side Tray's tabs list. +	// We have to do it despite removing the tab from Side Tray's child view tree +	// by addChild(). Otherwise the tab could be accessed by the pointer in LLSideTray::mTabs. +	if (!side_tray->removeTab(this)) +	{ +		llwarns << "Failed to remove tab " << getName() << " from side tray" << llendl; +		return; +	} + +	setVisible(true); // *HACK: restore visibility after being hidden by LLSideTray::selectTabByName(). +	floater_tab->addChild(this); +	floater_tab->setTitle(mTabTitle); + +	// Reshape the floater if needed. +	LLRect floater_rect; +	if (floater_tab->hasSavedRect()) +	{ +		// We've got saved rect for the floater, hence no need to reshape it. +		floater_rect = floater_tab->getLocalRect();  	}  	else  	{ -		if (!side_tray->addTab(this)) -		{ -			llwarns << "Failed to add tab " << getName() << " to side tray" << llendl; -			return; -		} +		// Detaching for the first time. Reshape the floater. +		floater_rect = side_tray->getLocalRect(); +		floater_tab->reshape(floater_rect.getWidth(), floater_rect.getHeight()); +	} -		setRect(side_tray->getLocalRect()); -		reshape(getRect().getWidth(), getRect().getHeight()); +	// Reshape the panel. +	{ +		LLRect panel_rect = floater_rect; +		panel_rect.mTop -= floater_tab->getHeaderHeight(); +		setRect(panel_rect); +		reshape(panel_rect.getWidth(), panel_rect.getHeight()); +	} -		// Select the re-docked tab. -		side_tray->selectTabByName(getName()); +	// Set FOLLOWS_ALL flag for the tab to follow floater dimensions upon resizing. +	setFollowsAll(); -		if (side_tray->getCollapsed()) -		{ -			side_tray->expandSideBar(); -		} +	if (!side_tray->getCollapsed()) +	{ +		side_tray->collapseSideBar(); +	} + +	if (side_tray->getActiveTab() != this) +	{ +		// When a tab other then current active tab is detached from Side Tray +		// onOpen() should be called as tab visibility is changed. +		onOpen(LLSD());  	}  } @@ -460,6 +515,7 @@ BOOL LLSideTray::postBuild()  			getCollapseSignal().connect(boost::bind(&LLScreenChannelBase::resetPositionAndSize, (*it).channel, _2));  		}  	} +  	return true;  } @@ -467,6 +523,8 @@ void LLSideTray::handleLoginComplete()  {  	//reset tab to "home" tab if it was changesd during login process  	selectTabByName("sidebar_home"); + +	detachTabs();  }  LLSideTrayTab* LLSideTray::getTab(const std::string& name) @@ -901,6 +959,28 @@ void LLSideTray::arrange()  	mButtonsPanel->setVisible(hasTabs());  } +// Detach those tabs that were detached when the viewer exited last time. +void LLSideTray::detachTabs() +{ +	// copy mTabs because LLSideTray::toggleTabDocked() modifies it. +	child_vector_t tabs = mTabs; + +	for (child_vector_const_iter_t it = tabs.begin(); it != tabs.end(); ++it) +	{ +		LLSideTrayTab* tab = *it; + +		std::string floater_ctrl_name = LLFloater::getControlName("side_bar_tab", LLSD(tab->getName())); +		std::string vis_ctrl_name = LLFloaterReg::getVisibilityControlName(floater_ctrl_name); +		if (!LLUI::sSettingGroups["floater"]->controlExists(vis_ctrl_name)) continue; + +		bool is_visible = LLUI::sSettingGroups["floater"]->getBOOL(vis_ctrl_name); +		if (!is_visible) continue; + +		llassert(isTabAttached(tab->getName())); +		tab->toggleTabDocked(); +	} +} +  void LLSideTray::collapseSideBar()  {  	mCollapsed = true; diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index f60c72e7a3..248def8e3d 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -173,6 +173,7 @@ protected:  	LLButton*	createButton	(const std::string& name,const std::string& image,const std::string& tooltip,  									LLUICtrl::commit_callback_t callback);  	void		arrange			(); +	void		detachTabs		();  	void		reflectCollapseChange();  	void		toggleTabButton	(LLSideTrayTab* tab); diff --git a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml index 35df6a37f6..9ec3410afd 100644 --- a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml +++ b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml @@ -3,5 +3,6 @@   can_close="false"   can_resize="true"   save_rect="true" + save_visibility="true"   >  </floater>  | 
