diff options
| author | Richard Linden <none@none> | 2011-09-27 19:06:02 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2011-09-27 19:06:02 -0700 | 
| commit | 68d5141fb3ccb5e898caa83e9eab84d76134e28c (patch) | |
| tree | 02ecd4cf801e30e895520b49674ed455b94dfe89 | |
| parent | bce16356c9e1fb76bd92a3530375e4c6c7a5430a (diff) | |
EXP-1258 WIP toggle buttons between icons and icons+text modes
fixed button layout for icon+text
layout stack now uses floating point precision to avoid clamping panels to 0
| -rw-r--r-- | indra/llui/llbutton.cpp | 2 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.cpp | 252 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.h | 18 | ||||
| -rw-r--r-- | indra/llui/lltoolbar.cpp | 40 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_test_toolbar.xml | 4 | 
5 files changed, 123 insertions, 193 deletions
| diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 02ac928dfb..e1bea086b2 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -819,6 +819,7 @@ void LLButton::draw()  		{  		case LLFontGL::LEFT:  			text_left += overlay_width + mImgOverlayLabelSpace; +			text_width -= overlay_width + mImgOverlayLabelSpace;  			mImageOverlay->draw(  				mLeftHPad,  				center_y - (overlay_height / 2),  @@ -836,6 +837,7 @@ void LLButton::draw()  			break;  		case LLFontGL::RIGHT:  			text_right -= overlay_width + mImgOverlayLabelSpace; +			text_width -= overlay_width + mImgOverlayLabelSpace;  			mImageOverlay->draw(  				getRect().getWidth() - mRightHPad - overlay_width,  				center_y - (overlay_height / 2),  diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 0d1f608e61..89b3f671a4 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -55,11 +55,12 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)   	mMaxDim(p.max_dim),    	mAutoResize(p.auto_resize),   	mUserResize(p.user_resize), -	mFitContent(p.fit_content),  	mCollapsed(FALSE),  	mCollapseAmt(0.f),  	mVisibleAmt(1.f), // default to fully visible -	mResizeBar(NULL)  +	mResizeBar(NULL), +	mFractionalSize(0.f), +	mOrientation(LLLayoutStack::HORIZONTAL)  {  	// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value  	if (p.expanded_min_dim.isProvided()) @@ -89,9 +90,22 @@ LLLayoutPanel::~LLLayoutPanel()  	mResizeBar = NULL;  } -F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation) +void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent)  { -	if (orientation == LLLayoutStack::HORIZONTAL) +	if (mOrientation == LLLayoutStack::HORIZONTAL) +	{ +		mFractionalSize += width - llround(mFractionalSize); +	} +	else +	{ +		mFractionalSize += height - llround(mFractionalSize); +	} +	LLPanel::reshape(width, height, called_from_parent); +} + +F32 LLLayoutPanel::getCollapseFactor() +{ +	if (mOrientation == LLLayoutStack::HORIZONTAL)  	{  		F32 collapse_amt =   			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth())); @@ -105,14 +119,6 @@ F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientati  	}  } -void LLLayoutPanel::fitToContent() -{ -	if (mFitContent) -	{ -		setShape(calcBoundingRect()); -	} -} -  //  // LLLayoutStack  // @@ -158,11 +164,11 @@ void LLLayoutStack::draw()  		// scale clipping rectangle by visible amount  		if (mOrientation == HORIZONTAL)  		{ -			clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation)); +			clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());  		}  		else  		{ -			clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation)); +			clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());  		}  		LLPanel* panelp = (*panel_it); @@ -202,36 +208,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group)  	LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);  	if (panelp)  	{ +		panelp->mFractionalSize = (mOrientation == HORIZONTAL) +									? panelp->getRect().getWidth() +									: panelp->getRect().getHeight(); +		panelp->setOrientation(mOrientation);  		mPanels.push_back(panelp);  	}  	return LLView::addChild(child, tab_group);  } - -S32 LLLayoutStack::getDefaultHeight(S32 cur_height) -{ -	// if we are spanning our children (crude upward propagation of size) -	// then don't enforce our size on our children -	if (mOrientation == HORIZONTAL) -	{ -		cur_height = llmax(mMinHeight, getRect().getHeight()); -	} - -	return cur_height; -} - -S32 LLLayoutStack::getDefaultWidth(S32 cur_width) -{ -	// if we are spanning our children (crude upward propagation of size) -	// then don't enforce our size on our children -	if (mOrientation == VERTICAL) -	{ -		cur_width = llmax(mMinWidth, getRect().getWidth()); -	} - -	return cur_width; -} -  void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)  {  	LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move); @@ -326,14 +311,15 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  	createResizeBars();  	// calculate current extents -	S32 total_width = 0; -	S32 total_height = 0; +	F32 total_size = 0.f; +	// +	// animate visibility +	//  	e_panel_list_t::iterator panel_it;  	for (panel_it = mPanels.begin(); panel_it != mPanels.end();	++panel_it)  	{  		LLLayoutPanel* panelp = (*panel_it); -		panelp->fitToContent();  		if (panelp->getVisible())   		{  			if (mAnimate) @@ -371,181 +357,110 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  			}  		} -		if (panelp->mCollapsed) -		{ -			panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); -		} -		else -		{ -			panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); -		} +		F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f; +		panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); -		if (mOrientation == HORIZONTAL) +        total_size += panelp->mFractionalSize * panelp->getCollapseFactor(); +        // want n-1 panel gaps for n panels +		if (panel_it != mPanels.begin())  		{ -			// enforce minimize size constraint by default -			if (panelp->getRect().getWidth() < panelp->getRelevantMinDim()) -			{ -				panelp->reshape(panelp->getRelevantMinDim(), panelp->getRect().getHeight()); -			} -        	total_width += llround(panelp->getRect().getWidth() * panelp->getCollapseFactor(mOrientation)); -        	// want n-1 panel gaps for n panels -			if (panel_it != mPanels.begin()) -			{ -				total_width += mPanelSpacing; -			} -		} -		else //VERTICAL -		{ -			// enforce minimize size constraint by default -			if (panelp->getRect().getHeight() < panelp->getRelevantMinDim()) -			{ -				panelp->reshape(panelp->getRect().getWidth(), panelp->getRelevantMinDim()); -			} -			total_height += llround(panelp->getRect().getHeight() * panelp->getCollapseFactor(mOrientation)); -			if (panel_it != mPanels.begin()) -			{ -				total_height += mPanelSpacing; -			} +			total_size += mPanelSpacing;  		}  	}  	S32 num_resizable_panels = 0; -	S32 shrink_headroom_available = 0; -	S32 shrink_headroom_total = 0; +	F32 shrink_headroom_available = 0.f; +	F32 shrink_headroom_total = 0.f;  	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)  	{ +		LLLayoutPanel* panelp = (*panel_it); +  		// panels that are not fully visible do not count towards shrink headroom -		if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f)  +		if (panelp->getCollapseFactor() < 1.f)   		{  			continue;  		} -		S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight(); -		S32 relevant_min = (*panel_it)->getRelevantMinDim(); +		F32 cur_size = panelp->mFractionalSize; +		F32 min_size = (F32)panelp->getRelevantMinDim();  		// if currently resizing a panel or the panel is flagged as not automatically resizing  		// only track total available headroom, but don't use it for automatic resize logic -		if ((*panel_it)->mResizeBar->hasMouseCapture()  -			|| (!(*panel_it)->mAutoResize  +		if (panelp->mResizeBar->hasMouseCapture()  +			|| (!panelp->mAutoResize   				&& !force_resize))  		{ -			shrink_headroom_total += relevant_dimension - relevant_min; +			shrink_headroom_total += cur_size - min_size;  		}  		else  		{  			num_resizable_panels++; -			shrink_headroom_available += relevant_dimension - relevant_min; -			shrink_headroom_total += relevant_dimension - relevant_min; +			shrink_headroom_available += cur_size - min_size; +			shrink_headroom_total += cur_size - min_size;  		}  	}  	// calculate how many pixels need to be distributed among layout panels  	// positive means panels need to grow, negative means shrink -	S32 pixels_to_distribute; -	if (mOrientation == HORIZONTAL) -	{ -		pixels_to_distribute = getRect().getWidth() - total_width; -	} -	else //VERTICAL -	{ -		pixels_to_distribute = getRect().getHeight() - total_height; -	} +	F32 pixels_to_distribute = (mOrientation == HORIZONTAL) +							? getRect().getWidth() - total_size +							: getRect().getHeight() - total_size;  	// now we distribute the pixels... -	S32 cur_x = 0; -	S32 cur_y = getRect().getHeight(); +	F32 cur_x = 0.f; +	F32 cur_y = (F32)getRect().getHeight();  	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)  	{  		LLLayoutPanel* panelp = (*panel_it); -		S32 cur_width = panelp->getRect().getWidth(); -		S32 cur_height = panelp->getRect().getHeight(); -		S32 new_width = cur_width; -		S32 new_height = cur_height; -		S32 relevant_min = panelp->getRelevantMinDim(); - -		if (mOrientation == HORIZONTAL) -		{ -			new_width = llmax(relevant_min, new_width); -		} -		else -		{ -			new_height = llmax(relevant_min, new_height); -		} -		S32 delta_size = 0; +		F32 min_size = panelp->getRelevantMinDim(); +		F32 delta_size = 0.f;  		// if panel can automatically resize (not animating, and resize flag set)... -		if (panelp->getCollapseFactor(mOrientation) == 1.f  +		if (panelp->getCollapseFactor() == 1.f   			&& (force_resize || panelp->mAutoResize)   			&& !panelp->mResizeBar->hasMouseCapture())   		{ -			if (mOrientation == HORIZONTAL) +			if (pixels_to_distribute < 0.f)  			{ -				// if we're shrinking -				if (pixels_to_distribute < 0) -				{ -					// shrink proportionally to amount over minimum -					// so we can do this in one pass -					delta_size = (shrink_headroom_available > 0)  -						? llround((F32)pixels_to_distribute * ((F32)(cur_width - relevant_min) / (F32)shrink_headroom_available))  -						: 0; -					shrink_headroom_available -= (cur_width - relevant_min); -				} -				else -				{ -					// grow all elements equally -					delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); -					num_resizable_panels--; -				} -				pixels_to_distribute -= delta_size; -				new_width = llmax(relevant_min, cur_width + delta_size); +				// shrink proportionally to amount over minimum +				// so we can do this in one pass +				delta_size = (shrink_headroom_available > 0.f)  +					? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available)  +					: 0.f; +				shrink_headroom_available -= (panelp->mFractionalSize - min_size);  			}  			else  			{ -				new_width = getDefaultWidth(new_width); -			} - -			if (mOrientation == VERTICAL) -			{ -				if (pixels_to_distribute < 0) -				{ -					// shrink proportionally to amount over minimum -					// so we can do this in one pass -					delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0; -					shrink_headroom_available -= (cur_height - relevant_min); -				} -				else -				{ -					delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); -					num_resizable_panels--; -				} -				pixels_to_distribute -= delta_size; -				new_height = llmax(relevant_min, cur_height + delta_size); -			} -			else -			{ -				new_height = getDefaultHeight(new_height); -			} -		} -		else -		{ -			if (mOrientation == HORIZONTAL) -			{ -				new_height = getDefaultHeight(new_height); -			} -			else // VERTICAL -			{ -				new_width = getDefaultWidth(new_width); +				// grow all elements equally +				delta_size = pixels_to_distribute / (F32)num_resizable_panels; +				num_resizable_panels--;  			} +			 +			panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size); +			pixels_to_distribute -= delta_size;  		}  		// adjust running headroom count based on new sizes  		shrink_headroom_total += delta_size;  		LLRect panel_rect; -		panel_rect.setLeftTopAndSize(cur_x, cur_y, new_width, new_height); +		if (mOrientation == HORIZONTAL) +		{ +			panel_rect.setLeftTopAndSize(llround(cur_x),  +										llround(cur_y),  +										llround(panelp->mFractionalSize),  +										getRect().getHeight()); +		} +		else +		{ +			panel_rect.setLeftTopAndSize(llround(cur_x),  +										llround(cur_y),  +										getRect().getWidth(),  +										llround(panelp->mFractionalSize)); +		}  		panelp->setShape(panel_rect);  		LLRect resize_bar_rect = panel_rect; @@ -561,13 +476,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  		}  		(*panel_it)->mResizeBar->setRect(resize_bar_rect); +		F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing;  		if (mOrientation == HORIZONTAL)  		{ -			cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; +			cur_x += size;  		}  		else //VERTICAL  		{ -			cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; +			cur_y -= size;  		}  	} diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 2ed32a2fa9..5d79505fc3 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -126,8 +126,6 @@ protected:  private:  	void createResizeBars();  	void calcMinExtents(); -	S32 getDefaultHeight(S32 cur_height); -	S32 getDefaultWidth(S32 cur_width);  	const ELayoutOrientation mOrientation; @@ -161,16 +159,14 @@ public:  								min_dim,  								max_dim;  		Optional<bool>			user_resize, -								auto_resize, -								fit_content; +								auto_resize;  		Params()  		:	expanded_min_dim("expanded_min_dim", 0),  			min_dim("min_dim", 0),  			max_dim("max_dim", 0),  			user_resize("user_resize", true), -			auto_resize("auto_resize", true), -			fit_content("fit_content", false) +			auto_resize("auto_resize", true)  		{  			addSynonym(min_dim, "min_width");  			addSynonym(min_dim, "min_height"); @@ -183,6 +179,8 @@ public:  	void initFromParams(const Params& p); +	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); +  	S32 getMinDim() const { return mMinDim; }  	void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; } @@ -204,11 +202,12 @@ public:  		return min_dim;  	} +	void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; } +  protected:  	LLLayoutPanel(const Params& p); -	F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation); -	void fitToContent(); +	F32 getCollapseFactor();  	bool	mExpandedMinDimSpecified;  	S32		mExpandedMinDim; @@ -218,9 +217,10 @@ protected:  	bool	mAutoResize;  	bool	mUserResize;  	bool	mCollapsed; -	bool	mFitContent;  	F32		mVisibleAmt;  	F32		mCollapseAmt; +	F32		mFractionalSize; +	LLLayoutStack::ELayoutOrientation mOrientation;  	class LLResizeBar* mResizeBar;  }; diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 677d50a0c7..57a9151649 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -126,14 +126,13 @@ void LLToolBar::createContextMenu()  	{  		// Setup bindings specific to this instance for the context menu options -		LLUICtrl::CommitCallbackRegistry::Registrar& commit_reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar(); +		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit_reg;  		commit_reg.add("Toolbars.EnableSetting", boost::bind(&LLToolBar::onSettingEnable, this, _2)); -		LLUICtrl::EnableCallbackRegistry::Registrar& enable_reg = LLUICtrl::EnableCallbackRegistry::defaultRegistrar(); +		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_reg;  		enable_reg.add("Toolbars.CheckSetting", boost::bind(&LLToolBar::isSettingChecked, this, _2));  		// Create the context menu -  		LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  		if (menu) @@ -146,10 +145,6 @@ void LLToolBar::createContextMenu()  		{  			llwarns << "Unable to load toolbars context menu." << llendl;  		} - -		// Remove this instance's bindings -		commit_reg.remove("Toolbars.EnableSetting"); -		enable_reg.remove("Toolbars.CheckSetting");  	}  } @@ -184,7 +179,6 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)  	center_panel_p.rect = getLocalRect();  	center_panel_p.auto_resize = false;  	center_panel_p.user_resize = false; -	center_panel_p.fit_content = true;  	LLLayoutPanel* center_panel = LLUICtrlFactory::create<LLLayoutPanel>(center_panel_p);  	mCenteringStack->addChild(center_panel); @@ -196,6 +190,11 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)  	mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p)); +	BOOST_FOREACH(LLCommandId::Params params, p.commands) +	{ +		addCommand(params); +	} +  	mNeedsLayout = true;  } @@ -207,8 +206,8 @@ bool LLToolBar::addCommand(const LLCommandId& commandId)  	if (add_command)  	{ -	mButtonCommands.push_back(commandId); -	createButtons(); +		mButtonCommands.push_back(commandId); +		createButtons();  	}  	return add_command; @@ -220,9 +219,9 @@ bool LLToolBar::hasCommand(const LLCommandId& commandId) const  	if (commandId != LLCommandId::null)  	{ -		for (std::list<LLCommandId>::const_iterator cmd = mButtonCommands.begin(); cmd != mButtonCommands.end(); ++cmd) +		BOOST_FOREACH(LLCommandId cmd, mButtonCommands)  		{ -			if ((*cmd) == commandId) +			if (cmd == commandId)  			{  				has_command = true;  				break; @@ -410,11 +409,11 @@ void LLToolBar::updateLayoutAsNeeded()  			cur_start = row_pad_start;  			cur_row += max_row_girth + mPadBetween;  			max_row_girth = 0; -	} +		} -	LLRect button_rect; -	if (orientation == LLLayoutStack::HORIZONTAL) -	{ +		LLRect button_rect; +		if (orientation == LLLayoutStack::HORIZONTAL) +		{  			button_rect.setLeftTopAndSize(cur_start, panel_rect.mTop - cur_row, button_clamped_width, button->getRect().getHeight());  		}  		else // VERTICAL @@ -460,6 +459,9 @@ void LLToolBar::updateLayoutAsNeeded()  		mButtonPanel->reshape(total_girth, max_row_length);  	} +	// make parent fit button panel +	mButtonPanel->getParent()->setShape(mButtonPanel->getLocalRect()); +  	// re-center toolbar buttons  	mCenteringStack->updateLayout(); @@ -470,7 +472,13 @@ void LLToolBar::updateLayoutAsNeeded()  void LLToolBar::draw()  { +	if (mButtons.empty()) return;  	updateLayoutAsNeeded(); +	// rect may have shifted during layout +	LLUI::popMatrix(); +	LLUI::pushMatrix(); +	LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom, 0.f); +  	LLUICtrl::draw();  } diff --git a/indra/newview/skins/default/xui/en/floater_test_toolbar.xml b/indra/newview/skins/default/xui/en/floater_test_toolbar.xml index fbfbe51a69..067c1fed82 100644 --- a/indra/newview/skins/default/xui/en/floater_test_toolbar.xml +++ b/indra/newview/skins/default/xui/en/floater_test_toolbar.xml @@ -8,6 +8,7 @@   translate="false"   width="500">    <toolbar name="test_toolbar_top" +           button_display_mode="icons_with_text"             follows="left|right|top"             height="50"             width="500" @@ -21,6 +22,7 @@      <command name="chat"/>    </toolbar>    <toolbar name="test_toolbar_left" +           button_display_mode="icons_with_text"             follows="left|bottom|top"             height="380"             width="200" @@ -33,6 +35,7 @@      <command name="chat"/>    </toolbar>    <toolbar name="test_toolbar_right" +           button_display_mode="icons_with_text"             follows="right|bottom|top"             height="380"             width="200" @@ -44,6 +47,7 @@      <command name="chat"/>    </toolbar>    <toolbar name="test_toolbar_bottom" +           button_display_mode="icons_with_text"             follows="left|right|bottom"             height="50"             width="500" | 
