From bb9fe04b5fcfdb8f0f386fa4c11bcaed3dd1ddff Mon Sep 17 00:00:00 2001
From: richard <none@none>
Date: Wed, 28 Oct 2009 11:48:10 -0700
Subject: EXT-1949 - Viewer freezes on resizing IM window cleaned up some
 rectangle tracking logic and introduced LLInlineViewSegment param block
 reviewed by Leyla

---
 indra/llui/lltextbase.cpp                          | 89 +++++++++-------------
 indra/llui/lltextbase.h                            | 18 ++++-
 indra/llui/lltexteditor.cpp                        | 11 +--
 indra/llui/lltexteditor.h                          |  2 +-
 indra/newview/llchathistory.cpp                    | 13 +++-
 indra/newview/llchathistory.h                      |  4 +-
 .../default/xui/en/floater_preview_notecard.xml    |  2 +-
 .../skins/default/xui/en/widgets/chat_history.xml  |  4 +-
 8 files changed, 71 insertions(+), 72 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0add3fb500..66ee8f4c1a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -973,7 +973,7 @@ void LLTextBase::draw()
 							: hasFocus() 
 								? mFocusBgColor.get() 
 								: mWriteableBgColor.get();
-		gl_rect_2d(mDocumentView->getRect(), bg_color, TRUE);
+		gl_rect_2d(mTextRect, bg_color, TRUE);
 	}
 
 	// draw document view
@@ -1034,13 +1034,13 @@ S32 LLTextBase::getLeftOffset(S32 width)
 	switch (mHAlign)
 	{
 	case LLFontGL::LEFT:
-		return 0;
+		return mHPad;
 	case LLFontGL::HCENTER:
-		return (mTextRect.getWidth() - width) / 2;
+		return mHPad + (mTextRect.getWidth() - width - mHPad) / 2;
 	case LLFontGL::RIGHT:
 		return mTextRect.getWidth() - width;
 	default:
-		return 0;
+		return mHPad;
 	}
 }
 
@@ -1048,8 +1048,6 @@ S32 LLTextBase::getLeftOffset(S32 width)
 static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow");
 void LLTextBase::reflow(S32 start_index)
 {
-	if (!mReflowNeeded) return;
-
 	LLFastTimer ft(FTM_TEXT_REFLOW);
 
 	updateSegments();
@@ -1078,7 +1076,7 @@ void LLTextBase::reflow(S32 start_index)
 		segment_set_t::iterator seg_iter = mSegments.begin();
 		S32 seg_offset = 0;
 		S32 line_start_index = 0;
-		const S32 text_width = mTextRect.getWidth();  // optionally reserve room for margin
+		const S32 text_width = mTextRect.getWidth() - mHPad;  // reserve room for margin
 		S32 remaining_pixels = text_width;
 		LLWString text(getWText());
 		S32 line_count = 0;
@@ -2037,7 +2035,6 @@ void LLTextBase::updateRects()
 	}
 	else
 	{
-
 		mContentsRect = mLineInfoList.begin()->mRect;
 		for (line_list_t::const_iterator line_iter = ++mLineInfoList.begin();
 			line_iter != mLineInfoList.end();
@@ -2046,13 +2043,30 @@ void LLTextBase::updateRects()
 			mContentsRect.unionWith(line_iter->mRect);
 		}
 
-		mContentsRect.mRight += mHPad;
+		mContentsRect.mLeft = 0;
 		mContentsRect.mTop += mVPad;
-		// get around rounding errors when clipping text against rectangle
-		mContentsRect.stretch(1);
+
+		S32 delta_pos = -mContentsRect.mBottom;
+		// move line segments to fit new document rect
+		for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
+		{
+			it->mRect.translate(0, delta_pos);
+		}
+		mContentsRect.translate(0, delta_pos);
 	}
 
+	// update document container dimensions according to text contents
+	LLRect doc_rect = mContentsRect;
+	// use old mTextRect constraint document to width of viewable region
+	LLRect scroll_rect = mTextRect;
+	// doc_rect.mLeft should be 0
+	doc_rect.mRight = doc_rect.mLeft + scroll_rect.getWidth();
 
+	mDocumentView->setShape(doc_rect);
+
+	//update mTextRect *after* mDocumentView has been resized
+	// so that scrollbars are added if document needs to scroll
+	// since mTextRect does not include scrollbars
 	LLRect old_text_rect = mTextRect;
 	mTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();
 	//FIXME: replace border with image?
@@ -2060,43 +2074,10 @@ void LLTextBase::updateRects()
 	{
 		mTextRect.stretch(-1);
 	}
-	mTextRect.mLeft += mHPad;
-	mTextRect.mTop -= mVPad;
 	if (mTextRect != old_text_rect)
 	{
 		needsReflow();
 	}
-
-	// change document rect size too
-	LLRect document_rect;
-	if (mScroller)
-	{
-		// document is size of scroller or size of text contents, whichever is larger
-		document_rect.setOriginAndSize(0, 0, 
-									mScroller->getContentWindowRect().getWidth(), 
-									llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight()));
-	}
-	else
-	{
-		// document size is just extents of reflowed text, reset to origin 0,0
-		document_rect.set(0, 
-						getLocalRect().getHeight(), 
-						getLocalRect().getWidth(), 
-						llmin(0, getLocalRect().getHeight() - mContentsRect.getHeight()));
-	}
-	mDocumentView->setShape(document_rect);
-
-	// after making document big enough to hold all the text, move the text to fit in the document
-	if (!mLineInfoList.empty())
-	{
-		S32 delta_pos = mDocumentView->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad;
-		// move line segments to fit new document rect
-		for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
-		{
-			it->mRect.translate(0, delta_pos);
-		}
-		mContentsRect.translate(0, delta_pos);
-	}
 }
 
 
@@ -2442,12 +2423,14 @@ void LLNormalTextSegment::dump() const
 // LLInlineViewSegment
 //
 
-LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line, S32 hpad, S32 vpad)
+LLInlineViewSegment::LLInlineViewSegment(const Params& p, S32 start, S32 end)
 :	LLTextSegment(start, end),
-	mView(view),
-	mForceNewLine(force_new_line),
-	mHPad(hpad), // one sided padding (applied to left and right)
-	mVPad(vpad)
+	mView(p.view),
+	mForceNewLine(p.force_newline),
+	mLeftPad(p.left_pad),
+	mRightPad(p.right_pad),
+	mTopPad(p.top_pad),
+	mBottomPad(p.bottom_pad)
 {
 } 
 
@@ -2467,8 +2450,8 @@ void	LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 	}
 	else
 	{
-		width = mHPad * 2 + mView->getRect().getWidth();
-		height = mVPad * 2 + mView->getRect().getHeight();
+		width = mLeftPad + mRightPad + mView->getRect().getWidth();
+		height = mBottomPad + mTopPad + mView->getRect().getHeight();
 	}
 }
 
@@ -2491,14 +2474,14 @@ S32	LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 void LLInlineViewSegment::updateLayout(const LLTextBase& editor)
 {
 	LLRect start_rect = editor.getDocRectFromDocIndex(mStart);
-	mView->setOrigin(start_rect.mLeft + mHPad, start_rect.mBottom + mVPad);
+	mView->setOrigin(start_rect.mLeft + mLeftPad, start_rect.mBottom + mBottomPad);
 }
 
 F32	LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
 {
 	// return padded width of widget
 	// widget is actually drawn during mDocumentView's draw()
-	return (F32)(draw_rect.mLeft + mView->getRect().getWidth() + mHPad * 2);
+	return (F32)(draw_rect.mLeft + mView->getRect().getWidth() + mLeftPad + mRightPad);
 }
 
 void LLInlineViewSegment::unlinkFromDocument(LLTextBase* editor)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index d0787f001e..14fd786127 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -459,7 +459,17 @@ public:
 class LLInlineViewSegment : public LLTextSegment
 {
 public:
-	LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line, S32 hpad = 0, S32 vpad = 0);
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Mandatory<LLView*>		view;
+		Optional<bool>			force_newline;
+		Optional<S32>			left_pad,
+								right_pad,
+								bottom_pad,
+								top_pad;
+	};
+
+	LLInlineViewSegment(const Params& p, S32 start, S32 end);
 	~LLInlineViewSegment();
 	/*virtual*/ void		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
@@ -470,8 +480,10 @@ public:
 	/*virtual*/ void		linkToDocument(class LLTextBase* editor);
 
 private:
-	S32 mHPad;
-	S32 mVPad;
+	S32 mLeftPad;
+	S32 mRightPad;
+	S32 mTopPad;
+	S32 mBottomPad;
 	LLView* mView;
 	bool	mForceNewLine;
 };
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 570ca4b998..f0238dba49 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2307,7 +2307,7 @@ void LLTextEditor::insertText(const std::string &new_text)
 	setEnabled( enabled );
 }
 
-void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_new_line, S32 hpad, S32 vpad)
+void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo)
 {
 	// Save old state
 	S32 selection_start = mSelectionStart;
@@ -2321,12 +2321,9 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text,
 
 	setCursorPos(old_length);
 
-	LLWString widget_wide_text;
+	LLWString widget_wide_text = utf8str_to_wstring(text);
 
-	// Add carriage return if not first line
-	widget_wide_text = utf8str_to_wstring(widget_text);
-
-	LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size(), force_new_line, hpad, vpad);
+	LLTextSegmentPtr segment = new LLInlineViewSegment(params, old_length, old_length + widget_wide_text.size());
 	insert(getLength(), widget_wide_text, FALSE, segment);
 
 	needsReflow();
@@ -2349,7 +2346,7 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text,
 		setCursorPos(cursor_pos);
 	}
 
-	if( !allow_undo )
+	if (!allow_undo)
 	{
 		blockUndo();
 	}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 4847f4d117..10fc94dedc 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -166,7 +166,7 @@ public:
 	// inserts text at cursor
 	void			insertText(const std::string &text);
 
-	void			appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_newline, S32 hpad, S32 vpad);
+	void			appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
 	// Non-undoable
 	void			setText(const LLStringExplicit &utf8str);
 
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 94058365be..fbb57e35f4 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,7 +48,7 @@ mMessageSeparatorFilename(p.message_separator),
 mLeftTextPad(p.left_text_pad),
 mRightTextPad(p.right_text_pad),
 mLeftWidgetPad(p.left_widget_pad),
-mRightWidgetPad(p.rigth_widget_pad)
+mRightWidgetPad(p.right_widget_pad)
 {
 }
 
@@ -110,12 +110,19 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr
 	}
 	//Prepare the rect for the view
 	LLRect target_rect = getDocumentView()->getRect();
-	target_rect.mLeft += mLeftWidgetPad;
+	// squeeze down the widget by subtracting padding off left and right
+	target_rect.mLeft += mLeftWidgetPad + mHPad;
 	target_rect.mRight -= mRightWidgetPad;
 	view->reshape(target_rect.getWidth(), view->getRect().getHeight());
 	view->setOrigin(target_rect.mLeft, view->getRect().mBottom);
 
-	appendWidget(view, view_text, FALSE, TRUE, mLeftWidgetPad, 0);
+	LLInlineViewSegment::Params p;
+	p.view = view;
+	p.force_newline = true;
+	p.left_pad = mLeftWidgetPad;
+	p.right_pad = mRightWidgetPad;
+
+	appendWidget(p, view_text, false);
 
 	//Append the text message
 	message += '\n';
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index d6eccf896a..69066a0110 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -52,7 +52,7 @@ class LLChatHistory : public LLTextEditor
 			//Widget left padding from the scroll rect
 			Optional<S32>			left_widget_pad;
 			//Widget right padding from the scroll rect
-			Optional<S32>			rigth_widget_pad;
+			Optional<S32>			right_widget_pad;
 
 			Params()
 			:	message_header("message_header"),
@@ -60,7 +60,7 @@ class LLChatHistory : public LLTextEditor
 				left_text_pad("left_text_pad"),
 				right_text_pad("right_text_pad"),
 				left_widget_pad("left_widget_pad"),
-				rigth_widget_pad("rigth_widget_pad")
+				right_widget_pad("right_widget_pad")
 				{
 				}
 
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 8cdafe110a..d2b8455eab 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -83,7 +83,7 @@
         Loading...
     </text_editor>
     <button
-     follows="left|bottom"
+     follows="right|bottom"
      height="22"
      label="Save"
      label_selected="Save"
diff --git a/indra/newview/skins/default/xui/en/widgets/chat_history.xml b/indra/newview/skins/default/xui/en/widgets/chat_history.xml
index b72d59524e..502c396ed8 100644
--- a/indra/newview/skins/default/xui/en/widgets/chat_history.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chat_history.xml
@@ -4,8 +4,8 @@
     message_separator="panel_chat_separator.xml"
     left_text_pad="10"
 	right_text_pad="15"
-    left_widget_pad="5"
-	rigth_widget_pad="10"
+    left_widget_pad="0"
+	right_widget_pad="0"
 	max_length="2147483647"
 	enabled="false"
 	track_bottom="true"
-- 
cgit v1.2.3