diff options
Diffstat (limited to 'indra/llui')
32 files changed, 946 insertions, 576 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 7a5f9f9fd6..c025cd7939 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -976,7 +976,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)  			gGL.matrixMode(LLRender::MM_MODELVIEW);  			LLUI::pushMatrix();  			{ -				LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom, 0.f); +				LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom);  				child->draw();  			} diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f0d92d597a..705fe16559 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -908,9 +908,9 @@ void LLButton::draw()  		// Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars.  		mLastDrawCharsCount = mGLFont->render(label, 0,  			(F32)x, -			(F32)(mBottomVPad + y_offset), +			(F32)(getRect().getHeight() / 2 + mBottomVPad),  			label_color % alpha, -			mHAlign, LLFontGL::BOTTOM, +			mHAlign, LLFontGL::VCENTER,  			LLFontGL::NORMAL,  			mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,  			S32_MAX, text_width, diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp index 6910b962a1..14173fdbb0 100644 --- a/indra/llui/llclipboard.cpp +++ b/indra/llui/llclipboard.cpp @@ -34,109 +34,113 @@  #include "llview.h"  #include "llwindow.h" -// Global singleton -LLClipboard gClipboard; - - -LLClipboard::LLClipboard() +LLClipboard::LLClipboard() : +	mGeneration(0)  { -	mSourceItem = NULL; +	reset();  } -  LLClipboard::~LLClipboard()  { +	reset();  } - -void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id ) +void LLClipboard::reset()  { -	mSourceID = source_id; -	mString = src.substr(pos, len); -	LLView::getWindow()->copyTextToClipboard( mString ); +	// Increment the clipboard count +	mGeneration++; +	// Clear the clipboard +	mObjects.clear(); +	mCutMode = false; +	mString = LLWString();  } -void LLClipboard::copyFromString(const LLWString &src, const LLUUID& source_id ) +// Copy the input uuid to the LL clipboard +bool LLClipboard::copyToClipboard(const LLUUID& src, const LLAssetType::EType type)  { -	mSourceID = source_id; -	mString = src; -	LLView::getWindow()->copyTextToClipboard( mString ); +	reset(); +	return addToClipboard(src, type);  } -const LLWString& LLClipboard::getPasteWString( LLUUID* source_id ) +// Add the input uuid to the LL clipboard +// Convert the uuid to string and concatenate that string to the system clipboard if legit +bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type)  { -	if( mSourceID.notNull() ) +	bool res = false; +	if (src.notNull())  	{ -		LLWString temp_string; -		LLView::getWindow()->pasteTextFromClipboard(temp_string); - -		if( temp_string != mString ) +		res = true; +		if (LLAssetType::lookupIsAssetIDKnowable(type))  		{ -			mSourceID.setNull(); -			mString = temp_string; +			LLWString source = utf8str_to_wstring(src.asString()); +			res = addToClipboard(source, 0, source.size()); +		} +		if (res) +		{ +			mObjects.push_back(src); +			mGeneration++;  		}  	} -	else -	{ -		LLView::getWindow()->pasteTextFromClipboard(mString); -	} +	return res; +} -	if( source_id ) +bool LLClipboard::pasteFromClipboard(std::vector<LLUUID>& inv_objects) const +{ +	bool res = false; +	S32 count = mObjects.size(); +	if (count > 0)  	{ -		*source_id = mSourceID; +		res = true; +		inv_objects.clear(); +		for (S32 i = 0; i < count; i++) +		{ +			inv_objects.push_back(mObjects[i]); +		}  	} - -	return mString; +	return res;  } +// Returns true if the LL Clipboard has pasteable items in it +bool LLClipboard::hasContents() const +{ +	return (mObjects.size() > 0); +} -BOOL LLClipboard::canPasteString() const +// Returns true if the input uuid is in the list of clipboard objects +bool LLClipboard::isOnClipboard(const LLUUID& object) const  { -	return LLView::getWindow()->isClipboardTextAvailable(); +	std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object); +	return (iter != mObjects.end());  } +// Copy the input string to the LL and the system clipboard +bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary) +{ +	return addToClipboard(src, pos, len, use_primary); +} -void LLClipboard::copyFromPrimarySubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id ) +// Concatenate the input string to the LL and the system clipboard +bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)  { -	mSourceID = source_id;  	mString = src.substr(pos, len); -	LLView::getWindow()->copyTextToPrimary( mString ); +	return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));  } - -const LLWString& LLClipboard::getPastePrimaryWString( LLUUID* source_id ) +// Copy the System clipboard to the output string. +// Manage the LL Clipboard / System clipboard consistency +bool LLClipboard::pasteFromClipboard(LLWString &dst, bool use_primary)  { -	if( mSourceID.notNull() ) -	{ -		LLWString temp_string; -		LLView::getWindow()->pasteTextFromPrimary(temp_string); - -		if( temp_string != mString ) -		{ -			mSourceID.setNull(); -			mString = temp_string; -		} -	} -	else -	{ -		LLView::getWindow()->pasteTextFromPrimary(mString); -	} - -	if( source_id ) +	bool res = (use_primary ? LLView::getWindow()->pasteTextFromPrimary(dst) : LLView::getWindow()->pasteTextFromClipboard(dst)); +	if (res)  	{ -		*source_id = mSourceID; +		mString = dst;  	} - -	return mString; +	return res;  } - -BOOL LLClipboard::canPastePrimaryString() const +// Return true if there's something on the System clipboard +bool LLClipboard::isTextAvailable(bool use_primary) const  { -	return LLView::getWindow()->isPrimaryTextAvailable(); +	return (use_primary ? LLView::getWindow()->isPrimaryTextAvailable() : LLView::getWindow()->isClipboardTextAvailable());  } -void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)  -{ -	mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, ""); -} diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 9371b94284..fd2e7610df 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -27,46 +27,68 @@  #ifndef LL_LLCLIPBOARD_H  #define LL_LLCLIPBOARD_H +#include <boost/function.hpp>  #include "llstring.h"  #include "lluuid.h"  #include "stdenums.h" +#include "llsingleton.h" +#include "llassettype.h"  #include "llinventory.h" +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLClipboard +// +// This class is used to cut/copy/paste text strings and inventory items around  +// the world. Use LLClipboard::instance().method() to use its methods. +// Note that the text and UUIDs are loosely coupled only. There are few cases +// where the viewer does offer a serialized version of the UUID on the clipboard. +// In those case, the text is overridden when copying/cutting the item.  +// In all other cases, the text and the UUIDs are very much independent. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLClipboard +class LLClipboard : public LLSingleton<LLClipboard>  {  public:  	LLClipboard();  	~LLClipboard(); +	 +	// Clears the clipboard +	void reset(); +	// Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state) +	int	getGeneration() const { return mGeneration; } -	/* We support two flavors of clipboard.  The default is the explicitly -	   copy-and-pasted clipboard.  The second is the so-called 'primary' clipboard -	   which is implicitly copied upon selection on platforms which expect this -	   (i.e. X11/Linux). */ - -	void		copyFromSubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); -	void		copyFromString(const LLWString ©_from, const LLUUID& source_id = LLUUID::null ); -	BOOL		canPasteString() const; -	const LLWString&	getPasteWString(LLUUID* source_id = NULL); +	// Text strings management: +	// ------------------------ +	// We support two flavors of text clipboards. The default is the explicitly +	// copy-and-pasted clipboard. The second is the so-called 'primary' clipboard +	// which is implicitly copied upon selection on platforms which expect this +	// (i.e. X11/Linux, Mac). +	bool copyToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false); +	bool addToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false); +	bool pasteFromClipboard(LLWString& dst, bool use_primary = false); +	bool isTextAvailable(bool use_primary = false) const; +	 +	// Object list management: +	// ----------------------- +	// Clears and adds one single object to the clipboard +	bool copyToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE); +	// Adds one object to the current list of objects on the clipboard +	bool addToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE); +	// Gets a copy of the objects on the clipboard +	bool pasteFromClipboard(std::vector<LLUUID>& inventory_objects) const; +	 +	bool hasContents() const;										// True if the clipboard has pasteable objects +	bool isOnClipboard(const LLUUID& object) const;					// True if the input object uuid is on the clipboard -	void		copyFromPrimarySubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); -	BOOL		canPastePrimaryString() const; -	const LLWString&	getPastePrimaryWString(LLUUID* source_id = NULL);	 +	bool isCutMode() const { return mCutMode; } +	void setCutMode(bool mode) { mCutMode = mode; mGeneration++; } -	// Support clipboard for object known only by their uuid and asset type -	void		  setSourceObject(const LLUUID& source_id, LLAssetType::EType type); -	const LLInventoryObject* getSourceObject() { return mSourceItem; } -	  private: -	LLUUID      mSourceID; -	LLWString	mString; -	LLInventoryObject* mSourceItem; +	std::vector<LLUUID> mObjects;		// Objects on the clipboard. Can be empty while mString contains something licit (e.g. text from chat) +	LLWString mString;					// The text string. If mObjects is not empty, this string is reflecting them (UUIDs for the moment) if the asset type is knowable. +	bool mCutMode;						// This is a convenience flag for the viewer. +	int mGeneration;					// Incremented when the clipboard changes so that interested parties can check for changes on the clipboard.	  }; - -// Global singleton -extern LLClipboard gClipboard; - -  #endif  // LL_LLCLIPBOARD_H diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 89d8842393..806d2ef3f6 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -613,7 +613,7 @@ void LLComboBox::showList()  	}  	mList->setOrigin(rect.mLeft, rect.mBottom);  	mList->reshape(rect.getWidth(), rect.getHeight()); -	mList->translateIntoRect(root_view_local, FALSE); +	mList->translateIntoRect(root_view_local);  	// Make sure we didn't go off bottom of screen  	S32 x, y; diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index e01e331acf..e08ccb0b78 100644..100755 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -196,24 +196,24 @@ void LLContainerView::arrange(S32 width, S32 height, BOOL called_from_parent)  	if (total_height < height)  		total_height = height; +	LLRect my_rect = getRect();  	if (followsTop())  	{ -		// HACK: casting away const. Should use setRect or some helper function instead. -		const_cast<LLRect&>(getRect()).mBottom = getRect().mTop - total_height; +		my_rect.mBottom = my_rect.mTop - total_height;  	}  	else  	{ -		// HACK: casting away const. Should use setRect or some helper function instead. -		const_cast<LLRect&>(getRect()).mTop = getRect().mBottom + total_height; +		my_rect.mTop = my_rect.mBottom + total_height;  	} -	// HACK: casting away const. Should use setRect or some helper function instead. -		const_cast<LLRect&>(getRect()).mRight = getRect().mLeft + width; + +	my_rect.mRight = my_rect.mLeft + width; +	setRect(my_rect);  	top = total_height;  	if (mShowLabel) -		{ -			top -= 20; -		} +	{ +		top -= 20; +	}  	bottom = top; diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 42e6c3c786..5f69c6af31 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -244,7 +244,7 @@ void LLDragHandleTop::reshapeTitleBox()  	const LLFontGL* font = LLFontGL::getFontSansSerif();  	S32 title_width = getRect().getWidth();  	title_width -= LEFT_PAD + 2 * BORDER_PAD + getButtonsRect().getWidth(); -	S32 title_height = llround(font->getLineHeight()); +	S32 title_height = font->getLineHeight();  	LLRect title_rect;  	title_rect.setLeftTopAndSize(   		LEFT_PAD,  diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 33548151fd..8ca1e685a9 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -68,10 +68,10 @@ namespace LLInitParam  {  	void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()  	{ -		declare("none",       LLFloaterEnums::OPEN_POSITIONING_NONE); -		declare("cascading",  LLFloaterEnums::OPEN_POSITIONING_CASCADING); -		declare("centered",   LLFloaterEnums::OPEN_POSITIONING_CENTERED); -		declare("specified",  LLFloaterEnums::OPEN_POSITIONING_SPECIFIED); +		declare("relative",   LLFloaterEnums::POSITIONING_RELATIVE); +		declare("cascading",  LLFloaterEnums::POSITIONING_CASCADING); +		declare("centered",   LLFloaterEnums::POSITIONING_CENTERED); +		declare("specified",  LLFloaterEnums::POSITIONING_SPECIFIED);  	}  } @@ -177,9 +177,7 @@ LLFloater::Params::Params()  	save_visibility("save_visibility", false),  	can_dock("can_dock", false),  	show_title("show_title", true), -	open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE), -	specified_left("specified_left"), -	specified_bottom("specified_bottom"), +	positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE),  	header_height("header_height", 0),  	legacy_header_height("legacy_header_height", 0),  	close_image("close_image"), @@ -249,9 +247,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	mCanClose(p.can_close),  	mDragOnLeft(p.can_drag_on_left),  	mResizable(p.can_resize), -	mOpenPositioning(p.open_positioning), -	mSpecifiedLeft(p.specified_left), -	mSpecifiedBottom(p.specified_bottom), +	mPositioning(p.positioning),  	mMinWidth(p.min_width),  	mMinHeight(p.min_height),  	mHeaderHeight(p.header_height), @@ -270,6 +266,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	mMinimizeSignal(NULL)  //	mNotificationContext(NULL)  { +	mPosition.setFloater(*this);  //	mNotificationContext = new LLFloaterNotificationContext(getHandle());  	// Clicks stop here. @@ -546,10 +543,18 @@ LLFloater::~LLFloater()  void LLFloater::storeRectControl()  { -	if( mRectControl.size() > 1 ) +	if (!mRectControl.empty())  	{  		getControlGroup()->setRect( mRectControl, getRect() );  	} +	if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) +	{ +		getControlGroup()->setF32( mPosXControl, mPosition.mX ); +	} +	if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) +	{ +		getControlGroup()->setF32( mPosYControl, mPosition.mY ); +	}  }  void LLFloater::storeVisibilityControl() @@ -568,23 +573,6 @@ void LLFloater::storeDockStateControl()  	}  } -LLRect LLFloater::getSavedRect() const -{ -	LLRect rect; - -	if (mRectControl.size() > 1) -	{ -		rect = getControlGroup()->getRect(mRectControl); -	} - -	return rect; -} - -bool LLFloater::hasSavedRect() const -{ -	return !getSavedRect().isEmpty(); -} -  // static  std::string LLFloater::getControlName(const std::string& name, const LLSD& key)  { @@ -862,7 +850,7 @@ void LLFloater::applyControlsAndPosition(LLFloater* other)  	{  		if (!applyRectControl())  		{ -			applyPositioning(other); +			applyPositioning(other, true);  		}  	}  } @@ -871,29 +859,68 @@ bool LLFloater::applyRectControl()  {  	bool saved_rect = false; +	LLRect screen_rect = calcScreenRect(); +	mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); +	  	LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName);  	if (last_in_group && last_in_group != this)  	{  		// other floaters in our group, position ourselves relative to them and don't save the rect  		mRectControl.clear(); -		mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP; +		mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;  	} -	else if (mRectControl.size() > 1) +	else  	{ -		// If we have a saved rect, use it -		const LLRect& rect = getControlGroup()->getRect(mRectControl); -		saved_rect = rect.notEmpty(); -		if (saved_rect) +		bool rect_specified = false; +		if (!mRectControl.empty())  		{ -			setOrigin(rect.mLeft, rect.mBottom); - -			if (mResizable) +			// If we have a saved rect, use it +			const LLRect& rect = getControlGroup()->getRect(mRectControl); +			if (rect.notEmpty()) saved_rect = true; +			if (saved_rect)  			{ -				reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); +				setOrigin(rect.mLeft, rect.mBottom); + +				if (mResizable) +				{ +					reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); +				} +				mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +				LLRect screen_rect = calcScreenRect(); +				mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); +				rect_specified = true;  			}  		} + +		LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl); +		LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl); +		if (x_control.notNull()  +			&& y_control.notNull() +			&& !x_control->isDefault() +			&& !y_control->isDefault()) +		{ +			mPosition.mX = x_control->getValue().asReal(); +			mPosition.mY = y_control->getValue().asReal(); +			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +			applyRelativePosition(); + +			saved_rect = true; +		} + +		// remember updated position +		if (rect_specified) +		{ +			storeRectControl(); +		} +	} + +	if (saved_rect) +	{ +		// propagate any derived positioning data back to settings file +		storeRectControl();  	} +  	return saved_rect;  } @@ -910,50 +937,56 @@ bool LLFloater::applyDockState()  	return docked;  } -void LLFloater::applyPositioning(LLFloater* other) +void LLFloater::applyPositioning(LLFloater* other, bool on_open)  {  	// Otherwise position according to the positioning code -	switch (mOpenPositioning) +	switch (mPositioning)  	{ -	case LLFloaterEnums::OPEN_POSITIONING_CENTERED: +	case LLFloaterEnums::POSITIONING_CENTERED:  		center();  		break; -	case LLFloaterEnums::OPEN_POSITIONING_SPECIFIED: -		{ -			// Translate relative to snap rect -			setOrigin(mSpecifiedLeft, mSpecifiedBottom); -			const LLRect& snap_rect = gFloaterView->getSnapRect(); -			translate(snap_rect.mLeft, snap_rect.mBottom); -			translateIntoRect(snap_rect, FALSE); -		} +	case LLFloaterEnums::POSITIONING_SPECIFIED:  		break; -	case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP: -	case LLFloaterEnums::OPEN_POSITIONING_CASCADING: -		if (other != NULL && other != this) +	case LLFloaterEnums::POSITIONING_CASCADING: +		if (!on_open)  		{ -			stackWith(*other); +			applyRelativePosition();  		} -		else +		// fall through +	case LLFloaterEnums::POSITIONING_CASCADE_GROUP: +		if (on_open)  		{ -			static const U32 CASCADING_FLOATER_HOFFSET = 0; -			static const U32 CASCADING_FLOATER_VOFFSET = 0; +			if (other != NULL && other != this) +			{ +				stackWith(*other); +			} +			else +			{ +				static const U32 CASCADING_FLOATER_HOFFSET = 0; +				static const U32 CASCADING_FLOATER_VOFFSET = 0; -			const LLRect& snap_rect = gFloaterView->getSnapRect(); +				const LLRect& snap_rect = gFloaterView->getSnapRect(); -			const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; -			const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; +				const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; +				const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; -			S32 rect_height = getRect().getHeight(); -			setOrigin(horizontal_offset, vertical_offset - rect_height); +				S32 rect_height = getRect().getHeight(); +				setOrigin(horizontal_offset, vertical_offset - rect_height); -			translate(snap_rect.mLeft, snap_rect.mBottom); -			translateIntoRect(snap_rect, FALSE); +				translate(snap_rect.mLeft, snap_rect.mBottom); +			} +			setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);  		}  		break; -	case LLFloaterEnums::OPEN_POSITIONING_NONE: +	case LLFloaterEnums::POSITIONING_RELATIVE: +		{ +			applyRelativePosition(); + +			break; +		}  	default:  		// Do nothing  		break; @@ -1071,7 +1104,9 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)  	if (by_user && !isMinimized())  	{  		storeRectControl(); -		mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE; +		mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +		LLRect screen_rect = calcScreenRect(); +		mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();  	}  	// if not minimized, adjust all snapped dependents to new shape @@ -1249,6 +1284,7 @@ void LLFloater::setMinimized(BOOL minimize)  		// Reshape *after* setting mMinimized  		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); +		applyPositioning(NULL, false);  	}  	make_ui_sound("UISndWindowClose"); @@ -1589,7 +1625,7 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)  		if (mDocked)  		{  			setMinimized(FALSE); -			mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE; +			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;  		}  		updateTitleButtons(); @@ -1623,7 +1659,7 @@ void LLFloater::onClickTearOff(LLFloater* self)  		self->openFloater(self->getKey());  		// only force position for floaters that don't have that data saved -		if (self->mRectControl.size() <= 1) +		if (self->mRectControl.empty())  		{  			new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());  			self->setRect(new_rect); @@ -1681,6 +1717,8 @@ LLFloater* LLFloater::getClosableFloaterFromFocus()  	{  		if (it->hasFocus())  		{ +			LLFloater& floater = *it; +			focused_floater = &floater;  			break;  		}  	} @@ -1800,7 +1838,7 @@ void LLFloater::draw()  				const LLFontGL* font = LLFontGL::getFontSansSerif();  				LLRect r = getRect(); -				gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,  +				gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1,   					titlebar_focus_color % alpha, 0, TRUE);  			}  		} @@ -2161,19 +2199,14 @@ LLFloaterView::LLFloaterView (const Params& p)  	mSnapOffsetBottom(0),  	mSnapOffsetRight(0)  { +	mSnapView = getHandle();  }  // By default, adjust vertical.  void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)  { -	S32 old_right = mLastSnapRect.mRight; -	S32 old_top = mLastSnapRect.mTop; -  	LLView::reshape(width, height, called_from_parent); -	S32 new_right = getSnapRect().mRight; -	S32 new_top = getSnapRect().mTop; -  	mLastSnapRect = getSnapRect();  	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) @@ -2186,35 +2219,39 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)  			continue;  		} -		if (!floaterp->isMinimized()) +		if (!floaterp->isMinimized() && floaterp->getCanDrag())  		{ -			LLRect r = floaterp->getRect(); +			LLRect old_rect = floaterp->getRect(); +			floaterp->applyPositioning(NULL, false); +			LLRect new_rect = floaterp->getRect(); -			// Compute absolute distance from each edge of screen -			S32 left_offset = llabs(r.mLeft - 0); -			S32 right_offset = llabs(old_right - r.mRight); +			//LLRect r = floaterp->getRect(); -			S32 top_offset = llabs(old_top - r.mTop); -			S32 bottom_offset = llabs(r.mBottom - 0); +			//// Compute absolute distance from each edge of screen +			//S32 left_offset = llabs(r.mLeft - 0); +			//S32 right_offset = llabs(old_right - r.mRight); -			S32 translate_x = 0; -			S32 translate_y = 0; +			//S32 top_offset = llabs(old_top - r.mTop); +			//S32 bottom_offset = llabs(r.mBottom - 0); -			if (left_offset > right_offset) -			{ -				translate_x = new_right - old_right; -			} +			S32 translate_x = new_rect.mLeft - old_rect.mLeft; +			S32 translate_y = new_rect.mBottom - old_rect.mBottom; -			if (top_offset < bottom_offset) -			{ -				translate_y = new_top - old_top; -			} +			//if (left_offset > right_offset) +			//{ +			//	translate_x = new_right - old_right; +			//} + +			//if (top_offset < bottom_offset) +			//{ +			//	translate_y = new_top - old_top; +			//}  			// don't reposition immovable floaters -			if (floaterp->getCanDrag()) -			{ -				floaterp->translate(translate_x, translate_y); -			} +			//if (floaterp->getCanDrag()) +			//{ +			//	floaterp->translate(translate_x, translate_y); +			//}  			BOOST_FOREACH(LLHandle<LLFloater> dependent_floater, floaterp->mDependents)  			{  				if (dependent_floater.get()) @@ -2641,6 +2678,8 @@ void LLFloaterView::refresh()  	}  } +const S32 FLOATER_MIN_VISIBLE_PIXELS = 16; +  void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)  {  	if (floater->getParent() != this) @@ -2694,7 +2733,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out  	}  	// move window fully onscreen -	if (floater->translateIntoRect( getSnapRect(), allow_partial_outside )) +	if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))  	{  		floater->clearSnapTarget();  	} @@ -2908,9 +2947,11 @@ void LLFloater::setInstanceName(const std::string& name)  		std::string ctrl_name = getControlName(mInstanceName, mKey);  		// save_rect and save_visibility only apply to registered floaters -		if (!mRectControl.empty()) +		if (mSaveRect)  		{  			mRectControl = LLFloaterReg::declareRectControl(ctrl_name); +			mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); +			mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);  		}  		if (!mVisibilityControl.empty())  		{ @@ -2967,7 +3008,10 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	LLPanel::initFromParams(p);  	// override any follows flags -	setFollows(FOLLOWS_NONE); +	if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED) +	{ +		setFollows(FOLLOWS_NONE); +	}  	mTitle = p.title;  	mShortTitle = p.short_title; @@ -2986,14 +3030,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	mSingleInstance = p.single_instance;  	mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; -	mOpenPositioning = p.open_positioning; -	mSpecifiedLeft = p.specified_left; -	mSpecifiedBottom = p.specified_bottom; +	mPositioning = p.positioning; -	if (p.save_rect && mRectControl.empty()) -	{ -		mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set -	} +	mSaveRect = p.save_rect;  	if (p.save_visibility)  	{  		mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set @@ -3108,7 +3147,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str  		params.rect.left.set(0);  	}  	params.from_xui = true; -	applyXUILayout(params, parent); +	applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect());   	initFromParams(params);  	initFloater(params); @@ -3267,5 +3306,140 @@ void LLFloater::stackWith(LLFloater& other)  	next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());  	setShape(next_rect); + +	if (!other.getHost()) +	{ +		other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; +		other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); +	}  } +void LLFloater::applyRelativePosition() +{ +	LLRect snap_rect = gFloaterView->getSnapRect(); +	LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); +	snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); +	LLRect floater_screen_rect = calcScreenRect(); + +	LLCoordGL new_center = mPosition.convert(); +	LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY()); +	translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); +} + + +LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater) +:	coord_t((S32)x, (S32)y) +{ +	mFloater = floater.getHandle(); +} + + +LLCoordFloater::LLCoordFloater(const LLCoordCommon& other, LLFloater& floater) +{ +	mFloater = floater.getHandle(); +	convertFromCommon(other); +} + +LLCoordFloater& LLCoordFloater::operator=(const LLCoordFloater& other) +{ +	mFloater = other.mFloater; +	coord_t::operator =(other); +	return *this; +} + +void LLCoordFloater::setFloater(LLFloater& floater) +{ +	mFloater = floater.getHandle(); +} + +bool LLCoordFloater::operator==(const LLCoordFloater& other) const  +{  +	return mX == other.mX && mY == other.mY && mFloater == other.mFloater;  +} + +LLCoordCommon LL_COORD_FLOATER::convertToCommon() const +{ +	const LLCoordFloater& self = static_cast<const LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this)); + +	LLRect snap_rect = gFloaterView->getSnapRect(); +	LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); +	snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + +	LLFloater* floaterp = mFloater.get(); +	S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; +	S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; +	LLCoordCommon out; +	if (self.mX < -0.5f) +	{ +		out.mX = llround(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft)); +	} +	else if (self.mX > 0.5f) +	{ +		out.mX = llround(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)); +	} +	else +	{ +		out.mX = llround(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width)); +	} + +	if (self.mY < -0.5f) +	{ +		out.mY = llround(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom)); +	} +	else if (self.mY > 0.5f) +	{ +		out.mY = llround(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)); +	} +	else +	{ +		out.mY = llround(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height)); +	} + +	// return center point instead of lower left +	out.mX += floater_width / 2; +	out.mY += floater_height / 2; + +	return out; +} + +void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from) +{ +	LLCoordFloater& self = static_cast<LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this)); +	LLRect snap_rect = gFloaterView->getSnapRect(); +	LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); +	snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + + +	LLFloater* floaterp = mFloater.get(); +	S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; +	S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; + +	S32 from_x = from.mX - floater_width / 2; +	S32 from_y = from.mY - floater_height / 2; + +	if (from_x < snap_rect.mLeft) +	{ +		self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f); +	} +	else if (from_x + floater_width > snap_rect.mRight) +	{ +		self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); +	} +	else +	{ +		self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f); +	} + +	if (from_y < snap_rect.mBottom) +	{ +		self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f); +	} +	else if (from_y + floater_height > snap_rect.mTop) +	{ +		self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); +	} +	else +	{ +		self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f); +	} +} diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 59b35d206f..64d6dcea04 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -64,12 +64,12 @@ namespace LLFloaterEnums  {  	enum EOpenPositioning  	{ -		OPEN_POSITIONING_NONE, -		OPEN_POSITIONING_CASCADING, -		OPEN_POSITIONING_CASCADE_GROUP, -		OPEN_POSITIONING_CENTERED, -		OPEN_POSITIONING_SPECIFIED, -		OPEN_POSITIONING_COUNT +		POSITIONING_RELATIVE, +		POSITIONING_CASCADING, +		POSITIONING_CASCADE_GROUP, +		POSITIONING_CENTERED, +		POSITIONING_SPECIFIED, +		POSITIONING_COUNT  	};  } @@ -82,6 +82,37 @@ namespace LLInitParam  	};  } +struct LL_COORD_FLOATER +{ +	typedef F32 value_t; + +	LLCoordCommon convertToCommon() const; +	void convertFromCommon(const LLCoordCommon& from); +protected: +	LLHandle<LLFloater> mFloater; +}; + +struct LLCoordFloater : LLCoord<LL_COORD_FLOATER> +{ +	typedef LLCoord<LL_COORD_FLOATER> coord_t; + +	LLCoordFloater() {} +	LLCoordFloater(F32 x, F32 y, LLFloater& floater); +	LLCoordFloater(const LLCoordCommon& other, LLFloater& floater); + +	LLCoordFloater& operator=(const LLCoordCommon& other) +	{ +		convertFromCommon(other); +		return *this; +	} + +	LLCoordFloater& operator=(const LLCoordFloater& other); + +	bool operator==(const LLCoordFloater& other) const; +	bool operator!=(const LLCoordFloater& other) const { return !(*this == other); } + +	void setFloater(LLFloater& floater); +};  class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>  { @@ -132,10 +163,7 @@ public:  								can_dock,  								show_title; -		Optional<LLFloaterEnums::EOpenPositioning>	open_positioning; -		Optional<S32>								specified_left; -		Optional<S32>								specified_bottom; - +		Optional<LLFloaterEnums::EOpenPositioning>	positioning;  		Optional<S32>			header_height,  								legacy_header_height; // HACK see initFromXML() @@ -184,7 +212,7 @@ public:  	bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL);  	/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); -	/*virtual*/ BOOL canSnapTo(const LLView* other_view); +	/*virtual*/ BOOL canSnapTo(const LLView* other_view);   	/*virtual*/ void setSnappedTo(const LLView* snap_view);  	/*virtual*/ void setFocus( BOOL b );  	/*virtual*/ void setIsChrome(BOOL is_chrome); @@ -241,8 +269,6 @@ 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);  	static LLControlGroup*	getControlGroup(); @@ -324,7 +350,7 @@ public:  	void			enableResizeCtrls(bool enable, bool width = true, bool height = true); -	bool			isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); } +	bool			isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }  protected:  	void			applyControlsAndPosition(LLFloater* other); @@ -332,7 +358,9 @@ protected:  	virtual bool	applyRectControl();  	bool			applyDockState(); -	void			applyPositioning(LLFloater* other); +	void			applyPositioning(LLFloater* other, bool on_open); +	void			applyRelativePosition(); +  	void			storeRectControl();  	void			storeVisibilityControl();  	void			storeDockStateControl(); @@ -396,7 +424,10 @@ public:  	commit_signal_t* mMinimizeSignal;  protected: +	bool			mSaveRect;  	std::string		mRectControl; +	std::string		mPosXControl; +	std::string		mPosYControl;  	std::string		mVisibilityControl;  	std::string		mDocStateControl;  	LLSD			mKey;				// Key used for retrieving instances; set (for now) by LLFLoaterReg @@ -422,9 +453,8 @@ private:  	BOOL			mDragOnLeft;  	BOOL			mResizable; -	LLFloaterEnums::EOpenPositioning	mOpenPositioning; -	S32									mSpecifiedLeft; -	S32									mSpecifiedBottom; +	LLFloaterEnums::EOpenPositioning	mPositioning; +	LLCoordFloater	mPosition;  	S32				mMinWidth;  	S32				mMinHeight; diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index e144b68f5e..9115eb7174 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -96,7 +96,9 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()  		{  			LLFloater* inst = *iter; -			if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING)) +			if (inst->getVisible()  +				&& (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING) +					|| inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))  			{  				if (candidate_rect.mTop > inst->getRect().mTop)  				{ @@ -358,9 +360,7 @@ void LLFloaterReg::restoreVisibleInstances()  //static  std::string LLFloaterReg::getRectControlName(const std::string& name)  { -	std::string res = std::string("floater_rect_") + name; -	LLStringUtil::replaceChar( res, ' ', '_' ); -	return res; +	return std::string("floater_rect_") + getBaseControlName(name);  }  //static @@ -368,19 +368,48 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)  {  	std::string controlname = getRectControlName(name);  	LLFloater::getControlGroup()->declareRect(controlname, LLRect(), -												 llformat("Window Position and Size for %s", name.c_str()), +												 llformat("Window Size for %s", name.c_str()),  												 TRUE);  	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()), +											TRUE); +	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()), +											TRUE); + +	return controlname; +} + +  //static  std::string LLFloaterReg::getVisibilityControlName(const std::string& name)  { -	std::string res = std::string("floater_vis_") + name; +	return std::string("floater_vis_") + getBaseControlName(name); +} + +//static  +std::string LLFloaterReg::getBaseControlName(const std::string& name) +{ +	std::string res(name);  	LLStringUtil::replaceChar( res, ' ', '_' );  	return res;  } +  //static  std::string LLFloaterReg::declareVisibilityControl(const std::string& name)  { diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index 534cf8b40a..a1e1f8a988 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -115,9 +115,11 @@ public:  	// Control Variables  	static std::string getRectControlName(const std::string& name);  	static std::string declareRectControl(const std::string& name); +	static std::string declarePosXControl(const std::string& name); +	static std::string declarePosYControl(const std::string& name);  	static std::string getVisibilityControlName(const std::string& name);  	static std::string declareVisibilityControl(const std::string& name); - +	static std::string getBaseControlName(const std::string& name);  	static std::string declareDockStateControl(const std::string& name);  	static std::string getDockStateControlName(const std::string& name); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 2f1c2a47c9..4c730286da 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -36,7 +36,7 @@  #include "llcriticaldamp.h"  #include "boost/foreach.hpp" -static const F32 MIN_FRACTIONAL_SIZE = 0.0001f; +static const F32 MIN_FRACTIONAL_SIZE = 0.0f;  static const F32 MAX_FRACTIONAL_SIZE = 1.f;  static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack"); @@ -113,7 +113,26 @@ S32 LLLayoutPanel::getLayoutDim() const  					? getRect().getWidth()  					: getRect().getHeight()));  } -  + +S32 LLLayoutPanel::getTargetDim() const +{ +	return mTargetDim; +} + +void LLLayoutPanel::setTargetDim(S32 value) +{ +	LLRect new_rect(getRect()); +	if (mOrientation == LLLayoutStack::HORIZONTAL) +	{ +		new_rect.mRight = new_rect.mLeft + value; +	} +	else +	{ +		new_rect.mTop = new_rect.mBottom + value; +	} +	setShape(new_rect, true); +} +  S32 LLLayoutPanel::getVisibleDim() const  {  	F32 min_dim = getRelevantMinDim(); @@ -129,6 +148,12 @@ void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientatio  		? getRect().getWidth()  		: getRect().getHeight())); +	if (mAutoResize == FALSE  +		&& mUserResize == TRUE  +		&& mMinDim == -1 ) +	{ +		setMinDim(layout_dim); +	}  	mTargetDim = llmax(layout_dim, getMinDim());  } @@ -166,12 +191,15 @@ void LLLayoutPanel::handleReshape(const LLRect& new_rect, bool by_user)  	LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent());  	if (stackp)  	{ -		stackp->mNeedsLayout = true;  		if (by_user) -		{ -			// tell layout stack to account for new shape +		{	// tell layout stack to account for new shape +			 +			// make sure that panels have already been auto resized +			stackp->updateLayout(); +			// now apply requested size to panel  			stackp->updatePanelRect(this, new_rect);  		} +		stackp->mNeedsLayout = true;  	}  	LLPanel::handleReshape(new_rect, by_user);  } @@ -235,7 +263,6 @@ void LLLayoutStack::draw()  			drawChild(panelp, 0, 0, !clip_rect.isEmpty());  		}  	} -	mAnimatedThisFrame = false;  }  void LLLayoutStack::removeChild(LLView* view) @@ -304,9 +331,8 @@ void LLLayoutStack::updateLayout()  	if (!mNeedsLayout) return; -	bool animation_in_progress = animatePanels(); +	bool continue_animating = animatePanels();  	F32 total_visible_fraction = 0.f; -	F32 total_open_fraction = 0.f;  	S32 space_to_distribute = (mOrientation == HORIZONTAL)  							? getRect().getWidth()  							: getRect().getHeight(); @@ -318,20 +344,17 @@ void LLLayoutStack::updateLayout()  		if (panelp->mAutoResize)  		{  			panelp->mTargetDim = panelp->getRelevantMinDim(); -			if (!panelp->mCollapsed && panelp->getVisible()) -			{ -				total_open_fraction += panelp->mFractionalSize; -			}  		}  		space_to_distribute -= panelp->getVisibleDim() + llround((F32)mPanelSpacing * panelp->getVisibleAmount()); -		total_visible_fraction += panelp->mFractionalSize; +		total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor();  	} -	llassert(total_visible_fraction < 1.01f); +	llassert(total_visible_fraction < 1.05f);  	// don't need spacing after last panel  	space_to_distribute += panelp ? llround((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; +	S32 remaining_space = space_to_distribute;  	F32 fraction_distributed = 0.f;  	if (space_to_distribute > 0 && total_visible_fraction > 0.f)  	{	// give space proportionally to visible auto resize panels @@ -343,26 +366,23 @@ void LLLayoutStack::updateLayout()  				S32 delta = llround((F32)space_to_distribute * fraction_to_distribute);  				fraction_distributed += fraction_to_distribute;  				panelp->mTargetDim += delta; +				remaining_space -= delta;  			}  		}  	} -	if (fraction_distributed < total_visible_fraction) -	{	// distribute any left over pixels to non-collapsed, visible panels -		F32 fraction_left = total_visible_fraction - fraction_distributed; -		S32 space_left = llround((F32)space_to_distribute * (fraction_left / total_visible_fraction)); +	// distribute any left over pixels to non-collapsed, visible panels +	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) +	{ +		if (remaining_space == 0) break; -		BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) +		if (panelp->mAutoResize  +			&& !panelp->mCollapsed  +			&& panelp->getVisible())  		{ -			if (panelp->mAutoResize  -				&& !panelp->mCollapsed  -				&& panelp->getVisible()) -			{ -				S32 space_for_panel = llmax(0, llround((F32)space_left * (panelp->mFractionalSize / total_open_fraction))); -				panelp->mTargetDim += space_for_panel; -				space_left -= space_for_panel; -				total_open_fraction -= panelp->mFractionalSize; -			} +			S32 space_for_panel = remaining_space > 0 ? 1 : -1; +			panelp->mTargetDim += space_for_panel; +			remaining_space -= space_for_panel;  		}  	} @@ -416,7 +436,7 @@ void LLLayoutStack::updateLayout()  	// clear animation flag at end, since panel resizes will set it  	// and leave it set if there is any animation in progress -	mNeedsLayout = animation_in_progress; +	mNeedsLayout = continue_animating;  } // end LLLayoutStack::updateLayout  LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const @@ -489,38 +509,52 @@ void LLLayoutStack::updateClass()  	for (instance_iter it = beginInstances(); it != endInstances(); ++it)  	{  		it->updateLayout(); +		it->mAnimatedThisFrame = false;  	}  }  void LLLayoutStack::updateFractionalSizes()  { -	F32 total_resizable_dim = 0; -	S32 num_auto_resize_panels = 0; +	F32 total_resizable_dim = 0.f;  	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)  	{  		if (panelp->mAutoResize)  		{  			total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim()); -			num_auto_resize_panels++;  		}  	} -	F32 total_fractional_size = 0.f; -	  	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)  	{  		if (panelp->mAutoResize)  		{  			F32 panel_resizable_dim = llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));  			panelp->mFractionalSize = panel_resizable_dim > 0.f  -										? llclamp(panel_resizable_dim / total_resizable_dim, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE) -										: MIN_FRACTIONAL_SIZE; -			total_fractional_size += panelp->mFractionalSize; +				? llclamp(panel_resizable_dim / total_resizable_dim, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE) +				: MIN_FRACTIONAL_SIZE;  			llassert(!llisnan(panelp->mFractionalSize));  		}  	} +	normalizeFractionalSizes(); +} + + +void LLLayoutStack::normalizeFractionalSizes() +{ +	S32 num_auto_resize_panels = 0; +	F32 total_fractional_size = 0.f; +	 +	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) +	{ +		if (panelp->mAutoResize) +		{ +			total_fractional_size += panelp->mFractionalSize; +			num_auto_resize_panels++; +		} +	} +  	if (total_fractional_size == 0.f)  	{ // equal distribution  		BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) @@ -545,7 +579,7 @@ void LLLayoutStack::updateFractionalSizes()  bool LLLayoutStack::animatePanels()  { -	bool animation_in_progress = false; +	bool continue_animating = false;  	//  	// animate visibility @@ -565,14 +599,15 @@ bool LLLayoutStack::animatePanels()  					}  				} -				animation_in_progress = true; +				mAnimatedThisFrame = true; +				continue_animating = true;  			}  			else  			{  				if (panelp->mVisibleAmt != 1.f)  				{  					panelp->mVisibleAmt = 1.f; -					animation_in_progress = true; +					mAnimatedThisFrame = true;  				}  			}  		} @@ -589,14 +624,15 @@ bool LLLayoutStack::animatePanels()  					}  				} -				animation_in_progress = true; +				continue_animating = true; +				mAnimatedThisFrame = true;  			}  			else  			{  				if (panelp->mVisibleAmt != 0.f)  				{  					panelp->mVisibleAmt = 0.f; -					animation_in_progress = true; +					mAnimatedThisFrame = true;  				}  			}  		} @@ -604,22 +640,31 @@ bool LLLayoutStack::animatePanels()  		F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;  		if (panelp->mCollapseAmt != collapse_state)  		{ -			if (!mAnimatedThisFrame) +			if (mAnimate)  			{ -				panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); -			} -			animation_in_progress = true; +				if (!mAnimatedThisFrame) +				{ +					panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); +				} -			if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) +				if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) +				{ +					panelp->mCollapseAmt = collapse_state; +				} + +				mAnimatedThisFrame = true; +				continue_animating = true; +			} +			else  			{  				panelp->mCollapseAmt = collapse_state; +				mAnimatedThisFrame = true;  			}  		}  	} -	mAnimatedThisFrame = true; - -	return animation_in_progress; +	if (mAnimatedThisFrame) mNeedsLayout = true; +	return continue_animating;  }  void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& new_rect ) @@ -632,7 +677,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  	F32 total_visible_fraction = 0.f;  	F32 delta_auto_resize_headroom = 0.f; -	F32 total_auto_resize_headroom = 0.f; +	F32 original_auto_resize_headroom = 0.f;  	LLLayoutPanel* other_resize_panel = NULL;  	LLLayoutPanel* following_panel = NULL; @@ -641,8 +686,11 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  	{  		if (panelp->mAutoResize)  		{ -			total_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim()); -			total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor(); +			original_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim()); +			if (panelp->getVisible() && !panelp->mCollapsed) +			{ +				total_visible_fraction += panelp->mFractionalSize; +			}  		}  		if (panelp == resized_panel) @@ -656,18 +704,25 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  		}  	} -	if (resized_panel->mAutoResize == FALSE) + +	if (resized_panel->mAutoResize)  	{ -		delta_auto_resize_headroom += -delta_dim; +		if (!other_resize_panel || !other_resize_panel->mAutoResize) +		{ +			delta_auto_resize_headroom += delta_dim;	 +		}  	} -	if (other_resize_panel && other_resize_panel->mAutoResize == FALSE) +	else   	{ -		delta_auto_resize_headroom += delta_dim; +		if (!other_resize_panel || other_resize_panel->mAutoResize) +		{ +			delta_auto_resize_headroom -= delta_dim; +		}  	}  	F32 fraction_given_up = 0.f;  	F32 fraction_remaining = 1.f; -	F32 updated_auto_resize_headroom = total_auto_resize_headroom + delta_auto_resize_headroom; +	F32 updated_auto_resize_headroom = original_auto_resize_headroom + delta_auto_resize_headroom;  	enum  	{ @@ -691,14 +746,15 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  		case BEFORE_RESIZED_PANEL:  			if (panelp->mAutoResize)  			{	// freeze current size as fraction of overall auto_resize space -				F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom; +				F32 fractional_adjustment_factor = updated_auto_resize_headroom == 0.f +													? 1.f +													: original_auto_resize_headroom / updated_auto_resize_headroom;  				F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,  													MIN_FRACTIONAL_SIZE,  													MAX_FRACTIONAL_SIZE); -				F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize); -				fraction_given_up -= fraction_delta; +				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;  				fraction_remaining -= panelp->mFractionalSize; -				panelp->mFractionalSize += fraction_delta; +				panelp->mFractionalSize = new_fractional_size;  				llassert(!llisnan(panelp->mFractionalSize));  			}  			else @@ -711,7 +767,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  			{	// freeze new size as fraction  				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)  					? MAX_FRACTIONAL_SIZE -					: llclamp((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE); +					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);  				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;  				fraction_remaining -= panelp->mFractionalSize;  				panelp->mFractionalSize = new_fractional_size; @@ -720,7 +776,6 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  			else  			{	// freeze new size as original size  				panelp->mTargetDim = new_dim; -				fraction_remaining -= fraction_given_up;  			}  			which_panel = NEXT_PANEL;  			break; @@ -728,14 +783,14 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  			if (panelp->mAutoResize)  			{  				fraction_remaining -= panelp->mFractionalSize; -				if (fraction_given_up != 0.f) +				if (resized_panel->mAutoResize)  				{  					panelp->mFractionalSize = llclamp(panelp->mFractionalSize + fraction_given_up, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);  					fraction_given_up = 0.f;  				}  				else  				{ -					F32 new_fractional_size = llclamp((F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom)  +					F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom)   														/ updated_auto_resize_headroom,  													MIN_FRACTIONAL_SIZE,  													MAX_FRACTIONAL_SIZE); @@ -750,7 +805,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  			which_panel = AFTER_RESIZED_PANEL;  			break;  		case AFTER_RESIZED_PANEL: -			if (panelp->mAutoResize) +			if (panelp->mAutoResize && fraction_given_up != 0.f)  			{  				panelp->mFractionalSize = llclamp(panelp->mFractionalSize + (panelp->mFractionalSize / fraction_remaining) * fraction_given_up,  												MIN_FRACTIONAL_SIZE, @@ -760,6 +815,8 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&  			break;  		}  	} +	updateLayout(); +	normalizeFractionalSizes();  }  void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent) diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index efe93f6def..648cd5fdce 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -72,7 +72,7 @@ public:  	/*virtual*/ void draw();  	/*virtual*/ void removeChild(LLView*);  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); +	/*virtual*/ bool addChild(LLView* child, S32 tab_groupdatefractuiona = 0);  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -112,6 +112,7 @@ private:  	LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;  	LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const;  	void updateFractionalSizes(); +	void normalizeFractionalSizes();  	void updatePanelRect( LLLayoutPanel* param1, const LLRect& new_rect );  	S32 mPanelSpacing; @@ -154,10 +155,12 @@ public:  	void setVisible(BOOL visible);  	S32 getLayoutDim() const; -	S32 getMinDim() const { return (mMinDim >= 0 || mAutoResize) ? llmax(0, mMinDim) : getLayoutDim(); } +	S32 getTargetDim() const; +	void setTargetDim(S32 value); +	S32 getMinDim() const { return llmax(0, mMinDim); }  	void setMinDim(S32 value) { mMinDim = value; } -	S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : mMinDim; } +	S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : getMinDim(); }  	void setExpandedMinDim(S32 value) { mExpandedMinDim = value; }  	S32 getRelevantMinDim() const diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 06dfc90d83..d0fbf4b913 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1047,7 +1047,7 @@ void LLLineEditor::cut()  		// Prepare for possible rollback  		LLLineEditorRollback rollback( this ); -		gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); +		LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );  		deleteSelection();  		// Validate new string and rollback the if needed. @@ -1078,13 +1078,13 @@ void LLLineEditor::copy()  	{  		S32 left_pos = llmin( mSelectionStart, mSelectionEnd );  		S32 length = llabs( mSelectionStart - mSelectionEnd ); -		gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); +		LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );  	}  }  BOOL LLLineEditor::canPaste() const  { -	return !mReadOnly && gClipboard.canPasteString();  +	return !mReadOnly && LLClipboard::instance().isTextAvailable();   }  void LLLineEditor::paste() @@ -1115,14 +1115,7 @@ void LLLineEditor::pasteHelper(bool is_primary)  	if (can_paste_it)  	{  		LLWString paste; -		if (is_primary) -		{ -			paste = gClipboard.getPastePrimaryWString(); -		} -		else  -		{ -			paste = gClipboard.getPasteWString(); -		} +		LLClipboard::instance().pasteFromClipboard(paste, is_primary);  		if (!paste.empty())  		{ @@ -1209,13 +1202,13 @@ void LLLineEditor::copyPrimary()  	{  		S32 left_pos = llmin( mSelectionStart, mSelectionEnd );  		S32 length = llabs( mSelectionStart - mSelectionEnd ); -		gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length ); +		LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length, true);  	}  }  BOOL LLLineEditor::canPastePrimary() const  { -	return !mReadOnly && gClipboard.canPastePrimaryString();  +	return !mReadOnly && LLClipboard::instance().isTextAvailable(true);   }  void LLLineEditor::updatePrimary() @@ -1630,7 +1623,7 @@ void LLLineEditor::draw()  	LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );  	background.stretch( -mBorderThickness ); -	S32 lineeditor_v_pad = llround((background.getHeight() - mGLFont->getLineHeight())/2); +	S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2;  	drawBackground(); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 95ecbb1c94..ff6928ffda 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -317,7 +317,7 @@ void LLMenuItemGL::setJumpKey(KEY key)  // virtual   U32 LLMenuItemGL::getNominalHeight( void ) const   {  -	return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING;  +	return mFont->getLineHeight() + MENU_ITEM_PADDING;  }  //virtual @@ -508,19 +508,19 @@ void LLMenuItemGL::draw( void )  	{  		if( !mDrawBoolLabel.empty() )  		{ -			mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, +			mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,  						   LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );  		} -		mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, +		mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,  					   LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );  		if( !mDrawAccelLabel.empty() )  		{ -			mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, +			mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,  						   LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );  		}  		if( !mDrawBranchLabel.empty() )  		{ -			mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, +			mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,  						   LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );  		}  	} @@ -1966,7 +1966,7 @@ void LLMenuGL::arrange( void )  		// *FIX: create the item first and then ask for its dimensions?  		S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::getFontSansSerif()->getWidth( std::string("More") ); // *TODO: Translate -		S32 spillover_item_height = llround(LLFontGL::getFontSansSerif()->getLineHeight()) + MENU_ITEM_PADDING; +		S32 spillover_item_height = LLFontGL::getFontSansSerif()->getLineHeight() + MENU_ITEM_PADDING;  		// Scrolling support  		item_list_t::iterator first_visible_item_iter; @@ -3082,7 +3082,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)  		mouse_y + MOUSE_CURSOR_PADDING,   		CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,   		CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2); -	menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect, FALSE ); +	menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );  	menu->getParent()->sendChildToFront(menu);  } @@ -3425,7 +3425,7 @@ void LLMenuHolderGL::draw()  		LLUI::pushMatrix();  		{ -			LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom, 0.f); +			LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom);  			selecteditem->getMenu()->drawBackground(selecteditem, interpolant);  			selecteditem->draw();  		} diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index d232e27ef2..8aa548b974 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1412,6 +1412,7 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path  bool LLNotifications::loadTemplates()  { +	llinfos << "Reading notifications template" << llendl;  	std::vector<std::string> search_paths;  	std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; @@ -1484,6 +1485,8 @@ bool LLNotifications::loadTemplates()  		mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));  	} +	llinfos << "...done" << llendl; +  	return true;  } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 462d69be2e..3df2efcac3 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -690,7 +690,7 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;  // Abstract base class (interface) for a channel; also used for the master container.  // This lets us arrange channels into a call hierarchy. -// We maintain a heirarchy of notification channels; events are always started at the top +// We maintain a hierarchy of notification channels; events are always started at the top  // and propagated through the hierarchy only if they pass a filter.  // Any channel can be created with a parent. A null parent (empty string) means it's  // tied to the root of the tree (the LLNotifications class itself). diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index ad4cc20d9a..9b7e30bb04 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -378,19 +378,24 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height  	if (!mHideScrollbar)  	{ -		if( *visible_height < doc_height ) +		// Note: 1 pixel change can happen on final animation and should not trigger  +		// the display of sliders. +		if ((doc_height - *visible_height) > 1)  		{  			*show_v_scrollbar = TRUE;  			*visible_width -= scrollbar_size;  		} - -		if( *visible_width < doc_width ) +		if ((doc_width - *visible_width) > 1)  		{  			*show_h_scrollbar = TRUE;  			*visible_height -= scrollbar_size; +			// The view inside the scroll container should not be extended +			// to container's full height to ensure the correct computation +			// of *show_v_scrollbar after subtracting horizontal scrollbar_size. +  			// Must retest now that visible_height has changed -			if( !*show_v_scrollbar && (*visible_height < doc_height) ) +			if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )  			{  				*show_v_scrollbar = TRUE;  				*visible_width -= scrollbar_size; diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 3aa79cc255..d87c95b3d7 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -91,7 +91,7 @@ public:  	void			setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }  	LLRect			getVisibleContentRect();  	LLRect			getContentWindowRect(); -	const LLRect&	getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; } +	virtual const LLRect	getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }  	void			pageUp(S32 overlap = 0);  	void			pageDown(S32 overlap = 0);  	void			goToTop(); @@ -116,6 +116,9 @@ public:  	bool autoScroll(S32 x, S32 y); +protected: +	LLView*		mScrolledView; +  private:  	// internal scrollbar handlers  	virtual void scrollHorizontal( S32 new_pos ); @@ -124,7 +127,6 @@ private:  	void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;  	LLScrollbar* mScrollbar[SCROLLBAR_COUNT]; -	LLView*		mScrolledView;  	S32			mSize;  	BOOL		mIsOpaque;  	LLUIColor	mBackgroundColor; diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 9d25c7180d..8000efad0e 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -232,7 +232,7 @@ BOOL LLScrollListText::getVisible() const  //virtual   S32 LLScrollListText::getHeight() const  { -	return llround(mFont->getLineHeight()); +	return mFont->getLineHeight();  } @@ -306,7 +306,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col  			break;  		}  		LLRect highlight_rect(left - 2,  -				llround(mFont->getLineHeight()) + 1,  +				mFont->getLineHeight() + 1,   				left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,   				1);  		mRoundedRectImage->draw(highlight_rect, highlight_color); @@ -329,7 +329,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col  		break;  	}  	mFont->render(mText.getWString(), 0,  -					start_x, 2.f, +					start_x, 0.f,  					display_color,  					mFontAlignment,  					LLFontGL::BOTTOM,  diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 466fac33ea..b3e1b63db5 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2504,7 +2504,7 @@ void	LLScrollListCtrl::copy()  	{  		buffer += (*itor)->getContentsCSV() + "\n";  	} -	gClipboard.copyFromSubstring(utf8str_to_wstring(buffer), 0, buffer.length()); +	LLClipboard::instance().copyToClipboard(utf8str_to_wstring(buffer), 0, buffer.length());  }  // virtual diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index d95752e31c..5a1e96ab03 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -138,7 +138,7 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const  		LLUI::pushMatrix();  		{ -			LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f); +			LLUI::translate((F32) cur_x, (F32) rect.mBottom);  			cell->draw( fg_color, highlight_color );  		} diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 611df729b4..13655b5873 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -33,10 +33,10 @@  #include "v4color.h"  #include "llinitparam.h"  #include "llscrolllistcell.h" +#include "llcoord.h"  #include <vector> -class LLCoordGL;  class LLCheckBoxCtrl;  class LLResizeBar;  class LLScrollListCtrl; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index ec4db14790..04cce7878e 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -272,7 +272,7 @@ LLRect LLStatBar::getRequiredRect()  	{  		if (mDisplayHistory)  		{ -			rect.mTop = 67; +			rect.mTop = 35 + mStatp->getNumBins();  		}  		else  		{ diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0040be45c7..7aeeae298f 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1192,7 +1192,10 @@ void LLTextBase::reflow()  		// shrink document to minimum size (visible portion of text widget)  		// to force inlined widgets with follows set to shrink -		mDocumentView->reshape(mVisibleTextRect.getWidth(), mDocumentView->getRect().getHeight()); +		if (mWordWrap) +		{ +			mDocumentView->reshape(mVisibleTextRect.getWidth(), mDocumentView->getRect().getHeight()); +		}  		S32 cur_top = 0; @@ -2157,7 +2160,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const  	{   		// return default height rect in upper left  		local_rect = content_window_rect; -		local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight()); +		local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();  		return local_rect;  	} @@ -2380,6 +2383,9 @@ S32 LLTextBase::getEditableIndex(S32 index, bool increasing_direction)  void LLTextBase::updateRects()  { +	LLRect old_text_rect = mVisibleTextRect; +	mVisibleTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect(); +  	if (mLineInfoList.empty())   	{  		mTextBoundingRect = LLRect(0, mVPad, mHPad, 0); @@ -2395,10 +2401,24 @@ void LLTextBase::updateRects()  		}  		mTextBoundingRect.mTop += mVPad; -		// subtract a pixel off the bottom to deal with rounding errors in measuring font height -		mTextBoundingRect.mBottom -= 1; -		S32 delta_pos = -mTextBoundingRect.mBottom; +		S32 delta_pos = 0; +		 +		switch(mVAlign) +		{ +		case LLFontGL::TOP: +			delta_pos = llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom); +			break; +		case LLFontGL::VCENTER: +			delta_pos = (llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom) + (mVisibleTextRect.mBottom - mTextBoundingRect.mBottom)) / 2; +			break; +		case LLFontGL::BOTTOM: +			delta_pos = mVisibleTextRect.mBottom - mTextBoundingRect.mBottom; +			break; +		case LLFontGL::BASELINE: +			// do nothing +			break; +		}  		// move line segments to fit new document rect  		for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)  		{ @@ -2408,8 +2428,9 @@ void LLTextBase::updateRects()  	}  	// update document container dimensions according to text contents -	LLRect doc_rect = mTextBoundingRect; +	LLRect doc_rect;  	// use old mVisibleTextRect constraint document to width of viewable region +	doc_rect.mBottom = llmin(mVisibleTextRect.mBottom,  mTextBoundingRect.mBottom);  	doc_rect.mLeft = 0;  	// allow horizontal scrolling? @@ -2419,11 +2440,22 @@ void LLTextBase::updateRects()  	doc_rect.mRight = mScroller   		? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)  		: mVisibleTextRect.getWidth(); +	doc_rect.mTop = llmax(mVisibleTextRect.mTop, mTextBoundingRect.mTop);  	if (!mScroller)  	{  		// push doc rect to top of text widget -		doc_rect.translate(0, mVisibleTextRect.getHeight() - doc_rect.mTop); +		switch(mVAlign) +		{ +		case LLFontGL::TOP: +			doc_rect.translate(0, mVisibleTextRect.getHeight() - doc_rect.mTop); +			break; +		case LLFontGL::VCENTER: +			doc_rect.translate(0, (mVisibleTextRect.getHeight() - doc_rect.mTop) / 2); +		case LLFontGL::BOTTOM: +		default: +			break; +		}  	}  	mDocumentView->setShape(doc_rect); @@ -2431,7 +2463,6 @@ void LLTextBase::updateRects()  	//update mVisibleTextRect *after* mDocumentView has been resized  	// so that scrollbars are added if document needs to scroll  	// since mVisibleTextRect does not include scrollbars -	LLRect old_text_rect = mVisibleTextRect;  	mVisibleTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();  	//FIXME: replace border with image?  	if (mBorderVisible) @@ -2444,9 +2475,27 @@ void LLTextBase::updateRects()  	}  	// update document container again, using new mVisibleTextRect (that has scrollbars enabled as needed) +	doc_rect.mBottom = llmin(mVisibleTextRect.mBottom,  mTextBoundingRect.mBottom); +	doc_rect.mLeft = 0;  	doc_rect.mRight = mScroller   		? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)  		: mVisibleTextRect.getWidth(); +	doc_rect.mTop = llmax(mVisibleTextRect.mTop, mTextBoundingRect.mTop); +	if (!mScroller) +	{ +		// push doc rect to top of text widget +		switch(mVAlign) +		{ +		case LLFontGL::TOP: +			doc_rect.translate(0, mVisibleTextRect.getHeight() - doc_rect.mTop); +			break; +		case LLFontGL::VCENTER: +			doc_rect.translate(0, (mVisibleTextRect.getHeight() - doc_rect.mTop) / 2); +		case LLFontGL::BOTTOM: +		default: +			break; +		} +	}  	mDocumentView->setShape(doc_rect);  } @@ -2560,8 +2609,7 @@ BOOL LLTextSegment::handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE;  BOOL LLTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { return FALSE; }  const std::string&	LLTextSegment::getName() const   { -	static std::string empty_string(""); -	return empty_string;  +	return LLStringUtil::null;  }  void LLTextSegment::onMouseCaptureLost() {}  void LLTextSegment::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const {} @@ -2578,7 +2626,7 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e  	mToken(NULL),  	mEditor(editor)  { -	mFontHeight = llceil(mStyle->getFont()->getLineHeight()); +	mFontHeight = mStyle->getFont()->getLineHeight();  	LLUIImagePtr image = mStyle->getImage();  	if (image.notNull()) @@ -2594,7 +2642,7 @@ LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32  {  	mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color)); -	mFontHeight = llceil(mStyle->getFont()->getLineHeight()); +	mFontHeight = mStyle->getFont()->getLineHeight();  }  LLNormalTextSegment::~LLNormalTextSegment() @@ -2962,11 +3010,11 @@ LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1)  {  	LLStyleSP s( new LLStyle(LLStyle::Params().visible(true))); -	mFontHeight = llceil(s->getFont()->getLineHeight()); +	mFontHeight = s->getFont()->getLineHeight();  }  LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)  { -	mFontHeight = llceil(style->getFont()->getLineHeight()); +	mFontHeight = style->getFont()->getLineHeight();  }  LLLineBreakTextSegment::~LLLineBreakTextSegment()  { @@ -3003,7 +3051,7 @@ static const S32 IMAGE_HPAD = 3;  bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const  {  	width = 0; -	height = llceil(mStyle->getFont()->getLineHeight());; +	height = mStyle->getFont()->getLineHeight();  	LLUIImagePtr image = mStyle->getImage();  	if( num_chars>0 && image.notNull()) diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3a23ce1cac..9720dded6c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1332,7 +1332,7 @@ void LLTextEditor::cut()  	}  	S32 left_pos = llmin( mSelectionStart, mSelectionEnd );  	S32 length = llabs( mSelectionStart - mSelectionEnd ); -	gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID ); +	LLClipboard::instance().copyToClipboard( getWText(), left_pos, length);  	deleteSelection( FALSE );  	onKeyStroke(); @@ -1352,12 +1352,12 @@ void LLTextEditor::copy()  	}  	S32 left_pos = llmin( mSelectionStart, mSelectionEnd );  	S32 length = llabs( mSelectionStart - mSelectionEnd ); -	gClipboard.copyFromSubstring(getWText(), left_pos, length, mSourceID); +	LLClipboard::instance().copyToClipboard(getWText(), left_pos, length);  }  BOOL LLTextEditor::canPaste() const  { -	return !mReadOnly && gClipboard.canPasteString(); +	return !mReadOnly && LLClipboard::instance().isTextAvailable();  }  // paste from clipboard @@ -1393,16 +1393,8 @@ void LLTextEditor::pasteHelper(bool is_primary)  		return;  	} -	LLUUID source_id;  	LLWString paste; -	if (is_primary) -	{ -		paste = gClipboard.getPastePrimaryWString(&source_id); -	} -	else  -	{ -		paste = gClipboard.getPasteWString(&source_id); -	} +	LLClipboard::instance().pasteFromClipboard(paste, is_primary);  	if (paste.empty())  	{ @@ -1475,12 +1467,12 @@ void LLTextEditor::copyPrimary()  	}  	S32 left_pos = llmin( mSelectionStart, mSelectionEnd );  	S32 length = llabs( mSelectionStart - mSelectionEnd ); -	gClipboard.copyFromPrimarySubstring(getWText(), left_pos, length, mSourceID); +	LLClipboard::instance().copyToClipboard(getWText(), left_pos, length, true);  }  BOOL LLTextEditor::canPastePrimary() const  { -	return !mReadOnly && gClipboard.canPastePrimaryString(); +	return !mReadOnly && LLClipboard::instance().isTextAvailable(true);  }  void LLTextEditor::updatePrimary() @@ -1992,7 +1984,7 @@ void LLTextEditor::drawPreeditMarker()  		return;  	} -	const S32 line_height = llround( mDefaultFont->getLineHeight() ); +	const S32 line_height = mDefaultFont->getLineHeight();  	S32 line_start = getLineStart(cur_line);  	S32 line_y = mVisibleTextRect.mTop - line_height; @@ -2715,7 +2707,7 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect      const LLWString textString(getWText());  	const llwchar * const text = textString.c_str(); -	const S32 line_height = llround(mDefaultFont->getLineHeight()); +	const S32 line_height = mDefaultFont->getLineHeight();  	if (coord)  	{ @@ -2818,7 +2810,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)  S32 LLTextEditor::getPreeditFontSize() const  { -	return llround(mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); +	return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);  }  BOOL LLTextEditor::isDirty() const diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 9b31a6449d..81ea0ebf0c 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -827,7 +827,7 @@ void LLToolBar::draw()  	// rect may have shifted during layout  	LLUI::popMatrix();  	LLUI::pushMatrix(); -	LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom, 0.f); +	LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);  	// Position the caret   	LLIconCtrl* caret = getChild<LLIconCtrl>("caret"); diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 23cdd9ad9a..f737d48abf 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -180,6 +180,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)  	params.font = p.font;  	params.use_ellipses = true;  	params.wrap = p.wrap; +	params.font_valign = LLFontGL::VCENTER;  	params.parse_urls = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips  	mTextBox = LLUICtrlFactory::create<LLTextBox> (params);  	addChild(mTextBox); @@ -190,7 +191,6 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)  	{  		LLButton::Params icon_params;  		icon_params.name = "tooltip_info"; -		icon_params.label(""); // provid label but set to empty so name does not overwrite it -angela  		LLRect icon_rect;  		LLUIImage* imagep = p.image;  		TOOLTIP_ICON_SIZE = (imagep ? imagep->getWidth() : 16); @@ -291,6 +291,12 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)  	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());  	S32 text_height = mTextBox->getTextPixelHeight();  	mTextBox->reshape(text_width, text_height); +	if (mInfoButton) +	{ +		LLRect text_rect = mTextBox->getRect(); +		LLRect icon_rect = mInfoButton->getRect(); +		mTextBox->translate(0, icon_rect.getCenterY() - text_rect.getCenterY()); +	}  	// reshape tooltip panel to fit text box  	LLRect tooltip_rect = calcBoundingRect(); @@ -299,6 +305,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)  	tooltip_rect.mBottom = 0;  	tooltip_rect.mLeft = 0; +	mTextBox->reshape(mTextBox->getRect().getWidth(), llmax(mTextBox->getRect().getHeight(), tooltip_rect.getHeight() - 2 * mPadding)); +  	setShape(tooltip_rect);  } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 6b74c5a6be..b5e27616b7 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -972,43 +972,53 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor  // Draw gray and white checkerboard with black border  void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)  { -	// Initialize the first time this is called. -	const S32 PIXELS = 32; -	static GLubyte checkerboard[PIXELS * PIXELS]; -	static BOOL first = TRUE; -	if( first ) -	{ -		for( S32 i = 0; i < PIXELS; i++ ) +	if (!LLGLSLShader::sNoFixedFunction) +	{  +		// Initialize the first time this is called. +		const S32 PIXELS = 32; +		static GLubyte checkerboard[PIXELS * PIXELS]; +		static BOOL first = TRUE; +		if( first )  		{ -			for( S32 j = 0; j < PIXELS; j++ ) +			for( S32 i = 0; i < PIXELS; i++ )  			{ -				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; +				for( S32 j = 0; j < PIXELS; j++ ) +				{ +					checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; +				}  			} +			first = FALSE;  		} -		first = FALSE; -	} -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	// ...white squares -	gGL.color4f( 1.f, 1.f, 1.f, alpha ); -	gl_rect_2d(rect); +		// ...white squares +		gGL.color4f( 1.f, 1.f, 1.f, alpha ); +		gl_rect_2d(rect); -	// ...gray squares -	gGL.color4f( .7f, .7f, .7f, alpha ); -	gGL.flush(); +		// ...gray squares +		gGL.color4f( .7f, .7f, .7f, alpha ); +		gGL.flush(); -	if (!LLGLSLShader::sNoFixedFunction) -	{ //polygon stipple is deprecated  		glPolygonStipple( checkerboard );  		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);  		gl_rect_2d(rect);  	}  	else -	{ -		gl_rect_2d(rect); +	{ //polygon stipple is deprecated, use "Checker" texture +		LLPointer<LLUIImage> img = LLUI::getUIImage("Checker"); +		gGL.getTexUnit(0)->bind(img->getImage()); +		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + +		LLColor4 color(1.f, 1.f, 1.f, alpha); +		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f); + +		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), +			img->getImage(), color, uv_rect);  	} +	  	gGL.flush();  } @@ -1688,21 +1698,22 @@ void LLUI::translate(F32 x, F32 y, F32 z)  	gGL.translateUI(x,y,z);  	LLFontGL::sCurOrigin.mX += (S32) x;  	LLFontGL::sCurOrigin.mY += (S32) y; -	LLFontGL::sCurOrigin.mZ += z; +	LLFontGL::sCurDepth += z;  }  //static  void LLUI::pushMatrix()  {  	gGL.pushUIMatrix(); -	LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin); +	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));  }  //static  void LLUI::popMatrix()  {  	gGL.popUIMatrix(); -	LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin(); +	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first; +	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;  	LLFontGL::sOriginStack.pop_back();  } @@ -1712,7 +1723,7 @@ void LLUI::loadIdentity()  	gGL.loadUIIdentity();   	LLFontGL::sCurOrigin.mX = 0;  	LLFontGL::sCurOrigin.mY = 0; -	LLFontGL::sCurOrigin.mZ = 0; +	LLFontGL::sCurDepth = 0.f;  }  //static @@ -1735,10 +1746,7 @@ void LLUI::setMousePositionScreen(S32 x, S32 y)  	screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);  	screen_y = llround((F32)y * sGLScaleFactor.mV[VY]); -	LLCoordWindow window_point; -	LLView::getWindow()->convertCoords(LLCoordGL(screen_x, screen_y), &window_point); - -	LLView::getWindow()->setCursorPosition(window_point); +	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());  }  //static  @@ -1746,8 +1754,7 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)  {  	LLCoordWindow cursor_pos_window;  	getWindow()->getCursorPosition(&cursor_pos_window); -	LLCoordGL cursor_pos_gl; -	getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); +	LLCoordGL cursor_pos_gl(cursor_pos_window.convert());  	*x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);  	*y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);  } @@ -2052,7 +2059,7 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)  	// Start at spawn position (using left/top)  	view->setOrigin( local_x, local_y - view->getRect().getHeight());  	// Make sure we're on-screen and not overlapping the mouse -	view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect, FALSE ); +	view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect );  }  LLView* LLUI::resolvePath(LLView* context, const std::string& path) diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index ac69d3bf85..c4e073ccdb 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -128,17 +128,13 @@ void LLUIString::updateResult() const  	}  	mResult = mOrig; -	// get the defailt args + local args -	if (!mArgs || mArgs->empty()) +	// get the default args + local args +	LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs(); +	if (mArgs && !mArgs->empty())  	{ -		LLStringUtil::format(mResult, LLTrans::getDefaultArgs()); -	} -	else -	{ -		LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs();  		combined_args.insert(mArgs->begin(), mArgs->end()); -		LLStringUtil::format(mResult, combined_args);  	} +	LLStringUtil::format(mResult, combined_args);  }  void LLUIString::updateWResult() const diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index e1ee0a5b14..54843227b7 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1106,7 +1106,7 @@ void LLView::drawChildren()  				{  					LLUI::pushMatrix();  					{ -						LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f); +						LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom);  						// flag the fact we are in draw here, in case overridden draw() method attempts to remove this widget  						viewp->mInDraw = true;  						viewp->draw(); @@ -1159,7 +1159,7 @@ void LLView::drawDebugRect()  		if (getUseBoundingRect())  		{ -			LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom, 0.f); +			LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom);  		}  		LLRect debug_rect = getUseBoundingRect() ? mBoundingRect : mRect; @@ -1231,7 +1231,7 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr  			gGL.matrixMode(LLRender::MM_MODELVIEW);  			LLUI::pushMatrix();  			{ -				LLUI::translate((F32)childp->getRect().mLeft + x_offset, (F32)childp->getRect().mBottom + y_offset, 0.f); +				LLUI::translate((F32)childp->getRect().mLeft + x_offset, (F32)childp->getRect().mBottom + y_offset);  				childp->draw();  			}  			LLUI::popMatrix(); @@ -1300,7 +1300,10 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)  			S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;  			S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;  			viewp->translate( delta_x, delta_y ); -			viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); +			if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) +			{ +				viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); +			}  		}  	} @@ -1616,59 +1619,30 @@ LLView* LLView::findNextSibling(LLView* child)  } -LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, BOOL allow_partial_outside) +LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, S32 min_overlap_pixels)  {  	LLCoordGL delta; -	if (allow_partial_outside) -	{ -		const S32 KEEP_ONSCREEN_PIXELS = 16; +	const S32 KEEP_ONSCREEN_PIXELS_WIDTH = llmin(min_overlap_pixels, input.getWidth()); +	const S32 KEEP_ONSCREEN_PIXELS_HEIGHT = llmin(min_overlap_pixels, input.getHeight()); -		if( input.mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft ) -		{ -			delta.mX = constraint.mLeft - (input.mRight - KEEP_ONSCREEN_PIXELS); -		} -		else -		if( input.mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) -		{ -			delta.mX = constraint.mRight - (input.mLeft + KEEP_ONSCREEN_PIXELS); -		} +	if( input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH < constraint.mLeft ) +	{ +		delta.mX = constraint.mLeft - (input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH); +	} +	else if( input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH > constraint.mRight ) +	{ +		delta.mX = constraint.mRight - (input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH); +	} -		if( input.mTop > constraint.mTop ) -		{ -			delta.mY = constraint.mTop - input.mTop; -		} -		else -		if( input.mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) -		{ -			delta.mY = constraint.mBottom - (input.mTop - KEEP_ONSCREEN_PIXELS); -		} +	if( input.mTop > constraint.mTop ) +	{ +		delta.mY = constraint.mTop - input.mTop;  	}  	else +	if( input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT < constraint.mBottom )  	{ -		if( input.mLeft < constraint.mLeft ) -		{ -			delta.mX = constraint.mLeft - input.mLeft; -		} -		else -		if( input.mRight > constraint.mRight ) -		{ -			delta.mX = constraint.mRight - input.mRight; -			// compensate for left edge possible going off screen -			delta.mX += llmax( 0, input.getWidth() - constraint.getWidth() ); -		} - -		if( input.mTop > constraint.mTop ) -		{ -			delta.mY = constraint.mTop - input.mTop; -		} -		else -		if( input.mBottom < constraint.mBottom ) -		{ -			delta.mY = constraint.mBottom - input.mBottom; -			// compensate for top edge possible going off screen -			delta.mY -= llmax( 0, input.getHeight() - constraint.getHeight() ); -		} +		delta.mY = constraint.mBottom - (input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT);  	}  	return delta; @@ -1677,9 +1651,9 @@ LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, BO  // Moves the view so that it is entirely inside of constraint.  // If the view will not fit because it's too big, aligns with the top and left.  // (Why top and left?  That's where the drag bars are for floaters.) -BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outside ) +BOOL LLView::translateIntoRect(const LLRect& constraint, S32 min_overlap_pixels)  { -	LLCoordGL translation = getNeededTranslation(getRect(), constraint, allow_partial_outside); +	LLCoordGL translation = getNeededTranslation(getRect(), constraint, min_overlap_pixels);  	if (translation.mX != 0 || translation.mY != 0)  	{ @@ -1691,9 +1665,9 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs  // move this view into "inside" but not onto "exclude"  // NOTE: if this view is already contained in "inside", we ignore the "exclude" rect -BOOL LLView::translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside ) +BOOL LLView::translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, S32 min_overlap_pixels)  { -	LLCoordGL translation = getNeededTranslation(getRect(), inside, allow_partial_outside); +	LLCoordGL translation = getNeededTranslation(getRect(), inside, min_overlap_pixels);  	if (translation.mX != 0 || translation.mY != 0)  	{ @@ -1861,7 +1835,10 @@ const LLCtrlQuery & LLView::getFocusRootsQuery()  void	LLView::setShape(const LLRect& new_rect, bool by_user)  { -	handleReshape(new_rect, by_user); +	if (new_rect != getRect()) +	{ +		handleReshape(new_rect, by_user); +	}  }  void LLView::handleReshape(const LLRect& new_rect, bool by_user) @@ -2251,145 +2228,163 @@ static bool get_last_child_rect(LLView* parent, LLRect *rect)  }  //static -void LLView::applyXUILayout(LLView::Params& p, LLView* parent) +void LLView::applyXUILayout(LLView::Params& p, LLView* parent, LLRect layout_rect)  { +	if (!parent) return; +  	const S32 VPAD = 4;  	const S32 MIN_WIDGET_HEIGHT = 10;  	// *NOTE:  This will confuse export of floater/panel coordinates unless  	// the default is also "topleft".  JC -	if (p.layout().empty() && parent) +	if (p.layout().empty())  	{  		p.layout = parent->getLayout();  	} -	if (parent) +	if (layout_rect.isEmpty())  	{ -		LLRect parent_rect = parent->getLocalRect(); -		// overwrite uninitialized rect params, using context -		LLRect default_rect = parent->getLocalRect(); +		layout_rect = parent->getLocalRect(); +	} -		bool layout_topleft = (p.layout() == "topleft"); +	// overwrite uninitialized rect params, using context +	LLRect default_rect = parent->getLocalRect(); -		// convert negative or centered coordinates to parent relative values -		// Note: some of this logic matches the logic in TypedParam<LLRect>::setValueFromBlock() -		if (p.rect.left.isProvided() && p.rect.left < 0) p.rect.left = p.rect.left + parent_rect.getWidth(); -		if (p.rect.right.isProvided() && p.rect.right < 0) p.rect.right = p.rect.right + parent_rect.getWidth(); -		if (p.rect.bottom.isProvided() && p.rect.bottom < 0) p.rect.bottom = p.rect.bottom + parent_rect.getHeight(); -		if (p.rect.top.isProvided() && p.rect.top < 0) p.rect.top = p.rect.top + parent_rect.getHeight(); +	bool layout_topleft = (p.layout() == "topleft"); +	// convert negative or centered coordinates to parent relative values +	// Note: some of this logic matches the logic in TypedParam<LLRect>::setValueFromBlock() +	if (p.rect.left.isProvided())  +	{ +		p.rect.left = p.rect.left + ((p.rect.left >= 0) ? layout_rect.mLeft : layout_rect.mRight); +	} +	if (p.rect.right.isProvided()) +	{ +		p.rect.right = p.rect.right + ((p.rect.right >= 0) ? layout_rect.mLeft : layout_rect.mRight); +	} +	if (p.rect.bottom.isProvided())  +	{ +		p.rect.bottom = p.rect.bottom + ((p.rect.bottom >= 0) ? layout_rect.mBottom : layout_rect.mTop);  		if (layout_topleft)  		{  			//invert top to bottom -			if (p.rect.top.isProvided()) p.rect.top = parent_rect.getHeight() - p.rect.top; -			if (p.rect.bottom.isProvided()) p.rect.bottom = parent_rect.getHeight() - p.rect.bottom; +			p.rect.bottom = layout_rect.mBottom + layout_rect.mTop - p.rect.bottom;  		} - -		// DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels -		if (!p.rect.height.isProvided() && !p.rect.top.isProvided() && p.rect.height == 0) +	} +	if (p.rect.top.isProvided()) +	{ +		p.rect.top = p.rect.top + ((p.rect.top >= 0) ? layout_rect.mBottom : layout_rect.mTop); +		if (layout_topleft)  		{ -			p.rect.height = MIN_WIDGET_HEIGHT; +			//invert top to bottom +			p.rect.top = layout_rect.mBottom + layout_rect.mTop - p.rect.top;  		} +	} + +	// DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels +	if (!p.rect.height.isProvided() && !p.rect.top.isProvided() && p.rect.height == 0) +	{ +		p.rect.height = MIN_WIDGET_HEIGHT; +	} -		default_rect.translate(0, default_rect.getHeight()); +	default_rect.translate(0, default_rect.getHeight()); -		// If there was a recently constructed child, use its rectangle -		get_last_child_rect(parent, &default_rect); +	// If there was a recently constructed child, use its rectangle +	get_last_child_rect(parent, &default_rect); -		if (layout_topleft) +	if (layout_topleft) +	{ +		// Invert the sense of bottom_delta for topleft layout +		if (p.bottom_delta.isProvided())  		{ -			// Invert the sense of bottom_delta for topleft layout -			if (p.bottom_delta.isProvided()) -			{ -				p.bottom_delta = -p.bottom_delta; -			} -			else if (p.top_pad.isProvided())  -			{ -				p.bottom_delta = -(p.rect.height + p.top_pad); -			} -			else if (p.top_delta.isProvided()) -			{ -				p.bottom_delta = -					-(p.top_delta + p.rect.height - default_rect.getHeight()); -			} -			else if (!p.left_delta.isProvided() -					 && !p.left_pad.isProvided()) -			{ -				// set default position is just below last rect -				p.bottom_delta.set(-(p.rect.height + VPAD), false); -			} -			else -			{ -				p.bottom_delta.set(0, false); -			} -	 -			// default to same left edge -			if (!p.left_delta.isProvided()) -			{ -				p.left_delta.set(0, false); -			} -			if (p.left_pad.isProvided()) -			{ -				// left_pad is based on prior widget's right edge -				p.left_delta.set(p.left_pad + default_rect.getWidth(), false); -			} -			 -			default_rect.translate(p.left_delta, p.bottom_delta);				 +			p.bottom_delta = -p.bottom_delta;  		} -		else -		{	 -			// set default position is just below last rect -			if (!p.bottom_delta.isProvided()) -			{ -				p.bottom_delta.set(-(p.rect.height + VPAD), false); -			} -			if (!p.left_delta.isProvided()) -			{ -				p.left_delta.set(0, false); -			} -			default_rect.translate(p.left_delta, p.bottom_delta); +		else if (p.top_pad.isProvided())  +		{ +			p.bottom_delta = -(p.rect.height + p.top_pad);  		} - -		// this handles case where *both* x and x_delta are provided -		// ignore x in favor of default x + x_delta -		if (p.bottom_delta.isProvided()) p.rect.bottom.set(0, false); -		if (p.left_delta.isProvided()) p.rect.left.set(0, false); - -		// selectively apply rectangle defaults, making sure that -		// params are not flagged as having been "provided" -		// as rect params are overconstrained and rely on provided flags -		if (!p.rect.left.isProvided()) +		else if (p.top_delta.isProvided())  		{ -			p.rect.left.set(default_rect.mLeft, false); -			//HACK: get around the fact that setting a rect param component value won't invalidate the existing rect object value -			p.rect.paramChanged(p.rect.left, true); +			p.bottom_delta = +				-(p.top_delta + p.rect.height - default_rect.getHeight());  		} -		if (!p.rect.bottom.isProvided()) +		else if (!p.left_delta.isProvided() +					&& !p.left_pad.isProvided())  		{ -			p.rect.bottom.set(default_rect.mBottom, false); -			p.rect.paramChanged(p.rect.bottom, true); +			// set default position is just below last rect +			p.bottom_delta.set(-(p.rect.height + VPAD), false);  		} -		if (!p.rect.top.isProvided()) +		else  		{ -			p.rect.top.set(default_rect.mTop, false); -			p.rect.paramChanged(p.rect.top, true); +			p.bottom_delta.set(0, false);  		} -		if (!p.rect.right.isProvided()) +	 +		// default to same left edge +		if (!p.left_delta.isProvided())  		{ -			p.rect.right.set(default_rect.mRight, false); -			p.rect.paramChanged(p.rect.right, true); - +			p.left_delta.set(0, false);  		} -		if (!p.rect.width.isProvided()) +		if (p.left_pad.isProvided())  		{ -			p.rect.width.set(default_rect.getWidth(), false); -			p.rect.paramChanged(p.rect.width, true); +			// left_pad is based on prior widget's right edge +			p.left_delta.set(p.left_pad + default_rect.getWidth(), false);  		} -		if (!p.rect.height.isProvided()) +			 +		default_rect.translate(p.left_delta, p.bottom_delta);				 +	} +	else +	{	 +		// set default position is just below last rect +		if (!p.bottom_delta.isProvided()) +		{ +			p.bottom_delta.set(-(p.rect.height + VPAD), false); +		} +		if (!p.left_delta.isProvided())  		{ -			p.rect.height.set(default_rect.getHeight(), false); -			p.rect.paramChanged(p.rect.height, true); +			p.left_delta.set(0, false);  		} +		default_rect.translate(p.left_delta, p.bottom_delta); +	} + +	// this handles case where *both* x and x_delta are provided +	// ignore x in favor of default x + x_delta +	if (p.bottom_delta.isProvided()) p.rect.bottom.set(0, false); +	if (p.left_delta.isProvided()) p.rect.left.set(0, false); + +	// selectively apply rectangle defaults, making sure that +	// params are not flagged as having been "provided" +	// as rect params are overconstrained and rely on provided flags +	if (!p.rect.left.isProvided()) +	{ +		p.rect.left.set(default_rect.mLeft, false); +		//HACK: get around the fact that setting a rect param component value won't invalidate the existing rect object value +		p.rect.paramChanged(p.rect.left, true); +	} +	if (!p.rect.bottom.isProvided()) +	{ +		p.rect.bottom.set(default_rect.mBottom, false); +		p.rect.paramChanged(p.rect.bottom, true); +	} +	if (!p.rect.top.isProvided()) +	{ +		p.rect.top.set(default_rect.mTop, false); +		p.rect.paramChanged(p.rect.top, true); +	} +	if (!p.rect.right.isProvided()) +	{ +		p.rect.right.set(default_rect.mRight, false); +		p.rect.paramChanged(p.rect.right, true); + +	} +	if (!p.rect.width.isProvided()) +	{ +		p.rect.width.set(default_rect.getWidth(), false); +		p.rect.paramChanged(p.rect.width, true); +	} +	if (!p.rect.height.isProvided()) +	{ +		p.rect.height.set(default_rect.getHeight(), false); +		p.rect.paramChanged(p.rect.height, true);  	}  } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index f1fac5f69c..1c35349510 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -370,8 +370,8 @@ public:  	virtual void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	virtual void	translate( S32 x, S32 y );  	void			setOrigin( S32 x, S32 y )	{ mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } -	BOOL			translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside ); -	BOOL			translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside ); +	BOOL			translateIntoRect( const LLRect& constraint, S32 min_overlap_pixels = S32_MAX); +	BOOL			translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, S32 min_overlap_pixels = S32_MAX);  	void			centerWithin(const LLRect& bounds);  	void	setShape(const LLRect& new_rect, bool by_user = false); @@ -505,7 +505,7 @@ public:  	// Set up params after XML load before calling new(),  	// usually to adjust layout. -	static void applyXUILayout(Params& p, LLView* parent); +	static void applyXUILayout(Params& p, LLView* parent, LLRect layout_rect = LLRect());  	// For re-export of floaters and panels, convert the coordinate system  	// to be top-left based.  | 
