diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llbadge.cpp | 24 | ||||
-rw-r--r-- | indra/llui/llbadge.h | 3 | ||||
-rw-r--r-- | indra/llui/llbutton.cpp | 80 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 68 | ||||
-rw-r--r-- | indra/llui/llcombobox.cpp | 168 | ||||
-rw-r--r-- | indra/llui/llcombobox.h | 5 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 18 | ||||
-rw-r--r-- | indra/llui/llfolderviewitem.cpp | 24 | ||||
-rw-r--r-- | indra/llui/llfolderviewitem.h | 8 | ||||
-rw-r--r-- | indra/llui/llfolderviewmodel.h | 1 | ||||
-rw-r--r-- | indra/llui/lllineeditor.cpp | 60 | ||||
-rw-r--r-- | indra/llui/lllineeditor.h | 5 | ||||
-rw-r--r-- | indra/llui/llpanel.cpp | 22 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.cpp | 59 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.h | 27 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 148 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.h | 9 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 171 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 12 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 2 | ||||
-rw-r--r-- | indra/llui/llviewereventrecorder.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llviewmodel.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llviewmodel.h | 4 |
23 files changed, 631 insertions, 299 deletions
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp index 399f79ad2e..c6654ee0aa 100644 --- a/indra/llui/llbadge.cpp +++ b/indra/llui/llbadge.cpp @@ -27,6 +27,8 @@ #define LLBADGE_CPP #include "llbadge.h" +#include "llfontgl.h" +#include "llfontvertexbuffer.h" #include "llscrollcontainer.h" #include "lluictrlfactory.h" @@ -351,17 +353,17 @@ void LLBadge::draw() // // Draw the label // - - mGLFont->render(mLabel.getWString(), - badge_label_begin_offset, - badge_center_x + mLabelOffsetHoriz, - badge_center_y + mLabelOffsetVert, - mLabelColor % alpha, - LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position - LLFontGL::NORMAL, // normal text (not bold, italics, etc.) - LLFontGL::DROP_SHADOW_SOFT, - badge_char_length, badge_pixel_length, - right_position_out, do_not_use_ellipses); + mFontBuffer.render(mGLFont, + mLabel.getWString(), + badge_label_begin_offset, + badge_center_x + mLabelOffsetHoriz, + badge_center_y + mLabelOffsetVert, + mLabelColor % alpha, + LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position + LLFontGL::NORMAL, // normal text (not bold, italics, etc.) + LLFontGL::DROP_SHADOW_SOFT, + badge_char_length, badge_pixel_length, + right_position_out, do_not_use_ellipses); } } } diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h index 77fe76f0da..636e2c9ded 100644 --- a/indra/llui/llbadge.h +++ b/indra/llui/llbadge.h @@ -34,12 +34,14 @@ #include "llstring.h" #include "lluiimage.h" #include "llview.h" +#include "llfontvertexbuffer.h" // // Declarations // class LLFontGL; +class LLFontVertexBuffer; class LLScrollContainer; class LLUICtrlFactory; @@ -144,6 +146,7 @@ private: LLUIColor mBorderColor; const LLFontGL* mGLFont; + LLFontVertexBuffer mFontBuffer; LLPointer< LLUIImage > mImage; LLUIColor mImageColor; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 30968225a8..1bce31edb1 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -43,6 +43,8 @@ #include "llfloater.h" #include "llfloaterreg.h" #include "llfocusmgr.h" +#include "llfontgl.h" +#include "llfontvertexbuffer.h" #include "llwindow.h" #include "llnotificationsutil.h" #include "llrender.h" @@ -120,11 +122,10 @@ LLButton::Params::Params() LLButton::LLButton(const LLButton::Params& p) -: LLUICtrl(p), + : LLUICtrl(p), LLBadgeOwner(getHandle()), mMouseDownFrame(0), mMouseHeldDownCount(0), - mBorderEnabled( false ), mFlashing( false ), mCurGlowStrength(0.f), mNeedsHighlight(false), @@ -329,6 +330,30 @@ void LLButton::onCommit() LLUICtrl::onCommit(); } +void LLButton::setUnselectedLabelColor(const LLUIColor& c) +{ + mUnselectedLabelColor = c; + mFontBuffer.reset(); +} + +void LLButton::setSelectedLabelColor(const LLUIColor& c) +{ + mSelectedLabelColor = c; + mFontBuffer.reset(); +} + +void LLButton::setUseEllipses(bool use_ellipses) +{ + mUseEllipses = use_ellipses; + mFontBuffer.reset(); +} + +void LLButton::setUseFontColor(bool use_font_color) +{ + mUseFontColor = use_font_color; + mFontBuffer.reset(); +} + boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb) { return setClickedCallback(initCommitCallback(cb)); @@ -396,6 +421,18 @@ bool LLButton::postBuild() return LLUICtrl::postBuild(); } +void LLButton::onVisibilityChange(bool new_visibility) +{ + mFontBuffer.reset(); + return LLUICtrl::onVisibilityChange(new_visibility); +} + +void LLButton::dirtyRect() +{ + LLUICtrl::dirtyRect(); + mFontBuffer.reset(); +} + bool LLButton::handleUnicodeCharHere(llwchar uni_char) { bool handled = false; @@ -582,19 +619,25 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) { LLUICtrl::onMouseLeave(x, y, mask); - mNeedsHighlight = false; + setHighlight(false); } void LLButton::setHighlight(bool b) { - mNeedsHighlight = b; + if (mNeedsHighlight != b) + { + mNeedsHighlight = b; + mFontBuffer.reset(); + } } bool LLButton::handleHover(S32 x, S32 y, MASK mask) { if (isInEnabledChain() && (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this)) - mNeedsHighlight = true; + { + setHighlight(true); + } if (!childrenHandleHover(x, y, mask)) { @@ -954,7 +997,7 @@ void LLButton::draw() // LLFontGL::render expects S32 max_chars variable but process in a separate way -1 value. // Due to U32_MAX is equal to S32 -1 value I have rest this value for non-ellipses mode. // Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars. - mLastDrawCharsCount = mGLFont->render(label, 0, + mLastDrawCharsCount = mFontBuffer.render(mGLFont, label, 0, (F32)x, (F32)(getRect().getHeight() / 2 + mBottomVPad), label_color % alpha, @@ -996,6 +1039,7 @@ void LLButton::setToggleState(bool b) setFlashing(false); // stop flash state whenever the selected/unselected state if reset // Unselected label assignments autoResize(); + mFontBuffer.reset(); } } @@ -1025,11 +1069,13 @@ bool LLButton::toggleState() void LLButton::setLabel( const std::string& label ) { mUnselectedLabel = mSelectedLabel = label; + mFontBuffer.reset(); } void LLButton::setLabel( const LLUIString& label ) { mUnselectedLabel = mSelectedLabel = label; + mFontBuffer.reset(); } void LLButton::setLabel( const LLStringExplicit& label ) @@ -1043,17 +1089,32 @@ bool LLButton::setLabelArg( const std::string& key, const LLStringExplicit& text { mUnselectedLabel.setArg(key, text); mSelectedLabel.setArg(key, text); + mFontBuffer.reset(); return true; } void LLButton::setLabelUnselected( const LLStringExplicit& label ) { mUnselectedLabel = label; + mFontBuffer.reset(); } void LLButton::setLabelSelected( const LLStringExplicit& label ) { mSelectedLabel = label; + mFontBuffer.reset(); +} + +void LLButton::setDisabledLabelColor(const LLUIColor& c) +{ + mDisabledLabelColor = c; + mFontBuffer.reset(); +} + +void LLButton::setFont(const LLFontGL* font) +{ + mGLFont = (font ? font : LLFontGL::getFontSansSerif()); + mFontBuffer.reset(); } bool LLButton::labelIsTruncated() const @@ -1066,6 +1127,12 @@ const LLUIString& LLButton::getCurrentLabel() const return getToggleState() ? mSelectedLabel : mUnselectedLabel; } +void LLButton::setDropShadowedText(bool b) +{ + mDropShadowedText = b; + mFontBuffer.reset(); +} + void LLButton::setImageUnselected(LLPointer<LLUIImage> image) { mImageUnselected = image; @@ -1149,6 +1216,7 @@ void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image) mImageDisabledSelected = image; mDisabledImageColor = mImageColor; mFadeWhenDisabled = true; + mFontBuffer.reset(); } void LLButton::setImagePressed(LLPointer<LLUIImage> image) diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 4ecea6d473..890e7c2d1e 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -34,7 +34,6 @@ #include "lluictrl.h" #include "v4color.h" #include "llframetimer.h" -#include "llfontgl.h" #include "lluiimage.h" #include "lluistring.h" @@ -55,6 +54,8 @@ S32 round_up(S32 grid, S32 value); class LLUICtrlFactory; +class LLFontGL; +class LLFontVertexBuffer; // // Classes @@ -156,26 +157,29 @@ public: void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName, const LLUUID& imageID,const std::string& xmlTagName) const; - virtual bool handleUnicodeCharHere(llwchar uni_char); - virtual bool handleKeyHere(KEY key, MASK mask); - virtual bool handleMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleMouseUp(S32 x, S32 y, MASK mask); - virtual bool handleHover(S32 x, S32 y, MASK mask); - virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask); - virtual bool handleDoubleClick(S32 x, S32 y, MASK mask); - virtual void draw(); - /*virtual*/ bool postBuild(); + virtual bool handleUnicodeCharHere(llwchar uni_char) override; + virtual bool handleKeyHere(KEY key, MASK mask) override; + virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; + virtual bool handleMouseUp(S32 x, S32 y, MASK mask) override; + virtual bool handleHover(S32 x, S32 y, MASK mask) override; + virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask) override; + virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask) override; + virtual bool handleDoubleClick(S32 x, S32 y, MASK mask) override; + virtual void draw() override; + /*virtual*/ bool postBuild() override; - virtual void onMouseLeave(S32 x, S32 y, MASK mask); - virtual void onMouseCaptureLost(); + void onVisibilityChange(bool visible) override; + void dirtyRect() override; - virtual void onCommit(); + virtual void onMouseLeave(S32 x, S32 y, MASK mask) override; + virtual void onMouseCaptureLost() override; - void setUnselectedLabelColor( const LLUIColor& c ) { mUnselectedLabelColor = c; } - void setSelectedLabelColor( const LLUIColor& c ) { mSelectedLabelColor = c; } - void setUseEllipses( bool use_ellipses ) { mUseEllipses = use_ellipses; } - void setUseFontColor( bool use_font_color) { mUseFontColor = use_font_color; } + virtual void onCommit() override; + + void setUnselectedLabelColor(const LLUIColor& c); + void setSelectedLabelColor(const LLUIColor& c); + void setUseEllipses(bool use_ellipses); + void setUseFontColor(bool use_font_color); boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb); @@ -223,9 +227,8 @@ public: const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } - void setImageColor(const std::string& color_control); void setImageColor(const LLUIColor& c); - /*virtual*/ void setColor(const LLUIColor& c); + /*virtual*/ void setColor(const LLUIColor& c) override; void setImages(const std::string &image_name, const std::string &selected_name); @@ -243,15 +246,14 @@ public: void setLabel(const std::string& label); void setLabel(const LLUIString& label); void setLabel( const LLStringExplicit& label); - virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text ); + virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text ) override; void setLabelUnselected(const LLStringExplicit& label); void setLabelSelected(const LLStringExplicit& label); - void setDisabledLabelColor( const LLUIColor& c ) { mDisabledLabelColor = c; } + void setDisabledLabelColor(const LLUIColor& c); - void setFont(const LLFontGL *font) - { mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); } - const LLFontGL* getFont() const { return mGLFont; } - const std::string& getText() const { return getCurrentLabel().getString(); } + void setFont(const LLFontGL* font); + const LLFontGL* getFont() const override { return mGLFont; } + const std::string& getText() const override { return getCurrentLabel().getString(); } S32 getLastDrawCharsCount() const { return mLastDrawCharsCount; } bool labelIsTruncated() const; @@ -260,9 +262,7 @@ public: void setScaleImage(bool scale) { mScaleImage = scale; } bool getScaleImage() const { return mScaleImage; } - void setDropShadowedText(bool b) { mDropShadowedText = b; } - - void setBorderEnabled(bool b) { mBorderEnabled = b; } + void setDropShadowedText(bool b); void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } @@ -278,7 +278,6 @@ public: void setCommitOnReturn(bool commit) { mCommitOnReturn = commit; } bool getCommitOnReturn() const { return mCommitOnReturn; } - static void onHeldDown(void *userdata); // to be called by gIdleCallbacks static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname); static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); static void setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); @@ -305,8 +304,6 @@ protected: commit_signal_t* mMouseUpSignal; commit_signal_t* mHeldDownSignal; - const LLFontGL* mGLFont; - S32 mMouseDownFrame; S32 mMouseHeldDownCount; // Counter for parameter passed to held-down callback F32 mHeldDownDelay; // seconds, after which held-down callbacks get called @@ -358,7 +355,6 @@ protected: bool mAutoResize; bool mUseEllipses; bool mUseFontColor; - bool mBorderEnabled; bool mFlashing; LLFontGL::HAlign mHAlign; @@ -390,8 +386,12 @@ protected: bool mForceFlashing; // Stick flashing color even if button is pressed bool mHandleRightMouse; +private: + const LLFontGL* mGLFont; + LLFontVertexBuffer mFontBuffer; + protected: - virtual std::string _getSearchText() const + virtual std::string _getSearchText() const override { return getLabelUnselected() + getToolTip(); } diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index ee1700e009..a1c16ccdec 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -107,7 +107,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); button_params.rect(p.rect); - if(mAllowTextEntry) + if (mAllowTextEntry) { button_params.pad_right(2); } @@ -121,7 +121,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mButton = LLUICtrlFactory::create<LLButton>(button_params); - if(mAllowTextEntry) + if (mAllowTextEntry) { //redo to compensate for button hack that leaves space for a character //unless it is a "minimal combobox"(drop down) @@ -207,14 +207,27 @@ void LLComboBox::clear() void LLComboBox::onCommit() { - if (mAllowTextEntry && getCurrentIndex() != -1) + if (LLScrollListItem* item = mList->getFirstSelected()) { - // we have selected an existing item, blitz the manual text entry with - // the properly capitalized item - mTextEntry->setValue(getSimple()); - mTextEntry->setTentative(false); + if (mAllowTextEntry && mTextEntry) + { + // we have selected an existing item, blitz the manual text entry with + // the properly capitalized item + LLSD label = item->getColumn(0)->getValue(); + mTextEntry->setValue(label); + mTextEntry->setTentative(false); + } + setControlValue(item->getValue()); + } + else if (mAllowTextEntry) + { + setControlValue(mTextEntry->getValue()); } - setControlValue(getValue()); + else + { + setControlValue(LLSD()); + } + LLUICtrl::onCommit(); } @@ -349,6 +362,13 @@ bool LLComboBox::setSimple(const LLStringExplicit& name) // virtual void LLComboBox::setValue(const LLSD& value) { + if (LLScrollListItem* item = mList->getFirstSelected()) + { + LLSD item_value = item->getValue(); + if (item_value.asStringRef() == value.asStringRef()) + return; + } + bool found = mList->selectByValue(value); if (found) { @@ -372,10 +392,8 @@ const std::string LLComboBox::getSimple() const { return mTextEntry->getText(); } - else - { - return res; - } + + return res; } const std::string LLComboBox::getSelectedItemLabel(S32 column) const @@ -386,24 +404,22 @@ const std::string LLComboBox::getSelectedItemLabel(S32 column) const // virtual LLSD LLComboBox::getValue() const { - LLScrollListItem* item = mList->getFirstSelected(); - if( item ) + if (LLScrollListItem* item = mList->getFirstSelected()) { return item->getValue(); } - else if (mAllowTextEntry) + + if (mAllowTextEntry) { return mTextEntry->getValue(); } - else - { - return LLSD(); - } + + return LLSD(); } void LLComboBox::setLabel(const LLStringExplicit& name) { - if ( mTextEntry ) + if (mTextEntry) { mTextEntry->setText(name); if (mList->selectItemByLabel(name, false)) @@ -498,27 +514,80 @@ void LLComboBox::setButtonVisible(bool visible) } } -bool LLComboBox::setCurrentByIndex( S32 index ) +bool LLComboBox::setCurrentByIndex(S32 index) { - bool found = mList->selectNthItem( index ); - if (found) + if (LLScrollListItem* item = mList->getItemByIndex(index)) { - setLabel(getSelectedItemLabel()); - mLastSelectedIndex = index; + if (item->getEnabled()) + { + mList->selectItem(item, -1, true); + LLSD::String label = item->getColumn(0)->getValue().asString(); + if (mTextEntry) + { + mTextEntry->setText(label); + mTextEntry->setTentative(false); + } + if (!mAllowTextEntry) + { + mButton->setLabel(label); + } + mLastSelectedIndex = index; + return true; + } } - return found; + + return false; } S32 LLComboBox::getCurrentIndex() const { - LLScrollListItem* item = mList->getFirstSelected(); - if( item ) + if (LLScrollListItem* item = mList->getFirstSelected()) { - return mList->getItemIndex( item ); + return mList->getItemIndex(item); } return -1; } +bool LLComboBox::selectNextItem() +{ + S32 last_index = getItemCount() - 1; + if (last_index < 0) + return false; + + S32 current_index = getCurrentIndex(); + if (current_index >= last_index) + return false; + + S32 new_index = llmax(current_index, -1); + while (++new_index <= last_index) + { + if (setCurrentByIndex(new_index)) + return true; + } + + return false; +} + +bool LLComboBox::selectPrevItem() +{ + S32 last_index = getItemCount() - 1; + if (last_index < 0) + return false; + + S32 current_index = getCurrentIndex(); + if (!current_index) + return false; + + S32 new_index = current_index > 0 ? current_index : last_index + 1; + while (--new_index >= 0) + { + if (setCurrentByIndex(new_index)) + return true; + } + + return false; +} + void LLComboBox::setEnabledByValue(const LLSD& value, bool enabled) { LLScrollListItem *found = mList->getItem(value); @@ -878,15 +947,46 @@ bool LLComboBox::handleUnicodeCharHere(llwchar uni_char) // virtual bool LLComboBox::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if (mList->getVisible()) return mList->handleScrollWheel(x, y, clicks); + if (mList->getVisible()) + { + return mList->handleScrollWheel(x, y, clicks); + } + if (mAllowTextEntry) // We might be editable + { if (!mList->getFirstSelected()) // We aren't in the list, don't kill their text + { return false; + } + } - setCurrentByIndex(llclamp(getCurrentIndex() + clicks, 0, getItemCount() - 1)); - prearrangeList(); - onCommit(); - return true; + S32 current_index = getCurrentIndex(); + if (clicks > 0) + { + for (S32 i = 0; i < clicks; ++i) + { + if (!selectNextItem()) + break; + } + } + else + { + for (S32 i = 0; i < -clicks; ++i) + { + if (!selectPrevItem()) + break; + } + } + S32 new_index = getCurrentIndex(); + + if (new_index != current_index) + { + prearrangeList(); + onCommit(); + return true; + } + + return false; } void LLComboBox::setTextEntry(const LLStringExplicit& text) diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 9dc6fa9257..8be3eb57e4 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -163,9 +163,12 @@ public: bool remove(const std::string& name); // remove item "name", return true if found and removed - bool setCurrentByIndex( S32 index ); + bool setCurrentByIndex(S32 index); S32 getCurrentIndex() const; + bool selectNextItem(); + bool selectPrevItem(); + void setEnabledByValue(const LLSD& value, bool enabled); void createLineEditor(const Params&); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index ff174d8470..92fb4b75bf 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1983,6 +1983,9 @@ void LLFloater::onClickCloseBtn(bool app_quitting) // virtual void LLFloater::draw() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + LL_PROFILE_ZONE_TEXT(getTitle().c_str(), getTitle().length()); + const F32 alpha = getCurrentTransparency(); // draw background @@ -2039,21 +2042,6 @@ void LLFloater::draw() LLPanel::updateDefaultBtn(); - if( getDefaultButton() ) - { - if (hasFocus() && getDefaultButton()->getEnabled()) - { - LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - // is this button a direct descendent and not a nested widget (e.g. checkbox)? - bool focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && dynamic_cast<LLButton*>(focus_ctrl)->getParent() == this; - // only enable default button when current focus is not a button - getDefaultButton()->setBorderEnabled(!focus_is_child_button); - } - else - { - getDefaultButton()->setBorderEnabled(false); - } - } if (isMinimized()) { for (S32 i = 0; i < BUTTON_COUNT; i++) diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index e4f5664908..73803786a6 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -307,6 +307,7 @@ void LLFolderViewItem::refresh() LLFolderViewModelItem& vmi = *getViewModelItem(); mLabel = utf8str_to_wstring(vmi.getDisplayName()); + mLabelFontBuffer.reset(); setToolTip(vmi.getName()); // icons are slightly expensive to get, can be optimized // see LLInventoryIcon::getIcon() @@ -320,6 +321,7 @@ void LLFolderViewItem::refresh() // Can do a number of expensive checks, like checking active motions, wearables or friend list mLabelStyle = vmi.getLabelStyle(); mLabelSuffix = utf8str_to_wstring(vmi.getLabelSuffix()); + mSuffixFontBuffer.reset(); } // Dirty the filter flag of the model from the view (CHUI-849) @@ -775,8 +777,9 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L return mIsItemCut; } -void LLFolderViewItem::drawHighlight(const bool showContent, const bool hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, - const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor) +void LLFolderViewItem::drawHighlight(bool showContent, bool hasKeyboardFocus, + const LLUIColor& selectColor, const LLUIColor& flashColor, + const LLUIColor& focusOutlineColor, const LLUIColor& mouseOverColor) { const S32 focus_top = getRect().getHeight(); const S32 focus_bottom = getRect().getHeight() - mItemHeight; @@ -784,7 +787,7 @@ void LLFolderViewItem::drawHighlight(const bool showContent, const bool hasKeybo const S32 FOCUS_LEFT = 1; // Determine which background color to use for highlighting - const LLUIColor& bgColor = (isFlashing() ? flashColor : selectColor); + const LLUIColor& bgColor = isFlashing() ? flashColor : selectColor; //--------------------------------------------------------------------------------// // Draw highlight for selected items @@ -792,7 +795,6 @@ void LLFolderViewItem::drawHighlight(const bool showContent, const bool hasKeybo // items if mShowSingleSelection is false. // if (isHighlightAllowed()) - { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -801,7 +803,7 @@ void LLFolderViewItem::drawHighlight(const bool showContent, const bool hasKeybo { LLColor4 bg_color = bgColor; // do time-based fade of extra objects - F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f); + F32 fade_time = getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.f; if (getRoot() && getRoot()->getShowSingleSelection()) { // fading out @@ -890,7 +892,7 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y //--------------------------------------------------------------------------------// // Draw the actual label text // - font->render(mLabel, 0, x, y, color, + mLabelFontBuffer.render(font, mLabel, 0, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/true); } @@ -907,7 +909,7 @@ void LLFolderViewItem::draw() getViewModelItem()->update(); - if(!mSingleFolderMode) + if (!mSingleFolderMode) { drawOpenFolderArrow(default_params, sFgColor); } @@ -940,7 +942,7 @@ void LLFolderViewItem::draw() return; } - auto filter_string_length = mViewModelItem->hasFilterStringMatch() ? static_cast<S32>(mViewModelItem->getFilterStringSize()) : 0; + S32 filter_string_length = mViewModelItem->hasFilterStringMatch() ? (S32)mViewModelItem->getFilterStringSize() : 0; F32 right_x = 0; F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; F32 text_left = (F32)getLabelXPos(); @@ -999,9 +1001,9 @@ void LLFolderViewItem::draw() // if (!mLabelSuffix.empty()) { - suffix_font->render( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(), - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x); + mSuffixFontBuffer.render(suffix_font, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(), + LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x); } //--------------------------------------------------------------------------------// diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 60cdac3ab9..7ac28b1a8e 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -29,6 +29,7 @@ #include "llflashtimer.h" #include "llview.h" #include "lluiimage.h" +#include "llfontvertexbuffer.h" class LLFolderView; class LLFolderViewModelItem; @@ -297,8 +298,8 @@ public: // virtual void handleDropped(); virtual void draw(); void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color); - void drawHighlight(const bool showContent, const bool hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor); - void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x); + void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor); + void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x); virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, @@ -307,6 +308,9 @@ public: private: static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts + + LLFontVertexBuffer mLabelFontBuffer; + LLFontVertexBuffer mSuffixFontBuffer; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index b8d6d89971..9372818ca5 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -292,6 +292,7 @@ public: dirtyFilter(); requestSort(); } + virtual void removeChild(LLFolderViewModelItem* child) { mChildren.remove(child); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 60b6115b34..66b274c33f 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -436,6 +436,9 @@ void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit { mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars)); } + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); if (all_selected) { @@ -617,6 +620,10 @@ void LLLineEditor::replaceWithSuggestion(U32 index) mText.insert(it->first, suggestion); setCursor(it->first + (S32)suggestion.length()); + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); + break; } } @@ -969,6 +976,10 @@ void LLLineEditor::removeChar() mText.erase(getCursor() - 1, 1); setCursor(getCursor() - 1); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } else { @@ -992,6 +1003,10 @@ void LLLineEditor::addChar(const llwchar uni_char) return; mText.erase(getCursor(), 1); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } S32 cur_bytes = static_cast<S32>(mText.getString().size()); @@ -1022,6 +1037,10 @@ void LLLineEditor::addChar(const llwchar uni_char) mText.insert(getCursor(), w_buf); setCursor(getCursor() + 1); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } else { @@ -1186,6 +1205,10 @@ void LLLineEditor::deleteSelection() mText.erase(left_pos, selection_length); deselect(); setCursor(left_pos); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } } @@ -1346,6 +1369,10 @@ void LLLineEditor::pasteHelper(bool is_primary) setCursor( getCursor() + (S32)clean_string.length() ); deselect(); + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); + // Validate new string and rollback the if needed. bool need_to_rollback = mPrevalidator && !mPrevalidator.validate(mText.getWString()); if (need_to_rollback) @@ -1506,6 +1533,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask) { mText.assign(*(--mCurrentHistoryLine)); setCursorToEnd(); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } else { @@ -1523,6 +1554,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask) { mText.assign( *(++mCurrentHistoryLine) ); setCursorToEnd(); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } else { @@ -1897,7 +1932,8 @@ void LLLineEditor::draw() if( select_left > mScrollHPos ) { // unselected, left side - rendered_text = mGLFont->render( + rendered_text = mFontBufferPreSelection.render( + mGLFont, mText, mScrollHPos, rendered_pixels_right, text_bottom, text_color, @@ -1919,7 +1955,8 @@ void LLLineEditor::draw() gl_rect_2d(ll_round(rendered_pixels_right), cursor_top, ll_round(rendered_pixels_right)+width, cursor_bottom, color); LLColor4 tmp_color( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], alpha ); - rendered_text += mGLFont->render( + rendered_text += mFontBufferSelection.render( + mGLFont, mText, mScrollHPos + rendered_text, rendered_pixels_right, text_bottom, tmp_color, @@ -1934,7 +1971,8 @@ void LLLineEditor::draw() if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) ) { // unselected, right side - rendered_text += mGLFont->render( + rendered_text += mFontBufferPostSelection.render( + mGLFont, mText, mScrollHPos + rendered_text, rendered_pixels_right, text_bottom, text_color, @@ -1948,7 +1986,8 @@ void LLLineEditor::draw() } else { - rendered_text = mGLFont->render( + rendered_text = mFontBufferPreSelection.render( + mGLFont, mText, mScrollHPos, rendered_pixels_right, text_bottom, text_color, @@ -2108,7 +2147,8 @@ void LLLineEditor::draw() //to give indication that it is not text you typed in if (0 == mText.length() && (mReadOnly || mShowLabelFocused)) { - mGLFont->render(mLabel.getWString(), 0, + mFontBufferLabel.render(mGLFont, + mLabel.getWString(), 0, (F32)mTextLeftEdge, (F32)text_bottom, label_color, LLFontGL::LEFT, @@ -2133,7 +2173,8 @@ void LLLineEditor::draw() // draw label if no text provided if (0 == mText.length()) { - mGLFont->render(mLabel.getWString(), 0, + mFontBufferLabel.render(mGLFont, + mLabel.getWString(), 0, (F32)mTextLeftEdge, (F32)text_bottom, label_color, LLFontGL::LEFT, @@ -2404,12 +2445,16 @@ void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data) bool LLLineEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) { mText.setArg(key, text); + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); return true; } bool LLLineEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) { mLabel.setArg(key, text); + mFontBufferLabel.reset(); return true; } @@ -2508,6 +2553,9 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string, mPreeditOverwrittenWString.clear(); } mText.insert(insert_preedit_at, mPreeditWString); + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); mPreeditStandouts = preedit_standouts; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index cdd22413e7..12fe800acb 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -40,6 +40,7 @@ #include "llframetimer.h" #include "lleditmenuhandler.h" +#include "llfontvertexbuffer.h" #include "llspellcheckmenuhandler.h" #include "lluictrl.h" #include "lluiimage.h" @@ -344,6 +345,10 @@ protected: LLViewBorder* mBorder; const LLFontGL* mGLFont; + LLFontVertexBuffer mFontBufferPreSelection; + LLFontVertexBuffer mFontBufferSelection; + LLFontVertexBuffer mFontBufferPostSelection; + LLFontVertexBuffer mFontBufferLabel; S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes S32 mMaxLengthChars; // Maximum number of characters in the string S32 mCursorPos; // I-beam is just after the mCursorPos-th character. diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 8e96bdde80..db314cae0f 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -242,20 +242,6 @@ void LLPanel::draw() void LLPanel::updateDefaultBtn() { - if( mDefaultBtn) - { - if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) - { - LLButton* buttonp = dynamic_cast<LLButton*>(gFocusMgr.getKeyboardFocus()); - bool focus_is_child_button = buttonp && buttonp->getCommitOnReturn(); - // only enable default button when current focus is not a return-capturing button - mDefaultBtn->setBorderEnabled(!focus_is_child_button); - } - else - { - mDefaultBtn->setBorderEnabled(false); - } - } } void LLPanel::refresh() @@ -266,15 +252,7 @@ void LLPanel::refresh() void LLPanel::setDefaultBtn(LLButton* btn) { - if (mDefaultBtn && mDefaultBtn->getEnabled()) - { - mDefaultBtn->setBorderEnabled(false); - } mDefaultBtn = btn; - if (mDefaultBtn) - { - mDefaultBtn->setBorderEnabled(true); - } } void LLPanel::setDefaultBtn(std::string_view id) diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 7ef2e54429..a3108d77e8 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -30,6 +30,7 @@ #include "llscrolllistcell.h" #include "llcheckboxctrl.h" +#include "llfontvertexbuffer.h" #include "llui.h" // LLUIImage #include "lluictrlfactory.h" @@ -156,7 +157,7 @@ S32 LLScrollListIcon::getWidth() const } -void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const +void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) { if (mIcon) { @@ -236,7 +237,7 @@ S32 LLScrollListBar::getWidth() const } -void LLScrollListBar::draw(const LLColor4& color, const LLColor4& highlight_color) const +void LLScrollListBar::draw(const LLColor4& color, const LLColor4& highlight_color) { S32 bar_width = getWidth() - mLeftPad - mRightPad; S32 left = (S32)(bar_width - bar_width * mRatio); @@ -308,6 +309,19 @@ bool LLScrollListText::needsToolTip() const return mFont->getWidth(mText.getWString().c_str()) > getWidth(); } +void LLScrollListText::setTextWidth(S32 value) +{ + mTextWidth = value; + mFontBuffer.reset(); +} + +void LLScrollListText::setWidth(S32 width) +{ + LLScrollListCell::setWidth(width); + mTextWidth = width; + mFontBuffer.reset(); +} + //virtual bool LLScrollListText::getVisible() const { @@ -341,6 +355,7 @@ void LLScrollListText::setColor(const LLColor4& color) void LLScrollListText::setText(const LLStringExplicit& text) { mText = text; + mFontBuffer.reset(); } void LLScrollListText::setFontStyle(const U8 font_style) @@ -348,6 +363,13 @@ void LLScrollListText::setFontStyle(const U8 font_style) LLFontDescriptor new_desc(mFont->getFontDesc()); new_desc.setStyle(font_style); mFont = LLFontGL::getFont(new_desc); + mFontBuffer.reset(); +} + +void LLScrollListText::setAlignment(LLFontGL::HAlign align) +{ + mFontAlignment = align; + mFontBuffer.reset(); } //virtual @@ -375,7 +397,7 @@ const LLSD LLScrollListText::getAltValue() const } -void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const +void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) { LLColor4 display_color; if (mUseColor) @@ -426,17 +448,18 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col start_x = (F32)getWidth() * 0.5f; break; } - mFont->render(mText.getWString(), 0, - start_x, 0.f, - display_color, - mFontAlignment, - LLFontGL::BOTTOM, - 0, - LLFontGL::NO_SHADOW, - string_chars, - getTextWidth(), - &right_x, - true); + mFontBuffer.render(mFont, + mText.getWString(), 0, + start_x, 0.f, + display_color, + mFontAlignment, + LLFontGL::BOTTOM, + 0, + LLFontGL::NO_SHADOW, + string_chars, + getTextWidth(), + &right_x, + true); } // @@ -475,7 +498,7 @@ LLScrollListCheck::~LLScrollListCheck() mCheckBox = NULL; } -void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const +void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) { mCheckBox->draw(); } @@ -592,7 +615,7 @@ void LLScrollListIconText::setWidth(S32 width) } -void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color) const +void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color) { LLColor4 display_color; if (mUseColor) @@ -650,7 +673,9 @@ void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight start_icon_x = (S32)(center - (((F32)icon_space + mFont->getWidth(mText.getWString().c_str())) * 0.5f)); break; } - mFont->render(mText.getWString(), 0, + mFontBuffer.render( + mFont, + mText.getWString(), 0, start_text_x, 0.f, display_color, mFontAlignment, diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index c5d785ae52..e7ff5c8424 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -29,6 +29,7 @@ #define LLSCROLLLISTCELL_H #include "llfontgl.h" // HAlign +#include "llfontvertexbuffer.h" // HAlign #include "llpointer.h" // LLPointer<> #include "lluistring.h" #include "v4color.h" @@ -96,7 +97,7 @@ public: LLScrollListCell(const LLScrollListCell::Params&); virtual ~LLScrollListCell() {}; - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const {}; // truncate to given width, if possible + virtual void draw(const LLColor4& color, const LLColor4& highlight_color) {}; // truncate to given width, if possible virtual S32 getWidth() const {return mWidth;} virtual S32 getContentWidth() const { return 0; } virtual S32 getHeight() const { return 0; } @@ -127,7 +128,7 @@ class LLScrollListSpacer : public LLScrollListCell public: LLScrollListSpacer(const LLScrollListCell::Params& p) : LLScrollListCell(p) {} /*virtual*/ ~LLScrollListSpacer() {}; - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const {} + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) {} }; /* @@ -139,7 +140,7 @@ public: LLScrollListText(const LLScrollListCell::Params&); /*virtual*/ ~LLScrollListText(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color); /*virtual*/ S32 getContentWidth() const; /*virtual*/ S32 getHeight() const; /*virtual*/ void setValue(const LLSD& value); @@ -155,18 +156,20 @@ public: /*virtual*/ bool needsToolTip() const; S32 getTextWidth() const { return mTextWidth;} - void setTextWidth(S32 value) { mTextWidth = value;} - virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; } + void setTextWidth(S32 value); + virtual void setWidth(S32 width); void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style); - void setAlignment(LLFontGL::HAlign align) { mFontAlignment = align; } + void setAlignment(LLFontGL::HAlign align); protected: + LLUIString mText; LLUIString mAltText; S32 mTextWidth; const LLFontGL* mFont; + LLFontVertexBuffer mFontBuffer; LLColor4 mColor; LLColor4 mHighlightColor; U8 mUseColor; @@ -188,7 +191,7 @@ class LLScrollListIcon : public LLScrollListCell public: LLScrollListIcon(const LLScrollListCell::Params& p); /*virtual*/ ~LLScrollListIcon(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color); /*virtual*/ S32 getWidth() const; /*virtual*/ S32 getHeight() const; /*virtual*/ const LLSD getValue() const; @@ -207,7 +210,7 @@ class LLScrollListBar : public LLScrollListCell public: LLScrollListBar(const LLScrollListCell::Params& p); /*virtual*/ ~LLScrollListBar(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color); /*virtual*/ S32 getWidth() const; /*virtual*/ S32 getHeight() const; /*virtual*/ const LLSD getValue() const; @@ -229,7 +232,7 @@ class LLScrollListCheck : public LLScrollListCell public: LLScrollListCheck( const LLScrollListCell::Params&); /*virtual*/ ~LLScrollListCheck(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color); /*virtual*/ S32 getHeight() const { return 0; } /*virtual*/ const LLSD getValue() const; /*virtual*/ void setValue(const LLSD& value); @@ -264,13 +267,11 @@ class LLScrollListIconText : public LLScrollListText public: LLScrollListIconText(const LLScrollListCell::Params& p); /*virtual*/ ~LLScrollListIconText(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color); /*virtual*/ const LLSD getValue() const; /*virtual*/ void setValue(const LLSD& value); - - S32 getIconWidth() const; - /*virtual*/ void setWidth(S32 width);/* { LLScrollListCell::setWidth(width); mTextWidth = width - ; }*/ + /*virtual*/ void setWidth(S32 width); private: LLPointer<LLUIImage> mIcon; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index e711a6ed1b..445377d3a2 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -410,10 +410,8 @@ void LLScrollListCtrl::clearRows() LLScrollListItem* LLScrollListCtrl::getFirstSelected() const { - item_list::const_iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; if (item->getSelected()) { return item; @@ -425,10 +423,8 @@ LLScrollListItem* LLScrollListCtrl::getFirstSelected() const std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const { std::vector<LLScrollListItem*> ret; - item_list::const_iterator iter; - for(iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; if (item->getSelected()) { ret.push_back(item); @@ -441,9 +437,8 @@ S32 LLScrollListCtrl::getNumSelected() const { S32 numSelected = 0; - for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; if (item->getSelected()) { ++numSelected; @@ -460,10 +455,8 @@ S32 LLScrollListCtrl::getFirstSelectedIndex() const // make sure sort is up to date before returning an index updateSort(); - item_list::const_iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; if (item->getSelected()) { return CurSelectedIndex; @@ -476,29 +469,19 @@ S32 LLScrollListCtrl::getFirstSelectedIndex() const LLScrollListItem* LLScrollListCtrl::getFirstData() const { - if (mItemList.size() == 0) - { - return NULL; - } - return mItemList[0]; + return mItemList.empty() ? NULL : mItemList.front(); } LLScrollListItem* LLScrollListCtrl::getLastData() const { - if (mItemList.size() == 0) - { - return NULL; - } - return mItemList[mItemList.size() - 1]; + return mItemList.empty() ? NULL : mItemList.back(); } std::vector<LLScrollListItem*> LLScrollListCtrl::getAllData() const { std::vector<LLScrollListItem*> ret; - item_list::const_iterator iter; - for(iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; ret.push_back(item); } return ret; @@ -507,22 +490,20 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllData() const // returns first matching item LLScrollListItem* LLScrollListCtrl::getItem(const LLSD& sd) const { - std::string string_val = sd.asString(); + const std::string& string_val = sd.asStringRef(); - item_list::const_iterator iter; - for(iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; // assumes string representation is good enough for comparison - if (item->getValue().asString() == string_val) + if (item->getValue().asStringRef() == string_val) { return item; } } + return NULL; } - void LLScrollListCtrl::reshape( S32 width, S32 height, bool called_from_parent ) { LLUICtrl::reshape( width, height, called_from_parent ); @@ -567,15 +548,16 @@ void LLScrollListCtrl::updateLayout() void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) { S32 height = llmin( getRequiredRect().getHeight(), max_height ); - if(mPageLines) - height = llmin( mPageLines * mLineHeight + 2*mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height ); + if (mPageLines) + { + height = llmin(mPageLines * mLineHeight + 2 * mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height); + } S32 width = getRect().getWidth(); reshape( width, height ); } - LLRect LLScrollListCtrl::getRequiredRect() { S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); @@ -627,7 +609,8 @@ bool LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, bool r S32 i = 0; for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) { - if (i >= (S32)mColumnsIndexed.size()) break; + if (i >= (S32)mColumnsIndexed.size()) + break; cell->setWidth(mColumnsIndexed[i]->getWidth()); } @@ -650,23 +633,21 @@ S32 LLScrollListCtrl::calcMaxContentWidth() S32 max_item_width = 0; - ordered_columns_t::iterator column_itor; - for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) + for (LLScrollListColumn* column : mColumnsIndexed) { - LLScrollListColumn* column = *column_itor; - if (!column) continue; + if (!column) + continue; if (mColumnWidthsDirty) { // update max content width for this column, by looking at all items column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel.getWString().c_str()) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; - - column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + if (LLScrollListCell* cellp = item->getColumn(column->mIndex)) + { + column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + } } } max_item_width += column->mMaxContentWidth; @@ -683,7 +664,8 @@ bool LLScrollListCtrl::updateColumnWidths() for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) { LLScrollListColumn* column = *column_itor; - if (!column) continue; + if (!column) + continue; // update column width S32 new_width = 0; @@ -737,7 +719,6 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) } } - void LLScrollListCtrl::updateColumns(bool force_update) { if (!mColumnsDirty && !force_update) @@ -810,7 +791,8 @@ void LLScrollListCtrl::updateColumns(bool force_update) S32 i = 0; for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) { - if (i >= (S32)mColumnsIndexed.size()) break; + if (i >= (S32)mColumnsIndexed.size()) + break; cell->setWidth(mColumnsIndexed[i]->getWidth()); } @@ -837,8 +819,8 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height) mHeadingHeight = heading_height; updateLayout(); - } + void LLScrollListCtrl::setPageLines(S32 new_page_lines) { mPageLines = new_page_lines; @@ -880,6 +862,7 @@ bool LLScrollListCtrl::selectFirstItem() } first_item = false; } + if (mCommitOnSelectionChange) { commitIfChanged(); @@ -889,13 +872,13 @@ bool LLScrollListCtrl::selectFirstItem() // Deselects all other items // virtual -bool LLScrollListCtrl::selectNthItem( S32 target_index ) +bool LLScrollListCtrl::selectNthItem(S32 target_index) { return selectItemRange(target_index, target_index); } // virtual -bool LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) +bool LLScrollListCtrl::selectItemRange(S32 first_index, S32 last_index) { if (mItemList.empty()) { @@ -905,28 +888,24 @@ bool LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) // make sure sort is up to date updateSort(); - S32 listlen = (S32)mItemList.size(); - first_index = llclamp(first_index, 0, listlen-1); - - if (last_index < 0) - last_index = listlen-1; - else - last_index = llclamp(last_index, first_index, listlen-1); + S32 bottom = (S32)mItemList.size() - 1; + first_index = llclamp(first_index, 0, bottom); + last_index = last_index < 0 ? bottom : llclamp(last_index, first_index, bottom); bool success = false; S32 index = 0; for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); ) { LLScrollListItem *itemp = *iter; - if(!itemp) + if (!itemp) { iter = mItemList.erase(iter); - continue ; + continue; } - if( index >= first_index && index <= last_index ) + if (index >= first_index && index <= last_index) { - if( itemp->getEnabled() ) + if (itemp->getEnabled()) { // TODO: support range selection for cells selectItem(itemp, -1, false); @@ -1173,7 +1152,6 @@ void LLScrollListCtrl::selectPrevItem( bool extend_selection) mSearchString.clear(); } - void LLScrollListCtrl::selectNextItem( bool extend_selection) { LLScrollListItem* next_item = NULL; @@ -1217,8 +1195,6 @@ void LLScrollListCtrl::selectNextItem( bool extend_selection) mSearchString.clear(); } - - void LLScrollListCtrl::deselectAllItems(bool no_commit_on_change) { item_list::iterator iter; @@ -1290,16 +1266,14 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, boo LLStringUtil::toLower(target_text); } - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* item : mItemList) { - LLScrollListItem* item = *iter; std::string item_text = item->getColumn(column)->getValue().asString(); // Only select enabled items with matching names if (!case_sensitive) { LLStringUtil::toLower(item_text); } - if(item_text == target_text) + if (item_text == target_text) { return item; } @@ -1307,6 +1281,15 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, boo return NULL; } +LLScrollListItem* LLScrollListCtrl::getItemByIndex(S32 index) +{ + if (index >= 0 && index < (S32)mItemList.size()) + { + return mItemList[index]; + } + + return NULL; +} bool LLScrollListCtrl::selectItemByPrefix(const std::string& target, bool case_sensitive, S32 column) { @@ -1467,7 +1450,7 @@ U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitiv return found; } -const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const +std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const { LLScrollListItem* item; @@ -1511,7 +1494,10 @@ bool LLScrollListCtrl::setSelectedByValue(const LLSD& value, bool selected) { bool found = false; - if (selected && !mAllowMultipleSelection) deselectAllItems(true); + if (selected && !mAllowMultipleSelection) + { + deselectAllItems(true); + } item_list::iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -2638,9 +2624,7 @@ bool LLScrollListCtrl::isRepeatedChars(const LLWString& string) const void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, bool select_single_item) { - if (!itemp) return; - - if (!itemp->getSelected()) + if (itemp && !itemp->getSelected()) { if (mLastSelected) { @@ -2674,9 +2658,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, bool select void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { - if (!itemp) return; - - if (itemp->getSelected()) + if (itemp && itemp->getSelected()) { if (mLastSelected == itemp) { @@ -2882,7 +2864,7 @@ void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_ // LLEditMenuHandler functions // virtual -void LLScrollListCtrl::copy() +void LLScrollListCtrl::copy() { std::string buffer; @@ -2896,26 +2878,26 @@ void LLScrollListCtrl::copy() } // virtual -bool LLScrollListCtrl::canCopy() const +bool LLScrollListCtrl::canCopy() const { return (getFirstSelected() != NULL); } // virtual -void LLScrollListCtrl::cut() +void LLScrollListCtrl::cut() { copy(); doDelete(); } // virtual -bool LLScrollListCtrl::canCut() const +bool LLScrollListCtrl::canCut() const { return canCopy() && canDoDelete(); } // virtual -void LLScrollListCtrl::selectAll() +void LLScrollListCtrl::selectAll() { // Deselects all other items item_list::iterator iter; @@ -2935,13 +2917,13 @@ void LLScrollListCtrl::selectAll() } // virtual -bool LLScrollListCtrl::canSelectAll() const +bool LLScrollListCtrl::canSelectAll() const { return getCanSelect() && mAllowMultipleSelection && !(mMaxSelectable > 0 && mItemList.size() > mMaxSelectable); } // virtual -void LLScrollListCtrl::deselect() +void LLScrollListCtrl::deselect() { deselectAllItems(); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 1f9f26e08b..c24784338a 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -260,11 +260,12 @@ public: // one of which can be selected at a time. virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); - bool selectItemByLabel( const std::string& item, bool case_sensitive = true, S32 column = 0 ); // false if item not found + bool selectItemByLabel(const std::string& item, bool case_sensitive = true, S32 column = 0); // false if item not found bool selectItemByPrefix(const std::string& target, bool case_sensitive = true, S32 column = -1); bool selectItemByPrefix(const LLWString& target, bool case_sensitive = true, S32 column = -1); - LLScrollListItem* getItemByLabel( const std::string& item, bool case_sensitive = true, S32 column = 0 ); - const std::string getSelectedItemLabel(S32 column = 0) const; + LLScrollListItem* getItemByLabel(const std::string& item, bool case_sensitive = true, S32 column = 0); + LLScrollListItem* getItemByIndex(S32 index); + std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); // If multi select is on, select all element that include substring, @@ -559,6 +560,8 @@ private: sort_signal_t* mSortCallback; is_friend_signal_t* mIsFriendSignal; + + friend class LLComboBox; }; // end class LLScrollListCtrl #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0aebf7543c..e2d31085c4 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -948,7 +948,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) { - beforeValueChange(); segment_set_t::iterator seg_iter = getSegIterContaining(pos); while(seg_iter != mSegments.end()) @@ -1325,6 +1324,7 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent) //virtual void LLTextBase::draw() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // reflow if needed, on demand reflow(); @@ -2586,6 +2586,11 @@ const LLWString& LLTextBase::getWText() const return getViewModel()->getDisplay(); } +S32 LLTextBase::getTextGeneration() const +{ + return getViewModel()->getDisplayGeneration(); +} + // If round is true, if the position is on the right half of a character, the cursor // will be put to its right. If round is false, the cursor will always be put to the // character's left. @@ -3280,7 +3285,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e : LLTextSegment(start, end), mStyle( style ), mToken(NULL), - mEditor(editor) + mEditor(editor), + mLastGeneration(-1) { mFontHeight = mStyle->getFont()->getLineHeight(); @@ -3294,7 +3300,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e LLNormalTextSegment::LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible) : LLTextSegment(start, end), mToken(NULL), - mEditor(editor) + mEditor(editor), + mLastGeneration(-1) { mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color)); @@ -3313,25 +3320,41 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec { return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect); } + else + { + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); + } return draw_rect.mLeft; } // Draws a single text segment, reversing the color for selection if needed. F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect) { - F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha; - - const LLWString &text = getWText(); - F32 right_x = rect.mLeft; if (!mStyle->isVisible()) { return right_x; } - const LLFontGL* font = mStyle->getFont(); + F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha; + + const LLWString& text = getWText(); + S32 text_gen = mEditor.getTextGeneration(); + if (text_gen != mLastGeneration) + { + mLastGeneration = text_gen; + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); + } + + const LLFontGL* font = mStyle->getFont(); LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % (alpha * mStyle->getAlpha()); + bool use_font_buffers = useFontBuffers(); if( selection_start > seg_start ) { @@ -3339,16 +3362,40 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 start = seg_start; S32 end = llmin( selection_start, seg_end ); S32 length = end - start; - font->render(text, start, - rect, - color, - LLFontGL::LEFT, mEditor.mTextVAlign, - LLFontGL::NORMAL, - mStyle->getShadowType(), - length, - &right_x, - mEditor.getUseEllipses(), - mEditor.getUseColor()); + if (use_font_buffers) + { + mFontBufferPreSelection.render( + font, + text, start, + rect, + color, + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + } + else + { + // Font buffer doesn't do well with changes and huge notecard with a bunch + // of segments will see a lot of buffer updates, so instead use derect + // rendering to cache. + // Todo: instead of mLastGeneration make buffer invalidation more fine grained + // like string hash of a given segment. + font->render( + text, start, + rect, + color, + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + } } rect.mLeft = right_x; @@ -3359,16 +3406,35 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 end = llmin( selection_end, seg_end ); S32 length = end - start; - font->render(text, start, - rect, - mStyle->getSelectedColor().get(), - LLFontGL::LEFT, mEditor.mTextVAlign, - LLFontGL::NORMAL, - LLFontGL::NO_SHADOW, - length, - &right_x, - mEditor.getUseEllipses(), - mEditor.getUseColor()); + if (use_font_buffers) + { + mFontBufferSelection.render( + font, + text, start, + rect, + mStyle->getSelectedColor().get(), + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + LLFontGL::NO_SHADOW, + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + } + else + { + font->render( + text, start, + rect, + mStyle->getSelectedColor().get(), + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + LLFontGL::NO_SHADOW, + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + } } rect.mLeft = right_x; if( selection_end < seg_end ) @@ -3377,16 +3443,36 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 start = llmax( selection_end, seg_start ); S32 end = seg_end; S32 length = end - start; - font->render(text, start, - rect, - color, - LLFontGL::LEFT, mEditor.mTextVAlign, - LLFontGL::NORMAL, - mStyle->getShadowType(), - length, - &right_x, - mEditor.getUseEllipses(), - mEditor.getUseColor()); + if (use_font_buffers) + { + mFontBufferPostSelection.render( + font, + text, start, + rect, + color, + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + } + else + { + font->render( + text, start, + rect, + color, + LLFontGL::LEFT, mEditor.mTextVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses(), + mEditor.getUseColor()); + + } } return right_x; } @@ -3573,6 +3659,15 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin return num_chars; } +void LLNormalTextSegment::updateLayout(const class LLTextBase& editor) +{ + LLTextSegment::updateLayout(editor); + + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); +} + void LLNormalTextSegment::dump() const { LL_INFOS() << "Segment [" << diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 00cf66b134..eb4697da15 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -30,6 +30,7 @@ #include "v4color.h" #include "lleditmenuhandler.h" +#include "llfontvertexbuffer.h" #include "llspellcheckmenuhandler.h" #include "llstyle.h" #include "llkeywords.h" @@ -131,6 +132,7 @@ public: /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; + /*virtual*/ void updateLayout(const class LLTextBase& editor); /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool canEdit() const { return true; } /*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); } @@ -149,6 +151,7 @@ public: /*virtual*/ bool handleToolTip(S32 x, S32 y, MASK mask); protected: + virtual bool useFontBuffers() const { return true; } F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect); virtual const LLWString& getWText() const; @@ -161,6 +164,12 @@ protected: LLKeywordToken* mToken; std::string mTooltip; boost::signals2::connection mImageLoadedConnection; + + // font rendering + LLFontVertexBuffer mFontBufferPreSelection; + LLFontVertexBuffer mFontBufferSelection; + LLFontVertexBuffer mFontBufferPostSelection; + S32 mLastGeneration = -1; }; // This text segment is the same as LLNormalTextSegment, the only difference @@ -432,6 +441,7 @@ public: // wide-char versions void setWText(const LLWString& text); const LLWString& getWText() const; + S32 getTextGeneration() const; void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); @@ -475,7 +485,7 @@ public: LLRect getDocRectFromDocIndex(S32 pos) const; void setReadOnly(bool read_only) { mReadOnly = read_only; } - bool getReadOnly() { return mReadOnly; } + bool getReadOnly() const { return mReadOnly; } void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } bool getSkipLinkUnderline() { return mSkipLinkUnderline; } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 0b5acf19a1..e9e7070414 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -271,6 +271,8 @@ protected: virtual bool getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; virtual S32 getPreeditFontSize() const; virtual LLWString getPreeditString() const { return getWText(); } + + virtual bool useFontBuffers() const { return getReadOnly(); } // // Protected data // diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp index e5e0545dad..6d907d7e45 100644 --- a/indra/llui/llviewereventrecorder.cpp +++ b/indra/llui/llviewereventrecorder.cpp @@ -261,7 +261,7 @@ void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) { event.insert("event",LLSD("keyDown")); - LL_DEBUGS() << "[VITA] unicode key: " << uni_char << LL_ENDL; + LL_DEBUGS() << "[VITA] unicode key: " << (int)uni_char << LL_ENDL; LL_DEBUGS() << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << LL_ENDL; diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp index 93106b344f..35963c2b99 100644 --- a/indra/llui/llviewmodel.cpp +++ b/indra/llui/llviewmodel.cpp @@ -82,11 +82,20 @@ void LLTextViewModel::setValue(const LLSD& value) // approximate LLSD storage usage LLViewModel::setValue(value); mDisplay = utf8str_to_wstring(mStringValue = value.asString()); + mDisplayGeneration++; // mDisplay and mValue agree mUpdateFromDisplay = false; } +LLWString& LLTextViewModel::getEditableDisplay() +{ + mDirty = true; + mDisplayGeneration++; + mUpdateFromDisplay = true; + return mDisplay; +} + void LLTextViewModel::setDisplay(const LLWString& value) { // This is the strange way to alter the value. Normally we'd setValue() @@ -94,6 +103,7 @@ void LLTextViewModel::setDisplay(const LLWString& value) // value. But a text editor might want to edit the display string // directly, then convert back to UTF8 on commit. mDisplay = value; + mDisplayGeneration++; mDirty = true; // Don't immediately convert to UTF8 -- do it lazily -- we expect many // more setDisplay() calls than getValue() calls. Just flag that it needs diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index 6cf2200a81..16b0800ce2 100644 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -105,7 +105,8 @@ public: // New functions /// Get the stored value in string form const LLWString& getDisplay() const { return mDisplay; } - LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; } + S32 getDisplayGeneration() const { return mDisplayGeneration; } + LLWString& getEditableDisplay(); /** * Set the display string directly (see LLTextEditor). What the user is @@ -120,6 +121,7 @@ private: /// To avoid converting every widget's stored value from LLSD to LLWString /// every frame, cache the converted value LLWString mDisplay; + S32 mDisplayGeneration = -1; /// As the user edits individual characters (setDisplay()), defer /// LLWString-to-UTF8 conversions until s/he's done. |