From e67e9f63c30555467ac6a381e229e45150fb2509 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 14 Aug 2020 01:06:48 +0300
Subject: [PATCH] SL-13293 Fixed reshape behavior for scale change

---
 indra/llui/llcheckboxctrl.cpp    | 30 +++++++++++++++++++++++++++---
 indra/llui/lllayoutstack.cpp     |  2 +-
 indra/llui/lltextbase.cpp        |  2 +-
 indra/llui/lltextbox.cpp         |  4 ++--
 indra/llui/lltextbox.h           |  2 +-
 indra/llui/llview.cpp            |  4 +++-
 indra/newview/llpanellogin.cpp   | 10 ++++++++++
 indra/newview/llpanellogin.h     |  1 +
 indra/newview/llviewerwindow.cpp |  5 +++++
 9 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 6a51c4240b5..08da599ef24 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -187,10 +187,32 @@ void LLCheckBoxCtrl::clear()
 
 void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	S32 label_top = mLabel->getRect().mTop;
-	mLabel->reshapeToFitText();
+    LLRect rect = getRect();
+    S32 delta_width = width - rect.getWidth();
+    S32 delta_height = height - rect.getHeight();
 
-	LLRect label_rect = mLabel->getRect();
+    if (delta_width || delta_height)
+    {
+        // adjust our rectangle
+        rect.mRight = getRect().mLeft + width;
+        rect.mTop = getRect().mBottom + height;
+        setRect(rect);
+    }
+
+    // reshapeToFitText reshapes label to minimal size according to last bounding box
+    // it will work fine in case of decrease of space, but if we get more space or text
+    // becomes longer, label will fail to grow so reinit label's dimentions.
+    
+    static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
+    LLRect label_rect = mLabel->getRect();
+    S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
+    label_rect.mRight = label_rect.mLeft + new_width;
+    mLabel->setRect(label_rect);
+
+	S32 label_top = label_rect.mTop;
+	mLabel->reshapeToFitText(TRUE);
+
+    label_rect = mLabel->getRect();
 	if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN)
 	{
 		// reshapeToFitText uses LLView::reshape() which always reshapes
@@ -210,6 +232,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 		llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
 		llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
 	mButton->setShape(btn_rect);
+
+    updateBoundingRect();
 }
 
 //virtual
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 4aae1e374b7..29a156e9330 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -166,7 +166,7 @@ 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 (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return;
 
 	if (!mIgnoreReshape && mAutoResize == false)
 	{
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 83b851eed26..fc1301351d3 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1148,7 +1148,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask)
 
 void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	if (width != getRect().getWidth() || height != getRect().getHeight())
+	if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape)
 	{
 		bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false;
 
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 0afd32f3327..134afc005b3 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -163,13 +163,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text
 }
 
 
-void LLTextBox::reshapeToFitText()
+void LLTextBox::reshapeToFitText(BOOL called_from_parent)
 {
 	reflow();
 
 	S32 width = getTextPixelWidth();
 	S32 height = getTextPixelHeight();
-	reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE );
+	reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent );
 }
 
 
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 061d2dd23db..c3e3b619125 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -60,7 +60,7 @@ class LLTextBox :
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL );
 
-	void			reshapeToFitText();
+	void			reshapeToFitText(BOOL called_from_parent = FALSE);
 
 	S32				getTextPixelWidth();
 	S32				getTextPixelHeight();
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 593c8b12fc8..4a990cea813 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1387,7 +1387,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
 			S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;
 			S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;
 			viewp->translate( delta_x, delta_y );
-			if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight())
+			if (child_rect.getWidth() != viewp->getRect().getWidth()
+                || child_rect.getHeight() != viewp->getRect().getHeight()
+                || sForceReshape)
 			{
 				viewp->reshape(child_rect.getWidth(), child_rect.getHeight());
 			}
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 70757882d8c..849b75773d5 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -541,6 +541,16 @@ void LLPanelLogin::show(const LLRect &rect,
 	gFocusMgr.setDefaultKeyboardFocus(sInstance);
 }
 
+//static
+void LLPanelLogin::reshapePanel()
+{
+    if (sInstance)
+    {
+        LLRect rect = sInstance->getRect();
+        sInstance->reshape(rect.getWidth(), rect.getHeight());
+    }
+}
+
 //static
 void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
 {
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c9b8e1b6fcf..788c269ffd9 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -54,6 +54,7 @@ class LLPanelLogin:
 	static void show(const LLRect &rect,
 		void (*callback)(S32 option, void* user_data), 
 		void* callback_data);
+	static void reshapePanel();
 
 	static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
 	static void resetFields();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 5dd3270b2e5..c60a67f79d0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2407,6 +2407,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 		// round up when converting coordinates to make sure there are no gaps at edge of window
 		LLView::sForceReshape = display_scale_changed;
 		mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
+        if (display_scale_changed)
+        {
+            // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass()
+            LLPanelLogin::reshapePanel();
+        }
 		LLView::sForceReshape = FALSE;
 
 		// clear font width caches
-- 
GitLab