EXT-1949 - Viewer freezes on resizing IM window
cleaned up some rectangle tracking logic and introduced LLInlineViewSegment param block reviewed by Leylamaster
parent
afb9df7643
commit
bb9fe04b5f
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
Loading...
|
||||
</text_editor>
|
||||
<button
|
||||
follows="left|bottom"
|
||||
follows="right|bottom"
|
||||
height="22"
|
||||
label="Save"
|
||||
label_selected="Save"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue