diff options
author | Richard Nelson <richard@lindenlab.com> | 2009-10-08 01:48:50 +0000 |
---|---|---|
committer | Richard Nelson <richard@lindenlab.com> | 2009-10-08 01:48:50 +0000 |
commit | fd846da06cbd1a62023de8e9c3ec61d40e8cd226 (patch) | |
tree | d8fa86eabb9fecae5ce82d012abacd41beabacb6 /indra/llui | |
parent | e5d968ad404aac4e04b2ac4d58647db956b1ed62 (diff) |
only add LLScrollContainers to text widgets when requested, saving on LLTextBox construction time
combined clip and scroll attributes of text editors and text boxes...if you want to clip text, you need to introduce a scrollbar
moved clear to LLTextEditor so that text boxes won't empty out when calling LLPanel::clearCtrls()
EXT-1354 - added optional wrapping to LLTooltips...inspector tooltips don't wrap, everything else does
added LLFastTimer::reset call on application init to prime timers for pre-login timing
fixed tooltips positioning incorrectly due to mis-sized tooltipview
eliminated hide_scrollbar param for text editors
reviewed by Leyla
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llsearcheditor.cpp | 6 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 192 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 18 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 7 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 1 | ||||
-rw-r--r-- | indra/llui/lltooltip.cpp | 2 | ||||
-rw-r--r-- | indra/llui/lltooltip.h | 1 |
7 files changed, 130 insertions, 97 deletions
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index b87f645f3f..fad2b7bc99 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -37,9 +37,9 @@ #include "llsearcheditor.h" LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) -: LLUICtrl(p) - , mSearchButton(NULL) - , mClearButton(NULL) +: LLUICtrl(p), + mSearchButton(NULL), + mClearButton(NULL) { S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height; S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3dacf979c7..123e59ae6a 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -124,17 +124,6 @@ struct LLTextBase::line_end_compare ////////////////////////////////////////////////////////////////////////// // -// LLTextBase::DocumentPanel -// - - -LLTextBase::DocumentPanel::DocumentPanel(const Params& p) -: LLPanel(p) -{} - - -////////////////////////////////////////////////////////////////////////// -// // LLTextBase // @@ -157,8 +146,7 @@ LLTextBase::Params::Params() bg_readonly_color("bg_readonly_color"), bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), - hide_scrollbar("hide_scrollbar"), - clip_to_rect("clip_to_rect", true), + allow_scroll("allow_scroll", true), track_end("track_end", false), read_only("read_only", false), v_pad("v_pad", 0), @@ -205,35 +193,44 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mSelectionStart( 0 ), mSelectionEnd( 0 ), mIsSelecting( FALSE ), - mClip(p.clip_to_rect), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), mParseHTML(p.allow_html), mParseHighlights(p.parse_highlights), - mHideScrollbar(p.hide_scrollbar) -{ - LLScrollContainer::Params scroll_params; - scroll_params.name = "text scroller"; - scroll_params.rect = getLocalRect(); - scroll_params.follows.flags = FOLLOWS_ALL; - scroll_params.is_opaque = false; - scroll_params.mouse_opaque = false; - scroll_params.min_auto_scroll_rate = 200; - scroll_params.max_auto_scroll_rate = 800; - scroll_params.hide_scrollbar = p.hide_scrollbar; - scroll_params.border_visible = p.border_visible; - mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params); - addChild(mScroller); - - LLPanel::Params panel_params; - panel_params.name = "text_contents"; - panel_params.rect = LLRect(0, 500, 500, 0); - panel_params.background_visible = p.bg_visible; - panel_params.background_opaque = true; - panel_params.mouse_opaque = false; - - mDocumentPanel = LLUICtrlFactory::create<DocumentPanel>(panel_params); - mScroller->addChild(mDocumentPanel); + mBGVisible(p.bg_visible), + mScroller(NULL) +{ + if(p.allow_scroll) + { + LLScrollContainer::Params scroll_params; + scroll_params.name = "text scroller"; + scroll_params.rect = getLocalRect(); + scroll_params.follows.flags = FOLLOWS_ALL; + scroll_params.is_opaque = false; + scroll_params.mouse_opaque = false; + scroll_params.min_auto_scroll_rate = 200; + scroll_params.max_auto_scroll_rate = 800; + // all text widgets only show scrollbar on demand + scroll_params.hide_scrollbar = true; + scroll_params.border_visible = p.border_visible; + mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params); + addChild(mScroller); + } + + LLView::Params view_params; + view_params.name = "text_contents"; + view_params.rect = LLRect(0, 500, 500, 0); + view_params.mouse_opaque = false; + + mDocumentView = LLUICtrlFactory::create<LLView>(view_params); + if (mScroller) + { + mScroller->addChild(mDocumentView); + } + else + { + addChild(mDocumentView); + } createDefaultSegment(); @@ -314,7 +311,7 @@ void LLTextBase::drawSelectionBackground() LLRect selection_rect = mTextRect; // Skip through the lines we aren't drawing. - LLRect content_display_rect = mScroller->getVisibleContentRect(); + LLRect content_display_rect = getVisibleDocumentRect(); // binary search for line that starts before top of visible buffer line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); @@ -496,8 +493,7 @@ void LLTextBase::drawText() selection_right = llmax( mSelectionStart, mSelectionEnd ); } - LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); - LLRect content_rect = mScroller->getContentWindowRect(); + LLRect scrolled_view_rect = getVisibleDocumentRect(); std::pair<S32, S32> line_range = getVisibleLines(); S32 first_line = line_range.first; S32 last_line = line_range.second; @@ -540,7 +536,7 @@ void LLTextBase::drawText() LLRect text_rect(line.mRect.mLeft + mTextRect.mLeft - scrolled_view_rect.mLeft, line.mRect.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom, - mDocumentPanel->getRect().getWidth() - scrolled_view_rect.mLeft, + mDocumentView->getRect().getWidth() - scrolled_view_rect.mLeft, line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom); // draw a single line of text @@ -645,6 +641,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } onValueChange(pos, pos + insert_len); + needsReflow(); return insert_len; } @@ -704,6 +701,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) createDefaultSegment(); onValueChange(pos, pos); + needsReflow(); return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length } @@ -719,6 +717,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc) getViewModel()->setDisplay(text); onValueChange(pos, pos + 1); + needsReflow(); return 1; } @@ -949,29 +948,31 @@ void LLTextBase::draw() // then update scroll position, as cursor may have moved updateScrollFromCursor(); - LLColor4 bg_color = mReadOnly - ? mReadOnlyBgColor.get() - : hasFocus() - ? mFocusBgColor.get() - : mWriteableBgColor.get(); + if (mBGVisible) + { + // clip background rect against extents, if we support scrolling + LLLocalClipRect clip(getLocalRect(), mScroller != NULL); - mDocumentPanel->setBackgroundColor(bg_color); + LLColor4 bg_color = mReadOnly + ? mReadOnlyBgColor.get() + : hasFocus() + ? mFocusBgColor.get() + : mWriteableBgColor.get(); + gl_rect_2d(mDocumentView->getRect(), bg_color, TRUE); + } + // draw document view LLUICtrl::draw(); + { - LLLocalClipRect clip(mTextRect, mClip); + // only clip if we support scrolling (mScroller != NULL) + LLLocalClipRect clip(mTextRect, mScroller != NULL); drawSelectionBackground(); drawText(); drawCursor(); } } -//virtual -void LLTextBase::clear() -{ - getViewModel()->setDisplay(LLWStringUtil::null); - clearSegments(); -} //virtual void LLTextBase::setColor( const LLColor4& c ) @@ -1000,14 +1001,14 @@ void LLTextBase::updateScrollFromCursor() // Update scroll position even in read-only mode (when there's no cursor displayed) // because startOfDoc()/endOfDoc() modify cursor position. See EXT-736. - if (!mScrollNeeded) + if (!mScrollNeeded || !mScroller) { return; } mScrollNeeded = FALSE; // scroll so that the cursor is at the top of the page - LLRect scroller_doc_window = mScroller->getVisibleContentRect(); + LLRect scroller_doc_window = getVisibleDocumentRect(); LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom); mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5)); @@ -1042,7 +1043,7 @@ void LLTextBase::reflow(S32 start_index) { mReflowNeeded = FALSE; - bool scrolled_to_bottom = mScroller->isAtBottom(); + bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos); bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible @@ -1183,17 +1184,29 @@ void LLTextBase::reflow(S32 start_index) mContentsRect.stretch(1); } - // change mDocumentPanel document size to accomodate reflowed text + // change mDocumentView size to accomodate reflowed text LLRect document_rect; - document_rect.setOriginAndSize(1, 1, - mScroller->getContentWindowRect().getWidth(), - llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight())); - mDocumentPanel->setShape(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 = mDocumentPanel->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad; + 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) { @@ -1215,9 +1228,9 @@ void LLTextBase::reflow(S32 start_index) } // apply scroll constraints after reflowing text - if (!hasMouseCapture()) + if (!hasMouseCapture() && mScroller) { - LLRect visible_content_rect = mScroller->getVisibleContentRect(); + LLRect visible_content_rect = getVisibleDocumentRect(); if (scrolled_to_bottom && mTrackEnd) { // keep bottom of text buffer visible @@ -1329,7 +1342,7 @@ S32 LLTextBase::getLineOffsetFromDocIndex( S32 startpos, bool include_wordwrap) S32 LLTextBase::getFirstVisibleLine() const { - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); // binary search for line that starts before top of visible buffer line_list_t::const_iterator iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom()); @@ -1339,7 +1352,7 @@ S32 LLTextBase::getFirstVisibleLine() const std::pair<S32, S32> LLTextBase::getVisibleLines(bool fully_visible) { - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); line_list_t::const_iterator first_iter; line_list_t::const_iterator last_iter; @@ -1370,12 +1383,12 @@ LLTextViewModel* LLTextBase::getViewModel() const void LLTextBase::addDocumentChild(LLView* view) { - mDocumentPanel->addChild(view); + mDocumentView->addChild(view); } void LLTextBase::removeDocumentChild(LLView* view) { - mDocumentPanel->removeChild(view); + mDocumentView->removeChild(view); } @@ -1481,11 +1494,10 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) void LLTextBase::setText(const LLStringExplicit &utf8str) { // clear out the existing text and segments - clear(); - - truncate(); + getViewModel()->setDisplay(LLWStringUtil::null); - createDefaultSegment(); + clearSegments(); +// createDefaultSegment(); startOfDoc(); deselect(); @@ -1496,10 +1508,9 @@ void LLTextBase::setText(const LLStringExplicit &utf8str) appendText(text, false); - needsReflow(); - //resetDirty(); onValueChange(0, getLength()); + needsReflow(); } //virtual @@ -1767,7 +1778,7 @@ LLWString LLTextBase::getWText() const S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const { // Figure out which line we're nearest to. - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); // binary search for line that starts before local_y line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mTextRect.mBottom + visible_region.mBottom, compare_bottom()); @@ -1838,7 +1849,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const // 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 = mScroller->getVisibleContentRect(); + 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); @@ -1917,7 +1928,7 @@ void LLTextBase::endOfDoc() void LLTextBase::changePage( S32 delta ) { const S32 PIXEL_OVERLAP_ON_PAGE_CHANGE = 10; - if (delta == 0) return; + if (delta == 0 || !mScroller) return; LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); @@ -1970,7 +1981,7 @@ void LLTextBase::changeLine( S32 delta ) new_line = line + 1; } - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mTextRect.mBottom - visible_region.mBottom, TRUE); setCursorPos(new_cursor_pos, true); @@ -2047,7 +2058,7 @@ S32 LLTextBase::getEditableIndex(S32 index, bool increasing_direction) void LLTextBase::updateTextRect() { LLRect old_text_rect = mTextRect; - mTextRect = mScroller->getContentWindowRect(); + mTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect(); //FIXME: replace border with image? if (mBorderVisible) { @@ -2081,6 +2092,22 @@ void LLTextBase::endSelection() } } +// get portion of document that is visible in text editor +LLRect LLTextBase::getVisibleDocumentRect() const +{ + if (mScroller) + { + return mScroller->getVisibleContentRect(); + } + else + { + // entire document rect when not scrolling + LLRect doc_rect = mDocumentView->getLocalRect(); + doc_rect.translate(-mDocumentView->getRect().mLeft, -mDocumentView->getRect().mBottom); + return doc_rect; + } +} + // // LLTextSegment // @@ -2150,6 +2177,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec { if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart)) { + LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha; LLUIImagePtr image = mStyle->getImage(); S32 style_image_height = image->getHeight(); S32 style_image_width = image->getWidth(); @@ -2398,7 +2426,7 @@ 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.getDocumentPanel()->getRect(); + LLRect doc_rect = editor.getDocumentView()->getRect(); mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index f20134fd6d..903396c78a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -80,8 +80,7 @@ public: border_visible, track_end, read_only, - hide_scrollbar, - clip_to_rect, + allow_scroll, wrap, use_ellipses, allow_html, @@ -118,7 +117,6 @@ public: // LLUICtrl interface /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; } - /*virtual*/ void clear(); /*virtual*/ void setColor( const LLColor4& c ); /*virtual*/ void setValue(const LLSD& value ); /*virtual*/ LLTextViewModel* getViewModel() const; @@ -149,16 +147,13 @@ public: S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } - class DocumentPanel : public LLPanel - { - public: - DocumentPanel(const Params&); - }; void addDocumentChild(LLView* view); void removeDocumentChild(LLView* view); - const DocumentPanel* getDocumentPanel() const { return mDocumentPanel; } + const LLView* getDocumentView() const { return mDocumentView; } LLRect getTextRect() { return mTextRect; } LLRect getContentsRect(); + LLRect getVisibleDocumentRect() const; + S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; LLRect getLocalRectFromDocIndex(S32 pos) const; @@ -344,13 +339,12 @@ protected: bool mUseEllipses; bool mTrackEnd; // if true, keeps scroll position at end of document during resize bool mReadOnly; - bool mClip; - bool mHideScrollbar; + bool mBGVisible; // render background? S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes // support widgets LLContextMenu* mPopupMenu; - DocumentPanel* mDocumentPanel; + LLView* mDocumentView; class LLScrollContainer* mScroller; // transient state diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 997c5b8fa8..74373e7803 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2916,3 +2916,10 @@ void LLTextEditor::onKeyStroke() { mKeystrokeSignal(this); } + +//virtual +void LLTextEditor::clear() +{ + getViewModel()->setDisplay(LLWStringUtil::null); + clearSegments(); +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 0e5707a3a6..e232efbfb3 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -116,6 +116,7 @@ public: virtual void setEnabled(BOOL enabled); // uictrl overrides + virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL isDirty() const; diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index c55273cacf..f30e56b907 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -147,6 +147,7 @@ static LLDefaultChildRegistry::Register<LLToolTip> r("tool_tip"); LLToolTip::Params::Params() : max_width("max_width", 200), padding("padding", 4), + wrap("wrap", true), pos("pos"), message("message"), delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )), @@ -181,6 +182,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p) params.bg_visible = false; params.font = p.font; params.use_ellipses = true; + params.wrap = p.wrap; mTextBox = LLUICtrlFactory::create<LLTextBox> (params); addChild(mTextBox); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index 6715da1611..63e7249a12 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -83,6 +83,7 @@ public: Optional<LLUIImage*> image; Optional<S32> max_width; Optional<S32> padding; + Optional<bool> wrap; Params(); }; |