summaryrefslogtreecommitdiff
path: root/indra/llui/llpanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llpanel.cpp')
-rw-r--r--indra/llui/llpanel.cpp659
1 files changed, 611 insertions, 48 deletions
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 37feffd4b0..c130214b99 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -31,9 +31,18 @@
#include "llviewborder.h"
#include "llbutton.h"
+// LLLayoutStack
+#include "llgl.h"
+#include "llglheaders.h"
+#include "llresizebar.h"
+#include "llcriticaldamp.h"
+
LLPanel::panel_map_t LLPanel::sPanelMap;
LLPanel::alert_queue_t LLPanel::sAlertQueue;
+const S32 RESIZE_BAR_OVERLAP = 1;
+const S32 PANEL_STACK_GAP = RESIZE_BAR_HEIGHT;
+
void LLPanel::init()
{
// mRectControl
@@ -99,13 +108,16 @@ void LLPanel::addBorder(LLViewBorder::EBevel border_bevel,
addChild( mBorder );
}
+void LLPanel::removeBorder()
+{
+ delete mBorder;
+ mBorder = NULL;
+}
+
LLPanel::~LLPanel()
{
- if( !mRectControl.empty() )
- {
- LLUI::sConfigGroup->setRect( mRectControl, mRect );
- }
+ storeRectControl();
sPanelMap.erase(mViewHandle);
}
@@ -159,44 +171,41 @@ void LLPanel::setCtrlsEnabled( BOOL b )
void LLPanel::draw()
{
- if( getVisible() )
+ // draw background
+ if( mBgVisible )
{
- // draw background
- if( mBgVisible )
- {
- //RN: I don't see the point of this
- S32 left = 0;//LLPANEL_BORDER_WIDTH;
- S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH;
- S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH;
- S32 bottom = 0;//LLPANEL_BORDER_WIDTH;
+ //RN: I don't see the point of this
+ S32 left = 0;//LLPANEL_BORDER_WIDTH;
+ S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH;
+ S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH;
+ S32 bottom = 0;//LLPANEL_BORDER_WIDTH;
- if (mBgOpaque )
- {
- gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
- }
- else
- {
- gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
- }
+ if (mBgOpaque )
+ {
+ gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
}
-
- if( mDefaultBtn)
+ else
{
- if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
- {
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn();
- // only enable default button when current focus is not a return-capturing button
- mDefaultBtn->setBorderEnabled(!focus_is_child_button);
- }
- else
- {
- mDefaultBtn->setBorderEnabled(FALSE);
- }
+ gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
}
+ }
- LLView::draw();
+ if( mDefaultBtn)
+ {
+ if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
+ {
+ LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn();
+ // only enable default button when current focus is not a return-capturing button
+ mDefaultBtn->setBorderEnabled(!focus_is_child_button);
+ }
+ else
+ {
+ mDefaultBtn->setBorderEnabled(FALSE);
+ }
}
+
+ LLView::draw();
}
void LLPanel::refresh()
@@ -552,7 +561,7 @@ LLXMLNodePtr LLPanel::getXML(bool save_children) const
return node;
}
-LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parentp, LLUICtrlFactory *factory)
+LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *factory)
{
LLString name("panel");
node->getAttributeString("name", name);
@@ -561,11 +570,21 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parentp, LLUICtrlFactory *fa
// Fall back on a default panel, if there was no special factory.
if (!panelp)
{
- panelp = new LLPanel("tab panel");
+ LLRect rect;
+ createRect(node, rect, parent, LLRect());
+ panelp = new LLPanel(name, rect);
+ panelp->initPanelXML(node, parent, factory);
+ // preserve panel's width and height, but override the location
+ const LLRect& panelrect = panelp->getRect();
+ S32 w = panelrect.getWidth();
+ S32 h = panelrect.getHeight();
+ rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
+ panelp->setRect(rect);
+ }
+ else
+ {
+ panelp->initPanelXML(node, parent, factory);
}
-
- panelp->initPanelXML(node, parentp, factory);
-
return panelp;
}
@@ -577,11 +596,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
setPanelParameters(node, parent);
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- factory->createWidget(this, child);
- }
+ initChildrenXML(node, factory);
LLString xml_filename;
node->getAttributeString("filename", xml_filename);
@@ -590,8 +605,16 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
if (!xml_filename.empty())
{
+ // Preserve postion of embedded panel but allow panel to dictate width/height
+ LLRect rect(getRect());
didPost = factory->buildPanel(this, xml_filename, NULL);
- } else {
+ S32 w = getRect().getWidth();
+ S32 h = getRect().getHeight();
+ rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
+ setRect(rect);
+ }
+ else
+ {
didPost = FALSE;
}
@@ -604,10 +627,32 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
return didPost;
}
-void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp)
+void LLPanel::initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory)
+{
+ LLXMLNodePtr child;
+ for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ {
+ // look for string declarations for programmatic text
+ if (child->hasName("string"))
+ {
+ LLString string_name;
+ child->getAttributeString("name", string_name);
+ if (!string_name.empty())
+ {
+ mUIStrings[string_name] = LLUIString(child->getTextContents());
+ }
+ }
+ else
+ {
+ factory->createWidget(this, child);
+ }
+ }
+}
+
+void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent)
{
/////// Rect, follows, tool_tip, enabled, visible attributes ///////
- initFromXML(node, parentp);
+ initFromXML(node, parent);
/////// Border attributes ///////
BOOL border = FALSE;
@@ -632,6 +677,10 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp)
addBorder(bevel_style, border_style, border_thickness);
}
+ else
+ {
+ removeBorder();
+ }
/////// Background attributes ///////
BOOL background_visible = FALSE;
@@ -656,6 +705,30 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp)
setLabel(label);
}
+LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::format_map_t& args) const
+{
+ ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
+ if (found_it != mUIStrings.end())
+ {
+ // make a copy as format works in place
+ LLUIString formatted_string = found_it->second;
+ formatted_string.setArgList(args);
+ return formatted_string.getString();
+ }
+ return LLString::null;
+}
+
+LLUIString LLPanel::getUIString(const LLString& name) const
+{
+ ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
+ if (found_it != mUIStrings.end())
+ {
+ return found_it->second;
+ }
+ return LLUIString(LLString::null);
+}
+
+
void LLPanel::childSetVisible(const LLString& id, bool visible)
{
LLView* child = getChildByName(id, true);
@@ -1045,3 +1118,493 @@ void LLPanel::childDisplayNotFound()
LLAlertDialog::showXml("FloaterNotFound", args);
}
+void LLPanel::storeRectControl()
+{
+ if( !mRectControl.empty() )
+ {
+ LLUI::sConfigGroup->setRect( mRectControl, mRect );
+ }
+}
+
+
+//
+// LLLayoutStack
+//
+struct LLLayoutStack::LLEmbeddedPanel
+{
+ LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize) :
+ mPanel(panelp),
+ mMinWidth(min_width),
+ mMinHeight(min_height),
+ mAutoResize(auto_resize),
+ mOrientation(orientation),
+ mVisibleAmt(1.f) // default to fully visible
+ {
+ LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
+ LLRect resize_bar_rect = panelp->getRect();
+
+ S32 min_dim;
+ if (orientation == HORIZONTAL)
+ {
+ min_dim = mMinHeight;
+ }
+ else
+ {
+ min_dim = mMinWidth;
+ }
+ mResizeBar = new LLResizeBar("resizer", mPanel, LLRect(), min_dim, S32_MAX, side);
+ mResizeBar->setEnableSnapping(FALSE);
+ // panels initialized as hidden should not start out partially visible
+ if (!mPanel->getVisible())
+ {
+ mVisibleAmt = 0.f;
+ }
+ }
+
+ LLPanel* mPanel;
+ S32 mMinWidth;
+ S32 mMinHeight;
+ BOOL mAutoResize;
+ LLResizeBar* mResizeBar;
+ eLayoutOrientation mOrientation;
+ F32 mVisibleAmt;
+};
+
+LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
+ mOrientation(orientation),
+ mMinWidth(0),
+ mMinHeight(0)
+{
+}
+
+LLLayoutStack::~LLLayoutStack()
+{
+}
+
+void LLLayoutStack::draw()
+{
+ updateLayout();
+ {
+ // clip if outside nominal bounds
+ LLLocalClipRect clip(getLocalRect(), mRect.getWidth() > mMinWidth || mRect.getHeight() > mMinHeight);
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLRect clip_rect = (*panel_it)->mPanel->getRect();
+ // scale clipping rectangle by visible amount
+ if (mOrientation == HORIZONTAL)
+ {
+ clip_rect.mRight = clip_rect.mLeft + llround(clip_rect.getWidth() * (*panel_it)->mVisibleAmt);
+ }
+ else
+ {
+ clip_rect.mBottom = clip_rect.mTop - llround(clip_rect.getHeight() * (*panel_it)->mVisibleAmt);
+ }
+ LLLocalClipRect clip(clip_rect, (*panel_it)->mVisibleAmt < 1.f);
+ // only force drawing invisible children if visible amount is non-zero
+ drawChild((*panel_it)->mPanel, 0, 0, (*panel_it)->mVisibleAmt > 0.f);
+ }
+ }
+}
+
+void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
+{
+ LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl);
+
+ if (embedded_panelp)
+ {
+ mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
+ delete embedded_panelp;
+ }
+
+ calcMinExtents();
+
+ LLView::removeCtrl(ctrl);
+}
+
+void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLView::reshape(width, height, called_from_parent);
+ //updateLayout();
+}
+
+LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const
+{
+ LLXMLNodePtr node = LLView::getXML();
+ return node;
+}
+
+//static
+LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+{
+ LLString orientation_string("vertical");
+ node->getAttributeString("orientation", orientation_string);
+
+ eLayoutOrientation orientation = VERTICAL;
+
+ if (orientation_string == "horizontal")
+ {
+ orientation = HORIZONTAL;
+ }
+ else if (orientation_string == "vertical")
+ {
+ orientation = VERTICAL;
+ }
+ else
+ {
+ llwarns << "Unknown orientation " << orientation_string << ", using vertical" << llendl;
+ }
+
+ LLLayoutStack* layout_stackp = new LLLayoutStack(orientation);
+
+ layout_stackp->initFromXML(node, parent);
+
+ LLXMLNodePtr child;
+ for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ {
+ if (child->hasName("layout_panel"))
+ {
+ S32 min_width = 0;
+ S32 min_height = 0;
+ BOOL auto_resize = TRUE;
+
+ child->getAttributeS32("min_width", min_width);
+ child->getAttributeS32("min_height", min_height);
+ child->getAttributeBOOL("auto_resize", auto_resize);
+
+ LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
+ panelp->setFollowsNone();
+ if (panelp)
+ {
+ layout_stackp->addPanel(panelp, min_width, min_height, auto_resize);
+ }
+ }
+ }
+
+ return layout_stackp;
+}
+
+S32 LLLayoutStack::getMinWidth()
+{
+ return mMinWidth;
+}
+
+S32 LLLayoutStack::getMinHeight()
+{
+ return mMinHeight;
+}
+
+void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index)
+{
+ LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize);
+
+ mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
+ addChild(panel);
+ addChild(embedded_panel->mResizeBar);
+
+ // bring all resize bars to the front so that they are clickable even over the panels
+ // with a bit of overlap
+ for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ e_panel_list_t::iterator next_it = panel_it;
+ ++next_it;
+
+ LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
+ sendChildToFront(resize_barp);
+ // last resize bar is disabled, since its not between any two panels
+ if ( next_it == mPanels.end() )
+ {
+ resize_barp->setEnabled(FALSE);
+ }
+ else
+ {
+ resize_barp->setEnabled(TRUE);
+ }
+ }
+
+ //updateLayout();
+}
+
+void LLLayoutStack::removePanel(LLPanel* panel)
+{
+ removeChild(panel);
+ //updateLayout();
+}
+
+void LLLayoutStack::updateLayout(BOOL force_resize)
+{
+ calcMinExtents();
+
+ // calculate current extents
+ S32 cur_width = 0;
+ S32 cur_height = 0;
+
+ const F32 ANIM_OPEN_TIME = 0.02f;
+ const F32 ANIM_CLOSE_TIME = 0.02f;
+
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+ if (panelp->getVisible())
+ {
+ (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
+ if ((*panel_it)->mVisibleAmt > 0.99f)
+ {
+ (*panel_it)->mVisibleAmt = 1.f;
+ }
+ }
+ else // not visible
+ {
+ (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+ if ((*panel_it)->mVisibleAmt < 0.001f)
+ {
+ (*panel_it)->mVisibleAmt = 0.f;
+ }
+ }
+ if (mOrientation == HORIZONTAL)
+ {
+ // all panels get expanded to max of all the minimum dimensions
+ cur_height = llmax(mMinHeight, panelp->getRect().getHeight());
+ cur_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
+ if (panel_it != mPanels.end())
+ {
+ cur_width += PANEL_STACK_GAP;
+ }
+ }
+ else //VERTICAL
+ {
+ cur_width = llmax(mMinWidth, panelp->getRect().getWidth());
+ cur_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
+ if (panel_it != mPanels.end())
+ {
+ cur_height += PANEL_STACK_GAP;
+ }
+ }
+ }
+
+ S32 num_resizable_panels = 0;
+ S32 shrink_headroom_available = 0;
+ S32 shrink_headroom_total = 0;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ // panels that are not fully visible do not count towards shrink headroom
+ if ((*panel_it)->mVisibleAmt < 1.f)
+ continue;
+ // if currently resizing a panel or the panel is flagged as not automatically resizing
+ // only track total available headroom, but don't use it for automatic resize logic
+ if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize))
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ }
+ else //VERTICAL
+ {
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ }
+ }
+ else
+ {
+ num_resizable_panels++;
+ if (mOrientation == HORIZONTAL)
+ {
+ shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ }
+ else //VERTICAL
+ {
+ shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ }
+ }
+ }
+
+ // positive means panels need to grow, negative means shrink
+ S32 pixels_to_distribute;
+ if (mOrientation == HORIZONTAL)
+ {
+ pixels_to_distribute = mRect.getWidth() - cur_width;
+ }
+ else //VERTICAL
+ {
+ pixels_to_distribute = mRect.getHeight() - cur_height;
+ }
+
+ S32 cur_x = 0;
+ S32 cur_y = mRect.getHeight();
+
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+
+ S32 cur_width = panelp->getRect().getWidth();
+ S32 cur_height = panelp->getRect().getHeight();
+ S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
+ S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
+
+ S32 delta_size = 0;
+
+ // if panel can automatically resize (not animating, and resize flag set)...
+ if ((*panel_it)->mVisibleAmt == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture())
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ // if we're shrinking
+ if (pixels_to_distribute < 0)
+ {
+ // shrink proportionally to amount over minimum
+ delta_size = llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available);
+ }
+ else
+ {
+ // grow all elements equally
+ delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
+ }
+ new_width = llmax((*panel_it)->mMinWidth, panelp->getRect().getWidth() + delta_size);
+ }
+ else
+ {
+ new_width = llmax(mMinWidth, mRect.getWidth());
+ }
+
+ if (mOrientation == VERTICAL)
+ {
+ if (pixels_to_distribute < 0)
+ {
+ // shrink proportionally to amount over minimum
+ delta_size = llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available);
+ }
+ else
+ {
+ delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
+ }
+ new_height = llmax((*panel_it)->mMinHeight, panelp->getRect().getHeight() + delta_size);
+ }
+ else
+ {
+ new_height = llmax(mMinHeight, mRect.getHeight());
+ }
+ }
+ else // don't resize
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ new_height = llmax(mMinHeight, mRect.getHeight());
+ }
+ else // VERTICAL
+ {
+ new_width = llmax(mMinWidth, mRect.getWidth());
+ }
+ }
+
+ // adjust running headroom count based on new sizes
+ shrink_headroom_total += delta_size;
+
+ panelp->reshape(new_width, new_height);
+ panelp->setOrigin(cur_x, cur_y - new_height);
+
+ LLRect panel_rect = panelp->getRect();
+ LLRect resize_bar_rect = panel_rect;
+ if (mOrientation == HORIZONTAL)
+ {
+ resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP;
+ resize_bar_rect.mRight = panel_rect.mRight + PANEL_STACK_GAP + RESIZE_BAR_OVERLAP;
+ }
+ else
+ {
+ resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP;
+ resize_bar_rect.mBottom = panel_rect.mBottom - PANEL_STACK_GAP - RESIZE_BAR_OVERLAP;
+ }
+ (*panel_it)->mResizeBar->setRect(resize_bar_rect);
+
+ if (mOrientation == HORIZONTAL)
+ {
+ cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
+ }
+ else //VERTICAL
+ {
+ cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
+ }
+ }
+
+ // update resize bars with new limits
+ LLResizeBar* last_resize_bar = NULL;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+
+ if (mOrientation == HORIZONTAL)
+ {
+ (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinWidth, (*panel_it)->mMinWidth + shrink_headroom_total);
+ }
+ else //VERTICAL
+ {
+ (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinHeight, (*panel_it)->mMinHeight + shrink_headroom_total);
+ }
+ // hide resize bars for invisible panels
+ (*panel_it)->mResizeBar->setVisible(panelp->getVisible());
+ if (panelp->getVisible())
+ {
+ last_resize_bar = (*panel_it)->mResizeBar;
+ }
+ }
+
+ // hide last resize bar as there is nothing past it
+ if (last_resize_bar)
+ {
+ last_resize_bar->setVisible(FALSE);
+ }
+
+ // not enough room to fit existing contents
+ if (!force_resize &&
+ ((cur_y != -PANEL_STACK_GAP) || (cur_x != mRect.getWidth() + PANEL_STACK_GAP)))
+ {
+ // do another layout pass with all stacked elements contributing
+ // even those that don't usually resize
+ llassert_always(force_resize == FALSE);
+ updateLayout(TRUE);
+ }
+}
+
+LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp)
+{
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ if ((*panel_it)->mPanel == panelp)
+ {
+ return *panel_it;
+ }
+ }
+ return NULL;
+}
+
+void LLLayoutStack::calcMinExtents()
+{
+ mMinWidth = 0;
+ mMinHeight = 0;
+
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ mMinHeight = llmax(mMinHeight, (*panel_it)->mMinHeight);
+ mMinWidth += (*panel_it)->mMinWidth;
+ if (panel_it != mPanels.begin())
+ {
+ mMinWidth += PANEL_STACK_GAP;
+ }
+ }
+ else //VERTICAL
+ {
+ mMinWidth = llmax(mMinWidth, (*panel_it)->mMinWidth);
+ mMinHeight += (*panel_it)->mMinHeight;
+ if (panel_it != mPanels.begin())
+ {
+ mMinHeight += PANEL_STACK_GAP;
+ }
+ }
+ }
+}