diff options
Diffstat (limited to 'indra/llui')
| -rw-r--r-- | indra/llui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llui/llbadge.cpp | 263 | ||||
| -rw-r--r-- | indra/llui/llbadge.h | 152 | ||||
| -rw-r--r-- | indra/llui/llbutton.cpp | 94 | ||||
| -rw-r--r-- | indra/llui/llbutton.h | 12 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.cpp | 18 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.h | 4 | 
7 files changed, 530 insertions, 15 deletions
| diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 33ab2e93b5..fb585e062c 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -28,6 +28,7 @@ include_directories(  set(llui_SOURCE_FILES      llaccordionctrl.cpp      llaccordionctrltab.cpp +    llbadge.cpp      llbutton.cpp      llcheckboxctrl.cpp      llclipboard.cpp @@ -119,6 +120,7 @@ set(llui_HEADER_FILES      llaccordionctrl.h      llaccordionctrltab.h +    llbadge.h      llbutton.h      llcallbackmap.h      llcheckboxctrl.h diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp new file mode 100644 index 0000000000..ea934aa93b --- /dev/null +++ b/indra/llui/llbadge.cpp @@ -0,0 +1,263 @@ +/**  + * @file llbadge.cpp + * @brief Implementation for badges + * + * $LicenseInfo:firstyear=2001&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$ + */ + +#define LLBADGE_CPP +#include "llbadge.h" + +#include "lluictrlfactory.h" + + +static LLDefaultChildRegistry::Register<LLBadge> r("badge"); + +// Compiler optimization, generate extern template +template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const; + + +LLBadge::Params::Params() +	: image("image") +	, image_color("image_color") +	, label("label") +	, label_color("label_color") +	, location("location", LLRelPos::TOP_LEFT) +	, location_percent_hcenter("location_percent_hcenter") +	, location_percent_vcenter("location_percent_vcenter") +	, padding_horiz("padding_horiz") +	, padding_vert("padding_vert") +{ +	// We set a name here so the name isn't necessary in any xml files that use badges +	name = "badge"; +} + +bool LLBadge::Params::equals(const Params& a) const +{ +	bool comp = true; +	 +	// skip owner in comparison on purpose +	 +	comp &= (image() == a.image()); +	comp &= (image_color() == a.image_color()); +	comp &= (label() == a.label()); +	comp &= (label_color() == a.label_color()); +	comp &= (location() == a.location()); +	comp &= (location_percent_hcenter() == a.location_percent_hcenter()); +	comp &= (location_percent_vcenter() == a.location_percent_vcenter()); +	comp &= (padding_horiz() == a.padding_horiz()); +	comp &= (padding_vert() == a.padding_vert()); +	 +	return comp; +} + +LLBadge::LLBadge(const LLBadge::Params& p) +	: LLUICtrl(p) +	, mOwner(p.owner) +	, mGLFont(p.font) +	, mImage(p.image) +	, mImageColor(p.image_color) +	, mLabel(p.label) +	, mLabelColor(p.label_color) +	, mLocation(p.location) +	, mLocationPercentHCenter(0.5f) +	, mLocationPercentVCenter(0.5f) +	, mPaddingHoriz(p.padding_horiz) +	, mPaddingVert(p.padding_vert) +{ +	if (mImage.isNull()) +	{ +		llwarns << "Badge: " << getName() << " with no image!" << llendl; +	} + +	// +	// The following logic is to set the mLocationPercentHCenter and mLocationPercentVCenter +	// based on the Location enum and our horizontal and vertical location percentages.  The +	// draw code then uses this on the owner rectangle to compute the screen location for +	// the badge. +	// + +	if (!LLRelPos::IsCenter(mLocation)) +	{ +		F32 h_center = p.location_percent_hcenter * 0.01f; +		F32 v_center = p.location_percent_vcenter * 0.01f; + +		if (LLRelPos::IsRight(mLocation)) +		{ +			mLocationPercentHCenter = 0.5f * (1.0f + h_center); +		} +		else if (LLRelPos::IsLeft(mLocation)) +		{ +			mLocationPercentHCenter = 0.5f * (1.0f - h_center); +		} +			 +		if (LLRelPos::IsTop(mLocation)) +		{ +			mLocationPercentVCenter = 0.5f * (1.0f + v_center); +		} +		else if (LLRelPos::IsBottom(mLocation)) +		{ +			mLocationPercentVCenter = 0.5f * (1.0f - v_center); +		} +	} +} + +LLBadge::~LLBadge() +{ +} + +void LLBadge::setLabel(const LLStringExplicit& label) +{ +	mLabel = label; +} + +// +// This is a fallback function to render a rectangle for badges without a valid image +// +void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, const LLColor4U &color) +{ +	gGL.pushUIMatrix(); +	gGL.loadUIIdentity(); +	gGL.setSceneBlendType(LLRender::BT_REPLACE); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	 +	gGL.color4ubv(color.mV); +	gGL.texCoord2i(0, 0); +	 +	F32 x = LLFontGL::sCurOrigin.mX + centerX - width * 0.5f; +	F32 y = LLFontGL::sCurOrigin.mY + centerY - height * 0.5f; +	 +	LLRectf screen_rect(llround(x), +						llround(y), +						llround(x) + width, +						llround(y) + height); +	 +	LLVector3 vertices[4]; +	vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop,    1.0f); +	vertices[1] = LLVector3(screen_rect.mLeft,  screen_rect.mTop,    1.0f); +	vertices[2] = LLVector3(screen_rect.mLeft,  screen_rect.mBottom, 1.0f); +	vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f); +	 +	gGL.begin(LLRender::QUADS); +	{ +		gGL.vertexBatchPreTransformed(vertices, 4); +	} +	gGL.end(); +	 +	gGL.popUIMatrix(); +} + + +// virtual +void LLBadge::draw() +{ +	if (!mLabel.empty()) +	{ +		LLUICtrl* owner_ctrl = mOwner.get(); + +		if (owner_ctrl) +		{ +			// +			// Calculate badge position based on owner +			// +			 +			LLRect owner_rect; +			owner_ctrl->localRectToOtherView(owner_ctrl->getLocalRect(), & owner_rect, this); +			 +			F32 badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter; +			F32 badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter; + +			// +			// Calculate badge size based on label text +			// + +			LLWString badge_label_wstring = mLabel; +			 +			S32 badge_label_begin_offset = 0; +			S32 badge_char_length = S32_MAX; +			S32 badge_pixel_length = S32_MAX; +			F32 *right_position_out = NULL; +			BOOL do_not_use_ellipses = false; + +			F32 badge_width = (2.0f * mPaddingHoriz) + +				mGLFont->getWidthF32(badge_label_wstring.c_str(), badge_label_begin_offset, badge_char_length); + +			F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight(); + +			// +			// Draw button image, if available. +			// Otherwise draw basic rectangular button. +			// + +			F32 alpha = getDrawContext().mAlpha; + +			if (!mImage.isNull()) +			{ +				F32 badge_x = badge_center_x - badge_width * 0.5f; +				F32 badge_y = badge_center_y - badge_height * 0.5f; +			 +				mImage->drawSolid(badge_x, badge_y, badge_width, badge_height, mImageColor % alpha); +			} +			else +			{ +				lldebugs << "No image for badge " << getName() << " on owner " << owner_ctrl->getName() << llendl; +				 +				renderBadgeBackground(badge_center_x, badge_center_y, +									  badge_width, badge_height, +									  mImageColor % alpha); +			} + +			// +			// Draw the label +			// + +			mGLFont->render(badge_label_wstring, badge_label_begin_offset, +							badge_center_x, badge_center_y, +							mLabelColor % alpha, +							LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position +							LLFontGL::NORMAL, // normal text (not bold, italics, etc.) +							LLFontGL::DROP_SHADOW_SOFT, +							badge_char_length, badge_pixel_length, +							right_position_out, do_not_use_ellipses); +		} +	} +} + + +namespace LLInitParam +{ +	void TypeValues<LLRelPos::Location>::declareValues() +	{ +		declare("bottom",		LLRelPos::BOTTOM); +		declare("bottom_left",	LLRelPos::BOTTOM_LEFT); +		declare("bottom_right", LLRelPos::BOTTOM_RIGHT); +		declare("center",		LLRelPos::CENTER); +		declare("left",			LLRelPos::LEFT); +		declare("right",		LLRelPos::RIGHT); +		declare("top",			LLRelPos::TOP); +		declare("top_left",		LLRelPos::TOP_LEFT); +		declare("top_right",	LLRelPos::TOP_RIGHT); +	} +} + + +// eof diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h new file mode 100644 index 0000000000..c2e0a763b2 --- /dev/null +++ b/indra/llui/llbadge.h @@ -0,0 +1,152 @@ +/**  + * @file llbadge.h + * @brief Header for badges + * + * $LicenseInfo:firstyear=2001&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$ + */ + +#ifndef LL_LLBADGE_H +#define LL_LLBADGE_H + +#include <string> + +#include "lluicolor.h" +#include "lluictrl.h" +#include "llstring.h" +#include "lluiimage.h" + +// +// Declarations +// + +class LLUICtrlFactory; +class LLFontGL; + +// +// Relative Position Alignment +// + +namespace LLRelPos +{ +	enum Location +	{ +		CENTER	= 0, + +		LEFT	= (1 << 0), +		RIGHT	= (1 << 1), + +		TOP		= (1 << 2), +		BOTTOM	= (1 << 3), + +		BOTTOM_LEFT		= (BOTTOM | LEFT), +		BOTTOM_RIGHT	= (BOTTOM | RIGHT), + +		TOP_LEFT		= (TOP | LEFT), +		TOP_RIGHT		= (TOP | RIGHT), +	}; + +	inline bool IsBottom(Location relPos)	{ return (relPos & BOTTOM) == BOTTOM; } +	inline bool IsCenter(Location relPos)	{ return (relPos == CENTER); } +	inline bool IsLeft(Location relPos)		{ return (relPos & LEFT) == LEFT; } +	inline bool IsRight(Location relPos)	{ return (relPos & RIGHT) == RIGHT; } +	inline bool IsTop(Location relPos)		{ return (relPos & TOP) == TOP; } +} + +// NOTE: This needs to occur before Optional<LLRelPos::Location> declaration for proper compilation. +namespace LLInitParam +{ +	template<> +	struct TypeValues<LLRelPos::Location> : public TypeValuesHelper<LLRelPos::Location> +	{ +		static void declareValues(); +	}; +} + +// +// Classes +// + +class LLBadge +: public LLUICtrl +{ +public: +	struct Params  +	: public LLInitParam::Block<Params, LLUICtrl::Params> +	{ +		Optional< LLHandle<LLUICtrl> >	owner;	// Mandatory in code but not in xml +		 +		Optional< LLUIImage* >			image; +		Optional< LLUIColor >			image_color; +		 +		Optional< std::string >			label; +		Optional< LLUIColor >			label_color; + +		Optional< LLRelPos::Location >	location; +		Optional< U32 >					location_percent_hcenter; +		Optional< U32 >					location_percent_vcenter; + +		Optional< F32 >					padding_horiz; +		Optional< F32 >					padding_vert; +		 +		Params(); +		 +		bool equals(const Params&) const; +	}; +	 +protected: +	friend class LLUICtrlFactory; +	LLBadge(const Params& p); + +public: + +	~LLBadge(); +	 +	virtual void		draw(); + +	const std::string	getLabel() const { return wstring_to_utf8str(mLabel); } +	void				setLabel( const LLStringExplicit& label); + +private: +	const LLFontGL*			mGLFont; +	 +	LLPointer< LLUIImage >	mImage; +	LLUIColor				mImageColor; +	 +	LLUIString				mLabel; +	LLUIColor				mLabelColor; + +	LLRelPos::Location		mLocation; +	F32						mLocationPercentHCenter; +	F32						mLocationPercentVCenter; +	 +	LLHandle< LLUICtrl >	mOwner; + +	F32						mPaddingHoriz; +	F32						mPaddingVert; +}; + +// Build time optimization, generate once in .cpp file +#ifndef LLBADGE_CPP +extern template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const; +#endif + +#endif  // LL_LLBADGE_H diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 45ceaff696..a63281b3c1 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -56,6 +56,9 @@ static LLDefaultChildRegistry::Register<LLButton> r("button");  template class LLButton* LLView::getChild<class LLButton>(  	const std::string& name, BOOL recurse) const; + + +  // globals loaded from settings.xml  S32	LLBUTTON_H_PAD	= 0;  S32 BTN_HEIGHT_SMALL= 0; @@ -99,7 +102,8 @@ LLButton::Params::Params()  	scale_image("scale_image", true),  	hover_glow_amount("hover_glow_amount"),  	commit_on_return("commit_on_return", true), -	use_draw_context_alpha("use_draw_context_alpha", true) +	use_draw_context_alpha("use_draw_context_alpha", true), +	badge("badge")  {  	addSynonym(is_toggle, "toggle");  	held_down_delay.seconds = 0.5f; @@ -160,8 +164,8 @@ LLButton::LLButton(const LLButton::Params& p)  	mMouseDownSignal(NULL),  	mMouseUpSignal(NULL),  	mHeldDownSignal(NULL), -	mUseDrawContextAlpha(p.use_draw_context_alpha) - +	mUseDrawContextAlpha(p.use_draw_context_alpha), +	mBadge(NULL)  {  	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);  	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); @@ -244,6 +248,17 @@ LLButton::LLButton(const LLButton::Params& p)  	{  		setHeldDownCallback(initCommitCallback(p.mouse_held_callback));  	} +	 +	// Only create a badge here if a non-default one was provided. +	if (p.badge.isProvided()) +	{ +		if (!p.badge().equals(LLUICtrlFactory::getDefaultParams<LLBadge>())) +		{ +			LLBadge::Params badge_params(p.badge()); +			badge_params.owner = getUICtrlHandle(); +			mBadge = LLUICtrlFactory::create<LLBadge>(badge_params); +		} +	}  }  LLButton::~LLButton() @@ -327,6 +342,13 @@ boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb,  BOOL LLButton::postBuild()  {  	autoResize(); + +	// Attach the badge to the appropriate parent panel +	if (mBadge) +	{ +		addBadgeToParentPanel(); +	} +  	return TRUE;  }  BOOL LLButton::handleUnicodeCharHere(llwchar uni_char) @@ -867,7 +889,7 @@ void LLButton::draw()  			S32_MAX, text_width,  			NULL, mUseEllipses);  	} - +	  	LLUICtrl::draw();  } @@ -1063,6 +1085,70 @@ void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignmen  	}  } +void LLButton::addBadgeToParentPanel() +{ +	if (mBadge) +	{ +		// Find the appropriate parent panel for the badge + +		LLPanel * parentPanel = NULL; +		LLUICtrl * parent = getParentUICtrl(); +		 +		while (parent) +		{ +			parentPanel = dynamic_cast<LLPanel*>(parent); +		 +			if (parentPanel != NULL) +			{ +				break; +			} + +			parent = parent->getParentUICtrl(); +		} + +		if (parentPanel) +		{ +			parentPanel->addChild(mBadge); +		} +		else +		{ +			llwarns << "Unable to find parent panel for badge " << mBadge->getName() << " on button " << getName() << llendl; +		} +	} +	else +	{ +		llwarns << "Unable to add NULL badge to button " << getName() << llendl; +	} +} + +void LLButton::setBadgeLabel(const LLStringExplicit& label) +{ +	if (mBadge == NULL) +	{ +		LLBadge::Params badge_params(LLUICtrlFactory::getDefaultParams<LLBadge>()); +		badge_params.owner = getUICtrlHandle(); +		mBadge = LLUICtrlFactory::create<LLBadge>(badge_params); + +		addBadgeToParentPanel(); +	} + +	if (mBadge) +	{ +		mBadge->setLabel(label); + +		// +		// Push the badge to the front so it renders last +		// + +		LLUICtrl * parent = mBadge->getParentUICtrl(); + +		if (parent) +		{ +			parent->sendChildToFront(mBadge); +		} +	} +} +  void LLButton::onMouseCaptureLost()  {  	resetMouseDownTimer(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 0cfc393e05..232ab81e0d 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -27,6 +27,8 @@  #ifndef LL_LLBUTTON_H  #define LL_LLBUTTON_H +#include "lluuid.h" +#include "llbadge.h"  #include "llcontrol.h"  #include "lluictrl.h"  #include "v4color.h" @@ -52,8 +54,6 @@ S32 round_up(S32 grid, S32 value);  class LLUICtrlFactory; -class LLUIImage; -class LLUUID;  //  // Classes @@ -126,6 +126,8 @@ public:  		Optional<TimeIntervalParam>	held_down_delay;  		Optional<bool>			use_draw_context_alpha; +		 +		Optional<LLBadge::Params>	badge;  		Params();  	}; @@ -249,6 +251,8 @@ public:  	void			setImageDisabledSelected(LLPointer<LLUIImage> image);  	void			setImageFlash(LLPointer<LLUIImage> image);  	void			setImagePressed(LLPointer<LLUIImage> image); +	 +	void			setBadgeLabel(const LLStringExplicit& label);  	void			setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }  	BOOL			getCommitOnReturn() const { return mCommitOnReturn; } @@ -267,6 +271,8 @@ protected:  	LLPointer<LLUIImage> getImageUnselected() const	{ return mImageUnselected; }  	LLPointer<LLUIImage> getImageSelected() const	{ return mImageSelected; } +	void addBadgeToParentPanel(); +  	LLFrameTimer	mMouseDownTimer;  private: @@ -357,6 +363,8 @@ private:  	bool						mForcePressedState;  	LLFrameTimer				mFlashingTimer; +	 +	LLBadge*					mBadge;  };  // Build time optimization, generate once in .cpp file diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 9b6830a816..8a92796942 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -78,20 +78,20 @@ LLLayoutPanel::~LLLayoutPanel()  	delete mResizeBar;  	mResizeBar = NULL;  } -	 +  F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)  {  	if (orientation == LLLayoutStack::HORIZONTAL)  	{  		F32 collapse_amt =  -		clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth())); +			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));  		return mVisibleAmt * collapse_amt;  	}  	else  	{ -			F32 collapse_amt =  +		F32 collapse_amt =   			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight()))); -			return mVisibleAmt * collapse_amt; +		return mVisibleAmt * collapse_amt;  	}  } @@ -182,14 +182,14 @@ BOOL LLLayoutStack::postBuild()  }  bool LLLayoutStack::addChild(LLView* child, S32 tab_group) -		{ +{  	LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child); -			if (panelp) -			{ +	if (panelp) +	{  		mPanels.push_back(panelp); -			} +	}  	return LLView::addChild(child, tab_group); -		} +}  S32 LLLayoutStack::getDefaultHeight(S32 cur_height) diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 4ac8ef0ee9..2fc2cf3eb4 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -177,6 +177,10 @@ public:  	~LLLayoutPanel();  	void initFromParams(const Params& p); + +	S32 getMinDim() const { return mMinDim; } +	S32 getMaxDim() const { return mMaxDim; } +  	void setMinDim(S32 value) { mMinDim = value; }  	void setMaxDim(S32 value) { mMaxDim = value; } | 
