diff options
author | Richard Nelson <richard@lindenlab.com> | 2009-10-21 21:30:40 +0000 |
---|---|---|
committer | Richard Nelson <richard@lindenlab.com> | 2009-10-21 21:30:40 +0000 |
commit | b3d1eb82fadbf3a098abb49d2ef23cade4c6fe95 (patch) | |
tree | 60c0e7fc7897bb9594050262987200027f99cf58 | |
parent | a1770db93600d44fff9d0fa6d9637236a01ba352 (diff) |
fix for chat history layout bugs
EXT-1728 - there is no new line in the text copied on junction of 2 panels
EXT-1670 - fix chat history use of widgets
reviewed by James
-rw-r--r-- | indra/llui/llscrollbar.cpp | 18 | ||||
-rw-r--r-- | indra/llui/llscrollbar.h | 4 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 68 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 5 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 4 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 2 | ||||
-rw-r--r-- | indra/llui/lluictrlfactory.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llchathistory.cpp | 12 |
8 files changed, 73 insertions, 45 deletions
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 0d674528dc..dfd315d451 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -149,7 +149,8 @@ void LLScrollbar::setDocParams( S32 size, S32 pos ) updateThumbRect(); } -void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb) +// returns true if document position really changed +bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb) { pos = llclamp(pos, 0, getDocPosMax()); if (pos != mDocPos) @@ -166,7 +167,9 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb) { updateThumbRect(); } + return true; } + return false; } void LLScrollbar::setDocSize(S32 size) @@ -409,13 +412,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) { - S32 pos = llclamp(mDocPos + clicks * mStepSize, 0, getDocPosMax()); - if (pos != mDocPos) - { - setDocPos(pos, TRUE); - return TRUE; - } - return FALSE; + BOOL handled = changeLine( clicks * mStepSize, TRUE ); + return handled; } BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, @@ -578,9 +576,9 @@ void LLScrollbar::draw() } // end draw -void LLScrollbar::changeLine( S32 delta, BOOL update_thumb ) +bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb ) { - setDocPos(mDocPos + delta, update_thumb); + return setDocPos(mDocPos + delta, update_thumb); } void LLScrollbar::setValue(const LLSD& value) diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 865a1db409..a9f028f9ae 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -109,7 +109,7 @@ public: // How many "lines" the "document" has scrolled. // 0 <= DocPos <= DocSize - DocVisibile - void setDocPos( S32 pos, BOOL update_thumb = TRUE ); + bool setDocPos( S32 pos, BOOL update_thumb = TRUE ); S32 getDocPos() const { return mDocPos; } BOOL isAtBeginning(); @@ -133,7 +133,7 @@ public: private: void updateThumbRect(); - void changeLine(S32 delta, BOOL update_thumb ); + bool changeLine(S32 delta, BOOL update_thumb ); callback_t mChangeCallback; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 1d36a16ea7..22cce755b0 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1825,27 +1825,26 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round return pos; } -LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const +// returns rectangle of insertion caret +// in document coordinate frame from given index into text +LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const { - LLRect local_rect; if (mLineInfoList.empty()) { - local_rect = mTextRect; - local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight()); - return local_rect; + return LLRect(); } + LLRect doc_rect; + // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); - // find line that contains cursor line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - LLRect scrolled_view_rect = getVisibleDocumentRect(); - local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft + line_iter->mRect.mLeft; - local_rect.mBottom = mTextRect.mBottom + (line_iter->mRect.mBottom - scrolled_view_rect.mBottom); - local_rect.mTop = mTextRect.mBottom + (line_iter->mRect.mTop - scrolled_view_rect.mBottom); + doc_rect.mLeft = line_iter->mRect.mLeft; + doc_rect.mBottom = line_iter->mRect.mBottom; + doc_rect.mTop = line_iter->mRect.mTop; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -1863,7 +1862,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const // cursor advanced to right based on difference in offset of cursor to start of line S32 segment_width, segment_height; segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); - local_rect.mLeft += segment_width; + doc_rect.mLeft += segment_width; break; } @@ -1872,7 +1871,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const // add remainder of current text segment to cursor position S32 segment_width, segment_height; segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); - local_rect.mLeft += segment_width; + doc_rect.mLeft += segment_width; // offset will be 0 for all segments after the first line_seg_offset = 0; // go to next text segment on this line @@ -1880,7 +1879,31 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const } } - local_rect.mRight = local_rect.mLeft; + // set rect to 0 width + doc_rect.mRight = doc_rect.mLeft; + + return doc_rect; +} + +LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const +{ + LLRect local_rect; + if (mLineInfoList.empty()) + { + // return default height rect in upper left + local_rect = mTextRect; + local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight()); + return local_rect; + } + + // get the rect in document coordinates + LLRect doc_rect = getDocRectFromDocIndex(pos); + + // compensate for scrolled, inset view of doc + LLRect scrolled_view_rect = getVisibleDocumentRect(); + local_rect = doc_rect; + local_rect.translate(mTextRect.mLeft - scrolled_view_rect.mLeft, + mTextRect.mBottom - scrolled_view_rect.mBottom); return local_rect; } @@ -2416,10 +2439,12 @@ void LLNormalTextSegment::dump() const // LLInlineViewSegment // -LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line) +LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line, S32 hpad, S32 vpad) : LLTextSegment(start, end), mView(view), - mForceNewLine(force_new_line) + mForceNewLine(force_new_line), + mHPad(hpad), // one sided padding (applied to left and right) + mVPad(vpad) { } @@ -2439,8 +2464,8 @@ void LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt } else { - width = mView->getRect().getWidth(); - height = mView->getRect().getHeight(); + width = mHPad * 2 + mView->getRect().getWidth(); + height = mVPad * 2 + mView->getRect().getHeight(); } } @@ -2462,14 +2487,15 @@ S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin void LLInlineViewSegment::updateLayout(const LLTextBase& editor) { - LLRect start_rect = editor.getLocalRectFromDocIndex(mStart); - LLRect doc_rect = editor.getDocumentView()->getRect(); - mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom); + LLRect start_rect = editor.getDocRectFromDocIndex(mStart); + mView->setOrigin(start_rect.mLeft + mHPad, start_rect.mBottom + mVPad); } F32 LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { - return (F32)(draw_rect.mLeft + mView->getRect().getWidth()); + // return padded width of widget + // widget is actually drawn during mDocumentView's draw() + return (F32)(draw_rect.mLeft + mView->getRect().getWidth() + mHPad * 2); } void LLInlineViewSegment::unlinkFromDocument(LLTextBase* editor) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index c05a31baec..f0b8878491 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -157,6 +157,7 @@ public: S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; LLRect getLocalRectFromDocIndex(S32 pos) const; + LLRect getDocRectFromDocIndex(S32 pos) const; void setReadOnly(bool read_only) { mReadOnly = read_only; } bool getReadOnly() { return mReadOnly; } @@ -458,7 +459,7 @@ public: class LLInlineViewSegment : public LLTextSegment { public: - LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line); + LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line, S32 hpad = 0, S32 vpad = 0); ~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; @@ -469,6 +470,8 @@ public: /*virtual*/ void linkToDocument(class LLTextBase* editor); private: + S32 mHPad; + S32 mVPad; LLView* mView; bool mForceNewLine; }; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 953c5b292f..d507cf7ce4 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2276,7 +2276,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) +void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_new_line, S32 hpad, S32 vpad) { // Save old state S32 selection_start = mSelectionStart; @@ -2295,7 +2295,7 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_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); + LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size(), force_new_line, hpad, vpad); insert(getLength(), widget_wide_text, FALSE, segment); needsReflow(); diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 82f3956855..481a4d1a78 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -165,7 +165,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); + void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_newline, S32 hpad, S32 vpad); // Non-undoable void setText(const LLStringExplicit &utf8str); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index e2368cc05c..c3c0daed0f 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -85,8 +85,9 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlFactory::~LLUICtrlFactory() { - delete mDummyPanel; - mDummyPanel = NULL; + // go ahead and leak mDummyPanel since this is static destructor time + //delete mDummyPanel; + //mDummyPanel = NULL; } void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index cc21b636f1..ebf46a6e3f 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -101,12 +101,12 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr if (mLastFromName == from) { view = getSeparator(); - view_text = "\n"; + view_text = " "; } else { view = getHeader(avatar_id, from, time); - view_text = from + MESSAGE_USERNAME_DATE_SEPARATOR + time; + view_text = "\n" + from + MESSAGE_USERNAME_DATE_SEPARATOR + time; } //Prepare the rect for the view LLRect target_rect = getDocumentView()->getRect(); @@ -115,12 +115,12 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr view->reshape(target_rect.getWidth(), view->getRect().getHeight()); view->setOrigin(target_rect.mLeft, view->getRect().mBottom); - this->appendWidget(view, view_text, FALSE, TRUE); + appendWidget(view, view_text, FALSE, TRUE, mLeftWidgetPad, 0); //Append the text message - this->appendText(message, TRUE, style_params); + appendText(message, TRUE, style_params); mLastFromName = from; - this->blockUndo(); - this->setCursorAndScrollToEnd(); + blockUndo(); + setCursorAndScrollToEnd(); } |