EXT-1949 - Viewer freezes on resizing IM window

cleaned up some rectangle tracking logic and introduced LLInlineViewSegment param block
reviewed by Leyla
master
richard 2009-10-28 11:48:10 -07:00
parent afb9df7643
commit bb9fe04b5f
8 changed files with 71 additions and 72 deletions

View File

@ -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)

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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);

View File

@ -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';

View File

@ -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")
{
}

View File

@ -83,7 +83,7 @@
Loading...
</text_editor>
<button
follows="left|bottom"
follows="right|bottom"
height="22"
label="Save"
label_selected="Save"

View File

@ -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"