Commits

Anonymous committed 7ad600b

EXP-1181 WIP as a designer I would like to specify default floater positions using realtive coordinates
fixed build
moved conversion funcs to llwindow.cpp as they work on all platforms
refactored translateintorect to take overlap as parameter

Comments (0)

Files changed (7)

indra/llmath/llcoord.h

 #ifndef LL_LLCOORD_H
 #define LL_LLCOORD_H
 
-struct LL_COORD_TYPE_COMMON 
+struct LLCoordCommon
 {
-	typedef S32 value_t;
+	LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {}
+	LLCoordCommon() : mX(0), mY(0) {}
+	S32 mX;
+	S32 mY;
 };
 
 // A two-dimensional pixel value
 	LLCoord(S32 x, S32 y): mX(x), mY(y)
 	{}
 
-	LLCoord(const LLCoord<LL_COORD_TYPE_COMMON>& other)
+	LLCoord(const LLCoordCommon& other)
 	{
 		COORD_FRAME::convertFromCommon(other);
 	}
 
-	LLCoord<LL_COORD_TYPE_COMMON> convert() const
+	LLCoordCommon convert() const
 	{
 		return COORD_FRAME::convertToCommon();
 	}
 
 };
 
-typedef LLCoord<LL_COORD_TYPE_COMMON> LLCoordCommon;
-
 struct LL_COORD_TYPE_GL 
 {
 	typedef S32 value_t;

indra/llui/llcombobox.cpp

 	}
 	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;

indra/llui/llfloater.cpp

 			setOrigin(mSpecifiedLeft, mSpecifiedBottom);
 			const LLRect& snap_rect = gFloaterView->getSnapRect();
 			translate(snap_rect.mLeft, snap_rect.mBottom);
-			translateIntoRect(snap_rect, FALSE);
+			translateIntoRect(snap_rect);
 		}
 		break;
 
 			setOrigin(horizontal_offset, vertical_offset - rect_height);
 
 			translate(snap_rect.mLeft, snap_rect.mBottom);
-			translateIntoRect(snap_rect, FALSE);
+			translateIntoRect(snap_rect);
 		}
 		break;
 
 	}
 }
 
+const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
+
 void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)
 {
 	if (floater->getParent() != this)
 	}
 
 	// 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();
 	}
 LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
 {
 	const LLCoordFloater& self = static_cast<const LLCoordFloater&>(*this);
-	return LLCoordCommon(self.mX, self.mY);
+
+	LLRect snap_rect = gFloaterView->getSnapRect();
+	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&>(*this);
-	self.mX = from.mX;
-	self.mY = from.mY;
+	LLRect snap_rect = gFloaterView->getSnapRect();
+	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);
+	}
 }

indra/llui/llview.cpp

 }
 
 
-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_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_WIDTH < constraint.mLeft )
 	{
-		const S32 KEEP_ONSCREEN_PIXELS = 16;
+		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.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.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;
 // 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)
 	{
 
 // 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)
 	{

indra/llui/llview.h

 	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			translateIntoRect( const LLRect& constraint, S32 min_overlap_pixels = S32_MAX);
 	BOOL			translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
 	void			centerWithin(const LLRect& bounds);
 

indra/llwindow/llwindow.cpp

 {
 	return sWindowList.find(window) != sWindowList.end();
 }
+
+//coordinate conversion utility funcs that forward to llwindow
+LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
+{
+	const LLCoordWindow& self = static_cast<const LLCoordWindow&>(*this);
+
+	LLWindow* windowp = &(*LLWindow::beginInstances());
+	LLCoordGL out;
+	windowp->convertCoords(self, &out);
+	return out.convert();
+}
+
+void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
+{
+	LLCoordWindow& self = static_cast<LLCoordWindow&>(*this);
+
+	LLWindow* windowp = &(*LLWindow::beginInstances());
+	LLCoordGL from_gl(from);
+	windowp->convertCoords(from_gl, &self);
+}
+
+LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
+{
+	const LLCoordScreen& self = static_cast<const LLCoordScreen&>(*this);
+
+	LLWindow* windowp = &(*LLWindow::beginInstances());
+	LLCoordGL out;
+	windowp->convertCoords(self, &out);
+	return out.convert();
+}
+
+void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from)
+{
+	LLCoordScreen& self = static_cast<LLCoordScreen&>(*this);
+
+	LLWindow* windowp = &(*LLWindow::beginInstances());
+	LLCoordGL from_gl(from);
+	windowp->convertCoords(from_gl, &self);
+}

indra/llwindow/llwindowwin32.cpp

 	return TRUE;
 }
 
-LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
-{
-	const LLCoordWindow& self = static_cast<const LLCoordWindow&>(*this);
-
-	LLWindow* windowp = &(*LLWindow::beginInstances());
-	LLCoordGL out;
-	windowp->convertCoords(self, &out);
-	return out.convert();
-}
-
-void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
-{
-	LLCoordWindow& self = static_cast<LLCoordWindow&>(*this);
-
-	LLWindow* windowp = &(*LLWindow::beginInstances());
-	LLCoordGL from_gl(from);
-	windowp->convertCoords(from_gl, &self);
-}
-
-LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
-{
-	const LLCoordScreen& self = static_cast<const LLCoordScreen&>(*this);
-
-	LLWindow* windowp = &(*LLWindow::beginInstances());
-	LLCoordGL out;
-	windowp->convertCoords(self, &out);
-	return out.convert();
-}
-
-void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from)
-{
-	LLCoordScreen& self = static_cast<LLCoordScreen&>(*this);
-
-	LLWindow* windowp = &(*LLWindow::beginInstances());
-	LLCoordGL from_gl(from);
-	windowp->convertCoords(from_gl, &self);
-}
-
 BOOL LLWindowWin32::convertCoords(LLCoordWindow from, LLCoordGL* to)
 {
 	S32		client_height;