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
meow-7.2.2
Richard Linden 2012-02-07 22:50:49 -08:00
parent 4e08461f8a
commit f27ea1aff7
7 changed files with 143 additions and 101 deletions

View File

@ -26,9 +26,12 @@
#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
@ -45,12 +48,12 @@ public:
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();
}
@ -61,8 +64,6 @@ public:
};
typedef LLCoord<LL_COORD_TYPE_COMMON> LLCoordCommon;
struct LL_COORD_TYPE_GL
{
typedef S32 value_t;

View File

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

View File

@ -926,7 +926,7 @@ void LLFloater::applyPositioning(LLFloater* other)
setOrigin(mSpecifiedLeft, mSpecifiedBottom);
const LLRect& snap_rect = gFloaterView->getSnapRect();
translate(snap_rect.mLeft, snap_rect.mBottom);
translateIntoRect(snap_rect, FALSE);
translateIntoRect(snap_rect);
}
break;
@ -950,7 +950,7 @@ void LLFloater::applyPositioning(LLFloater* other)
setOrigin(horizontal_offset, vertical_offset - rect_height);
translate(snap_rect.mLeft, snap_rect.mBottom);
translateIntoRect(snap_rect, FALSE);
translateIntoRect(snap_rect);
}
break;
@ -2644,6 +2644,8 @@ void LLFloaterView::refresh()
}
}
const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)
{
if (floater->getParent() != this)
@ -2697,7 +2699,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();
}
@ -3305,12 +3307,79 @@ bool LLCoordFloater::operator==(const LLCoordFloater& other) const
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);
}
}

View File

@ -1616,59 +1616,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_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;
@ -1677,9 +1648,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 +1662,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)
{

View File

@ -370,7 +370,7 @@ 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 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);

View File

@ -436,3 +436,42 @@ BOOL LLWindowManager::isWindowValid(LLWindow *window)
{
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);
}

View File

@ -2560,44 +2560,6 @@ BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordWindow *to)
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;