From 5285a7fa7ec67c2337c5f071e6785b143e24c9a6 Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Thu, 1 Jul 2010 20:00:00 +0300 Subject: EXT-7565 FIXED Would be nice to preserve selection while switching between folder/list view modes - Created callback called 'SaveSelecton' (which preserves selection while switching between folder/list view modes) for folder/list view modes buttons in LLPanelOutfitEdit. - Added 'scrollToShowFirstSelectedItem' method in the LLFlatListView which scrools and shows the first selected item in case multiselection. - It's possible to set selection for flat list view items before list is build. The result is that any items will be selected. To get rid of it: 1. Overrided LLFlatListView::selectItemByValue method in LLInventoryItemsList so that if list is not created yet, items ids are saved to the vector. 2. Added 'LLInventoryItemsList::updateSelection()' method which selects items with ids from that vector when list is created. - A little refactoring: moved funcionality of updating WearablesPanel's verb buttons to the separate method called LLPanelOutfitEdit::updateWearablesPanelVerbButtons() to made code more readable and self-explanatory Reviewed by Vadim Savchuk and Neal Orman at https://codereview.productengine.com/secondlife/r/579/ --HG-- branch : product-engine --- indra/llui/llflatlistview.cpp | 12 ++++++++++++ indra/llui/llflatlistview.h | 1 + 2 files changed, 13 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index b87851490d..a3debdb19a 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -776,6 +776,18 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select) return true; } +void LLFlatListView::scrollToShowFirstSelectedItem() +{ + if (!mSelectedItemPairs.size()) return; + + LLRect selected_rc = mSelectedItemPairs.front()->first->getRect(); + + if (selected_rc.isValid()) + { + scrollToShowRect(selected_rc); + } +} + LLRect LLFlatListView::getLastSelectedItemRect() { if (!mSelectedItemPairs.size()) diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index ded46d8122..bf72289c47 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -293,6 +293,7 @@ public: bool updateValue(const LLSD& old_value, const LLSD& new_value); + void scrollToShowFirstSelectedItem(); void selectFirstItem (); void selectLastItem (); -- cgit v1.2.3 From 4965f9f2d5da84d3b60ccb1bc63497fdbfa99e51 Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Tue, 13 Jul 2010 18:43:30 +0300 Subject: EXT-7668 FIXED prohibited deselecting a single selected item w/o using CTRL Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/746/ --HG-- branch : product-engine --- indra/llui/llflatlistview.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index f9e08a3f4c..fbc6295d49 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -608,8 +608,14 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) return; } - if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(); - selectItemPair(item_pair, select_item); + //no need to do additional commit on selection reset + if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(true); + + //only CTRL usage allows to deselect an item, usual clicking on an item cannot deselect it + if (mask & MASK_CONTROL) + selectItemPair(item_pair, select_item); + else + selectItemPair(item_pair, true); } void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask) -- cgit v1.2.3 From 2c722547ea57c1510a82200242a3ccff2e505d17 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 15 Jul 2010 10:20:06 -0700 Subject: changed allow_html to parse_urls to be clearer about its meaning allow_html still supported as alternate --- indra/llui/lldraghandle.cpp | 2 +- indra/llui/lltextbase.cpp | 5 +++-- indra/llui/lltextbase.h | 2 +- indra/llui/lltooltip.cpp | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 9f83fcca35..b52cb2b751 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -113,7 +113,7 @@ void LLDragHandleTop::setTitle(const std::string& title) params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); params.font_shadow(LLFontGL::DROP_SHADOW_SOFT); params.use_ellipses = true; - params.allow_html = false; //cancel URL replacement in floater title + params.parse_urls = false; //cancel URL replacement in floater title mTitleBox = LLUICtrlFactory::create (params); addChild( mTitleBox ); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ed03645944..dd0b7ebad1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -167,11 +167,12 @@ LLTextBase::Params::Params() font_shadow("font_shadow"), wrap("wrap"), use_ellipses("use_ellipses", false), - allow_html("allow_html", false), + parse_urls("parse_urls", false), parse_highlights("parse_highlights", false) { addSynonym(track_end, "track_bottom"); addSynonym(wrap, "word_wrap"); + addSynonym(parse_urls, "allow_html"); } @@ -209,7 +210,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mPlainText ( p.plain_text ), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), - mParseHTML(p.allow_html), + mParseHTML(p.parse_urls), mParseHighlights(p.parse_highlights), mBGVisible(p.bg_visible), mScroller(NULL), diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 4b0eeeb7d6..bd41272f11 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -251,7 +251,7 @@ public: plain_text, wrap, use_ellipses, - allow_html, + parse_urls, parse_highlights, clip_partial; diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index ed7fd02e14..025725476e 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -186,7 +186,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p) params.font = p.font; params.use_ellipses = true; params.wrap = p.wrap; - params.allow_html = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips + params.parse_urls = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips mTextBox = LLUICtrlFactory::create (params); addChild(mTextBox); -- cgit v1.2.3 From 551f74125bacfe8353a4b13692d2fdb0cc29958b Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 15 Jul 2010 16:32:50 -0700 Subject: Changes to allow disabling an LLTextBox (or LLTextBox subclass) to gray out the text. Due to some legacy issues, text boxes will not gray out on disable unless they have their text_readonly_color property in xui set to "LabelDisabledColor" (or some other color distinct from their text color). Reviewed by Richard. --- indra/llui/lltextbase.cpp | 3 --- indra/llui/lltextbox.cpp | 11 +++++++++++ indra/llui/lltextbox.h | 2 ++ indra/llui/lltexteditor.cpp | 3 +++ 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ed03645944..5175583dc9 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -269,9 +269,6 @@ void LLTextBase::initFromParams(const LLTextBase::Params& p) { mReadOnly = p.read_only; } - - // HACK: text editors always need to be enabled so that we can scroll - LLView::setEnabled(true); } bool LLTextBase::truncate() diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index a1f5b5726b..686179b94e 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -119,6 +119,17 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) return handled; } +void LLTextBox::setEnabled(BOOL enabled) +{ + // just treat enabled as read-only flag + bool read_only = !enabled; + if (read_only != mReadOnly) + { + LLTextBase::setReadOnly(read_only); + updateSegments(); + } +} + void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params ) { // does string argument insertion diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 3a045534d3..b2ccde94c6 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -58,6 +58,8 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ void setEnabled(BOOL enabled); + /*virtual*/ void setText( const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params() ); void setRightAlign() { mHAlign = LLFontGL::RIGHT; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 130cda3784..6781c23416 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -289,6 +289,9 @@ void LLTextEditor::initFromParams( const LLTextEditor::Params& p) { LLTextBase::initFromParams(p); + // HACK: text editors always need to be enabled so that we can scroll + LLView::setEnabled(true); + if (p.commit_on_focus_lost.isProvided()) { mCommitOnFocusLost = p.commit_on_focus_lost; -- cgit v1.2.3 From 053fa9dc9a0ed2cedaa33b1aee4615adc04e909d Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Fri, 16 Jul 2010 19:03:13 +0300 Subject: EXT-8188 FIXED Added SelectionEnabled flag to fix accordion tab header highlighting. Reviewed by Neal Orman at https://codereview.productengine.com/secondlife/r/735/. --HG-- branch : product-engine --- indra/llui/llaccordionctrltab.cpp | 5 +++-- indra/llui/llaccordionctrltab.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 37fc571bbd..0cccd4e6de 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -358,6 +358,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) ,mPaddingBottom(p.padding_bottom) ,mCanOpenClose(true) ,mFitPanel(p.fit_panel) + ,mSelectionEnabled(p.selection_enabled) ,mContainerPanel(NULL) ,mScrollbar(NULL) { @@ -371,7 +372,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) mHeader = LLUICtrlFactory::create(headerParams); addChild(mHeader, 1); - if (p.selection_enabled) + if (mSelectionEnabled) { LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this)); } @@ -797,7 +798,7 @@ void LLAccordionCtrlTab::showAndFocusHeader() { LLAccordionCtrlTabHeader* header = getChild(DD_HEADER_NAME); header->setFocus(true); - header->setSelected(true); + header->setSelected(mSelectionEnabled); LLRect screen_rc; LLRect selected_rc = header->getRect(); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 5646a355d0..1344ce0a30 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -241,6 +241,8 @@ private: bool mStoredOpenCloseState; bool mWasStateStored; + bool mSelectionEnabled; + LLScrollbar* mScrollbar; LLView* mContainerPanel; -- cgit v1.2.3 From 5eaab96a0b6bcf22db53f2783c0c2716ec872967 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 16 Jul 2010 17:11:51 -0700 Subject: EXT-8465 FIX Text selection is often unreadable --- indra/llui/llstyle.cpp | 12 ++++++------ indra/llui/llstyle.h | 37 ++++++++++++++++++------------------- indra/llui/lltextbase.cpp | 31 ++++++++++++------------------- indra/llui/lltextbase.h | 6 +++++- 4 files changed, 41 insertions(+), 45 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index b8f93b6a0e..d63f67b4c1 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -42,6 +42,8 @@ LLStyle::Params::Params() : visible("visible", true), drop_shadow("drop_shadow", LLFontGL::NO_SHADOW), color("color", LLColor4::black), + readonly_color("readonly_color", LLColor4::black), + selected_color("selected_color", LLColor4::black), font("font", LLFontGL::getFontMonospace()), image("image"), link_href("href") @@ -49,12 +51,10 @@ LLStyle::Params::Params() LLStyle::LLStyle(const LLStyle::Params& p) -: mItalic(FALSE), - mBold(FALSE), - mUnderline(FALSE), - mVisible(p.visible), - mColor(p.color()), - mReadOnlyColor(p.readonly_color()), +: mVisible(p.visible), + mColor(p.color), + mReadOnlyColor(p.readonly_color), + mSelectedColor(p.selected_color), mFont(p.font()), mLink(p.link_href), mDropShadow(p.drop_shadow), diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 2067e8e8be..44d9da7a1e 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -47,7 +47,8 @@ public: Optional visible; Optional drop_shadow; Optional color, - readonly_color; + readonly_color, + selected_color; Optional font; Optional image; Optional link_href; @@ -55,11 +56,14 @@ public: }; LLStyle(const Params& p = Params()); public: - const LLColor4& getColor() const { return mColor; } - void setColor(const LLColor4 &color) { mColor = color; } + const LLUIColor& getColor() const { return mColor; } + void setColor(const LLUIColor &color) { mColor = color; } - const LLColor4& getReadOnlyColor() const { return mReadOnlyColor; } - void setReadOnlyColor(const LLColor4& color) { mReadOnlyColor = color; } + const LLUIColor& getReadOnlyColor() const { return mReadOnlyColor; } + void setReadOnlyColor(const LLUIColor& color) { mReadOnlyColor = color; } + + const LLUIColor& getSelectedColor() const { return mSelectedColor; } + void setSelectedColor(const LLUIColor& color) { mSelectedColor = color; } BOOL isVisible() const; void setVisible(BOOL is_visible); @@ -79,41 +83,36 @@ public: BOOL isImage() const { return mImagep.notNull(); } - // inlined here to make it easier to compare to member data below. -MG bool operator==(const LLStyle &rhs) const { return mVisible == rhs.mVisible && mColor == rhs.mColor && mReadOnlyColor == rhs.mReadOnlyColor + && mSelectedColor == rhs.mSelectedColor && mFont == rhs.mFont && mLink == rhs.mLink && mImagep == rhs.mImagep - && mItalic == rhs.mItalic - && mBold == rhs.mBold - && mUnderline == rhs.mUnderline && mDropShadow == rhs.mDropShadow; } bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } public: - BOOL mItalic; - BOOL mBold; - BOOL mUnderline; LLFontGL::ShadowType mDropShadow; protected: ~LLStyle() { } private: - BOOL mVisible; - LLUIColor mColor; - LLUIColor mReadOnlyColor; - std::string mFontName; - const LLFontGL* mFont; // cached for performance - std::string mLink; - LLUIImagePtr mImagep; + BOOL mVisible; + LLUIColor mColor; + LLUIColor mReadOnlyColor; + LLUIColor mSelectedColor; + std::string mFontName; + const LLFontGL* mFont; + std::string mLink; + LLUIImagePtr mImagep; }; typedef LLPointer LLStyleSP; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index dd0b7ebad1..538924e5d1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -155,6 +155,8 @@ LLTextBase::Params::Params() bg_readonly_color("bg_readonly_color"), bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), + text_selected_color("text_selected_color"), + bg_selected_color("bg_selected_color"), allow_scroll("allow_scroll", true), plain_text("plain_text",false), track_end("track_end", false), @@ -191,6 +193,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mWriteableBgColor(p.bg_writeable_color), mReadOnlyBgColor(p.bg_readonly_color), mFocusBgColor(p.bg_focus_color), + mTextSelectedColor(p.text_selected_color), + mSelectedBGColor(p.bg_selected_color), mReflowIndex(S32_MAX), mCursorPos( 0 ), mScrollNeeded(FALSE), @@ -302,11 +306,14 @@ bool LLTextBase::truncate() const LLStyle::Params& LLTextBase::getDefaultStyleParams() { + //FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html + //and eliminate color member values if (mStyleDirty) { mDefaultStyle - .color(LLUIColor(&mFgColor)) + .color(LLUIColor(&mFgColor)) // pass linked color instead of copy of mFGColor .readonly_color(LLUIColor(&mReadOnlyFgColor)) + .selected_color(LLUIColor(&mTextSelectedColor)) .font(mDefaultFont) .drop_shadow(mFontShadow); mStyleDirty = false; @@ -404,7 +411,7 @@ void LLTextBase::drawSelectionBackground() // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - const LLColor4& color = mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get(); + const LLColor4& color = mSelectedBGColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); @@ -444,7 +451,6 @@ void LLTextBase::drawCursor() } else { - //segmentp = mSegments.back(); return; } @@ -478,21 +484,8 @@ void LLTextBase::drawCursor() { LLColor4 text_color; const LLFontGL* fontp; - if (segmentp) - { - text_color = segmentp->getColor(); - fontp = segmentp->getStyle()->getFont(); - } - else if (mReadOnly) - { - text_color = mReadOnlyFgColor.get(); - fontp = mDefaultFont; - } - else - { - text_color = mFgColor.get(); - fontp = mDefaultFont; - } + text_color = segmentp->getColor(); + fontp = segmentp->getStyle()->getFont(); fontp->render(text, mCursorPos, cursor_rect, LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha), LLFontGL::LEFT, mVAlign, @@ -2482,7 +2475,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele font->render(text, start, rect, - LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), + mStyle->getSelectedColor().get(), LLFontGL::LEFT, mEditor.mVAlign, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index bd41272f11..86f0e55a1d 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -241,7 +241,9 @@ public: text_readonly_color, bg_readonly_color, bg_writeable_color, - bg_focus_color; + bg_focus_color, + text_selected_color, + bg_selected_color; Optional bg_visible, border_visible, @@ -507,6 +509,8 @@ protected: LLUIColor mWriteableBgColor; LLUIColor mReadOnlyBgColor; LLUIColor mFocusBgColor; + LLUIColor mTextSelectedColor; + LLUIColor mSelectedBGColor; // cursor S32 mCursorPos; // I-beam is just after the mCursorPos-th character. -- cgit v1.2.3 From 054e31512d2fae6670b384b247db5156b48796fb Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Wed, 21 Jul 2010 19:25:36 +0300 Subject: EXT-8401 FIXED Added new text prevalidation callback to allow ascii characters and new line in text editor. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/786/. --HG-- branch : product-engine --- indra/llui/lltextvalidate.cpp | 18 ++++++++++++++++++ indra/llui/lltextvalidate.h | 1 + 2 files changed, 19 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 8b6bc5bd7d..53c4d21151 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -50,6 +50,7 @@ namespace LLTextValidate declare("alpha_num_space", validateAlphaNumSpace); declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe); declare("ascii_printable_no_space", validateASCIIPrintableNoSpace); + declare("ascii_with_newline", validateASCIIWithNewLine); } // Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. @@ -299,4 +300,21 @@ namespace LLTextValidate } return rv; } + + // Used for multiline text stored on the server. + // Example is landmark description in Places SP. + bool validateASCIIWithNewLine(const LLWString &str) + { + bool rv = TRUE; + S32 len = str.length(); + while(len--) + { + if (str[len] < 0x20 && str[len] != 0xA || str[len] > 0x7f) + { + rv = FALSE; + break; + } + } + return rv; + } } diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index ffb4e85e7c..c033f5045b 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -57,6 +57,7 @@ namespace LLTextValidate bool validateASCIIPrintableNoPipe(const LLWString &str); bool validateASCIIPrintableNoSpace(const LLWString &str); bool validateASCII(const LLWString &str); + bool validateASCIIWithNewLine(const LLWString &str); } -- cgit v1.2.3 From 50d8cc6d377b90b27c57b390eb6626223a1685a7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 23 Jul 2010 22:07:15 -0700 Subject: first pass ui rendering performance improvements --- indra/llui/lllocalcliprect.cpp | 42 ++++++------------------------------------ indra/llui/lllocalcliprect.h | 26 +++++++++++++++++++++----- indra/llui/lltextbase.cpp | 15 ++++++++++----- 3 files changed, 37 insertions(+), 46 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 43c21e250c..55329f64e4 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -33,33 +33,8 @@ #include "lllocalcliprect.h" #include "llfontgl.h" -#include "llgl.h" #include "llui.h" -#include - -//--------------------------------------------------------------------------- -// LLScreenClipRect -// implementation class in screen space -//--------------------------------------------------------------------------- -class LLScreenClipRect -{ -public: - LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); - virtual ~LLScreenClipRect(); - -private: - static void pushClipRect(const LLRect& rect); - static void popClipRect(); - static void updateScissorRegion(); - -private: - LLGLState mScissorState; - BOOL mEnabled; - - static std::stack sClipRectStack; -}; - /*static*/ std::stack LLScreenClipRect::sClipRectStack; @@ -131,16 +106,11 @@ void LLScreenClipRect::updateScissorRegion() // LLLocalClipRect //--------------------------------------------------------------------------- LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -{ - LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX, - rect.mTop + LLFontGL::sCurOrigin.mY, - rect.mRight + LLFontGL::sCurOrigin.mX, - rect.mBottom + LLFontGL::sCurOrigin.mY); - mScreenClipRect = new LLScreenClipRect(screen, enabled); -} +: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, + rect.mTop + LLFontGL::sCurOrigin.mY, + rect.mRight + LLFontGL::sCurOrigin.mX, + rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) +{} LLLocalClipRect::~LLLocalClipRect() -{ - delete mScreenClipRect; - mScreenClipRect = NULL; -} +{} diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h index cd0c55ca72..36413f1496 100644 --- a/indra/llui/lllocalcliprect.h +++ b/indra/llui/lllocalcliprect.h @@ -31,7 +31,9 @@ #ifndef LLLOCALCLIPRECT_H #define LLLOCALCLIPRECT_H +#include "llgl.h" #include "llrect.h" // can't forward declare, it's templated +#include // Clip rendering to a specific rectangle using GL scissor // Just create one of these on the stack: @@ -39,15 +41,29 @@ // LLLocalClipRect(rect); // draw(); // } -class LLLocalClipRect +class LLScreenClipRect { public: - LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); - ~LLLocalClipRect(); + LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); + virtual ~LLScreenClipRect(); + +private: + static void pushClipRect(const LLRect& rect); + static void popClipRect(); + static void updateScissorRegion(); private: - // implementation class - class LLScreenClipRect* mScreenClipRect; + LLGLState mScissorState; + BOOL mEnabled; + + static std::stack sClipRectStack; +}; + +class LLLocalClipRect : public LLScreenClipRect +{ +public: + LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); + ~LLLocalClipRect(); }; #endif diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 617c496d6a..0587b3f48d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1012,22 +1012,25 @@ void LLTextBase::draw() if (mBGVisible) { // clip background rect against extents, if we support scrolling - LLLocalClipRect clip(doc_rect, mScroller != NULL); - + LLRect bg_rect = mVisibleTextRect; + if (mScroller) + { + bg_rect.intersectWith(doc_rect); + } LLColor4 bg_color = mReadOnly ? mReadOnlyBgColor.get() : hasFocus() ? mFocusBgColor.get() : mWriteableBgColor.get(); - gl_rect_2d(mVisibleTextRect, bg_color, TRUE); + gl_rect_2d(doc_rect, bg_color, TRUE); } // draw document view LLUICtrl::draw(); { - // only clip if we support scrolling (mScroller != NULL) - LLLocalClipRect clip(doc_rect, mScroller != NULL); + // only clip if we support scrolling or have word wrap turned off + LLLocalClipRect clip(doc_rect, !getWordWrap() || mScroller != NULL); drawSelectionBackground(); drawText(); drawCursor(); @@ -1495,6 +1498,7 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index) // when there are no segments, we return the end iterator, which must be checked by caller if (mSegments.size() <= 1) { return mSegments.begin(); } + //FIXME: avoid operator new somehow (without running into refcount problems) segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index)); return it; } @@ -2269,6 +2273,7 @@ void LLTextBase::updateRects() // allow horizontal scrolling? // if so, use entire width of text contents // otherwise, stop at width of mVisibleTextRect + //FIXME: consider use of getWordWrap() instead doc_rect.mRight = mScroller ? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight) : mVisibleTextRect.getWidth(); -- cgit v1.2.3 From 4919f0b341804680a90818386b8f8ccf0a5f5f81 Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Mon, 26 Jul 2010 18:10:29 +0300 Subject: EXT-8010 FIXED Implemented special behaviour of avatar links. Avatar links are now underlined only on hover. Also they have the same color as other links. - Underlining text and getting it back to normal are done in handleHover() and draw() of new LLOnHoverChangeableTextSegment class derived from LLNormalTextSegment. This class has two pointers to styles- one for style which will be used for text on hover, and another otherwise. This special type of text segment is used if link's boolean member mUnderlineOnHoverOnly is true. So it is URL's flag depending on which textbase adds new text segment(like it currently happens with mDisabledLink). - Changed avatar link color in colors.xml to emphasis (because it was white before and was inconsistent with other links). Reviewed by Richard Nelson at https://codereview.productengine.com/secondlife/r/749/ --HG-- branch : product-engine --- indra/llui/lltextbase.cpp | 58 ++++++++++++++++++++++++++++++++++++++------ indra/llui/lltextbase.h | 19 +++++++++++++-- indra/llui/llurlentry.cpp | 19 +++++++++++++++ indra/llui/llurlentry.h | 5 ++++ indra/llui/llurlmatch.cpp | 6 +++-- indra/llui/llurlmatch.h | 6 ++++- indra/llui/llurlregistry.cpp | 6 +++-- 7 files changed, 105 insertions(+), 14 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 617c496d6a..34d58db7f8 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1642,7 +1642,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para } else { - appendAndHighlightText(match.getLabel(), part, link_params); + appendAndHighlightText(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); // set the tooltip for the Url label if (! match.getTooltip().empty()) @@ -1725,7 +1725,7 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s insertStringNoUndo(getLength(), widget_wide_text, &segments); } -void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) { // Save old state S32 selection_start = mSelectionStart; @@ -1756,7 +1756,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 cur_length = getLength(); LLStyleConstSP sp(new LLStyle(highlight_params)); - LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); + LLTextSegmentPtr segmentp; + if(underline_on_hover_only) + { + highlight_params.font.style("NORMAL"); + LLStyleConstSP normal_sp(new LLStyle(highlight_params)); + segmentp = new LLOnHoverChangeableTextSegment(sp, normal_sp, cur_length, cur_length + wide_text.size(), *this); + } + else + { + segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); + } segment_vec_t segments; segments.push_back(segmentp); insertStringNoUndo(cur_length, wide_text, &segments); @@ -1771,7 +1781,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 segment_start = old_length; S32 segment_end = old_length + wide_text.size(); LLStyleConstSP sp(new LLStyle(style_params)); - segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); + if (underline_on_hover_only) + { + LLStyle::Params normal_style_params(style_params); + normal_style_params.font.style("NORMAL"); + LLStyleConstSP normal_sp(new LLStyle(normal_style_params)); + segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this )); + } + else + { + segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); + } insertStringNoUndo(getLength(), wide_text, &segments); } @@ -1795,7 +1815,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig } } -void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) { if (new_text.empty()) return; @@ -1807,7 +1827,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig if(pos!=start) { std::string str = std::string(new_text,start,pos-start); - appendAndHighlightTextImpl(str,highlight_part, style_params); + appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); } appendLineBreakSegment(style_params); start = pos+1; @@ -1815,7 +1835,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig } std::string str = std::string(new_text,start,new_text.length()-start); - appendAndHighlightTextImpl(str,highlight_part, style_params); + appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); } @@ -2675,6 +2695,30 @@ void LLNormalTextSegment::dump() const llendl; } +// +// LLOnHoverChangeableTextSegment +// + +LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ): + LLNormalTextSegment(normal_style, start, end, editor), + mHoveredStyle(style), + mNormalStyle(normal_style){} + +/*virtual*/ +F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ + F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect); + mStyle = mNormalStyle; + return result; +} + +/*virtual*/ +BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask) +{ + mStyle = mHoveredStyle; + return LLNormalTextSegment::handleHover(x, y, mask); +} + // // LLInlineViewSegment diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 86f0e55a1d..4b83d5effb 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -145,6 +145,21 @@ protected: boost::signals2::connection mImageLoadedConnection; }; +// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment) +class LLOnHoverChangeableTextSegment : public LLNormalTextSegment +{ +public: + LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ); + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); +protected: + // Style used for text when mouse pointer is over segment + LLStyleConstSP mHoveredStyle; + // Style used for text when mouse pointer is outside segment + LLStyleConstSP mNormalStyle; + +}; + class LLIndexSegment : public LLTextSegment { public: @@ -443,7 +458,7 @@ protected: S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep); + void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false); // manage segments @@ -486,7 +501,7 @@ protected: void replaceUrlLabel(const std::string &url, const std::string &label); void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); - void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params); + void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false); protected: diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e075699a6e..17d211fb36 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -363,6 +363,12 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const return LLTrans::getString("TooltipAgentUrl"); } +bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const +{ + std::string url = getUrl(string); + return LLStringUtil::endsWith(url, "/about"); +} + std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { if (!gCacheName) @@ -730,6 +736,19 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const return LLUrlEntryBase::getTooltip(string); } +bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const +{ + std::string url = getUrl(string); + LLUrlMatch match; + if (LLUrlRegistry::instance().findUrl(url, match)) + { + return match.underlineOnHoverOnly(); + } + + // unrecognized URL? should not happen + return LLUrlEntryBase::underlineOnHoverOnly(string); +} + // // LLUrlEntryWorldMap Describes secondlife:/// URLs // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 7d718b67a9..f8588dd760 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -94,6 +94,9 @@ public: /// is this a match for a URL that should not be hyperlinked? bool isLinkDisabled() const { return mDisabledLink; } + /// Should this link text be underlined only when mouse is hovered over it? + virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } + virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } protected: @@ -173,6 +176,7 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getTooltip(const std::string &string) const; /*virtual*/ LLUUID getID(const std::string &string) const; + /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; private: void onAgentNameReceived(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); @@ -275,6 +279,7 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; /*virtual*/ std::string getTooltip(const std::string &string) const; + /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; }; /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 7c96665ce4..a6d3dcb40f 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -43,7 +43,8 @@ LLUrlMatch::LLUrlMatch() : mIcon(""), mMenuName(""), mLocation(""), - mDisabledLink(false) + mDisabledLink(false), + mUnderlineOnHoverOnly(false) { } @@ -51,7 +52,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, const std::string &menu, const std::string &location, - bool disabled_link, const LLUUID& id) + bool disabled_link, const LLUUID& id, bool underline_on_hover_only) { mStart = start; mEnd = end; @@ -64,4 +65,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mLocation = location; mDisabledLink = disabled_link; mID = id; + mUnderlineOnHoverOnly = underline_on_hover_only; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 78dd2c528f..7090dd3f93 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -86,12 +86,15 @@ public: /// is this a match for a URL that should not be hyperlinked? bool isLinkDisabled() const { return mDisabledLink; } + /// Should this link text be underlined only when mouse is hovered over it? + bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } + /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, const std::string &menu, const std::string &location, bool disabled_link - , const LLUUID& id ); + , const LLUUID& id, bool underline_on_hover_only = false ); const LLUUID& getID() const { return mID;} @@ -108,6 +111,7 @@ private: LLUUID mID; LLUIColor mColor; bool mDisabledLink; + bool mUnderlineOnHoverOnly; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 1f86f72faa..b37a52cad2 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -184,7 +184,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getMenuName(), match_entry->getLocation(url), match_entry->isLinkDisabled(), - match_entry->getID(url)); + match_entry->getID(url), + match_entry->underlineOnHoverOnly(url)); return true; } @@ -219,7 +220,8 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getMenuName(), match.getLocation(), match.isLinkDisabled(), - match.getID()); + match.getID(), + match.underlineOnHoverOnly()); return true; } return false; -- cgit v1.2.3 From a486b553e152209158089161463e37a4963aee75 Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Thu, 29 Jul 2010 20:05:53 +0300 Subject: EXT-8043 FIXED Fixed wrong position of notifications when 'Move' or 'View' floaters are open and docked. Bug was caused by LLDockableFloater's mOverlapsScreenChannel to false only in one of it's constructors. So some floaters got initial value of mOverlapsScreenChannel depending on system- that's why bug reproduced on Windows and didn't reproduce on Linux. - Moved setting mOverlapsScreenChannel to false into LLDockableFloater's init() which is called by all of it's constructors. Reviewed by Alexei Arabadji at https://codereview.productengine.com/secondlife/r/818 --HG-- branch : product-engine --- indra/llui/lldockablefloater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 3d8670fef2..4f5fcddbf4 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -49,12 +49,12 @@ void LLDockableFloater::init(LLDockableFloater* thiz) thiz->setCanClose(TRUE); thiz->setCanDock(true); thiz->setCanMinimize(TRUE); + thiz->setOverlapsScreenChannel(false); } LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) - , mOverlapsScreenChannel(false) { init(this); mUseTongue = true; -- cgit v1.2.3 From b5a94da19b7f6aa63f2860a29c0d50e21a7e8104 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 29 Jul 2010 11:56:19 -0700 Subject: fix for vertical truncation of sidebar headers --- indra/llui/lltextbase.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a580345b6c..4bcf7e6980 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1029,8 +1029,10 @@ void LLTextBase::draw() LLUICtrl::draw(); { - // only clip if we support scrolling or have word wrap turned off - LLLocalClipRect clip(doc_rect, !getWordWrap() || mScroller != NULL); + // only clip if we support scrolling... + // since convention is that text boxes never vertically truncate their contents + // regardless of rect bounds + LLLocalClipRect clip(doc_rect, mScroller != NULL); drawSelectionBackground(); drawText(); drawCursor(); -- cgit v1.2.3 From 989552161d94a0371bb0f9a19da379a523881889 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 30 Jul 2010 09:56:49 -0700 Subject: added LLPanel::childSetAction() that does not take a void* argument implemented childGetVisibleTab/PanelWithHelp using breadth-first-search iterator moved tentative state from llview to lluictrl changes llcallbackmap to use boost::function --- indra/llui/llcallbackmap.h | 3 ++- indra/llui/llpanel.cpp | 66 ++++++++++++---------------------------------- indra/llui/llpanel.h | 4 ++- indra/llui/lluictrl.h | 4 +-- indra/llui/llview.cpp | 24 +++++++++-------- indra/llui/llview.h | 6 +++-- 6 files changed, 41 insertions(+), 66 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h index 97b1e2fc50..60c4fc6b6d 100644 --- a/indra/llui/llcallbackmap.h +++ b/indra/llui/llcallbackmap.h @@ -35,12 +35,13 @@ #include #include +#include class LLCallbackMap { public: // callback definition. - typedef void* (*callback_t)(void* data); + typedef boost::function callback_t; typedef std::map map_t; typedef map_t::iterator map_iter_t; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 9ebdcb87c6..0f769bd6dc 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -661,7 +661,7 @@ void LLPanel::childSetEnabled(const std::string& id, bool enabled) void LLPanel::childSetTentative(const std::string& id, bool tentative) { - LLView* child = findChild(id); + LLUICtrl* child = findChild(id); if (child) { child->setTentative(tentative); @@ -860,13 +860,16 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const return NULL; } -static LLPanel *childGetVisibleTabWithHelp(LLView *parent) +LLPanel* LLPanel::childGetVisibleTabWithHelp() { LLView *child; - // look through immediate children first for an active tab with help - for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + bfs_tree_iterator_t it = beginTreeBFS(); + // skip ourselves + ++it; + for (; it != endTreeBFS(); ++it) { + child = *it; LLPanel *curTabPanel = NULL; // do we have a tab container? @@ -890,36 +893,21 @@ static LLPanel *childGetVisibleTabWithHelp(LLView *parent) } } - // then try a bit harder and recurse through all children - for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) - { - if (child->getVisible()) - { - LLPanel* tab = ::childGetVisibleTabWithHelp(child); - if (tab) - { - return tab; - } - } - } - // couldn't find any active tabs with a help topic string return NULL; } -LLPanel *LLPanel::childGetVisibleTabWithHelp() -{ - // find a visible tab with a help topic (to determine help context) - return ::childGetVisibleTabWithHelp(this); -} -static LLPanel *childGetVisiblePanelWithHelp(LLView *parent) +LLPanel *LLPanel::childGetVisiblePanelWithHelp() { LLView *child; - // look through immediate children first for an active panel with help - for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + bfs_tree_iterator_t it = beginTreeBFS(); + // skip ourselves + ++it; + for (; it != endTreeBFS(); ++it) { + child = *it; // do we have a panel with a help topic? LLPanel *panel = dynamic_cast(child); if (panel && panel->getVisible() && !panel->getHelpTopic().empty()) @@ -928,39 +916,19 @@ static LLPanel *childGetVisiblePanelWithHelp(LLView *parent) } } - // then try a bit harder and recurse through all children - for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) - { - if (child->getVisible()) - { - LLPanel* panel = ::childGetVisiblePanelWithHelp(child); - if (panel) - { - return panel; - } - } - } - // couldn't find any active panels with a help topic string return NULL; } -LLPanel *LLPanel::childGetVisiblePanelWithHelp() +void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function) { - // find a visible tab with a help topic (to determine help context) - return ::childGetVisiblePanelWithHelp(this); -} - -void LLPanel::childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) ) -{ - LLLineEditor* child = findChild(id); - if (child) + LLButton* button = findChild(id); + if (button) { - child->setPrevalidate(func); + button->setClickedCallback(function); } } - void LLPanel::childSetAction(const std::string& id, boost::function function, void* value) { LLButton* button = findChild(id); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 03e3dc0c0e..784054cd86 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -170,6 +170,7 @@ public: std::string getString(const std::string& name) const; // ** Wrappers for setting child properties by name ** -TomY + // WARNING: These are deprecated, please use getChild("name")->doStuff() idiom instead // LLView void childSetVisible(const std::string& name, bool visible); @@ -233,7 +234,8 @@ public: void childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) ); // LLButton - void childSetAction(const std::string& id, boost::function function, void* value = NULL); + void childSetAction(const std::string& id, boost::function function, void* value); + void childSetAction(const std::string& id, const commit_signal_t::slot_type& function); // LLTextBox void childSetActionTextbox(const std::string& id, boost::function function, void* value = NULL); diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 1f9d2c9049..259104f72c 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -147,8 +147,6 @@ public: // LLView interface /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); /*virtual*/ BOOL isCtrl() const; - /*virtual*/ void setTentative(BOOL b); - /*virtual*/ BOOL getTentative() const; /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ BOOL canFocusChildren() const; @@ -180,6 +178,8 @@ public: void setMakeVisibleControlVariable(LLControlVariable* control); void setMakeInvisibleControlVariable(LLControlVariable* control); + virtual void setTentative(BOOL b); + virtual BOOL getTentative() const; virtual void setValue(const LLSD& value); virtual LLSD getValue() const; /// When two widgets are displaying the same data (e.g. during a skin diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 394ec957d5..9e68277b0f 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -433,17 +433,6 @@ BOOL LLView::canFocusChildren() const return TRUE; } -//virtual -void LLView::setTentative(BOOL b) -{ -} - -//virtual -BOOL LLView::getTentative() const -{ - return FALSE; -} - //virtual void LLView::setEnabled(BOOL enabled) { @@ -2784,6 +2773,19 @@ LLView::tree_post_iterator_t LLView::endTreeDFSPost() return tree_post_iterator_t(); } +LLView::bfs_tree_iterator_t LLView::beginTreeBFS() +{ + return bfs_tree_iterator_t(this, + boost::bind(boost::mem_fn(&LLView::beginChild), _1), + boost::bind(boost::mem_fn(&LLView::endChild), _1)); +} + +LLView::bfs_tree_iterator_t LLView::endTreeBFS() +{ + // an empty iterator is an "end" iterator + return bfs_tree_iterator_t(); +} + LLView::root_to_view_iterator_t LLView::beginRootToView() { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 8e705ed701..745a1b6e74 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -289,8 +289,6 @@ public: // children, etc. virtual void deleteAllChildren(); - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; void setAllChildrenEnabled(BOOL b); virtual void setVisible(BOOL visible); @@ -357,6 +355,10 @@ public: tree_post_iterator_t beginTreeDFSPost(); tree_post_iterator_t endTreeDFSPost(); + typedef LLTreeBFSIter bfs_tree_iterator_t; + bfs_tree_iterator_t beginTreeBFS(); + bfs_tree_iterator_t endTreeBFS(); + typedef LLTreeDownIter root_to_view_iterator_t; root_to_view_iterator_t beginRootToView(); -- cgit v1.2.3 From d72a21aca1b9692941c066b7aaca69952c27de68 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 30 Jul 2010 15:17:32 -0700 Subject: further UI rendering performance improvements --- indra/llui/lllocalcliprect.cpp | 6 +- indra/llui/lltextbase.cpp | 12 +- indra/llui/lltextbase.h | 2 +- indra/llui/lltexteditor.cpp | 7 +- indra/llui/llui.cpp | 390 +++++++++++++++++++++-------------------- indra/llui/llui.h | 2 - indra/llui/llview.cpp | 38 ++-- indra/llui/llview.h | 1 - 8 files changed, 246 insertions(+), 212 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 55329f64e4..805d5879f7 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -45,9 +45,9 @@ LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) if (mEnabled) { pushClipRect(rect); + mScissorState.setEnabled(!sClipRectStack.empty()); + updateScissorRegion(); } - mScissorState.setEnabled(!sClipRectStack.empty()); - updateScissorRegion(); } LLScreenClipRect::~LLScreenClipRect() @@ -55,8 +55,8 @@ LLScreenClipRect::~LLScreenClipRect() if (mEnabled) { popClipRect(); + updateScissorRegion(); } - updateScissorRegion(); } //static diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 4bcf7e6980..cde08c7b19 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1495,24 +1495,32 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index) { + static LLPointer index_segment = new LLIndexSegment(); + if (index > getLength()) { return mSegments.end(); } // when there are no segments, we return the end iterator, which must be checked by caller if (mSegments.size() <= 1) { return mSegments.begin(); } //FIXME: avoid operator new somehow (without running into refcount problems) - segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index)); + index_segment->setStart(index); + index_segment->setEnd(index); + segment_set_t::iterator it = mSegments.upper_bound(index_segment); return it; } LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 index) const { + static LLPointer index_segment = new LLIndexSegment(); + if (index > getLength()) { return mSegments.end(); } // when there are no segments, we return the end iterator, which must be checked by caller if (mSegments.size() <= 1) { return mSegments.begin(); } - LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index)); + index_segment->setStart(index); + index_segment->setEnd(index); + LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(index_segment); return it; } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 4b83d5effb..db010d1cf6 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -163,7 +163,7 @@ protected: class LLIndexSegment : public LLTextSegment { public: - LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {} + LLIndexSegment() : LLTextSegment(0, 0) {} }; class LLInlineViewSegment : public LLTextSegment diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 6781c23416..482a53e4af 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -461,8 +461,13 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const const LLTextSegmentPtr LLTextEditor::getPreviousSegment() const { + static LLPointer index_segment = new LLIndexSegment; + + index_segment->setStart(mCursorPos); + index_segment->setEnd(mCursorPos); + // find segment index at character to left of cursor (or rightmost edge of selection) - segment_set_t::const_iterator it = mSegments.lower_bound(new LLIndexSegment(mCursorPos)); + segment_set_t::const_iterator it = mSegments.lower_bound(index_segment); if (it != mSegments.end()) { diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 7f9dca08d2..ee308f575a 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -466,7 +466,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect) { stop_glerror(); @@ -476,36 +476,53 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex return; } + // add in offset of current image to current ui translation + const LLVector3 ui_translation = gGL.getUITranslation() + LLVector3(x, y, 0.f); + const LLVector3 ui_scale = gGL.getUIScale(); + + F32 uv_width = uv_outer_rect.getWidth(); + F32 uv_height = uv_outer_rect.getHeight(); + // shrink scaling region to be proportional to clipped image region - LLRectf scale_rect_uv( - uv_rect.mLeft + (scale_rect.mLeft * uv_rect.getWidth()), - uv_rect.mBottom + (scale_rect.mTop * uv_rect.getHeight()), - uv_rect.mLeft + (scale_rect.mRight * uv_rect.getWidth()), - uv_rect.mBottom + (scale_rect.mBottom * uv_rect.getHeight())); - - S32 image_natural_width = llround((F32)image->getWidth(0) * uv_rect.getWidth()); - S32 image_natural_height = llround((F32)image->getHeight(0) * uv_rect.getHeight()); - - LLRect draw_rect(0, height, width, 0); - LLRect draw_scale_rect(llround(scale_rect_uv.mLeft * (F32)image->getWidth(0)), - llround(scale_rect_uv.mTop * (F32)image->getHeight(0)), - llround(scale_rect_uv.mRight * (F32)image->getWidth(0)), - llround(scale_rect_uv.mBottom * (F32)image->getHeight(0))); - // scale fixed region of image to drawn region - draw_scale_rect.mRight += width - image_natural_width; - draw_scale_rect.mTop += height - image_natural_height; - - S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight); - S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop); - - F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - scale_rect.getWidth())); - F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - scale_rect.getHeight())); - - F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); - draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale); - draw_scale_rect.mTop = llround(lerp((F32)height, (F32)draw_scale_rect.mTop, shrink_scale)); - draw_scale_rect.mRight = llround(lerp((F32)width, (F32)draw_scale_rect.mRight, shrink_scale)); - draw_scale_rect.mBottom = llround((F32)draw_scale_rect.mBottom * shrink_scale); + LLRectf uv_center_rect( + uv_outer_rect.mLeft + (center_rect.mLeft * uv_width), + uv_outer_rect.mBottom + (center_rect.mTop * uv_height), + uv_outer_rect.mLeft + (center_rect.mRight * uv_width), + uv_outer_rect.mBottom + (center_rect.mBottom * uv_height)); + + F32 image_width = image->getWidth(0); + F32 image_height = image->getHeight(0); + + S32 image_natural_width = llround(image_width * uv_width); + S32 image_natural_height = llround(image_height * uv_height); + + LLRectf draw_center_rect( uv_center_rect.mLeft * image_width, + uv_center_rect.mTop * image_height, + uv_center_rect.mRight * image_width, + uv_center_rect.mBottom * image_height); + + { // scale fixed region of image to drawn region + draw_center_rect.mRight += width - image_natural_width; + draw_center_rect.mTop += height - image_natural_height; + + F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight); + F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop); + + F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth())); + F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight())); + + F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); + + draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]); + draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale * ui_scale.mV[VY])); + draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale * ui_scale.mV[VX])); + draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]); + } + + LLRectf draw_outer_rect(ui_translation.mV[VX], + ui_translation.mV[VY] + height * ui_scale.mV[VY], + ui_translation.mV[VX] + width * ui_scale.mV[VX], + ui_translation.mV[VY]); LLGLSUIDefault gls_ui; @@ -515,136 +532,174 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); } - gGL.pushUIMatrix(); - { - gGL.translateUI((F32)x, (F32)y, 0.f); + gGL.getTexUnit(0)->bind(image); - gGL.getTexUnit(0)->bind(image); + gGL.color4fv(color.mV); + + const S32 NUM_VERTICES = 9 * 4; // 9 quads + LLVector2 uv[NUM_VERTICES]; + LLVector3 pos[NUM_VERTICES]; - gGL.color4fv(color.mV); - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2i(0, 0); + S32 index = 0; - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, 0); + gGL.begin(LLRender::QUADS); + { + // draw bottom left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(0, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - // draw bottom middle - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, 0); + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, 0); + // draw bottom middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - // draw bottom right - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, 0); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2i(width, 0); + // draw bottom right + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(width, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - // draw left - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(0, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + // draw left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(0, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - // draw middle - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + // draw middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - // draw right - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(width, draw_scale_rect.mBottom); + // draw right + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); - gGL.vertex2i(width, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - // draw top left - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(0, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + // draw top left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, height); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2i(0, height); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; - // draw top middle - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + // draw top middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mRight, height); + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, height); + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; - // draw top right - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); - gGL.vertex2i(width, draw_scale_rect.mTop); + // draw top right + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2i(width, height); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mRight, height); - } - gGL.end(); + uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); } - gGL.popUIMatrix(); + gGL.end(); if (solid_color) { @@ -674,25 +729,36 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre if (degrees == 0.f) { - gGL.pushUIMatrix(); - gGL.translateUI((F32)x, (F32)y, 0.f); - + const S32 NUM_VERTICES = 4; // 9 quads + LLVector2 uv[NUM_VERTICES]; + LLVector3 pos[NUM_VERTICES]; + gGL.begin(LLRender::QUADS); { - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2i(width, height ); + LLVector3 ui_translation = gGL.getUITranslation(); + ui_translation.mV[VX] += x; + ui_translation.mV[VY] += y; + S32 index = 0; - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2i(0, height ); + uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); + pos[index] = LLVector3(ui_translation.mV[VX] + width, ui_translation.mV[VY] + height, 0.f); + index++; - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2i(0, 0); + uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); + pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + height, 0.f); + index++; - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2i(width, 0); + uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); + pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); + index++; + + uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); + pos[index] = LLVector3(ui_translation.mV[VX] + width, ui_translation.mV[VY], 0.f); + index++; + + gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); } gGL.end(); - gGL.popUIMatrix(); } else { @@ -761,25 +827,6 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL LLUI::setLineWidth(1.f); } - -void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom) -{ - gGL.color4fv( LLColor4::white.mV ); - glLogicOp( GL_XOR ); - stop_glerror(); - - gGL.begin(LLRender::QUADS); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.end(); - - glLogicOp( GL_COPY ); - stop_glerror(); -} - - void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) { if (end_angle < start_angle) @@ -1013,42 +1060,6 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, gGL.end(); } -// Draws spokes around a circle. -void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = F_TWO_PI / count; - const F32 HALF_DELTA = DELTA * 0.5f; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius * cos( HALF_DELTA ); - F32 y1 = outer_radius * sin( HALF_DELTA ); - F32 x2 = inner_radius * cos( HALF_DELTA ); - F32 y2 = inner_radius * sin( HALF_DELTA ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin( LLRender::LINES ); - { - while( count-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - void gl_rect_2d_simple_tex( S32 width, S32 height ) { gGL.begin( LLRender::QUADS ); @@ -1236,6 +1247,7 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.popUIMatrix(); } +//FIXME: rewrite to use scissor? void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c18262ef76..745d0ff662 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -96,7 +96,6 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac); void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); @@ -105,7 +104,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); void gl_rect_2d_simple_tex( S32 width, S32 height ); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 9e68277b0f..4d3708302b 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -403,28 +403,40 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const return (a_score == b_score) ? a < b : a_score < b_score; } -bool LLView::trueToRoot(const boost::function& predicate) const +BOOL LLView::isInVisibleChain() const { - const LLView* cur_view = this; - while(cur_view) + BOOL visible = TRUE; + + const LLView* viewp = this; + while(viewp) { - if(!predicate(cur_view)) + if (!viewp->getVisible()) { - return false; + visible = FALSE; + break; } - cur_view = cur_view->getParent(); + viewp = viewp->getParent(); } - return true; -} - -BOOL LLView::isInVisibleChain() const -{ - return trueToRoot(&LLView::getVisible); + + return visible; } BOOL LLView::isInEnabledChain() const { - return trueToRoot(&LLView::getEnabled); + BOOL enabled = TRUE; + + const LLView* viewp = this; + while(viewp) + { + if (!viewp->getEnabled()) + { + enabled = FALSE; + break; + } + viewp = viewp->getParent(); + } + + return enabled; } // virtual diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 745a1b6e74..37f5232f91 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -273,7 +273,6 @@ public: S32 getDefaultTabGroup() const { return mDefaultTabGroup; } S32 getLastTabGroup() { return mLastTabGroup; } - bool trueToRoot(const boost::function& predicate) const; BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; -- cgit v1.2.3 From cba6943b27d447719f88bc9515da773eb3aea288 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 30 Jul 2010 17:41:41 -0700 Subject: optimizations in button rendering --- indra/llui/llbutton.cpp | 12 +++++++----- indra/llui/llbutton.h | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index aeedf62379..5a4f0515fc 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -120,6 +120,7 @@ LLButton::LLButton(const LLButton::Params& p) mFlashing( FALSE ), mCurGlowStrength(0.f), mNeedsHighlight(FALSE), + mMouseOver(false), mUnselectedLabel(p.label()), mSelectedLabel(p.label_selected()), mGLFont(p.font), @@ -504,7 +505,11 @@ void LLButton::onMouseEnter(S32 x, S32 y, MASK mask) LLUICtrl::onMouseEnter(x, y, mask); if (isInEnabledChain()) + { mNeedsHighlight = TRUE; + } + + mMouseOver = true; } void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) @@ -512,6 +517,7 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) LLUICtrl::onMouseLeave(x, y, mask); mNeedsHighlight = FALSE; + mMouseOver = true; } void LLButton::setHighlight(bool b) @@ -565,14 +571,10 @@ void LLButton::draw() } // Unselected image assignments - S32 local_mouse_x; - S32 local_mouse_y; - LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); - bool enabled = isInEnabledChain(); bool pressed = pressed_by_keyboard - || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) + || (hasMouseCapture() && mMouseOver) || mForcePressedState; bool selected = getToggleState(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index f4af19b696..5f25084b35 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -356,6 +356,7 @@ private: BOOL mCommitOnReturn; BOOL mFadeWhenDisabled; bool mForcePressedState; + bool mMouseOver; LLFrameTimer mFlashingTimer; }; -- cgit v1.2.3 From 713417aeeb33f10146b15f1a5da91a6da01b4af1 Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Mon, 2 Aug 2010 21:00:02 +0300 Subject: EXT-5609 FIXED Avoided showing script floater undocked if it was created in mouselook mode. Commiting on behalf of Alex Productengine. - Added check if floater is constructed in mouselook mode and added forcing dock state when floater is shown after constructing in mouselook mode. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/830/ --HG-- branch : product-engine --- indra/llui/lldockablefloater.cpp | 15 +++++++++++++++ indra/llui/lldockablefloater.h | 7 +++++++ 2 files changed, 22 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 4f5fcddbf4..f9983278d1 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -50,6 +50,7 @@ void LLDockableFloater::init(LLDockableFloater* thiz) thiz->setCanDock(true); thiz->setCanMinimize(TRUE); thiz->setOverlapsScreenChannel(false); + thiz->mForceDocking = false; } LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, @@ -81,6 +82,12 @@ LLDockableFloater::~LLDockableFloater() BOOL LLDockableFloater::postBuild() { + // Remember we should force docking when the floater is opened for the first time + if (mIsDockedStateForcedCallback != NULL && mIsDockedStateForcedCallback()) + { + mForceDocking = true; + } + mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); LLFloater::setDocked(true); return LLView::postBuild(); @@ -134,6 +141,14 @@ void LLDockableFloater::resetInstance() void LLDockableFloater::setVisible(BOOL visible) { + // Force docking if requested + if (visible && mForceDocking) + { + setCanDock(true); + setDocked(true); + mForceDocking = false; + } + if(visible && isDocked()) { resetInstance(); diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 2b1ce99ae2..054d59b984 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -130,6 +130,10 @@ protected: void setDockControl(LLDockControl* dockControl); const LLUIImagePtr& getDockTongue(); + // Checks if docking should be forced. + // It may be useful e.g. if floater created in mouselook mode (see EXT-5609) + boost::function mIsDockedStateForcedCallback; + private: std::auto_ptr mDockControl; LLUIImagePtr mDockTongue; @@ -143,6 +147,9 @@ private: bool mUseTongue; bool mOverlapsScreenChannel; + + // Force docking when the floater is being shown for the first time. + bool mForceDocking; }; #endif /* LL_DOCKABLEFLOATER_H */ -- cgit v1.2.3 From df5d5b841484b5f94b86177cfc7d29a5d9a5b94e Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 2 Aug 2010 18:54:31 -0700 Subject: EXT-8545 FIX Button art and other images are positioned incorrectly when UI scale != 1.0 --- indra/llui/llui.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index ee308f575a..5d8b628776 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -477,8 +477,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex } // add in offset of current image to current ui translation - const LLVector3 ui_translation = gGL.getUITranslation() + LLVector3(x, y, 0.f); const LLVector3 ui_scale = gGL.getUIScale(); + const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale); F32 uv_width = uv_outer_rect.getWidth(); F32 uv_height = uv_outer_rect.getHeight(); @@ -514,8 +514,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]); - draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale * ui_scale.mV[VY])); - draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale * ui_scale.mV[VX])); + draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]); + draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]); draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]); } @@ -735,17 +735,21 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre gGL.begin(LLRender::QUADS); { + LLVector3 ui_scale = gGL.getUIScale(); LLVector3 ui_translation = gGL.getUITranslation(); ui_translation.mV[VX] += x; ui_translation.mV[VY] += y; + ui_translation.scaleVec(ui_scale); S32 index = 0; + S32 scaled_width = llround(width * ui_scale.mV[VX]); + S32 scaled_height = llround(height * ui_scale.mV[VY]); uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX] + width, ui_translation.mV[VY] + height, 0.f); + pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); index++; uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + height, 0.f); + pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); index++; uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); @@ -753,7 +757,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre index++; uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); - pos[index] = LLVector3(ui_translation.mV[VX] + width, ui_translation.mV[VY], 0.f); + pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); index++; gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); -- cgit v1.2.3 From ec06fa16ec73d033ac70f9896f382aa4af993403 Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Wed, 4 Aug 2010 11:45:47 +0300 Subject: EXT-8424 FIXED ([HARD CODED] ALL LANGS: \"More\" menu option is untranslated under Advanced menu (French viewer) > Shortcuts) Set translated label from strings.xml Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/831/ --HG-- branch : product-engine --- indra/llui/llmenugl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 12007f7b52..46a7215707 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -58,6 +58,7 @@ #include "llbutton.h" #include "llfontgl.h" #include "llresmgr.h" +#include "lltrans.h" #include "llui.h" #include "llstl.h" @@ -2272,8 +2273,9 @@ void LLMenuGL::createSpilloverBranch() // technically, you can't tear off spillover menus, but we're passing the handle // along just to be safe LLMenuGL::Params p; + std::string label = LLTrans::getString("More"); p.name("More"); - p.label("More"); // *TODO: Translate + p.label(label); p.bg_color(mBackgroundColor); p.bg_visible(true); p.can_tear_off(false); @@ -2282,7 +2284,7 @@ void LLMenuGL::createSpilloverBranch() LLMenuItemBranchGL::Params branch_params; branch_params.name = "More"; - branch_params.label = "More"; // *TODO: Translate + branch_params.label = label; branch_params.branch = mSpilloverMenu; branch_params.font.style = "italic"; -- cgit v1.2.3 From 326ad1933b0df66f801577c6da290a6dab54d367 Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Fri, 6 Aug 2010 18:50:24 +0300 Subject: EXT-8207 FIXED (Unexpected camera zoom occures if scroll location history drop-down list by mouse wheel) Added parameter for scroll list control that determines opaque of mouse scroll wheel event. Set this parameter to \"true\" in combobox of navigation panel. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/829/ --HG-- branch : product-engine --- indra/llui/llscrolllistctrl.cpp | 8 ++++++++ indra/llui/llscrolllistctrl.h | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index d4d161f2c9..bb43c19c2c 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -135,6 +135,7 @@ LLScrollListCtrl::Params::Params() search_column("search_column", 0), sort_column("sort_column", -1), sort_ascending("sort_ascending", true), + mouse_wheel_opaque("mouse_wheel_opaque", false), commit_on_keyboard_movement("commit_on_keyboard_movement", true), heading_height("heading_height"), page_lines("page_lines", 0), @@ -163,6 +164,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) : LLUICtrl(p), mLineHeight(0), mScrollLines(0), + mMouseWheelOpaque(p.mouse_wheel_opaque), mPageLines(p.page_lines), mMaxSelectable(0), mAllowKeyboardMovement(TRUE), @@ -1536,6 +1538,12 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL handled = FALSE; // Pretend the mouse is over the scrollbar handled = mScrollbar->handleScrollWheel( 0, 0, clicks ); + + if (mMouseWheelOpaque) + { + return TRUE; + } + return handled; } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 1f0ef585db..19cb7e2bfe 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -102,7 +102,8 @@ public: { // behavioral flags Optional multi_select, - commit_on_keyboard_movement; + commit_on_keyboard_movement, + mouse_wheel_opaque; // display flags Optional has_border, @@ -449,6 +450,7 @@ private: BOOL mCommitOnSelectionChange; BOOL mSelectionChanged; BOOL mNeedsScroll; + BOOL mMouseWheelOpaque; BOOL mCanSelect; const BOOL mDisplayColumnHeaders; BOOL mColumnsDirty; -- cgit v1.2.3 From 76922597c219f27c5372a8a92e26e77338eb2dc2 Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Fri, 6 Aug 2010 22:34:18 +0300 Subject: EXT-4379 FIXED tab_stop parameter initialization that prevented inventory panel from passing focus to folder view's scroll container. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/823/. --HG-- branch : product-engine --- indra/llui/lluictrl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llui') diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index ff330f863a..c91e225fd2 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -101,6 +101,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) : LLView(p), mTentative(FALSE), mIsChrome(FALSE), + mTabStop(FALSE), mViewModel(viewmodel), mControlVariable(NULL), mEnabledControlVariable(NULL), -- cgit v1.2.3 From 55c887225f230822f5ffcd1b1a01a87d17653bd7 Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Mon, 9 Aug 2010 15:14:45 +0300 Subject: EXT-8010 ADDITIONAL FIX Fixed problems with avatar links underlining. There were two problems: 1. Underlining broke when avatar's first and second name were on different lines. 2. There was no underline on hover for avatar miniinspector links in plaintext IM. - First problem was caused by calling LLOnHoverChangeableTextSegment::draw() for the same segment twice- for first and second name that were on different lines, while handleHover() was called only once. So handleHover() was called -> text was underlined -> first part of segment was drawn underlined -> its draw set style back to normal -> second part of segment was drawn without underlining. Fixed this by setting style back to normal only when drawing the last part of the segment. - Second problem was caused by unusual way of appending link to text in chat history. Changed it so that LLTextBase::appendText() now receives link not inside style params, but directly. Also added "/inspect" ending to check in LLUrlEntryAgent::underlineOnHoverOnly(). Reviewed by Richard Nelson at https://codereview.productengine.com/secondlife/r/833/ --HG-- branch : product-engine --- indra/llui/lltextbase.cpp | 5 ++++- indra/llui/llurlentry.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cde08c7b19..3792f18c97 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2723,7 +2723,10 @@ LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP s F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect); - mStyle = mNormalStyle; + if (end == mEnd - mStart) + { + mStyle = mNormalStyle; + } return result; } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 17d211fb36..bf7b25910f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -366,7 +366,7 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const { std::string url = getUrl(string); - return LLStringUtil::endsWith(url, "/about"); + return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect"); } std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) -- cgit v1.2.3 From 7bce6580dc2849b99ae6eedd5c373b653ab5186d Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Mon, 9 Aug 2010 15:23:00 +0300 Subject: EXT-7593 FIXED Added passing focus to the selected outfit tab when My Outfits tab is open. - Removed "tab_stop" from outfit tabs to prevent passing focus to a tab chosen by default from LLUICtrl::focusFirstItem(). Besides the order of passing focus between outfit tabs by pressing "Tab" was undetermined. - Had to remove const from the return of LLAccordionCtrl::getSelectedTab() to use the returned pointer for setting focus. Reviewed by Neal Orman at https://codereview.productengine.com/secondlife/r/846/. --HG-- branch : product-engine --- indra/llui/llaccordionctrl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index f26a380e5f..6fc9ca86a3 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -139,7 +139,7 @@ public: */ const LLAccordionCtrlTab* getExpandedTab() const; - const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } + LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } bool getFitParent() const {return mFitParent;} -- cgit v1.2.3 From 7312471e7f6ed54170f8c38809b34a001bd7c82b Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Thu, 12 Aug 2010 13:19:23 +0300 Subject: EXT-7951 FIXED (Mini-Location panel appearance design issues) - Added callback on show\hide Mini Location Panel event. This callback sets proper initial minimized position depending on state (shown or hidded) Mini Location Panel. Also callback shifts vertically already minimized floaters so that they don't overlap Mini Location Panel Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/851/ --HG-- branch : product-engine --- indra/llui/llfloater.cpp | 14 ++++++++++++++ indra/llui/llfloater.h | 3 +++ 2 files changed, 17 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 22d6f6ca52..838f93d3f9 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2285,6 +2285,7 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) S32 floater_header_size = default_params.header_height; static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); LLRect snap_rect_local = getLocalSnapRect(); + snap_rect_local.mTop += mMinimizePositionVOffset; for(S32 col = snap_rect_local.mLeft; col < snap_rect_local.getWidth() - minimized_width; col += minimized_width) @@ -2382,6 +2383,19 @@ BOOL LLFloaterView::allChildrenClosed() return true; } +void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset) +{ + for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); + + if (floaterp && floaterp->isMinimized()) + { + floaterp->translate(x_offset, y_offset); + } + } +} + void LLFloaterView::refresh() { // Constrain children to be entirely on the screen diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 42f422f91c..e7d365238b 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -455,6 +455,7 @@ public: // Given a child of gFloaterView, make sure this view can fit entirely onscreen. void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside); + void setMinimizePositionVerticalOffset(S32 offset) { mMinimizePositionVOffset = offset; } void getMinimizePosition( S32 *left, S32 *bottom); void restoreAll(); // un-minimize all floaters typedef std::set skip_list_t; @@ -471,6 +472,7 @@ public: // attempt to close all floaters void closeAllChildren(bool app_quitting); BOOL allChildrenClosed(); + void shiftFloaters(S32 x_offset, S32 y_offset); LLFloater* getFrontmost() const; LLFloater* getBackmost() const; @@ -490,6 +492,7 @@ private: BOOL mFocusCycleMode; S32 mSnapOffsetBottom; S32 mSnapOffsetRight; + S32 mMinimizePositionVOffset; }; // -- cgit v1.2.3 From f523a589a7b4456d86e6ef90ff5b77ae0b416eae Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Fri, 13 Aug 2010 19:33:18 +0300 Subject: EXT-8536 FIXED Fixed wrong behaviour of slidercontrol's lineeditor revert on escape. Though bug description mentioned only appearance, bug reproduced for all slidercontrols. The cause of returning on escape to old value instead of last commited one was that on commit slidercontrol set text for it's lineeditor which was the same as the one currently typed into lineeditor(and it seems logical). But LLLineEditor::setText() has check at it's beginning which compares text which is being set to the one which is already there. If this check succeeds, we exit the method and thus saving of value for revert is not reached. That's why when revert happened on escape older value then the last commited was set in lineeditor. - Added additional call of setText() in sliderctrl to force changes in currently set text so that on next call with "real" text saving of reverted value was reached. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/856/ --HG-- branch : product-engine --- indra/llui/llsliderctrl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 04958075db..1c410cc1aa 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -235,6 +235,10 @@ void LLSliderCtrl::updateText() std::string text = llformat(format.c_str(), displayed_value); if( mEditor ) { + // Setting editor text here to "" before using actual text is here because if text which + // is set is the same as the one which is actually typed into lineeditor, LLLineEditor::setText() + // will exit at it's beginning, so text for revert on escape won't be saved. (EXT-8536) + mEditor->setText( LLStringUtil::null ); mEditor->setText( text ); } else -- cgit v1.2.3 From a0ca74794be2176b57b754ebb6872fcf8c30c48c Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Tue, 17 Aug 2010 22:34:50 +0300 Subject: EXT-8357 FIXED ESC key sometimes failing to de-focus the sidebar. I've found out that the only case when pressing ESC doesn't transfer focus from side tray to game area is when a flat list view (people, groups, teleport history, etc) is focused. So, I fixed LLFlatListView to handle pressing ESC as expected. Reviewed by Sergey Litovchuk at https://codereview.productengine.com/secondlife/r/862/ --HG-- branch : product-engine --- indra/llui/llflatlistview.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 70558f8eb8..8de44455de 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -669,6 +669,14 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask) } break; } + case KEY_ESCAPE: + { + if (mask == MASK_NONE) + { + setFocus(FALSE); // pass focus to the game area (EXT-8357) + } + break; + } default: break; } -- cgit v1.2.3 From b5fc9c3254a1bb83d1d454cea95db85f36f40ccf Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Mon, 23 Aug 2010 13:12:56 +0100 Subject: VWR-20899 FIXED Minor potential memory leak in LLFlatListView::addItem --- indra/llui/llflatlistview.cpp | 3 +++ indra/llui/llflatlistview.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index f266af03ee..b28399a36b 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -87,6 +87,9 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null* mItemsPanel->addChild(item); break; default: + LL_WARNS("") << "Unsupported position." << LL_ENDL; + delete new_pair; + return false; break; } diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 8667af048b..afd0176d98 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -54,6 +54,7 @@ */ class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler { + LOG_CLASS(LLFlatListView); public: /** @@ -448,6 +449,7 @@ private: */ class LLFlatListViewEx : public LLFlatListView { + LOG_CLASS(LLFlatListViewEx); public: struct Params : public LLInitParam::Block { -- cgit v1.2.3 From 98cc2365034a93c69704daa69efb389799cc9627 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Tue, 24 Aug 2010 18:44:39 +0100 Subject: Backed out changeset a62bf7c0af21 Backing out this merge that I pushed (prematurely) to the wrong place. --- indra/llui/llaccordionctrl.h | 2 +- indra/llui/llaccordionctrltab.cpp | 3 +- indra/llui/llaccordionctrltab.h | 2 - indra/llui/llbutton.cpp | 12 +- indra/llui/llbutton.h | 1 - indra/llui/llcallbackmap.h | 3 +- indra/llui/lldockablefloater.cpp | 17 +- indra/llui/lldockablefloater.h | 7 - indra/llui/lldraghandle.cpp | 2 +- indra/llui/llflatlistview.cpp | 28 +-- indra/llui/llflatlistview.h | 1 - indra/llui/llfloater.cpp | 14 -- indra/llui/llfloater.h | 3 - indra/llui/lllocalcliprect.cpp | 48 ++++- indra/llui/lllocalcliprect.h | 26 +-- indra/llui/llmenugl.cpp | 6 +- indra/llui/llpanel.cpp | 66 +++++-- indra/llui/llpanel.h | 4 +- indra/llui/llscrolllistctrl.cpp | 8 - indra/llui/llscrolllistctrl.h | 4 +- indra/llui/llsliderctrl.cpp | 4 - indra/llui/llstyle.cpp | 12 +- indra/llui/llstyle.h | 37 ++-- indra/llui/lltextbase.cpp | 121 ++++-------- indra/llui/lltextbase.h | 29 +-- indra/llui/lltextbox.cpp | 11 -- indra/llui/lltextbox.h | 2 - indra/llui/lltexteditor.cpp | 10 +- indra/llui/lltextvalidate.cpp | 18 -- indra/llui/lltextvalidate.h | 1 - indra/llui/lltooltip.cpp | 2 +- indra/llui/llui.cpp | 400 ++++++++++++++++++-------------------- indra/llui/llui.h | 2 + indra/llui/lluictrl.cpp | 1 - indra/llui/lluictrl.h | 4 +- indra/llui/llurlentry.cpp | 19 -- indra/llui/llurlentry.h | 5 - indra/llui/llurlmatch.cpp | 6 +- indra/llui/llurlmatch.h | 6 +- indra/llui/llurlregistry.cpp | 6 +- indra/llui/llview.cpp | 62 +++--- indra/llui/llview.h | 7 +- 42 files changed, 402 insertions(+), 620 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index 1fe64c472e..e2de4b9d3b 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -133,7 +133,7 @@ public: */ const LLAccordionCtrlTab* getExpandedTab() const; - LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } + const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } bool getFitParent() const {return mFitParent;} diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index b7da5f4a1b..4e0537f592 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -353,7 +353,6 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) ,mPaddingBottom(p.padding_bottom) ,mCanOpenClose(true) ,mFitPanel(p.fit_panel) - ,mSelectionEnabled(p.selection_enabled) ,mContainerPanel(NULL) ,mScrollbar(NULL) { @@ -825,7 +824,7 @@ void LLAccordionCtrlTab::showAndFocusHeader() { LLAccordionCtrlTabHeader* header = getChild(DD_HEADER_NAME); header->setFocus(true); - header->setSelected(mSelectionEnabled); + header->setSelected(true); LLRect screen_rc; LLRect selected_rc = header->getRect(); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index d6ac8cbc8f..8ae91ad651 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -236,8 +236,6 @@ private: bool mStoredOpenCloseState; bool mWasStateStored; - bool mSelectionEnabled; - LLScrollbar* mScrollbar; LLView* mContainerPanel; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f0f34ebd4f..ac5651e4b6 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -114,7 +114,6 @@ LLButton::LLButton(const LLButton::Params& p) mFlashing( FALSE ), mCurGlowStrength(0.f), mNeedsHighlight(FALSE), - mMouseOver(false), mUnselectedLabel(p.label()), mSelectedLabel(p.label_selected()), mGLFont(p.font), @@ -499,11 +498,7 @@ void LLButton::onMouseEnter(S32 x, S32 y, MASK mask) LLUICtrl::onMouseEnter(x, y, mask); if (isInEnabledChain()) - { mNeedsHighlight = TRUE; - } - - mMouseOver = true; } void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) @@ -511,7 +506,6 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) LLUICtrl::onMouseLeave(x, y, mask); mNeedsHighlight = FALSE; - mMouseOver = true; } void LLButton::setHighlight(bool b) @@ -565,10 +559,14 @@ void LLButton::draw() } // Unselected image assignments + S32 local_mouse_x; + S32 local_mouse_y; + LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); + bool enabled = isInEnabledChain(); bool pressed = pressed_by_keyboard - || (hasMouseCapture() && mMouseOver) + || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) || mForcePressedState; bool selected = getToggleState(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index d87ceb7c42..2d5fefa78c 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -350,7 +350,6 @@ private: BOOL mCommitOnReturn; BOOL mFadeWhenDisabled; bool mForcePressedState; - bool mMouseOver; LLFrameTimer mFlashingTimer; }; diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h index 0a10877c09..eb8b423b29 100644 --- a/indra/llui/llcallbackmap.h +++ b/indra/llui/llcallbackmap.h @@ -29,13 +29,12 @@ #include #include -#include class LLCallbackMap { public: // callback definition. - typedef boost::function callback_t; + typedef void* (*callback_t)(void* data); typedef std::map map_t; typedef map_t::iterator map_iter_t; diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index ca2dc644a4..bf55239f1b 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -43,13 +43,12 @@ void LLDockableFloater::init(LLDockableFloater* thiz) thiz->setCanClose(TRUE); thiz->setCanDock(true); thiz->setCanMinimize(TRUE); - thiz->setOverlapsScreenChannel(false); - thiz->mForceDocking = false; } LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) + , mOverlapsScreenChannel(false) { init(this); mUseTongue = true; @@ -76,12 +75,6 @@ LLDockableFloater::~LLDockableFloater() BOOL LLDockableFloater::postBuild() { - // Remember we should force docking when the floater is opened for the first time - if (mIsDockedStateForcedCallback != NULL && mIsDockedStateForcedCallback()) - { - mForceDocking = true; - } - mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); LLFloater::setDocked(true); return LLView::postBuild(); @@ -135,14 +128,6 @@ void LLDockableFloater::resetInstance() void LLDockableFloater::setVisible(BOOL visible) { - // Force docking if requested - if (visible && mForceDocking) - { - setCanDock(true); - setDocked(true); - mForceDocking = false; - } - if(visible && isDocked()) { resetInstance(); diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 8deb6c1159..86dcf670b1 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -124,10 +124,6 @@ protected: void setDockControl(LLDockControl* dockControl); const LLUIImagePtr& getDockTongue(); - // Checks if docking should be forced. - // It may be useful e.g. if floater created in mouselook mode (see EXT-5609) - boost::function mIsDockedStateForcedCallback; - private: std::auto_ptr mDockControl; LLUIImagePtr mDockTongue; @@ -141,9 +137,6 @@ private: bool mUseTongue; bool mOverlapsScreenChannel; - - // Force docking when the floater is being shown for the first time. - bool mForceDocking; }; #endif /* LL_DOCKABLEFLOATER_H */ diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 42e6c3c786..9ad7c01bd5 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -107,7 +107,7 @@ void LLDragHandleTop::setTitle(const std::string& title) params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); params.font_shadow(LLFontGL::DROP_SHADOW_SOFT); params.use_ellipses = true; - params.parse_urls = false; //cancel URL replacement in floater title + params.allow_html = false; //cancel URL replacement in floater title mTitleBox = LLUICtrlFactory::create (params); addChild( mTitleBox ); } diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index c57c02f4b1..b28399a36b 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -607,14 +607,8 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) return; } - //no need to do additional commit on selection reset - if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(true); - - //only CTRL usage allows to deselect an item, usual clicking on an item cannot deselect it - if (mask & MASK_CONTROL) + if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(); selectItemPair(item_pair, select_item); - else - selectItemPair(item_pair, true); } void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask) @@ -666,14 +660,6 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask) } break; } - case KEY_ESCAPE: - { - if (mask == MASK_NONE) - { - setFocus(FALSE); // pass focus to the game area (EXT-8357) - } - break; - } default: break; } @@ -789,18 +775,6 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select) return true; } -void LLFlatListView::scrollToShowFirstSelectedItem() -{ - if (!mSelectedItemPairs.size()) return; - - LLRect selected_rc = mSelectedItemPairs.front()->first->getRect(); - - if (selected_rc.isValid()) - { - scrollToShowRect(selected_rc); - } -} - LLRect LLFlatListView::getLastSelectedItemRect() { if (!mSelectedItemPairs.size()) diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 0515853698..afd0176d98 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -292,7 +292,6 @@ public: bool updateValue(const LLSD& old_value, const LLSD& new_value); - void scrollToShowFirstSelectedItem(); void selectFirstItem (); void selectLastItem (); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e1203971ea..3cfb2c5d4a 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2279,7 +2279,6 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) S32 floater_header_size = default_params.header_height; static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); LLRect snap_rect_local = getLocalSnapRect(); - snap_rect_local.mTop += mMinimizePositionVOffset; for(S32 col = snap_rect_local.mLeft; col < snap_rect_local.getWidth() - minimized_width; col += minimized_width) @@ -2377,19 +2376,6 @@ BOOL LLFloaterView::allChildrenClosed() return true; } -void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset) -{ - for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); - - if (floaterp && floaterp->isMinimized()) - { - floaterp->translate(x_offset, y_offset); - } - } -} - void LLFloaterView::refresh() { // Constrain children to be entirely on the screen diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 5e482cbac3..2deae29607 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -449,7 +449,6 @@ public: // Given a child of gFloaterView, make sure this view can fit entirely onscreen. void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside); - void setMinimizePositionVerticalOffset(S32 offset) { mMinimizePositionVOffset = offset; } void getMinimizePosition( S32 *left, S32 *bottom); void restoreAll(); // un-minimize all floaters typedef std::set skip_list_t; @@ -466,7 +465,6 @@ public: // attempt to close all floaters void closeAllChildren(bool app_quitting); BOOL allChildrenClosed(); - void shiftFloaters(S32 x_offset, S32 y_offset); LLFloater* getFrontmost() const; LLFloater* getBackmost() const; @@ -486,7 +484,6 @@ private: BOOL mFocusCycleMode; S32 mSnapOffsetBottom; S32 mSnapOffsetRight; - S32 mMinimizePositionVOffset; }; // diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 6841301219..1a311bb13a 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -27,8 +27,33 @@ #include "lllocalcliprect.h" #include "llfontgl.h" +#include "llgl.h" #include "llui.h" +#include + +//--------------------------------------------------------------------------- +// LLScreenClipRect +// implementation class in screen space +//--------------------------------------------------------------------------- +class LLScreenClipRect +{ +public: + LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); + virtual ~LLScreenClipRect(); + +private: + static void pushClipRect(const LLRect& rect); + static void popClipRect(); + static void updateScissorRegion(); + +private: + LLGLState mScissorState; + BOOL mEnabled; + + static std::stack sClipRectStack; +}; + /*static*/ std::stack LLScreenClipRect::sClipRectStack; @@ -39,9 +64,9 @@ LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) if (mEnabled) { pushClipRect(rect); - mScissorState.setEnabled(!sClipRectStack.empty()); - updateScissorRegion(); } + mScissorState.setEnabled(!sClipRectStack.empty()); + updateScissorRegion(); } LLScreenClipRect::~LLScreenClipRect() @@ -49,8 +74,8 @@ LLScreenClipRect::~LLScreenClipRect() if (mEnabled) { popClipRect(); - updateScissorRegion(); } + updateScissorRegion(); } //static @@ -100,11 +125,16 @@ void LLScreenClipRect::updateScissorRegion() // LLLocalClipRect //--------------------------------------------------------------------------- LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, - rect.mTop + LLFontGL::sCurOrigin.mY, - rect.mRight + LLFontGL::sCurOrigin.mX, - rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) -{} +{ + LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX, + rect.mTop + LLFontGL::sCurOrigin.mY, + rect.mRight + LLFontGL::sCurOrigin.mX, + rect.mBottom + LLFontGL::sCurOrigin.mY); + mScreenClipRect = new LLScreenClipRect(screen, enabled); +} LLLocalClipRect::~LLLocalClipRect() -{} +{ + delete mScreenClipRect; + mScreenClipRect = NULL; +} diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h index eeeaf2adb6..0097958916 100644 --- a/indra/llui/lllocalcliprect.h +++ b/indra/llui/lllocalcliprect.h @@ -25,9 +25,7 @@ #ifndef LLLOCALCLIPRECT_H #define LLLOCALCLIPRECT_H -#include "llgl.h" #include "llrect.h" // can't forward declare, it's templated -#include // Clip rendering to a specific rectangle using GL scissor // Just create one of these on the stack: @@ -35,29 +33,15 @@ // LLLocalClipRect(rect); // draw(); // } -class LLScreenClipRect -{ -public: - LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); - virtual ~LLScreenClipRect(); - -private: - static void pushClipRect(const LLRect& rect); - static void popClipRect(); - static void updateScissorRegion(); - -private: - LLGLState mScissorState; - BOOL mEnabled; - - static std::stack sClipRectStack; -}; - -class LLLocalClipRect : public LLScreenClipRect +class LLLocalClipRect { public: LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); ~LLLocalClipRect(); + +private: + // implementation class + class LLScreenClipRect* mScreenClipRect; }; #endif diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 3e652ea960..c533610381 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -52,7 +52,6 @@ #include "llbutton.h" #include "llfontgl.h" #include "llresmgr.h" -#include "lltrans.h" #include "llui.h" #include "llstl.h" @@ -2267,9 +2266,8 @@ void LLMenuGL::createSpilloverBranch() // technically, you can't tear off spillover menus, but we're passing the handle // along just to be safe LLMenuGL::Params p; - std::string label = LLTrans::getString("More"); p.name("More"); - p.label(label); + p.label("More"); // *TODO: Translate p.bg_color(mBackgroundColor); p.bg_visible(true); p.can_tear_off(false); @@ -2278,7 +2276,7 @@ void LLMenuGL::createSpilloverBranch() LLMenuItemBranchGL::Params branch_params; branch_params.name = "More"; - branch_params.label = label; + branch_params.label = "More"; // *TODO: Translate branch_params.branch = mSpilloverMenu; branch_params.font.style = "italic"; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index b2e08c48c5..6fe36bbc0c 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -655,7 +655,7 @@ void LLPanel::childSetEnabled(const std::string& id, bool enabled) void LLPanel::childSetTentative(const std::string& id, bool tentative) { - LLUICtrl* child = findChild(id); + LLView* child = findChild(id); if (child) { child->setTentative(tentative); @@ -854,16 +854,13 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const return NULL; } -LLPanel* LLPanel::childGetVisibleTabWithHelp() +static LLPanel *childGetVisibleTabWithHelp(LLView *parent) { LLView *child; - bfs_tree_iterator_t it = beginTreeBFS(); - // skip ourselves - ++it; - for (; it != endTreeBFS(); ++it) + // look through immediate children first for an active tab with help + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) { - child = *it; LLPanel *curTabPanel = NULL; // do we have a tab container? @@ -887,21 +884,36 @@ LLPanel* LLPanel::childGetVisibleTabWithHelp() } } + // then try a bit harder and recurse through all children + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + { + if (child->getVisible()) + { + LLPanel* tab = ::childGetVisibleTabWithHelp(child); + if (tab) + { + return tab; + } + } + } + // couldn't find any active tabs with a help topic string return NULL; } +LLPanel *LLPanel::childGetVisibleTabWithHelp() +{ + // find a visible tab with a help topic (to determine help context) + return ::childGetVisibleTabWithHelp(this); +} -LLPanel *LLPanel::childGetVisiblePanelWithHelp() +static LLPanel *childGetVisiblePanelWithHelp(LLView *parent) { LLView *child; - bfs_tree_iterator_t it = beginTreeBFS(); - // skip ourselves - ++it; - for (; it != endTreeBFS(); ++it) + // look through immediate children first for an active panel with help + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) { - child = *it; // do we have a panel with a help topic? LLPanel *panel = dynamic_cast(child); if (panel && panel->getVisible() && !panel->getHelpTopic().empty()) @@ -910,19 +922,39 @@ LLPanel *LLPanel::childGetVisiblePanelWithHelp() } } + // then try a bit harder and recurse through all children + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + { + if (child->getVisible()) + { + LLPanel* panel = ::childGetVisiblePanelWithHelp(child); + if (panel) + { + return panel; + } + } + } + // couldn't find any active panels with a help topic string return NULL; } -void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function) +LLPanel *LLPanel::childGetVisiblePanelWithHelp() { - LLButton* button = findChild(id); - if (button) + // find a visible tab with a help topic (to determine help context) + return ::childGetVisiblePanelWithHelp(this); +} + +void LLPanel::childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) ) +{ + LLLineEditor* child = findChild(id); + if (child) { - button->setClickedCallback(function); + child->setPrevalidate(func); } } + void LLPanel::childSetAction(const std::string& id, boost::function function, void* value) { LLButton* button = findChild(id); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index a7224648c1..ca8bb77b77 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -164,7 +164,6 @@ public: std::string getString(const std::string& name) const; // ** Wrappers for setting child properties by name ** -TomY - // WARNING: These are deprecated, please use getChild("name")->doStuff() idiom instead // LLView void childSetVisible(const std::string& name, bool visible); @@ -228,8 +227,7 @@ public: void childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) ); // LLButton - void childSetAction(const std::string& id, boost::function function, void* value); - void childSetAction(const std::string& id, const commit_signal_t::slot_type& function); + void childSetAction(const std::string& id, boost::function function, void* value = NULL); // LLTextBox void childSetActionTextbox(const std::string& id, boost::function function, void* value = NULL); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 84e438cfb7..3f4ab0fbc8 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -129,7 +129,6 @@ LLScrollListCtrl::Params::Params() search_column("search_column", 0), sort_column("sort_column", -1), sort_ascending("sort_ascending", true), - mouse_wheel_opaque("mouse_wheel_opaque", false), commit_on_keyboard_movement("commit_on_keyboard_movement", true), heading_height("heading_height"), page_lines("page_lines", 0), @@ -158,7 +157,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) : LLUICtrl(p), mLineHeight(0), mScrollLines(0), - mMouseWheelOpaque(p.mouse_wheel_opaque), mPageLines(p.page_lines), mMaxSelectable(0), mAllowKeyboardMovement(TRUE), @@ -1532,12 +1530,6 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL handled = FALSE; // Pretend the mouse is over the scrollbar handled = mScrollbar->handleScrollWheel( 0, 0, clicks ); - - if (mMouseWheelOpaque) - { - return TRUE; - } - return handled; } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8a2f893ba2..30618866af 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -96,8 +96,7 @@ public: { // behavioral flags Optional multi_select, - commit_on_keyboard_movement, - mouse_wheel_opaque; + commit_on_keyboard_movement; // display flags Optional has_border, @@ -444,7 +443,6 @@ private: BOOL mCommitOnSelectionChange; BOOL mSelectionChanged; BOOL mNeedsScroll; - BOOL mMouseWheelOpaque; BOOL mCanSelect; const BOOL mDisplayColumnHeaders; BOOL mColumnsDirty; diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index d760178e35..904c458e85 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -229,10 +229,6 @@ void LLSliderCtrl::updateText() std::string text = llformat(format.c_str(), displayed_value); if( mEditor ) { - // Setting editor text here to "" before using actual text is here because if text which - // is set is the same as the one which is actually typed into lineeditor, LLLineEditor::setText() - // will exit at it's beginning, so text for revert on escape won't be saved. (EXT-8536) - mEditor->setText( LLStringUtil::null ); mEditor->setText( text ); } else diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 5e09cee78b..93314d7bc0 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -36,8 +36,6 @@ LLStyle::Params::Params() : visible("visible", true), drop_shadow("drop_shadow", LLFontGL::NO_SHADOW), color("color", LLColor4::black), - readonly_color("readonly_color", LLColor4::black), - selected_color("selected_color", LLColor4::black), font("font", LLFontGL::getFontMonospace()), image("image"), link_href("href") @@ -45,10 +43,12 @@ LLStyle::Params::Params() LLStyle::LLStyle(const LLStyle::Params& p) -: mVisible(p.visible), - mColor(p.color), - mReadOnlyColor(p.readonly_color), - mSelectedColor(p.selected_color), +: mItalic(FALSE), + mBold(FALSE), + mUnderline(FALSE), + mVisible(p.visible), + mColor(p.color()), + mReadOnlyColor(p.readonly_color()), mFont(p.font()), mLink(p.link_href), mDropShadow(p.drop_shadow), diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 66cd639936..bfd0d72e85 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -41,8 +41,7 @@ public: Optional visible; Optional drop_shadow; Optional color, - readonly_color, - selected_color; + readonly_color; Optional font; Optional image; Optional link_href; @@ -50,14 +49,11 @@ public: }; LLStyle(const Params& p = Params()); public: - const LLUIColor& getColor() const { return mColor; } - void setColor(const LLUIColor &color) { mColor = color; } + const LLColor4& getColor() const { return mColor; } + void setColor(const LLColor4 &color) { mColor = color; } - const LLUIColor& getReadOnlyColor() const { return mReadOnlyColor; } - void setReadOnlyColor(const LLUIColor& color) { mReadOnlyColor = color; } - - const LLUIColor& getSelectedColor() const { return mSelectedColor; } - void setSelectedColor(const LLUIColor& color) { mSelectedColor = color; } + const LLColor4& getReadOnlyColor() const { return mReadOnlyColor; } + void setReadOnlyColor(const LLColor4& color) { mReadOnlyColor = color; } BOOL isVisible() const; void setVisible(BOOL is_visible); @@ -77,36 +73,41 @@ public: BOOL isImage() const { return mImagep.notNull(); } + // inlined here to make it easier to compare to member data below. -MG bool operator==(const LLStyle &rhs) const { return mVisible == rhs.mVisible && mColor == rhs.mColor && mReadOnlyColor == rhs.mReadOnlyColor - && mSelectedColor == rhs.mSelectedColor && mFont == rhs.mFont && mLink == rhs.mLink && mImagep == rhs.mImagep + && mItalic == rhs.mItalic + && mBold == rhs.mBold + && mUnderline == rhs.mUnderline && mDropShadow == rhs.mDropShadow; } bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } public: + BOOL mItalic; + BOOL mBold; + BOOL mUnderline; LLFontGL::ShadowType mDropShadow; protected: ~LLStyle() { } private: - BOOL mVisible; - LLUIColor mColor; - LLUIColor mReadOnlyColor; - LLUIColor mSelectedColor; - std::string mFontName; - const LLFontGL* mFont; - std::string mLink; - LLUIImagePtr mImagep; + BOOL mVisible; + LLUIColor mColor; + LLUIColor mReadOnlyColor; + std::string mFontName; + const LLFontGL* mFont; // cached for performance + std::string mLink; + LLUIImagePtr mImagep; }; typedef LLPointer LLStyleSP; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8d91aa2284..60c313b6ce 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -149,8 +149,6 @@ LLTextBase::Params::Params() bg_readonly_color("bg_readonly_color"), bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), - text_selected_color("text_selected_color"), - bg_selected_color("bg_selected_color"), allow_scroll("allow_scroll", true), plain_text("plain_text",false), track_end("track_end", false), @@ -163,12 +161,11 @@ LLTextBase::Params::Params() font_shadow("font_shadow"), wrap("wrap"), use_ellipses("use_ellipses", false), - parse_urls("parse_urls", false), + allow_html("allow_html", false), parse_highlights("parse_highlights", false) { addSynonym(track_end, "track_bottom"); addSynonym(wrap, "word_wrap"); - addSynonym(parse_urls, "allow_html"); } @@ -187,8 +184,6 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mWriteableBgColor(p.bg_writeable_color), mReadOnlyBgColor(p.bg_readonly_color), mFocusBgColor(p.bg_focus_color), - mTextSelectedColor(p.text_selected_color), - mSelectedBGColor(p.bg_selected_color), mReflowIndex(S32_MAX), mCursorPos( 0 ), mScrollNeeded(FALSE), @@ -208,7 +203,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mPlainText ( p.plain_text ), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), - mParseHTML(p.parse_urls), + mParseHTML(p.allow_html), mParseHighlights(p.parse_highlights), mBGVisible(p.bg_visible), mScroller(NULL), @@ -268,6 +263,9 @@ void LLTextBase::initFromParams(const LLTextBase::Params& p) { mReadOnly = p.read_only; } + + // HACK: text editors always need to be enabled so that we can scroll + LLView::setEnabled(true); } bool LLTextBase::truncate() @@ -297,14 +295,11 @@ bool LLTextBase::truncate() const LLStyle::Params& LLTextBase::getDefaultStyleParams() { - //FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html - //and eliminate color member values if (mStyleDirty) { mDefaultStyle - .color(LLUIColor(&mFgColor)) // pass linked color instead of copy of mFGColor + .color(LLUIColor(&mFgColor)) .readonly_color(LLUIColor(&mReadOnlyFgColor)) - .selected_color(LLUIColor(&mTextSelectedColor)) .font(mDefaultFont) .drop_shadow(mFontShadow); mStyleDirty = false; @@ -402,7 +397,7 @@ void LLTextBase::drawSelectionBackground() // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - const LLColor4& color = mSelectedBGColor; + const LLColor4& color = mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get(); F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); @@ -442,6 +437,7 @@ void LLTextBase::drawCursor() } else { + //segmentp = mSegments.back(); return; } @@ -475,8 +471,21 @@ void LLTextBase::drawCursor() { LLColor4 text_color; const LLFontGL* fontp; + if (segmentp) + { text_color = segmentp->getColor(); fontp = segmentp->getStyle()->getFont(); + } + else if (mReadOnly) + { + text_color = mReadOnlyFgColor.get(); + fontp = mDefaultFont; + } + else + { + text_color = mFgColor.get(); + fontp = mDefaultFont; + } fontp->render(text, mCursorPos, cursor_rect, LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha), LLFontGL::LEFT, mVAlign, @@ -1006,26 +1015,21 @@ void LLTextBase::draw() if (mBGVisible) { // clip background rect against extents, if we support scrolling - LLRect bg_rect = mVisibleTextRect; - if (mScroller) - { - bg_rect.intersectWith(doc_rect); - } + LLLocalClipRect clip(doc_rect, mScroller != NULL); + LLColor4 bg_color = mReadOnly ? mReadOnlyBgColor.get() : hasFocus() ? mFocusBgColor.get() : mWriteableBgColor.get(); - gl_rect_2d(doc_rect, bg_color, TRUE); + gl_rect_2d(mVisibleTextRect, bg_color, TRUE); } // draw document view LLUICtrl::draw(); { - // only clip if we support scrolling... - // since convention is that text boxes never vertically truncate their contents - // regardless of rect bounds + // only clip if we support scrolling (mScroller != NULL) LLLocalClipRect clip(doc_rect, mScroller != NULL); drawSelectionBackground(); drawText(); @@ -1489,32 +1493,23 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index) { - static LLPointer index_segment = new LLIndexSegment(); - if (index > getLength()) { return mSegments.end(); } // when there are no segments, we return the end iterator, which must be checked by caller if (mSegments.size() <= 1) { return mSegments.begin(); } - //FIXME: avoid operator new somehow (without running into refcount problems) - index_segment->setStart(index); - index_segment->setEnd(index); - segment_set_t::iterator it = mSegments.upper_bound(index_segment); + segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index)); return it; } LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 index) const { - static LLPointer index_segment = new LLIndexSegment(); - if (index > getLength()) { return mSegments.end(); } // when there are no segments, we return the end iterator, which must be checked by caller if (mSegments.size() <= 1) { return mSegments.begin(); } - index_segment->setStart(index); - index_segment->setEnd(index); - LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(index_segment); + LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index)); return it; } @@ -1650,7 +1645,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para } else { - appendAndHighlightText(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); + appendAndHighlightText(match.getLabel(), part, link_params); // set the tooltip for the Url label if (! match.getTooltip().empty()) @@ -1733,7 +1728,7 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s insertStringNoUndo(getLength(), widget_wide_text, &segments); } -void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) { // Save old state S32 selection_start = mSelectionStart; @@ -1764,17 +1759,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 cur_length = getLength(); LLStyleConstSP sp(new LLStyle(highlight_params)); - LLTextSegmentPtr segmentp; - if(underline_on_hover_only) - { - highlight_params.font.style("NORMAL"); - LLStyleConstSP normal_sp(new LLStyle(highlight_params)); - segmentp = new LLOnHoverChangeableTextSegment(sp, normal_sp, cur_length, cur_length + wide_text.size(), *this); - } - else - { - segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); - } + LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); segment_vec_t segments; segments.push_back(segmentp); insertStringNoUndo(cur_length, wide_text, &segments); @@ -1789,17 +1774,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 segment_start = old_length; S32 segment_end = old_length + wide_text.size(); LLStyleConstSP sp(new LLStyle(style_params)); - if (underline_on_hover_only) - { - LLStyle::Params normal_style_params(style_params); - normal_style_params.font.style("NORMAL"); - LLStyleConstSP normal_sp(new LLStyle(normal_style_params)); - segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this )); - } - else - { segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); - } insertStringNoUndo(getLength(), wide_text, &segments); } @@ -1823,7 +1798,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig } } -void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) { if (new_text.empty()) return; @@ -1835,7 +1810,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig if(pos!=start) { std::string str = std::string(new_text,start,pos-start); - appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); + appendAndHighlightTextImpl(str,highlight_part, style_params); } appendLineBreakSegment(style_params); start = pos+1; @@ -1843,7 +1818,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig } std::string str = std::string(new_text,start,new_text.length()-start); - appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); + appendAndHighlightTextImpl(str,highlight_part, style_params); } @@ -2297,7 +2272,6 @@ void LLTextBase::updateRects() // allow horizontal scrolling? // if so, use entire width of text contents // otherwise, stop at width of mVisibleTextRect - //FIXME: consider use of getWordWrap() instead doc_rect.mRight = mScroller ? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight) : mVisibleTextRect.getWidth(); @@ -2507,7 +2481,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele font->render(text, start, rect, - mStyle->getSelectedColor().get(), + LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), LLFontGL::LEFT, mEditor.mVAlign, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, @@ -2704,33 +2678,6 @@ void LLNormalTextSegment::dump() const llendl; } -// -// LLOnHoverChangeableTextSegment -// - -LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ): - LLNormalTextSegment(normal_style, start, end, editor), - mHoveredStyle(style), - mNormalStyle(normal_style){} - -/*virtual*/ -F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) -{ - F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect); - if (end == mEnd - mStart) - { - mStyle = mNormalStyle; - } - return result; -} - -/*virtual*/ -BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask) -{ - mStyle = mHoveredStyle; - return LLNormalTextSegment::handleHover(x, y, mask); -} - // // LLInlineViewSegment diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index e5dfecad54..86ab8f357d 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -139,25 +139,10 @@ protected: boost::signals2::connection mImageLoadedConnection; }; -// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment) -class LLOnHoverChangeableTextSegment : public LLNormalTextSegment -{ -public: - LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ); - /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); -protected: - // Style used for text when mouse pointer is over segment - LLStyleConstSP mHoveredStyle; - // Style used for text when mouse pointer is outside segment - LLStyleConstSP mNormalStyle; - -}; - class LLIndexSegment : public LLTextSegment { public: - LLIndexSegment() : LLTextSegment(0, 0) {} + LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {} }; class LLInlineViewSegment : public LLTextSegment @@ -250,9 +235,7 @@ public: text_readonly_color, bg_readonly_color, bg_writeable_color, - bg_focus_color, - text_selected_color, - bg_selected_color; + bg_focus_color; Optional bg_visible, border_visible, @@ -262,7 +245,7 @@ public: plain_text, wrap, use_ellipses, - parse_urls, + allow_html, parse_highlights, clip_partial; @@ -452,7 +435,7 @@ protected: S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false); + void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep); // manage segments @@ -495,7 +478,7 @@ protected: void replaceUrlLabel(const std::string &url, const std::string &label); void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); - void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false); + void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params); protected: @@ -518,8 +501,6 @@ protected: LLUIColor mWriteableBgColor; LLUIColor mReadOnlyBgColor; LLUIColor mFocusBgColor; - LLUIColor mTextSelectedColor; - LLUIColor mSelectedBGColor; // cursor S32 mCursorPos; // I-beam is just after the mCursorPos-th character. diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 6a905b7ec0..3e2422c88b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -113,17 +113,6 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) return handled; } -void LLTextBox::setEnabled(BOOL enabled) -{ - // just treat enabled as read-only flag - bool read_only = !enabled; - if (read_only != mReadOnly) - { - LLTextBase::setReadOnly(read_only); - updateSegments(); - } -} - void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params ) { // does string argument insertion diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 071e18c638..4634dd0ff2 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -52,8 +52,6 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ void setEnabled(BOOL enabled); - /*virtual*/ void setText( const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params() ); void setRightAlign() { mHAlign = LLFontGL::RIGHT; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 94bf716e7d..e09df60704 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -283,9 +283,6 @@ void LLTextEditor::initFromParams( const LLTextEditor::Params& p) { LLTextBase::initFromParams(p); - // HACK: text editors always need to be enabled so that we can scroll - LLView::setEnabled(true); - if (p.commit_on_focus_lost.isProvided()) { mCommitOnFocusLost = p.commit_on_focus_lost; @@ -455,13 +452,8 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const const LLTextSegmentPtr LLTextEditor::getPreviousSegment() const { - static LLPointer index_segment = new LLIndexSegment; - - index_segment->setStart(mCursorPos); - index_segment->setEnd(mCursorPos); - // find segment index at character to left of cursor (or rightmost edge of selection) - segment_set_t::const_iterator it = mSegments.lower_bound(index_segment); + segment_set_t::const_iterator it = mSegments.lower_bound(new LLIndexSegment(mCursorPos)); if (it != mSegments.end()) { diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 4b9faa0560..d7260369ec 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -44,7 +44,6 @@ namespace LLTextValidate declare("alpha_num_space", validateAlphaNumSpace); declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe); declare("ascii_printable_no_space", validateASCIIPrintableNoSpace); - declare("ascii_with_newline", validateASCIIWithNewLine); } // Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. @@ -294,21 +293,4 @@ namespace LLTextValidate } return rv; } - - // Used for multiline text stored on the server. - // Example is landmark description in Places SP. - bool validateASCIIWithNewLine(const LLWString &str) - { - bool rv = TRUE; - S32 len = str.length(); - while(len--) - { - if (str[len] < 0x20 && str[len] != 0xA || str[len] > 0x7f) - { - rv = FALSE; - break; - } - } - return rv; - } } diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index 84644be30c..1b61eca051 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -51,7 +51,6 @@ namespace LLTextValidate bool validateASCIIPrintableNoPipe(const LLWString &str); bool validateASCIIPrintableNoSpace(const LLWString &str); bool validateASCII(const LLWString &str); - bool validateASCIIWithNewLine(const LLWString &str); } diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index b02d3122fe..8ab4a119e5 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -180,7 +180,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p) params.font = p.font; params.use_ellipses = true; params.wrap = p.wrap; - params.parse_urls = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips + params.allow_html = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips mTextBox = LLUICtrlFactory::create (params); addChild(mTextBox); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index d33d8e3178..03223b45f7 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -460,7 +460,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) { stop_glerror(); @@ -470,53 +470,36 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex return; } - // add in offset of current image to current ui translation - const LLVector3 ui_scale = gGL.getUIScale(); - const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale); - - F32 uv_width = uv_outer_rect.getWidth(); - F32 uv_height = uv_outer_rect.getHeight(); - // shrink scaling region to be proportional to clipped image region - LLRectf uv_center_rect( - uv_outer_rect.mLeft + (center_rect.mLeft * uv_width), - uv_outer_rect.mBottom + (center_rect.mTop * uv_height), - uv_outer_rect.mLeft + (center_rect.mRight * uv_width), - uv_outer_rect.mBottom + (center_rect.mBottom * uv_height)); - - F32 image_width = image->getWidth(0); - F32 image_height = image->getHeight(0); - - S32 image_natural_width = llround(image_width * uv_width); - S32 image_natural_height = llround(image_height * uv_height); - - LLRectf draw_center_rect( uv_center_rect.mLeft * image_width, - uv_center_rect.mTop * image_height, - uv_center_rect.mRight * image_width, - uv_center_rect.mBottom * image_height); - - { // scale fixed region of image to drawn region - draw_center_rect.mRight += width - image_natural_width; - draw_center_rect.mTop += height - image_natural_height; - - F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight); - F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop); - - F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth())); - F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight())); - - F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); - - draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]); - draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]); - draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]); - draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]); - } - - LLRectf draw_outer_rect(ui_translation.mV[VX], - ui_translation.mV[VY] + height * ui_scale.mV[VY], - ui_translation.mV[VX] + width * ui_scale.mV[VX], - ui_translation.mV[VY]); + LLRectf scale_rect_uv( + uv_rect.mLeft + (scale_rect.mLeft * uv_rect.getWidth()), + uv_rect.mBottom + (scale_rect.mTop * uv_rect.getHeight()), + uv_rect.mLeft + (scale_rect.mRight * uv_rect.getWidth()), + uv_rect.mBottom + (scale_rect.mBottom * uv_rect.getHeight())); + + S32 image_natural_width = llround((F32)image->getWidth(0) * uv_rect.getWidth()); + S32 image_natural_height = llround((F32)image->getHeight(0) * uv_rect.getHeight()); + + LLRect draw_rect(0, height, width, 0); + LLRect draw_scale_rect(llround(scale_rect_uv.mLeft * (F32)image->getWidth(0)), + llround(scale_rect_uv.mTop * (F32)image->getHeight(0)), + llround(scale_rect_uv.mRight * (F32)image->getWidth(0)), + llround(scale_rect_uv.mBottom * (F32)image->getHeight(0))); + // scale fixed region of image to drawn region + draw_scale_rect.mRight += width - image_natural_width; + draw_scale_rect.mTop += height - image_natural_height; + + S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight); + S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop); + + F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - scale_rect.getWidth())); + F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - scale_rect.getHeight())); + + F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); + draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale); + draw_scale_rect.mTop = llround(lerp((F32)height, (F32)draw_scale_rect.mTop, shrink_scale)); + draw_scale_rect.mRight = llround(lerp((F32)width, (F32)draw_scale_rect.mRight, shrink_scale)); + draw_scale_rect.mBottom = llround((F32)draw_scale_rect.mBottom * shrink_scale); LLGLSUIDefault gls_ui; @@ -526,174 +509,136 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); } - gGL.getTexUnit(0)->bind(image); - - gGL.color4fv(color.mV); - - const S32 NUM_VERTICES = 9 * 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector3 pos[NUM_VERTICES]; - - S32 index = 0; - - gGL.begin(LLRender::QUADS); + gGL.pushUIMatrix(); { - // draw bottom left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; + gGL.translateUI((F32)x, (F32)y, 0.f); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; + gGL.getTexUnit(0)->bind(image); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.color4fv(color.mV); + + gGL.begin(LLRender::QUADS); + { + // draw bottom left + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(0, 0); - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, 0); - // draw bottom middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(0, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + // draw bottom middle + gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, 0); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, 0); - // draw bottom right - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + // draw bottom right + gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, 0); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(width, 0); - // draw left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(width, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + // draw left + gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(0, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - // draw middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(0, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + // draw middle + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - // draw right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + // draw right + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); + gGL.vertex2i(width, draw_scale_rect.mBottom); - // draw top left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); + gGL.vertex2i(width, draw_scale_rect.mTop); + + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + // draw top left + gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(0, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, height); - // draw top middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(0, height); - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + // draw top middle + gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, height); - // draw top right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, height); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); - index++; + // draw top right + gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); + gGL.vertex2i(width, draw_scale_rect.mTop); - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2i(width, height); - gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); + gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, height); + } + gGL.end(); } - gGL.end(); + gGL.popUIMatrix(); if (solid_color) { @@ -723,40 +668,25 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre if (degrees == 0.f) { - const S32 NUM_VERTICES = 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector3 pos[NUM_VERTICES]; - + gGL.pushUIMatrix(); + gGL.translateUI((F32)x, (F32)y, 0.f); + gGL.begin(LLRender::QUADS); { - LLVector3 ui_scale = gGL.getUIScale(); - LLVector3 ui_translation = gGL.getUITranslation(); - ui_translation.mV[VX] += x; - ui_translation.mV[VY] += y; - ui_translation.scaleVec(ui_scale); - S32 index = 0; - S32 scaled_width = llround(width * ui_scale.mV[VX]); - S32 scaled_height = llround(height * ui_scale.mV[VY]); - - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); - pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); - pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); - index++; - - gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2i(width, height ); + + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(0, height ); + + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(0, 0); + + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(width, 0); } gGL.end(); + gGL.popUIMatrix(); } else { @@ -825,6 +755,25 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL LLUI::setLineWidth(1.f); } + +void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom) +{ + gGL.color4fv( LLColor4::white.mV ); + glLogicOp( GL_XOR ); + stop_glerror(); + + gGL.begin(LLRender::QUADS); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.end(); + + glLogicOp( GL_COPY ); + stop_glerror(); +} + + void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) { if (end_angle < start_angle) @@ -1058,6 +1007,42 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, gGL.end(); } +// Draws spokes around a circle. +void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) +{ + const F32 DELTA = F_TWO_PI / count; + const F32 HALF_DELTA = DELTA * 0.5f; + const F32 SIN_DELTA = sin( DELTA ); + const F32 COS_DELTA = cos( DELTA ); + + F32 x1 = outer_radius * cos( HALF_DELTA ); + F32 y1 = outer_radius * sin( HALF_DELTA ); + F32 x2 = inner_radius * cos( HALF_DELTA ); + F32 y2 = inner_radius * sin( HALF_DELTA ); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.begin( LLRender::LINES ); + { + while( count-- ) + { + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); + + F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; + y1 = x1 * SIN_DELTA + y1 * COS_DELTA; + x1 = x1_new; + + F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; + y2 = x2 * SIN_DELTA + y2 * COS_DELTA; + x2 = x2_new; + } + } + gGL.end(); +} + void gl_rect_2d_simple_tex( S32 width, S32 height ) { gGL.begin( LLRender::QUADS ); @@ -1245,7 +1230,6 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.popUIMatrix(); } -//FIXME: rewrite to use scissor? void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, diff --git a/indra/llui/llui.h b/indra/llui/llui.h index fc545c85d5..afec2e9c26 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -90,6 +90,7 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac); void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); +void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); @@ -98,6 +99,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); void gl_rect_2d_simple_tex( S32 width, S32 height ); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 3ac3bf8c41..294c96f8f4 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -95,7 +95,6 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) : LLView(p), mTentative(FALSE), mIsChrome(FALSE), - mTabStop(FALSE), mViewModel(viewmodel), mControlVariable(NULL), mEnabledControlVariable(NULL), diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 76dfdf754c..71fd5034df 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -141,6 +141,8 @@ public: // LLView interface /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); /*virtual*/ BOOL isCtrl() const; + /*virtual*/ void setTentative(BOOL b); + /*virtual*/ BOOL getTentative() const; /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ BOOL canFocusChildren() const; @@ -172,8 +174,6 @@ public: void setMakeVisibleControlVariable(LLControlVariable* control); void setMakeInvisibleControlVariable(LLControlVariable* control); - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; virtual void setValue(const LLSD& value); virtual LLSD getValue() const; /// When two widgets are displaying the same data (e.g. during a skin diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 5680ab8bd4..a34ede439a 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -357,12 +357,6 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const return LLTrans::getString("TooltipAgentUrl"); } -bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const -{ - std::string url = getUrl(string); - return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect"); -} - std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { if (!gCacheName) @@ -730,19 +724,6 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const return LLUrlEntryBase::getTooltip(string); } -bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const -{ - std::string url = getUrl(string); - LLUrlMatch match; - if (LLUrlRegistry::instance().findUrl(url, match)) - { - return match.underlineOnHoverOnly(); - } - - // unrecognized URL? should not happen - return LLUrlEntryBase::underlineOnHoverOnly(string); -} - // // LLUrlEntryWorldMap Describes secondlife:/// URLs // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index e25eaa7555..d868e01aa6 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -88,9 +88,6 @@ public: /// is this a match for a URL that should not be hyperlinked? bool isLinkDisabled() const { return mDisabledLink; } - /// Should this link text be underlined only when mouse is hovered over it? - virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } - virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } protected: @@ -170,7 +167,6 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getTooltip(const std::string &string) const; /*virtual*/ LLUUID getID(const std::string &string) const; - /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; private: void onAgentNameReceived(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); @@ -273,7 +269,6 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; /*virtual*/ std::string getTooltip(const std::string &string) const; - /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; }; /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index e53b0c4370..4ec97091a3 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -37,8 +37,7 @@ LLUrlMatch::LLUrlMatch() : mIcon(""), mMenuName(""), mLocation(""), - mDisabledLink(false), - mUnderlineOnHoverOnly(false) + mDisabledLink(false) { } @@ -46,7 +45,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, const std::string &menu, const std::string &location, - bool disabled_link, const LLUUID& id, bool underline_on_hover_only) + bool disabled_link, const LLUUID& id) { mStart = start; mEnd = end; @@ -59,5 +58,4 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mLocation = location; mDisabledLink = disabled_link; mID = id; - mUnderlineOnHoverOnly = underline_on_hover_only; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index d1b2112ee7..7a4f0bc10e 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -80,15 +80,12 @@ public: /// is this a match for a URL that should not be hyperlinked? bool isLinkDisabled() const { return mDisabledLink; } - /// Should this link text be underlined only when mouse is hovered over it? - bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } - /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, const std::string &menu, const std::string &location, bool disabled_link - , const LLUUID& id, bool underline_on_hover_only = false ); + , const LLUUID& id ); const LLUUID& getID() const { return mID;} @@ -105,7 +102,6 @@ private: LLUUID mID; LLUIColor mColor; bool mDisabledLink; - bool mUnderlineOnHoverOnly; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 9d215cf7ef..1c103a628b 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -178,8 +178,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getMenuName(), match_entry->getLocation(url), match_entry->isLinkDisabled(), - match_entry->getID(url), - match_entry->underlineOnHoverOnly(url)); + match_entry->getID(url)); return true; } @@ -214,8 +213,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getMenuName(), match.getLocation(), match.isLinkDisabled(), - match.getID(), - match.underlineOnHoverOnly()); + match.getID()); return true; } return false; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index fe5ef269a9..42ce7b84fe 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -397,40 +397,28 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const return (a_score == b_score) ? a < b : a_score < b_score; } -BOOL LLView::isInVisibleChain() const +bool LLView::trueToRoot(const boost::function& predicate) const { - BOOL visible = TRUE; - - const LLView* viewp = this; - while(viewp) + const LLView* cur_view = this; + while(cur_view) { - if (!viewp->getVisible()) + if(!predicate(cur_view)) { - visible = FALSE; - break; + return false; } - viewp = viewp->getParent(); + cur_view = cur_view->getParent(); } - - return visible; + return true; } -BOOL LLView::isInEnabledChain() const +BOOL LLView::isInVisibleChain() const { - BOOL enabled = TRUE; + return trueToRoot(&LLView::getVisible); +} - const LLView* viewp = this; - while(viewp) - { - if (!viewp->getEnabled()) - { - enabled = FALSE; - break; - } - viewp = viewp->getParent(); - } - - return enabled; +BOOL LLView::isInEnabledChain() const +{ + return trueToRoot(&LLView::getEnabled); } // virtual @@ -439,6 +427,17 @@ BOOL LLView::canFocusChildren() const return TRUE; } +//virtual +void LLView::setTentative(BOOL b) +{ +} + +//virtual +BOOL LLView::getTentative() const +{ + return FALSE; +} + //virtual void LLView::setEnabled(BOOL enabled) { @@ -2779,19 +2778,6 @@ LLView::tree_post_iterator_t LLView::endTreeDFSPost() return tree_post_iterator_t(); } -LLView::bfs_tree_iterator_t LLView::beginTreeBFS() -{ - return bfs_tree_iterator_t(this, - boost::bind(boost::mem_fn(&LLView::beginChild), _1), - boost::bind(boost::mem_fn(&LLView::endChild), _1)); -} - -LLView::bfs_tree_iterator_t LLView::endTreeBFS() -{ - // an empty iterator is an "end" iterator - return bfs_tree_iterator_t(); -} - LLView::root_to_view_iterator_t LLView::beginRootToView() { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index f7175112bf..b9cecb0f84 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -267,6 +267,7 @@ public: S32 getDefaultTabGroup() const { return mDefaultTabGroup; } S32 getLastTabGroup() { return mLastTabGroup; } + bool trueToRoot(const boost::function& predicate) const; BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; @@ -282,6 +283,8 @@ public: // children, etc. virtual void deleteAllChildren(); + virtual void setTentative(BOOL b); + virtual BOOL getTentative() const; void setAllChildrenEnabled(BOOL b); virtual void setVisible(BOOL visible); @@ -348,10 +351,6 @@ public: tree_post_iterator_t beginTreeDFSPost(); tree_post_iterator_t endTreeDFSPost(); - typedef LLTreeBFSIter bfs_tree_iterator_t; - bfs_tree_iterator_t beginTreeBFS(); - bfs_tree_iterator_t endTreeBFS(); - typedef LLTreeDownIter root_to_view_iterator_t; root_to_view_iterator_t beginRootToView(); -- cgit v1.2.3