summaryrefslogtreecommitdiff
path: root/indra/llui/llaccordionctrltab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llaccordionctrltab.cpp')
-rw-r--r--indra/llui/llaccordionctrltab.cpp54
1 files changed, 48 insertions, 6 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index ac66525030..828bfb289b 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -248,10 +248,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height, bool called_from_parent /* = true */)
{
S32 header_height = mHeaderTextbox->getTextPixelHeight();
+ LLRect old_header_rect = mHeaderTextbox->getRect();
LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2);
- mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
- mHeaderTextbox->setRect(textboxRect);
+ if (old_header_rect.getHeight() != textboxRect.getHeight()
+ || old_header_rect.mLeft != textboxRect.mLeft
+ || old_header_rect.mTop != textboxRect.mTop
+ || old_header_rect.getWidth() > textboxRect.getWidth() // reducing header's width
+ || (old_header_rect.getWidth() < textboxRect.getWidth() && old_header_rect.getWidth() < mHeaderTextbox->getTextPixelWidth()))
+ {
+ // Expensive text reflow
+ // Update if position or height changes
+ // Update if width reduces
+ // But do not update if text already fits and width increases (arguably LLTextBox::reshape should be smarter, not Accordion)
+ mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
+ mHeaderTextbox->setRect(textboxRect);
+ }
if (mHeaderTextbox->getTextPixelWidth() > mHeaderTextbox->getRect().getWidth())
{
@@ -416,8 +428,11 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, bool called_from_parent
LLRect headerRect;
headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT);
- mHeader->setRect(headerRect);
- mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ if (mHeader->getRect() != headerRect)
+ {
+ mHeader->setRect(headerRect);
+ mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ }
if (!mDisplayChildren)
return;
@@ -464,7 +479,34 @@ void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
// Translate to parent coordinatess to check if we are in visible rectangle
rect.translate(getRect().mLeft, getRect().mBottom);
- if (!getRect().contains(rect))
+ bool needs_to_scroll = false;
+ const LLRect &acc_rect = getRect();
+ if (!acc_rect.contains(rect))
+ {
+ if (acc_rect.mTop < rect.mBottom || acc_rect.mBottom > rect.mTop)
+ {
+ // Content fully not in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.getHeight() >= rect.getHeight())
+ {
+ // Content can be displayed fully, but only partially in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.mTop <= rect.mTop || acc_rect.mBottom >= rect.mBottom)
+ {
+ // Intersects, but too big to be displayed fully
+ S32 covered_height = acc_rect.mTop > rect.mTop ? rect.mTop - acc_rect.mBottom : acc_rect.mTop - rect.mBottom;
+ constexpr F32 covered_ratio = 0.7f;
+ if (covered_height < covered_ratio * acc_rect.getHeight())
+ {
+ // Try to show bigger portion of the content
+ needs_to_scroll = true;
+ }
+ }
+ // else too big and in the middle of the view as is
+ }
+ if (needs_to_scroll)
{
// for accordition's scroll, height is in pixels
// Back to local coords and calculate position for scroller
@@ -932,7 +974,7 @@ void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect)
show_hide_scrollbar(child_rect);
updateLayout(child_rect);
}
- else
+ else if (mContainerPanel->getRect() != child_rect)
{
mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight());
mContainerPanel->setRect(child_rect);