diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2012-06-04 15:28:08 -0400 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2012-06-04 15:28:08 -0400 | 
| commit | 6ee04562208100fc164bd3818ab3ba73f060d90c (patch) | |
| tree | 27b544b1832a9f3d88b39bc66a5e676d5aba511b /indra/llui | |
| parent | 8dae8290b7be728d0c70205b1f27b08f899c9d32 (diff) | |
| parent | a519e34f02b4b2663fe082ba9ad12f1b423669cb (diff) | |
merge
Diffstat (limited to 'indra/llui')
| -rw-r--r-- | indra/llui/llclipboard.cpp | 136 | ||||
| -rw-r--r-- | indra/llui/llclipboard.h | 72 | ||||
| -rw-r--r-- | indra/llui/llfloater.cpp | 274 | ||||
| -rw-r--r-- | indra/llui/llfloater.h | 32 | ||||
| -rw-r--r-- | indra/llui/llfloaterreg.cpp | 41 | ||||
| -rw-r--r-- | indra/llui/llfloaterreg.h | 4 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.cpp | 73 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.h | 2 | ||||
| -rw-r--r-- | indra/llui/lllineeditor.cpp | 19 | ||||
| -rw-r--r-- | indra/llui/llscrollcontainer.cpp | 15 | ||||
| -rw-r--r-- | indra/llui/llscrollcontainer.h | 6 | ||||
| -rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 2 | ||||
| -rw-r--r-- | indra/llui/lltexteditor.cpp | 20 | ||||
| -rw-r--r-- | indra/llui/llview.cpp | 225 | ||||
| -rw-r--r-- | indra/llui/llview.h | 2 | 
15 files changed, 544 insertions, 379 deletions
| 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/llfloater.cpp b/indra/llui/llfloater.cpp index 22b20969fc..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), @@ -547,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() @@ -569,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)  { @@ -863,7 +850,7 @@ void LLFloater::applyControlsAndPosition(LLFloater* other)  	{  		if (!applyRectControl())  		{ -			applyPositioning(other); +			applyPositioning(other, true);  		}  	}  } @@ -872,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;  } @@ -911,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); -		} +	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); +				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; @@ -1072,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 @@ -1250,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"); @@ -1590,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(); @@ -1624,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); @@ -2164,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) @@ -2189,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()) @@ -2913,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())  		{ @@ -2972,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; @@ -2991,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 @@ -3113,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); @@ -3272,8 +3306,27 @@ 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)  { @@ -3306,9 +3359,12 @@ bool LLCoordFloater::operator==(const LLCoordFloater& other) const  LLCoordCommon LL_COORD_FLOATER::convertToCommon() const  { -	const LLCoordFloater& self = static_cast<const LLCoordFloater&>(*this); +	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; @@ -3348,8 +3404,12 @@ LLCoordCommon LL_COORD_FLOATER::convertToCommon() const  void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from)  { -	LLCoordFloater& self = static_cast<LLCoordFloater&>(*this); +	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; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index a7cc9ae961..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  	};  } @@ -163,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() @@ -272,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(); @@ -355,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); @@ -363,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(); @@ -427,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 @@ -453,9 +453,7 @@ private:  	BOOL			mDragOnLeft;  	BOOL			mResizable; -	LLFloaterEnums::EOpenPositioning	mOpenPositioning; -	S32									mSpecifiedLeft; -	S32									mSpecifiedBottom; +	LLFloaterEnums::EOpenPositioning	mPositioning;  	LLCoordFloater	mPosition;  	S32				mMinWidth; 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 ae262f794e..4c730286da 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -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(); @@ -172,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);  } @@ -241,7 +263,6 @@ void LLLayoutStack::draw()  			drawChild(panelp, 0, 0, !clip_rect.isEmpty());  		}  	} -	mAnimatedThisFrame = false;  }  void LLLayoutStack::removeChild(LLView* view) @@ -310,7 +331,7 @@ void LLLayoutStack::updateLayout()  	if (!mNeedsLayout) return; -	bool animation_in_progress = animatePanels(); +	bool continue_animating = animatePanels();  	F32 total_visible_fraction = 0.f;  	S32 space_to_distribute = (mOrientation == HORIZONTAL)  							? getRect().getWidth() @@ -415,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 @@ -488,6 +509,7 @@ void LLLayoutStack::updateClass()  	for (instance_iter it = beginInstances(); it != endInstances(); ++it)  	{  		it->updateLayout(); +		it->mAnimatedThisFrame = false;  	}  } @@ -557,7 +579,7 @@ void LLLayoutStack::normalizeFractionalSizes()  bool LLLayoutStack::animatePanels()  { -	bool animation_in_progress = false; +	bool continue_animating = false;  	//  	// animate visibility @@ -577,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;  				}  			}  		} @@ -601,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;  				}  			}  		} @@ -616,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 ) diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index d32caec5f9..648cd5fdce 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -155,6 +155,8 @@ public:  	void setVisible(BOOL visible);  	S32 getLayoutDim() const; +	S32 getTargetDim() const; +	void setTargetDim(S32 value);  	S32 getMinDim() const { return llmax(0, mMinDim); }  	void setMinDim(S32 value) { mMinDim = value; } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 7e84814c51..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() diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 20bed050ad..9b7e30bb04 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -389,10 +389,17 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height  		{  			*show_h_scrollbar = TRUE;  			*visible_height -= scrollbar_size; -			// Note: Do *not* recompute *show_v_scrollbar here because with -			// the (- scrollbar_size) we just did we will always add a vertical scrollbar -			// even if the height of the items is actually less than the visible size. -			// Fear not though: there's enough calcVisibleSize() calls to add a vertical slider later. + +			// 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 && ((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/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/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3409b6817d..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() diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 421166dcd4..54843227b7 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1835,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) @@ -2225,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.rect.height.set(default_rect.getHeight(), false); -			p.rect.paramChanged(p.rect.height, true); +			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); +	} + +	// 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 fd19309a56..1c35349510 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -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. | 
