From cd4204b2730350eede126190814621b65308c422 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 16 Jan 2012 11:03:33 -0800 Subject: EXP-1758 WIP Progress spinner not shown during merketplace synch if Merchant Outbox floater was previously minimized rewrote layout_stack resizing logic to be symmetrical --- indra/llui/lllayoutstack.cpp | 784 +++++++++++++++++++++++++------------------ 1 file changed, 463 insertions(+), 321 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 0e7060e22c..b67030dc34 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -34,10 +34,13 @@ #include "llpanel.h" #include "llresizebar.h" #include "llcriticaldamp.h" +#include "boost/foreach.hpp" static LLDefaultChildRegistry::Register register_layout_stack("layout_stack"); static LLLayoutStack::LayoutStackRegistry::Register register_layout_panel("layout_panel"); +static const F32 MAX_FRACTIONAL_VALUE = 0.99999f; + void LLLayoutStack::OrientationNames::declareValues() { declare("horizontal", HORIZONTAL); @@ -49,15 +52,12 @@ void LLLayoutStack::OrientationNames::declareValues() // LLLayoutPanel::Params::Params() : expanded_min_dim("expanded_min_dim", 0), - min_dim("min_dim", 0), - max_dim("max_dim", S32_MAX), - user_resize("user_resize", true), + min_dim("min_dim", -1), + user_resize("user_resize", false), auto_resize("auto_resize", true) { addSynonym(min_dim, "min_width"); addSynonym(min_dim, "min_height"); - addSynonym(max_dim, "max_width"); - addSynonym(max_dim, "max_height"); } LLLayoutPanel::LLLayoutPanel(const Params& p) @@ -65,7 +65,6 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mExpandedMinDimSpecified(false), mExpandedMinDim(p.min_dim), mMinDim(p.min_dim), - mMaxDim(p.max_dim), mAutoResize(p.auto_resize), mUserResize(p.user_resize), mCollapsed(FALSE), @@ -73,6 +72,8 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mVisibleAmt(1.f), // default to fully visible mResizeBar(NULL), mFractionalSize(0.f), + mTargetDim(0), + mIgnoreReshape(false), mOrientation(LLLayoutStack::HORIZONTAL) { // Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value @@ -103,33 +104,85 @@ LLLayoutPanel::~LLLayoutPanel() mResizeBar = NULL; } -void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent) +F32 LLLayoutPanel::getAutoResizeFactor() const +{ + return mVisibleAmt * (1.f - mCollapseAmt); +} + +F32 LLLayoutPanel::getVisibleAmount() const +{ + return mVisibleAmt; +} + +S32 LLLayoutPanel::getLayoutDim() const +{ + return llround((mOrientation == LLLayoutStack::HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight()); +} + +S32 LLLayoutPanel::getVisibleDim() const +{ + F32 min_dim = getRelevantMinDim(); + return llround(mVisibleAmt + * (min_dim + + (((F32)mTargetDim - min_dim) * (1.f - mCollapseAmt)))); +} + +void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation ) { - if (mOrientation == LLLayoutStack::HORIZONTAL) + mOrientation = orientation; + S32 layout_dim = llround((mOrientation == LLLayoutStack::HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight()); + + if (mMinDim == -1) { - mFractionalSize += width - llround(mFractionalSize); + if (!mAutoResize) + { + setMinDim(layout_dim); + } + else + { + setMinDim(0); + } } - else + + mTargetDim = llmax(layout_dim, getMinDim()); +} + +void LLLayoutPanel::setVisible( BOOL visible ) +{ + if (visible != getVisible()) { - mFractionalSize += height - llround(mFractionalSize); + LLLayoutStack* stackp = dynamic_cast(getParent()); + stackp->mNeedsLayout = true; } - LLPanel::reshape(width, height, called_from_parent); + LLPanel::setVisible(visible); } -F32 LLLayoutPanel::getCollapseFactor() +void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ ) { - if (mOrientation == LLLayoutStack::HORIZONTAL) + if (!mIgnoreReshape && !mAutoResize) { - F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth())); - return mVisibleAmt * collapse_amt; + mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; } - else + LLPanel::reshape(width, height, called_from_parent); +} + +void LLLayoutPanel::handleReshape(const LLRect& new_rect, bool by_user) +{ + LLLayoutStack* stackp = dynamic_cast(getParent()); + if (stackp) { - F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getHeight()))); - return mVisibleAmt * collapse_amt; + stackp->mNeedsLayout = true; + if (by_user) + { + // tell layout stack to account for new shape + stackp->updatePanelRect(this, new_rect); + } } + LLPanel::handleReshape(new_rect, by_user); } // @@ -147,12 +200,11 @@ LLLayoutStack::Params::Params() LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) : LLView(p), - mMinWidth(0), - mMinHeight(0), mPanelSpacing(p.border_size), mOrientation(p.orientation), mAnimate(p.animate), mAnimatedThisFrame(false), + mNeedsLayout(true), mClip(p.clip), mOpenTimeConstant(p.open_time_constant), mCloseTimeConstant(p.close_time_constant) @@ -169,26 +221,26 @@ void LLLayoutStack::draw() { updateLayout(); - e_panel_list_t::iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + // always clip to stack itself + LLLocalClipRect clip(getLocalRect()); + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { // clip to layout rectangle, not bounding rectangle - LLRect clip_rect = (*panel_it)->getRect(); + LLRect clip_rect = panelp->getRect(); // scale clipping rectangle by visible amount if (mOrientation == HORIZONTAL) { - clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor()); + clip_rect.mRight = clip_rect.mLeft + panelp->getVisibleDim(); } else { - clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor()); + clip_rect.mBottom = clip_rect.mTop - panelp->getVisibleDim(); } - LLPanel* panelp = (*panel_it); - - LLLocalClipRect clip(clip_rect, mClip); - // only force drawing invisible children if visible amount is non-zero - drawChild(panelp, 0, 0, !clip_rect.isEmpty()); + {LLLocalClipRect clip(clip_rect, mClip); + // only force drawing invisible children if visible amount is non-zero + drawChild(panelp, 0, 0, !clip_rect.isEmpty()); + } } mAnimatedThisFrame = false; } @@ -201,12 +253,10 @@ void LLLayoutStack::removeChild(LLView* view) { mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp)); delete embedded_panelp; + updateFractionalSizes(); + mNeedsLayout = true; } - // need to update resizebars - - calcMinExtents(); - LLView::removeChild(view); } @@ -221,29 +271,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group) LLLayoutPanel* panelp = dynamic_cast(child); if (panelp) { - panelp->mFractionalSize = (mOrientation == HORIZONTAL) - ? panelp->getRect().getWidth() - : panelp->getRect().getHeight(); panelp->setOrientation(mOrientation); mPanels.push_back(panelp); + createResizeBar(panelp); + mNeedsLayout = true; } - return LLView::addChild(child, tab_group); -} - -void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front) -{ - LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move); - LLLayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel); + BOOL result = LLView::addChild(child, tab_group); - if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel) - { - llwarns << "One of the panels was not found in stack or NULL was passed instead of valid panel" << llendl; - return; - } - e_panel_list_t::iterator it = std::find(mPanels.begin(), mPanels.end(), embedded_panel_to_move); - mPanels.erase(it); - it = move_to_front ? mPanels.begin() : std::find(mPanels.begin(), mPanels.end(), embedded_target_panel); - mPanels.insert(it, embedded_panel_to_move); + updateFractionalSizes(); + return result; } void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate) @@ -258,23 +294,19 @@ void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate) } } -void LLLayoutStack::removePanel(LLPanel* panel) -{ - removeChild(panel); -} - void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) { LLLayoutPanel* panel_container = findEmbeddedPanel(panel); if (!panel_container) return; panel_container->mCollapsed = collapsed; + mNeedsLayout = true; } void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize) { LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); - + if (panel) { panel->mAutoResize = auto_resize; @@ -291,51 +323,246 @@ void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_ } } -bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp) + +static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks"); + +void LLLayoutStack::updateLayout() +{ + LLFastTimer ft(FTM_UPDATE_LAYOUT); + + if (!mNeedsLayout) return; + + bool animation_in_progress = animatePanels(); + F32 total_visible_fraction = 0.f; + S32 space_to_distribute = (mOrientation == HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight(); + + // first, assign minimum dimensions + LLLayoutPanel* panelp = NULL; + BOOST_FOREACH(panelp, mPanels) + { + if (panelp->mAutoResize) + { + panelp->mTargetDim = panelp->getRelevantMinDim(); + } + space_to_distribute -= panelp->getVisibleDim() + llround((F32)mPanelSpacing * panelp->getVisibleAmount()); + total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor(); + } + + llassert(total_visible_fraction < 1.01f); + + // don't need spacing after last panel + space_to_distribute += panelp ? llround((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; + + // scale up space to distribute, since some of might will go to an invisible fraction of the auto-resize space + space_to_distribute = (total_visible_fraction > 0.f) + ? llround((F32)space_to_distribute / total_visible_fraction) + : space_to_distribute; + + if (space_to_distribute > 0) + { // give space proportionally to auto resize panels, even invisible ones + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize == TRUE) + { + S32 delta = llround((F32)space_to_distribute * panelp->mFractionalSize/* * panelp->getAutoResizeFactor()*/); + panelp->mTargetDim += delta; + } + } + } + + F32 cur_pos = (mOrientation == HORIZONTAL) ? 0.f : (F32)getRect().getHeight(); + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + F32 panel_dim = panelp->mTargetDim; + F32 panel_visible_dim = panelp->getVisibleDim(); + + LLRect panel_rect; + if (mOrientation == HORIZONTAL) + { + panel_rect.setLeftTopAndSize(llround(cur_pos), + getRect().getHeight(), + llround(panel_dim), + getRect().getHeight()); + } + else + { + panel_rect.setLeftTopAndSize(0, + llround(cur_pos), + getRect().getWidth(), + llround(panel_dim)); + } + panelp->setIgnoreReshape(true); + panelp->setShape(panel_rect); + panelp->setIgnoreReshape(false); + + static LLUICachedControl resize_bar_overlap ("UIResizeBarOverlap", 0); + LLRect resize_bar_rect(panel_rect); + + F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount(); + if (mOrientation == HORIZONTAL) + { + resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap; + resize_bar_rect.mRight = panel_rect.mRight + panel_spacing + resize_bar_overlap; + + cur_pos += panel_visible_dim + panel_spacing; + } + else //VERTICAL + { + resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap; + resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing - resize_bar_overlap; + + cur_pos -= panel_visible_dim + panel_spacing; + } + panelp->mResizeBar->setShape(resize_bar_rect); + } + + updateResizeBarLimits(); + + // 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; +} // end LLLayoutStack::updateLayout + +LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const +{ + if (!panelp) return NULL; + + e_panel_list_t::const_iterator panel_it; + BOOST_FOREACH(LLLayoutPanel* p, mPanels) + { + if (p == panelp) + { + return p; + } + } + return NULL; +} + +LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const { - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* result = NULL; - if (panel && min_dimp) + BOOST_FOREACH(LLLayoutPanel* p, mPanels) { - *min_dimp = panel->getRelevantMinDim(); + if (p->getName() == name) + { + result = p; + break; + } } - return NULL != panel; + return result; } -bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_dimp) +void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp) { - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); + BOOST_FOREACH(LLLayoutPanel* lp, mPanels) + { + if (lp->mResizeBar == NULL) + { + LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; + LLRect resize_bar_rect = getRect(); - if (panel) + LLResizeBar::Params resize_params; + resize_params.name("resize"); + resize_params.resizing_view(lp); + resize_params.min_size(lp->getRelevantMinDim()); + resize_params.side(side); + resize_params.snapping_enabled(false); + LLResizeBar* resize_bar = LLUICtrlFactory::create(resize_params); + lp->mResizeBar = resize_bar; + LLView::addChild(resize_bar, 0); + } + } + // 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) { - if (max_dimp) *max_dimp = panel->mMaxDim; + LLResizeBar* resize_barp = (*panel_it)->mResizeBar; + sendChildToFront(resize_barp); } +} - return NULL != panel; +// update layout stack animations, etc. once per frame +// NOTE: we use this to size world view based on animating UI, *before* we draw the UI +// we might still need to call updateLayout during UI draw phase, in case UI elements +// are resizing themselves dynamically +//static +void LLLayoutStack::updateClass() +{ + for (instance_iter it = beginInstances(); it != endInstances(); ++it) + { + it->updateLayout(); + } } -static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks"); -void LLLayoutStack::updateLayout(BOOL force_resize) +void LLLayoutStack::updateFractionalSizes() { - LLFastTimer ft(FTM_UPDATE_LAYOUT); - static LLUICachedControl resize_bar_overlap ("UIResizeBarOverlap", 0); - calcMinExtents(); - createResizeBars(); + F32 total_resizable_dim = 0; + S32 num_auto_resize_panels = 0; + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim()); + num_auto_resize_panels++; + } + } - // calculate current extents - F32 total_size = 0.f; + F32 total_fractional_size = 0.f; + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + F32 panel_resizable_dim = llmax(0.f, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim())); + panelp->mFractionalSize = llmin(MAX_FRACTIONAL_VALUE, (panel_resizable_dim == 0.f) + ? (1.f - MAX_FRACTIONAL_VALUE) + : panel_resizable_dim / total_resizable_dim); + total_fractional_size += panelp->mFractionalSize; + // check for NaNs + llassert(panelp->mFractionalSize == panelp->mFractionalSize); + } + } + if (total_fractional_size == 0.f) + { // equal distribution + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + panelp->mFractionalSize = 1.f / (F32)num_auto_resize_panels; + } + } + } + else + { // renormalize + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + panelp->mFractionalSize /= total_fractional_size; + } + } + } +} + +bool LLLayoutStack::animatePanels() +{ + bool animation_in_progress = false; + // // animate visibility // - e_panel_list_t::iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - LLLayoutPanel* panelp = (*panel_it); - if (panelp->getVisible()) + if (panelp->getVisible()) { - if (mAnimate) + if (mAnimate && panelp->mVisibleAmt < 1.f) { if (!mAnimatedThisFrame) { @@ -345,15 +572,21 @@ void LLLayoutStack::updateLayout(BOOL force_resize) panelp->mVisibleAmt = 1.f; } } + + animation_in_progress = true; } else { - panelp->mVisibleAmt = 1.f; + if (panelp->mVisibleAmt != 1.f) + { + panelp->mVisibleAmt = 1.f; + animation_in_progress = true; + } } } else // not visible { - if (mAnimate) + if (mAnimate && panelp->mVisibleAmt > 0.f) { if (!mAnimatedThisFrame) { @@ -363,297 +596,206 @@ void LLLayoutStack::updateLayout(BOOL force_resize) panelp->mVisibleAmt = 0.f; } } + + animation_in_progress = true; } else { - panelp->mVisibleAmt = 0.f; + if (panelp->mVisibleAmt != 0.f) + { + panelp->mVisibleAmt = 0.f; + animation_in_progress = true; + } } } F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f; - panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); - - total_size += panelp->mFractionalSize * panelp->getCollapseFactor(); - // want n-1 panel gaps for n panels - if (panel_it != mPanels.begin()) - { - total_size += mPanelSpacing; - } - } - - S32 num_resizable_panels = 0; - F32 shrink_headroom_available = 0.f; - F32 shrink_headroom_total = 0.f; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - - // panels that are not fully visible do not count towards shrink headroom - if (panelp->getCollapseFactor() < 1.f) - { - continue; - } - - F32 cur_size = panelp->mFractionalSize; - F32 min_size = (F32)panelp->getRelevantMinDim(); - - // 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 (panelp->mResizeBar->hasMouseCapture() - || (!panelp->mAutoResize - && !force_resize)) - { - shrink_headroom_total += cur_size - min_size; - } - else - { - num_resizable_panels++; - - shrink_headroom_available += cur_size - min_size; - shrink_headroom_total += cur_size - min_size; - } - } - - // calculate how many pixels need to be distributed among layout panels - // positive means panels need to grow, negative means shrink - F32 pixels_to_distribute = (mOrientation == HORIZONTAL) - ? getRect().getWidth() - total_size - : getRect().getHeight() - total_size; - - // now we distribute the pixels... - F32 cur_x = 0.f; - F32 cur_y = (F32)getRect().getHeight(); - - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - - F32 min_size = panelp->getRelevantMinDim(); - F32 delta_size = 0.f; - - // if panel can automatically resize (not animating, and resize flag set)... - if (panelp->getCollapseFactor() == 1.f - && (force_resize || panelp->mAutoResize) - && !panelp->mResizeBar->hasMouseCapture()) + if (panelp->mCollapseAmt != collapse_state) { - if (pixels_to_distribute < 0.f) + if (!mAnimatedThisFrame) { - // shrink proportionally to amount over minimum - // so we can do this in one pass - delta_size = (shrink_headroom_available > 0.f) - ? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available) - : 0.f; - shrink_headroom_available -= (panelp->mFractionalSize - min_size); + panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } - else + animation_in_progress = true; + + if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) { - // grow all elements equally - delta_size = pixels_to_distribute / (F32)num_resizable_panels; - num_resizable_panels--; + panelp->mCollapseAmt = collapse_state; } - - panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size); - pixels_to_distribute -= delta_size; } + } - // adjust running headroom count based on new sizes - shrink_headroom_total += delta_size; + mAnimatedThisFrame = true; - LLRect panel_rect; - if (mOrientation == HORIZONTAL) - { - panel_rect.setLeftTopAndSize(llround(cur_x), - llround(cur_y), - llround(panelp->mFractionalSize), - getRect().getHeight()); - } - else - { - panel_rect.setLeftTopAndSize(llround(cur_x), - llround(cur_y), - getRect().getWidth(), - llround(panelp->mFractionalSize)); - } - panelp->setShape(panel_rect); + return animation_in_progress; +} - 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 + mPanelSpacing + resize_bar_overlap; - } - else - { - resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap; - resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - resize_bar_overlap; - } - (*panel_it)->mResizeBar->setRect(resize_bar_rect); +void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& new_rect ) +{ + S32 new_dim = (mOrientation == HORIZONTAL) + ? new_rect.getWidth() + : new_rect.getHeight(); + S32 delta_dim = new_dim - resized_panel->getVisibleDim(); + if (delta_dim == 0) return; - F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing; - if (mOrientation == HORIZONTAL) - { - cur_x += size; - } - else //VERTICAL - { - cur_y -= size; - } - } + F32 total_visible_fraction = 0.f; + F32 delta_auto_resize_headroom = 0.f; + F32 total_auto_resize_headroom = 0.f; - // update resize bars with new limits - LLLayoutPanel* last_resizeable_panel = NULL; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - S32 relevant_min = panelp->getRelevantMinDim(); + LLLayoutPanel* other_resize_panel = NULL; + LLLayoutPanel* following_panel = NULL; - if (mOrientation == HORIZONTAL) + BOOST_REVERSE_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) { - (*panel_it)->mResizeBar->setResizeLimits( - relevant_min, - relevant_min + llround(shrink_headroom_total)); + total_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim()); + total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor(); } - else //VERTICAL + + if (panelp == resized_panel) { - (*panel_it)->mResizeBar->setResizeLimits( - relevant_min, - relevant_min + llround(shrink_headroom_total)); + other_resize_panel = following_panel; } - // toggle resize bars based on panel visibility, resizability, etc - BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize; - (*panel_it)->mResizeBar->setVisible(resize_bar_enabled); - - if ((*panel_it)->mUserResize || (*panel_it)->mAutoResize) + if (panelp->getVisible() && !panelp->mCollapsed) { - last_resizeable_panel = (*panel_it); + following_panel = panelp; } } - // hide last resize bar as there is nothing past it - // resize bars need to be in between two resizable panels - if (last_resizeable_panel) + if (resized_panel->mAutoResize == FALSE) { - last_resizeable_panel->mResizeBar->setVisible(FALSE); + delta_auto_resize_headroom += -delta_dim; } - - // not enough room to fit existing contents - if (force_resize == FALSE - // layout did not complete by reaching target position - && ((mOrientation == VERTICAL && llround(cur_y) != -mPanelSpacing) - || (mOrientation == HORIZONTAL && llround(cur_x) != getRect().getWidth() + mPanelSpacing))) + if (other_resize_panel && other_resize_panel->mAutoResize == FALSE) { - // do another layout pass with all stacked elements contributing - // even those that don't usually resize - llassert_always(force_resize == FALSE); - updateLayout(TRUE); + delta_auto_resize_headroom += delta_dim; } - mAnimatedThisFrame = true; -} // end LLLayoutStack::updateLayout + //delta_auto_resize_headroom = (total_visible_fraction > 0.f) + // ? delta_auto_resize_headroom / total_visible_fraction + // : 0.f; -LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const -{ - if (!panelp) return NULL; + F32 fraction_given_up = 0.f; + F32 fraction_remaining = 1.f; + F32 updated_auto_resize_headroom = total_auto_resize_headroom + delta_auto_resize_headroom; - e_panel_list_t::const_iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + enum { - if ((*panel_it) == panelp) - { - return *panel_it; - } - } - return NULL; -} - -LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const -{ - LLLayoutPanel* result = NULL; + BEFORE_RESIZED_PANEL, + RESIZED_PANEL, + NEXT_PANEL, + AFTER_RESIZED_PANEL + } which_panel = BEFORE_RESIZED_PANEL; - for (e_panel_list_t::const_iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - LLLayoutPanel* p = *panel_it; + if (!panelp->getVisible() || panelp->mCollapsed) continue; - if (p->getName() == name) + if (panelp == resized_panel) { - result = p; - break; + which_panel = RESIZED_PANEL; } - } - - return result; -} -// Compute sum of min_width or min_height of children -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) + switch(which_panel) { - mMinWidth += (*panel_it)->getRelevantMinDim(); - if (panel_it != mPanels.begin()) + case BEFORE_RESIZED_PANEL: + if (panelp->mAutoResize) + { // freeze current size as fraction of overall auto_resize space + F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom; + F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor, + 0.f, + MAX_FRACTIONAL_VALUE); + F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize); + fraction_given_up -= fraction_delta; + fraction_remaining -= panelp->mFractionalSize; + panelp->mFractionalSize += fraction_delta; + llassert(!llisnan(panelp->mFractionalSize)); + } + else { - mMinWidth += mPanelSpacing; + // leave non auto-resize panels alone } - } - else //VERTICAL - { - mMinHeight += (*panel_it)->getRelevantMinDim(); - if (panel_it != mPanels.begin()) + break; + case RESIZED_PANEL: + if (panelp->mAutoResize) + { // freeze new size as fraction + F32 new_fractional_size = (updated_auto_resize_headroom == 0.f) + ? 1.f + : llmin(MAX_FRACTIONAL_VALUE, ((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom)); + fraction_given_up -= new_fractional_size - panelp->mFractionalSize; + fraction_remaining -= panelp->mFractionalSize; + panelp->mFractionalSize = new_fractional_size; + llassert(!llisnan(panelp->mFractionalSize)); + } + else + { // freeze new size as original size + panelp->mTargetDim = new_dim; + fraction_remaining -= fraction_given_up; + } + which_panel = NEXT_PANEL; + break; + case NEXT_PANEL: + if (panelp->mAutoResize) + { + F32 new_fractional_size = (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) + / updated_auto_resize_headroom; + fraction_given_up -= new_fractional_size - panelp->mFractionalSize; + fraction_remaining -= panelp->mFractionalSize; + panelp->mFractionalSize = new_fractional_size; + } + else + { + panelp->mTargetDim -= delta_dim; + } + which_panel = AFTER_RESIZED_PANEL; + break; + case AFTER_RESIZED_PANEL: + if (panelp->mAutoResize) { - mMinHeight += mPanelSpacing; + panelp->mFractionalSize += (panelp->mFractionalSize / fraction_remaining) * fraction_given_up; } + default: + break; } } } -void LLLayoutStack::createResizeBars() +void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent) { - for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + mNeedsLayout = true; + LLView::reshape(width, height, called_from_parent); +} + +void LLLayoutStack::updateResizeBarLimits() +{ + LLLayoutPanel* previous_visible_panelp = NULL; + BOOST_REVERSE_FOREACH(LLLayoutPanel* visible_panelp, mPanels) { - LLLayoutPanel* lp = (*panel_it); - if (lp->mResizeBar == NULL) + if (!visible_panelp->getVisible() || visible_panelp->mCollapsed) { - LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; - LLRect resize_bar_rect = getRect(); - - LLResizeBar::Params resize_params; - resize_params.name("resize"); - resize_params.resizing_view(lp); - resize_params.min_size(lp->getRelevantMinDim()); - resize_params.side(side); - resize_params.snapping_enabled(false); - LLResizeBar* resize_bar = LLUICtrlFactory::create(resize_params); - lp->mResizeBar = resize_bar; - LLView::addChild(resize_bar, 0); + visible_panelp->mResizeBar->setVisible(FALSE); + continue; + } - // 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) - { - LLResizeBar* resize_barp = (*panel_it)->mResizeBar; - sendChildToFront(resize_barp); - } + // toggle resize bars based on panel visibility, resizability, etc + if (visible_panelp->mUserResize + && previous_visible_panelp + && previous_visible_panelp->mUserResize) + { + visible_panelp->mResizeBar->setVisible(TRUE); + visible_panelp->mResizeBar->setResizeLimits(visible_panelp->getRelevantMinDim(), + visible_panelp->getVisibleDim() + + (previous_visible_panelp->getVisibleDim() + - previous_visible_panelp->getRelevantMinDim())); + } + else + { + visible_panelp->mResizeBar->setVisible(FALSE); } - } -} -// update layout stack animations, etc. once per frame -// NOTE: we use this to size world view based on animating UI, *before* we draw the UI -// we might still need to call updateLayout during UI draw phase, in case UI elements -// are resizing themselves dynamically -//static -void LLLayoutStack::updateClass() -{ - for (instance_iter it = beginInstances(); it != endInstances(); ++it) - { - it->updateLayout(); + previous_visible_panelp = visible_panelp; } } -- cgit v1.2.3 From 7092a07045e0bc17c503c0bc81e3f038bd1516e8 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 16 Jan 2012 14:35:00 -0800 Subject: Fix Mac build issue --- indra/llui/lllayoutstack.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index b67030dc34..a1e8eebb47 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -116,9 +116,9 @@ F32 LLLayoutPanel::getVisibleAmount() const S32 LLLayoutPanel::getLayoutDim() const { - return llround((mOrientation == LLLayoutStack::HORIZONTAL) + return llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL) ? getRect().getWidth() - : getRect().getHeight()); + : getRect().getHeight())); } S32 LLLayoutPanel::getVisibleDim() const @@ -132,9 +132,9 @@ S32 LLLayoutPanel::getVisibleDim() const void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation ) { mOrientation = orientation; - S32 layout_dim = llround((mOrientation == LLLayoutStack::HORIZONTAL) + S32 layout_dim = llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL) ? getRect().getWidth() - : getRect().getHeight()); + : getRect().getHeight())); if (mMinDim == -1) { -- cgit v1.2.3 From 0e7956a4cbdb0772ff6175307475ee6fc8b620ea Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 17 Jan 2012 07:39:14 -0800 Subject: EXP-1758 : Fix crash on login on Mac (bad pointer reference). Might need more work if the intent was to always get that pointer. --- indra/llui/lllayoutstack.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index a1e8eebb47..ac10afe594 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -156,7 +156,10 @@ void LLLayoutPanel::setVisible( BOOL visible ) if (visible != getVisible()) { LLLayoutStack* stackp = dynamic_cast(getParent()); - stackp->mNeedsLayout = true; + if (stackp) + { + stackp->mNeedsLayout = true; + } } LLPanel::setVisible(visible); } -- cgit v1.2.3 From 2589a7e135a9e894eb7bbe0cb1e032c105f72bf8 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 17 Jan 2012 12:17:03 -0800 Subject: fix for crash in assert when programmatically toggling user resize --- indra/llui/lllayoutstack.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index ac10afe594..000f729e29 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -314,6 +314,8 @@ void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL au { panel->mAutoResize = auto_resize; } + + mNeedsLayout = true; } void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize) @@ -324,6 +326,8 @@ void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_ { panel->mUserResize = user_resize; } + + mNeedsLayout = true; } -- cgit v1.2.3 From 1fede65af23248293d4033b8f7557875b499e191 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 17 Jan 2012 16:05:10 -0800 Subject: EXP-1810 FIX Cannot resize Received items panel in Inventory window --- indra/llui/lllayoutstack.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 000f729e29..f7b34bbb38 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -39,8 +39,6 @@ static LLDefaultChildRegistry::Register register_layout_stack("layout_stack"); static LLLayoutStack::LayoutStackRegistry::Register register_layout_panel("layout_panel"); -static const F32 MAX_FRACTIONAL_VALUE = 0.99999f; - void LLLayoutStack::OrientationNames::declareValues() { declare("horizontal", HORIZONTAL); @@ -328,6 +326,7 @@ void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_ } mNeedsLayout = true; + updateFractionalSizes(); } @@ -527,8 +526,8 @@ void LLLayoutStack::updateFractionalSizes() if (panelp->mAutoResize) { F32 panel_resizable_dim = llmax(0.f, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim())); - panelp->mFractionalSize = llmin(MAX_FRACTIONAL_VALUE, (panel_resizable_dim == 0.f) - ? (1.f - MAX_FRACTIONAL_VALUE) + panelp->mFractionalSize = llmin(1.f, (panel_resizable_dim == 0.f) + ? 0.f : panel_resizable_dim / total_resizable_dim); total_fractional_size += panelp->mFractionalSize; // check for NaNs @@ -714,7 +713,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom; F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor, 0.f, - MAX_FRACTIONAL_VALUE); + 1.f); F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize); fraction_given_up -= fraction_delta; fraction_remaining -= panelp->mFractionalSize; @@ -731,7 +730,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& { // freeze new size as fraction F32 new_fractional_size = (updated_auto_resize_headroom == 0.f) ? 1.f - : llmin(MAX_FRACTIONAL_VALUE, ((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom)); + : llmin(1.f, ((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom)); fraction_given_up -= new_fractional_size - panelp->mFractionalSize; fraction_remaining -= panelp->mFractionalSize; panelp->mFractionalSize = new_fractional_size; @@ -747,11 +746,20 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& case NEXT_PANEL: if (panelp->mAutoResize) { - F32 new_fractional_size = (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) - / updated_auto_resize_headroom; - fraction_given_up -= new_fractional_size - panelp->mFractionalSize; fraction_remaining -= panelp->mFractionalSize; - panelp->mFractionalSize = new_fractional_size; + if (fraction_given_up != 0.f) + { + panelp->mFractionalSize += fraction_given_up; + fraction_given_up = 0.f; + } + else + { + F32 new_fractional_size = llmin(1.f, + (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) + / updated_auto_resize_headroom); + fraction_given_up -= new_fractional_size - panelp->mFractionalSize; + panelp->mFractionalSize = new_fractional_size; + } } else { @@ -788,9 +796,9 @@ void LLLayoutStack::updateResizeBarLimits() } // toggle resize bars based on panel visibility, resizability, etc - if (visible_panelp->mUserResize - && previous_visible_panelp - && previous_visible_panelp->mUserResize) + if (previous_visible_panelp + && (visible_panelp->mUserResize + || previous_visible_panelp->mUserResize)) { visible_panelp->mResizeBar->setVisible(TRUE); visible_panelp->mResizeBar->setResizeLimits(visible_panelp->getRelevantMinDim(), -- cgit v1.2.3 From 1eae229cf2470bee506d72ddecbd1305f305670b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 17 Jan 2012 16:28:12 -0800 Subject: EXP-1809 FIX Buttons in right toolbar clipped and can be out of position --- indra/llui/lllayoutstack.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index f7b34bbb38..a309e3ff97 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -167,6 +167,11 @@ void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= if (!mIgnoreReshape && !mAutoResize) { mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; + LLLayoutStack* stackp = dynamic_cast(getParent()); + if (stackp) + { + stackp->mNeedsLayout = true; + } } LLPanel::reshape(width, height, called_from_parent); } -- cgit v1.2.3 From 40687a930c2e37a4da15ff15f004611a734583d7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 18 Jan 2012 12:59:44 -0800 Subject: EXP-1812 FIX Cannot resize location bar / favorites in top navigation bar in viewer --- indra/llui/lllayoutstack.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index a309e3ff97..9909032707 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -201,6 +201,7 @@ LLLayoutStack::Params::Params() clip("clip", true), open_time_constant("open_time_constant", 0.02f), close_time_constant("close_time_constant", 0.03f), + resize_bar_overlap("resize_bar_overlap", 1), border_size("border_size", LLCachedControl(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) {} @@ -213,7 +214,8 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) mNeedsLayout(true), mClip(p.clip), mOpenTimeConstant(p.open_time_constant), - mCloseTimeConstant(p.close_time_constant) + mCloseTimeConstant(p.close_time_constant), + mResizeBarOverlap(p.resize_bar_overlap) {} LLLayoutStack::~LLLayoutStack() @@ -409,21 +411,20 @@ void LLLayoutStack::updateLayout() panelp->setShape(panel_rect); panelp->setIgnoreReshape(false); - static LLUICachedControl resize_bar_overlap ("UIResizeBarOverlap", 0); LLRect resize_bar_rect(panel_rect); F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount(); if (mOrientation == HORIZONTAL) { - resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap; - resize_bar_rect.mRight = panel_rect.mRight + panel_spacing + resize_bar_overlap; + resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap; + resize_bar_rect.mRight = panel_rect.mRight + panel_spacing + mResizeBarOverlap; cur_pos += panel_visible_dim + panel_spacing; } else //VERTICAL { - resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap; - resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing - resize_bar_overlap; + resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap; + resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing - mResizeBarOverlap; cur_pos -= panel_visible_dim + panel_spacing; } -- cgit v1.2.3 From 02641d4ef33fd6f296a9a29700ecdd55ef9dffd8 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 18 Jan 2012 16:32:07 -0800 Subject: Fix a Linux compilation failure --- indra/llui/lllayoutstack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 9909032707..34d13610b7 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -417,14 +417,14 @@ void LLLayoutStack::updateLayout() if (mOrientation == HORIZONTAL) { resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap; - resize_bar_rect.mRight = panel_rect.mRight + panel_spacing + mResizeBarOverlap; + resize_bar_rect.mRight = panel_rect.mRight + (S32)(llround(panel_spacing)) + mResizeBarOverlap; cur_pos += panel_visible_dim + panel_spacing; } else //VERTICAL { resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap; - resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing - mResizeBarOverlap; + resize_bar_rect.mBottom = panel_rect.mBottom - (S32)(llround(panel_spacing)) - mResizeBarOverlap; cur_pos -= panel_visible_dim + panel_spacing; } -- cgit v1.2.3 From a662b888ed02691b7790c23e31c7d8bcf7cf7f5b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Jan 2012 19:40:46 -0800 Subject: EXP-1824 FIX Received Items panel does not collapse correct when Height of panel is maximized in Inventory window --- indra/llui/lllayoutstack.cpp | 120 +++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 55 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 34d13610b7..073592b6ec 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -36,6 +36,9 @@ #include "llcriticaldamp.h" #include "boost/foreach.hpp" +static const F32 MIN_FRACTIONAL_SIZE = 0.0001f; +static const F32 MAX_FRACTIONAL_SIZE = 1.f; + static LLDefaultChildRegistry::Register register_layout_stack("layout_stack"); static LLLayoutStack::LayoutStackRegistry::Register register_layout_panel("layout_panel"); @@ -60,7 +63,6 @@ LLLayoutPanel::Params::Params() LLLayoutPanel::LLLayoutPanel(const Params& p) : LLPanel(p), - mExpandedMinDimSpecified(false), mExpandedMinDim(p.min_dim), mMinDim(p.min_dim), mAutoResize(p.auto_resize), @@ -69,7 +71,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mCollapseAmt(0.f), mVisibleAmt(1.f), // default to fully visible mResizeBar(NULL), - mFractionalSize(0.f), + mFractionalSize(MIN_FRACTIONAL_SIZE), mTargetDim(0), mIgnoreReshape(false), mOrientation(LLLayoutStack::HORIZONTAL) @@ -77,7 +79,6 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) // Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value if (p.expanded_min_dim.isProvided()) { - mExpandedMinDimSpecified = true; mExpandedMinDim = p.expanded_min_dim(); } @@ -134,18 +135,6 @@ void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientatio ? getRect().getWidth() : getRect().getHeight())); - if (mMinDim == -1) - { - if (!mAutoResize) - { - setMinDim(layout_dim); - } - else - { - setMinDim(0); - } - } - mTargetDim = llmax(layout_dim, getMinDim()); } @@ -164,6 +153,8 @@ void LLLayoutPanel::setVisible( BOOL visible ) void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ ) { + if (width == getRect().getWidth() && height == getRect().getHeight()) return; + if (!mIgnoreReshape && !mAutoResize) { mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; @@ -347,6 +338,7 @@ void LLLayoutStack::updateLayout() bool animation_in_progress = animatePanels(); F32 total_visible_fraction = 0.f; + F32 total_open_fraction = 0.f; S32 space_to_distribute = (mOrientation == HORIZONTAL) ? getRect().getWidth() : getRect().getHeight(); @@ -358,9 +350,13 @@ void LLLayoutStack::updateLayout() if (panelp->mAutoResize) { panelp->mTargetDim = panelp->getRelevantMinDim(); + if (!panelp->mCollapsed && panelp->getVisible()) + { + total_open_fraction += panelp->mFractionalSize; + } } space_to_distribute -= panelp->getVisibleDim() + llround((F32)mPanelSpacing * panelp->getVisibleAmount()); - total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor(); + total_visible_fraction += panelp->mFractionalSize; } llassert(total_visible_fraction < 1.01f); @@ -368,28 +364,45 @@ void LLLayoutStack::updateLayout() // don't need spacing after last panel space_to_distribute += panelp ? llround((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; - // scale up space to distribute, since some of might will go to an invisible fraction of the auto-resize space - space_to_distribute = (total_visible_fraction > 0.f) - ? llround((F32)space_to_distribute / total_visible_fraction) - : space_to_distribute; - - if (space_to_distribute > 0) - { // give space proportionally to auto resize panels, even invisible ones + F32 fraction_distributed = 0.f; + if (space_to_distribute > 0 && total_visible_fraction > 0.f) + { // give space proportionally to visible auto resize panels BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { if (panelp->mAutoResize == TRUE) { - S32 delta = llround((F32)space_to_distribute * panelp->mFractionalSize/* * panelp->getAutoResizeFactor()*/); + F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); + S32 delta = llround((F32)space_to_distribute * fraction_to_distribute); + fraction_distributed += fraction_to_distribute; panelp->mTargetDim += delta; } } } + if (fraction_distributed < total_visible_fraction) + { // distribute any left over pixels to non-collapsed, visible panels + F32 fraction_left = total_visible_fraction - fraction_distributed; + S32 space_left = llround((F32)space_to_distribute * (fraction_left / total_visible_fraction)); + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize + && !panelp->mCollapsed + && panelp->getVisible()) + { + S32 space_for_panel = llmax(0, llround((F32)space_left * (panelp->mFractionalSize / total_open_fraction))); + panelp->mTargetDim += space_for_panel; + space_left -= space_for_panel; + total_open_fraction -= panelp->mFractionalSize; + } + } + } + F32 cur_pos = (mOrientation == HORIZONTAL) ? 0.f : (F32)getRect().getHeight(); BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - F32 panel_dim = panelp->mTargetDim; + F32 panel_dim = llmax(panelp->getExpandedMinDim(), panelp->mTargetDim); F32 panel_visible_dim = panelp->getVisibleDim(); LLRect panel_rect; @@ -403,9 +416,9 @@ void LLLayoutStack::updateLayout() else { panel_rect.setLeftTopAndSize(0, - llround(cur_pos), - getRect().getWidth(), - llround(panel_dim)); + llround(cur_pos), + getRect().getWidth(), + llround(panel_dim)); } panelp->setIgnoreReshape(true); panelp->setShape(panel_rect); @@ -531,13 +544,12 @@ void LLLayoutStack::updateFractionalSizes() { if (panelp->mAutoResize) { - F32 panel_resizable_dim = llmax(0.f, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim())); - panelp->mFractionalSize = llmin(1.f, (panel_resizable_dim == 0.f) - ? 0.f - : panel_resizable_dim / total_resizable_dim); + F32 panel_resizable_dim = llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim())); + panelp->mFractionalSize = panel_resizable_dim > 0.f + ? llclamp(panel_resizable_dim / total_resizable_dim, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE) + : MIN_FRACTIONAL_SIZE; total_fractional_size += panelp->mFractionalSize; - // check for NaNs - llassert(panelp->mFractionalSize == panelp->mFractionalSize); + llassert(!llisnan(panelp->mFractionalSize)); } } @@ -547,7 +559,7 @@ void LLLayoutStack::updateFractionalSizes() { if (panelp->mAutoResize) { - panelp->mFractionalSize = 1.f / (F32)num_auto_resize_panels; + panelp->mFractionalSize = MAX_FRACTIONAL_SIZE / (F32)num_auto_resize_panels; } } } @@ -685,11 +697,6 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& delta_auto_resize_headroom += delta_dim; } - - //delta_auto_resize_headroom = (total_visible_fraction > 0.f) - // ? delta_auto_resize_headroom / total_visible_fraction - // : 0.f; - F32 fraction_given_up = 0.f; F32 fraction_remaining = 1.f; F32 updated_auto_resize_headroom = total_auto_resize_headroom + delta_auto_resize_headroom; @@ -718,8 +725,8 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& { // freeze current size as fraction of overall auto_resize space F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom; F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor, - 0.f, - 1.f); + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize); fraction_given_up -= fraction_delta; fraction_remaining -= panelp->mFractionalSize; @@ -735,8 +742,8 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& if (panelp->mAutoResize) { // freeze new size as fraction F32 new_fractional_size = (updated_auto_resize_headroom == 0.f) - ? 1.f - : llmin(1.f, ((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom)); + ? MAX_FRACTIONAL_SIZE + : llclamp((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE); fraction_given_up -= new_fractional_size - panelp->mFractionalSize; fraction_remaining -= panelp->mFractionalSize; panelp->mFractionalSize = new_fractional_size; @@ -755,14 +762,15 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& fraction_remaining -= panelp->mFractionalSize; if (fraction_given_up != 0.f) { - panelp->mFractionalSize += fraction_given_up; + panelp->mFractionalSize = llclamp(panelp->mFractionalSize + fraction_given_up, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE); fraction_given_up = 0.f; } else { - F32 new_fractional_size = llmin(1.f, - (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) - / updated_auto_resize_headroom); + F32 new_fractional_size = llclamp((F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) + / updated_auto_resize_headroom, + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); fraction_given_up -= new_fractional_size - panelp->mFractionalSize; panelp->mFractionalSize = new_fractional_size; } @@ -776,7 +784,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& case AFTER_RESIZED_PANEL: if (panelp->mAutoResize) { - panelp->mFractionalSize += (panelp->mFractionalSize / fraction_remaining) * fraction_given_up; + panelp->mFractionalSize = llclamp(panelp->mFractionalSize + (panelp->mFractionalSize / fraction_remaining) * fraction_given_up, + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); } default: break; @@ -802,15 +812,15 @@ void LLLayoutStack::updateResizeBarLimits() } // toggle resize bars based on panel visibility, resizability, etc - if (previous_visible_panelp - && (visible_panelp->mUserResize - || previous_visible_panelp->mUserResize)) + if (previous_visible_panelp + && (visible_panelp->mUserResize || previous_visible_panelp->mUserResize) // one of the pair is user resizable + && (visible_panelp->mAutoResize || visible_panelp->mUserResize) // current panel is resizable + && (previous_visible_panelp->mAutoResize || previous_visible_panelp->mUserResize)) // previous panel is resizable { visible_panelp->mResizeBar->setVisible(TRUE); + S32 previous_panel_headroom = previous_visible_panelp->getVisibleDim() - previous_visible_panelp->getRelevantMinDim(); visible_panelp->mResizeBar->setResizeLimits(visible_panelp->getRelevantMinDim(), - visible_panelp->getVisibleDim() - + (previous_visible_panelp->getVisibleDim() - - previous_visible_panelp->getRelevantMinDim())); + visible_panelp->getVisibleDim() + previous_panel_headroom); } else { -- cgit v1.2.3 From 29ad432c8bdc3a69c7241de28e217d27b71947d6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Jan 2012 19:52:49 -0800 Subject: made layoutPanels have constant user_resize and auto_resize attributes --- indra/llui/lllayoutstack.cpp | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) (limited to 'indra/llui/lllayoutstack.cpp') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 073592b6ec..2f1c2a47c9 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -63,7 +63,7 @@ LLLayoutPanel::Params::Params() LLLayoutPanel::LLLayoutPanel(const Params& p) : LLPanel(p), - mExpandedMinDim(p.min_dim), + mExpandedMinDim(p.expanded_min_dim.isProvided() ? p.expanded_min_dim : p.min_dim), mMinDim(p.min_dim), mAutoResize(p.auto_resize), mUserResize(p.user_resize), @@ -76,12 +76,6 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mIgnoreReshape(false), mOrientation(LLLayoutStack::HORIZONTAL) { - // Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value - if (p.expanded_min_dim.isProvided()) - { - mExpandedMinDim = p.expanded_min_dim(); - } - // panels initialized as hidden should not start out partially visible if (!getVisible()) { @@ -155,7 +149,7 @@ void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= { if (width == getRect().getWidth() && height == getRect().getHeight()) return; - if (!mIgnoreReshape && !mAutoResize) + if (!mIgnoreReshape && mAutoResize == false) { mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; LLLayoutStack* stackp = dynamic_cast(getParent()); @@ -302,32 +296,6 @@ void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) mNeedsLayout = true; } -void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize) -{ - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); - - if (panel) - { - panel->mAutoResize = auto_resize; - } - - mNeedsLayout = true; -} - -void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize) -{ - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); - - if (panel) - { - panel->mUserResize = user_resize; - } - - mNeedsLayout = true; - updateFractionalSizes(); -} - - static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks"); void LLLayoutStack::updateLayout() @@ -369,7 +337,7 @@ void LLLayoutStack::updateLayout() { // give space proportionally to visible auto resize panels BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - if (panelp->mAutoResize == TRUE) + if (panelp->mAutoResize) { F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); S32 delta = llround((F32)space_to_distribute * fraction_to_distribute); -- cgit v1.2.3