summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llaccordionctrltab.h4
-rw-r--r--indra/llui/llbadge.cpp40
-rw-r--r--indra/llui/llbadge.h3
-rw-r--r--indra/llui/llbutton.cpp82
-rw-r--r--indra/llui/llbutton.h68
-rw-r--r--indra/llui/llchatentry.cpp17
-rw-r--r--indra/llui/llchatentry.h2
-rw-r--r--indra/llui/llchatmentionhelper.cpp158
-rw-r--r--indra/llui/llchatmentionhelper.h66
-rw-r--r--indra/llui/llcheckboxctrl.h8
-rw-r--r--indra/llui/llcombobox.cpp168
-rw-r--r--indra/llui/llcombobox.h5
-rw-r--r--indra/llui/llcommandmanager.cpp2
-rw-r--r--indra/llui/llcontainerview.h18
-rw-r--r--indra/llui/lldockablefloater.h4
-rw-r--r--indra/llui/lldockcontrol.cpp2
-rw-r--r--indra/llui/lldockcontrol.h8
-rw-r--r--indra/llui/lldraghandle.h2
-rw-r--r--indra/llui/llemojihelper.cpp11
-rw-r--r--indra/llui/llemojihelper.h7
-rw-r--r--indra/llui/llfiltereditor.h2
-rw-r--r--indra/llui/llflashtimer.cpp4
-rw-r--r--indra/llui/llflashtimer.h4
-rw-r--r--indra/llui/llflatlistview.cpp8
-rw-r--r--indra/llui/llflatlistview.h40
-rw-r--r--indra/llui/llfloater.cpp44
-rw-r--r--indra/llui/llfloater.h45
-rw-r--r--indra/llui/llfloaterreglistener.h1
-rw-r--r--indra/llui/llflyoutbutton.h2
-rw-r--r--indra/llui/llfocusmgr.cpp6
-rw-r--r--indra/llui/llfocusmgr.h3
-rw-r--r--indra/llui/llfolderview.cpp42
-rw-r--r--indra/llui/llfolderview.h32
-rw-r--r--indra/llui/llfolderviewitem.cpp140
-rw-r--r--indra/llui/llfolderviewitem.h24
-rw-r--r--indra/llui/llfolderviewmodel.h1
-rw-r--r--indra/llui/llkeywords.cpp2
-rw-r--r--indra/llui/llkeywords.h4
-rw-r--r--indra/llui/lllayoutstack.cpp4
-rw-r--r--indra/llui/lllayoutstack.h6
-rw-r--r--indra/llui/lllineeditor.cpp130
-rw-r--r--indra/llui/lllineeditor.h13
-rw-r--r--indra/llui/llmenubutton.h4
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llmenugl.h2
-rw-r--r--indra/llui/llmultifloater.cpp2
-rw-r--r--indra/llui/llmultifloater.h2
-rw-r--r--indra/llui/llmultislider.h8
-rw-r--r--indra/llui/llmultisliderctrl.h9
-rw-r--r--indra/llui/llnotifications.cpp41
-rw-r--r--indra/llui/llnotifications.h9
-rw-r--r--indra/llui/llpanel.cpp22
-rw-r--r--indra/llui/llprogressbar.h4
-rw-r--r--indra/llui/llresizebar.h2
-rw-r--r--indra/llui/llresizehandle.h12
-rw-r--r--indra/llui/llrngwriter.h2
-rw-r--r--indra/llui/llscrolllistcell.cpp59
-rw-r--r--indra/llui/llscrolllistcell.h29
-rw-r--r--indra/llui/llscrolllistctrl.cpp146
-rw-r--r--indra/llui/llscrolllistctrl.h18
-rw-r--r--indra/llui/llsearchablecontrol.h10
-rw-r--r--indra/llui/llsliderctrl.h1
-rw-r--r--indra/llui/llspinctrl.h1
-rw-r--r--indra/llui/llstatbar.cpp10
-rw-r--r--indra/llui/llstatbar.h2
-rw-r--r--indra/llui/llstatgraph.cpp1
-rw-r--r--indra/llui/llstatgraph.h7
-rw-r--r--indra/llui/llstatview.h1
-rw-r--r--indra/llui/llstyle.cpp15
-rw-r--r--indra/llui/llstyle.h22
-rw-r--r--indra/llui/lltabcontainer.cpp10
-rw-r--r--indra/llui/lltabcontainer.h12
-rw-r--r--indra/llui/lltextbase.cpp426
-rw-r--r--indra/llui/lltextbase.h60
-rw-r--r--indra/llui/lltextbox.cpp3
-rw-r--r--indra/llui/lltextbox.h38
-rw-r--r--indra/llui/lltexteditor.cpp207
-rw-r--r--indra/llui/lltexteditor.h19
-rw-r--r--indra/llui/lltoolbar.h4
-rw-r--r--indra/llui/lltooltip.cpp8
-rw-r--r--indra/llui/lltooltip.h30
-rw-r--r--indra/llui/lltrans.cpp20
-rw-r--r--indra/llui/lltrans.h18
-rw-r--r--indra/llui/lltransutil.cpp2
-rw-r--r--indra/llui/llui.h14
-rw-r--r--indra/llui/lluiconstants.h20
-rw-r--r--indra/llui/lluictrl.h6
-rw-r--r--indra/llui/lluictrlfactory.h2
-rw-r--r--indra/llui/lluistring.cpp6
-rw-r--r--indra/llui/lluistring.h7
-rw-r--r--indra/llui/llundo.h6
-rw-r--r--indra/llui/llurlaction.h2
-rw-r--r--indra/llui/llurlentry.cpp120
-rw-r--r--indra/llui/llurlentry.h49
-rw-r--r--indra/llui/llurlmatch.cpp10
-rw-r--r--indra/llui/llurlmatch.h12
-rw-r--r--indra/llui/llurlregistry.cpp47
-rw-r--r--indra/llui/llurlregistry.h6
-rw-r--r--indra/llui/llview.cpp19
-rw-r--r--indra/llui/llview.h24
-rw-r--r--indra/llui/llviewborder.h1
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rw-r--r--indra/llui/llviewereventrecorder.h2
-rw-r--r--indra/llui/llviewmodel.cpp10
-rw-r--r--indra/llui/llviewmodel.h4
-rw-r--r--indra/llui/llvirtualtrackball.h23
-rw-r--r--indra/llui/llwindowshade.h2
-rw-r--r--indra/llui/llxuiparser.cpp2
-rw-r--r--indra/llui/llxyvector.h18
110 files changed, 1941 insertions, 1007 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 5991a5b35e..83b3a220a0 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -18,6 +18,7 @@ set(llui_SOURCE_FILES
llbadgeowner.cpp
llbutton.cpp
llchatentry.cpp
+ llchatmentionhelper.cpp
llcheckboxctrl.cpp
llclipboard.cpp
llcombobox.cpp
@@ -130,6 +131,7 @@ set(llui_HEADER_FILES
llcallbackmap.h
llchatentry.h
llchat.h
+ llchatmentionhelper.h
llcheckboxctrl.h
llclipboard.h
llcombobox.h
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index cf3569683e..3fdcf9f7f2 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -126,7 +126,7 @@ public:
void setSelected(bool is_selected);
- bool getCollapsible() { return mCollapsible; };
+ bool getCollapsible() const { return mCollapsible; };
void setCollapsible(bool collapsible) { mCollapsible = collapsible; };
void changeOpenClose(bool is_open);
@@ -181,7 +181,7 @@ public:
void setHeaderVisible(bool value);
- bool getHeaderVisible() { return mHeaderVisible;}
+ bool getHeaderVisible() const { return mHeaderVisible;}
S32 mExpandedHeight; // Height of expanded ctrl.
// Used to restore height after expand.
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index de06d56ae0..42b6f1f07b 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"
@@ -202,17 +204,15 @@ void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, cons
(F32)ll_round(x) + width,
(F32)ll_round(y) + height);
- LLVector4a vertices[6];
- vertices[0].set(screen_rect.mLeft, screen_rect.mTop, 1.0f);
- vertices[1].set(screen_rect.mLeft, screen_rect.mBottom, 1.0f);
- vertices[2].set(screen_rect.mRight, screen_rect.mTop, 1.0f);
- vertices[3].set(screen_rect.mRight, screen_rect.mTop, 1.0f);
- vertices[4].set(screen_rect.mLeft, screen_rect.mBottom, 1.0f);
- vertices[5].set(screen_rect.mRight, screen_rect.mBottom, 1.0f);
+ LLVector4a vertices[4];
+ vertices[0].set(screen_rect.mLeft, screen_rect.mTop, 1.0f);
+ vertices[1].set(screen_rect.mRight, screen_rect.mTop, 1.0f);
+ vertices[2].set(screen_rect.mLeft, screen_rect.mBottom, 1.0f);
+ vertices[3].set(screen_rect.mRight, screen_rect.mBottom, 1.0f);
- gGL.begin(LLRender::TRIANGLES);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
{
- gGL.vertexBatchPreTransformed(vertices, 6);
+ gGL.vertexBatchPreTransformed(vertices, 4);
}
gGL.end();
@@ -353,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..d2534b3939 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))
{
@@ -794,7 +837,7 @@ void LLButton::draw()
// Highlight if needed
if( ll::ui::SearchableControl::getHighlighted() )
- label_color = ll::ui::SearchableControl::getHighlightColor();
+ label_color = ll::ui::SearchableControl::getHighlightFontColor();
// overlay with keyboard focus border
if (hasFocus())
@@ -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/llchatentry.cpp b/indra/llui/llchatentry.cpp
index da5afd0386..7506cd99c0 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -45,12 +45,14 @@ LLChatEntry::LLChatEntry(const Params& p)
mExpandLinesCount(p.expand_lines_count),
mPrevLinesCount(0),
mSingleLineMode(false),
- mPrevExpandedLineCount(S32_MAX)
+ mPrevExpandedLineCount(S32_MAX),
+ mCurrentInput("")
{
// Initialize current history line iterator
mCurrentHistoryLine = mLineHistory.begin();
mAutoIndent = false;
+ mShowChatMentionPicker = true;
keepSelectionOnReturn(true);
}
@@ -189,6 +191,7 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
{
needsReflow();
}
+ mCurrentInput = "";
break;
case KEY_UP:
@@ -196,6 +199,11 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
{
if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
{
+ if (mCurrentHistoryLine == mLineHistory.end())
+ {
+ mCurrentInput = getText();
+ }
+
setText(*(--mCurrentHistoryLine));
endOfDoc();
}
@@ -210,16 +218,15 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
case KEY_DOWN:
if (mHasHistory && MASK_CONTROL == mask)
{
- if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) )
+ if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1))
{
setText(*(++mCurrentHistoryLine));
endOfDoc();
}
- else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) )
+ else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1))
{
mCurrentHistoryLine++;
- std::string empty("");
- setText(empty);
+ setText(mCurrentInput);
needsReflow();
endOfDoc();
}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 5621ede1e7..9a0e8ee91e 100644
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -101,6 +101,8 @@ private:
S32 mExpandLinesCount;
S32 mPrevLinesCount;
S32 mPrevExpandedLineCount;
+
+ std::string mCurrentInput;
};
#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/llchatmentionhelper.cpp b/indra/llui/llchatmentionhelper.cpp
new file mode 100644
index 0000000000..5745389a58
--- /dev/null
+++ b/indra/llui/llchatmentionhelper.cpp
@@ -0,0 +1,158 @@
+/**
+* @file llchatmentionhelper.cpp
+*
+* $LicenseInfo:firstyear=2025&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2025, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "llchatmentionhelper.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lluictrl.h"
+
+constexpr char CHAT_MENTION_HELPER_FLOATER[] = "chat_mention_picker";
+
+bool LLChatMentionHelper::isActive(const LLUICtrl* ctrl) const
+{
+ return mHostHandle.get() == ctrl;
+}
+
+bool LLChatMentionHelper::isCursorInNameMention(const LLWString& wtext, S32 cursor_pos, S32* mention_start_pos) const
+{
+ if (cursor_pos <= 0 || cursor_pos > static_cast<S32>(wtext.size()))
+ return false;
+
+ // Find the beginning of the current word
+ S32 start = cursor_pos - 1;
+ while (start > 0 && wtext[start - 1] != U32(' ') && wtext[start - 1] != U32('\n'))
+ {
+ --start;
+ }
+
+ if (wtext[start] != U32('@'))
+ return false;
+
+ if (mention_start_pos)
+ *mention_start_pos = start;
+
+ S32 word_length = cursor_pos - start;
+
+ if (word_length == 1)
+ {
+ return true;
+ }
+
+ // Get the name after '@'
+ std::string name = wstring_to_utf8str(wtext.substr(start + 1, word_length - 1));
+ LLStringUtil::toLower(name);
+ for (const auto& av_name : mAvatarNames)
+ {
+ if (av_name == name || av_name.find(name) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void LLChatMentionHelper::showHelper(LLUICtrl* host_ctrl, S32 local_x, S32 local_y, const std::string& av_name, std::function<void(std::string)> cb)
+{
+ if (mHelperHandle.isDead())
+ {
+ LLFloater* av_picker_floater = LLFloaterReg::getInstance(CHAT_MENTION_HELPER_FLOATER);
+ mHelperHandle = av_picker_floater->getHandle();
+ mHelperCommitConn = av_picker_floater->setCommitCallback([&](LLUICtrl* ctrl, const LLSD& param) { onCommitName(param.asString()); });
+ }
+ setHostCtrl(host_ctrl);
+ mNameCommitCb = cb;
+
+ S32 floater_x, floater_y;
+ if (!host_ctrl->localPointToOtherView(local_x, local_y, &floater_x, &floater_y, gFloaterView))
+ {
+ LL_WARNS() << "Cannot show helper for non-floater controls." << LL_ENDL;
+ return;
+ }
+
+ LLFloater* av_picker_floater = mHelperHandle.get();
+ LLRect rect = av_picker_floater->getRect();
+ rect.setLeftTopAndSize(floater_x, floater_y + rect.getHeight(), rect.getWidth(), rect.getHeight());
+ av_picker_floater->setRect(rect);
+ if (av_picker_floater->isShown())
+ {
+ av_picker_floater->onOpen(LLSD().with("av_name", av_name));
+ }
+ else
+ {
+ av_picker_floater->openFloater(LLSD().with("av_name", av_name));
+ }
+}
+
+void LLChatMentionHelper::hideHelper(const LLUICtrl* ctrl)
+{
+ if ((ctrl && !isActive(ctrl)))
+ {
+ return;
+ }
+ setHostCtrl(nullptr);
+}
+
+bool LLChatMentionHelper::handleKey(const LLUICtrl* ctrl, KEY key, MASK mask)
+{
+ if (mHelperHandle.isDead() || !isActive(ctrl))
+ {
+ return false;
+ }
+
+ return mHelperHandle.get()->handleKey(key, mask, true);
+}
+
+void LLChatMentionHelper::onCommitName(std::string name_url)
+{
+ if (!mHostHandle.isDead() && mNameCommitCb)
+ {
+ mNameCommitCb(name_url);
+ }
+}
+
+void LLChatMentionHelper::setHostCtrl(LLUICtrl* host_ctrl)
+{
+ const LLUICtrl* pCurHostCtrl = mHostHandle.get();
+ if (pCurHostCtrl != host_ctrl)
+ {
+ mHostCtrlFocusLostConn.disconnect();
+ mHostHandle.markDead();
+ mNameCommitCb = {};
+
+ if (!mHelperHandle.isDead())
+ {
+ mHelperHandle.get()->closeFloater();
+ }
+
+ if (host_ctrl)
+ {
+ mHostHandle = host_ctrl->getHandle();
+ mHostCtrlFocusLostConn = host_ctrl->setFocusLostCallback(std::bind([&]() { hideHelper(getHostCtrl()); }));
+ }
+ }
+}
diff --git a/indra/llui/llchatmentionhelper.h b/indra/llui/llchatmentionhelper.h
new file mode 100644
index 0000000000..5f95d06f31
--- /dev/null
+++ b/indra/llui/llchatmentionhelper.h
@@ -0,0 +1,66 @@
+/**
+* @file llchatmentionhelper.h
+* @brief Header file for LLChatMentionHelper
+*
+* $LicenseInfo:firstyear=2025&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2025, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#pragma once
+
+#include "llhandle.h"
+#include "llsingleton.h"
+
+#include <boost/signals2.hpp>
+
+class LLFloater;
+class LLUICtrl;
+
+class LLChatMentionHelper : public LLSingleton<LLChatMentionHelper>
+{
+ LLSINGLETON(LLChatMentionHelper) {}
+ ~LLChatMentionHelper() override {}
+
+public:
+
+ bool isActive(const LLUICtrl* ctrl) const;
+ bool isCursorInNameMention(const LLWString& wtext, S32 cursor_pos, S32* mention_start_pos = nullptr) const;
+ void showHelper(LLUICtrl* host_ctrl, S32 local_x, S32 local_y, const std::string& av_name, std::function<void(std::string)> commit_cb);
+ void hideHelper(const LLUICtrl* ctrl = nullptr);
+
+ bool handleKey(const LLUICtrl* ctrl, KEY key, MASK mask);
+ void onCommitName(std::string name_url);
+
+ void updateAvatarList(std::vector<std::string> av_names) { mAvatarNames = av_names; }
+
+protected:
+ void setHostCtrl(LLUICtrl* host_ctrl);
+ LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
+
+private:
+ LLHandle<LLUICtrl> mHostHandle;
+ LLHandle<LLFloater> mHelperHandle;
+ boost::signals2::connection mHostCtrlFocusLostConn;
+ boost::signals2::connection mHelperCommitConn;
+ std::function<void(std::string)> mNameCommitCb;
+
+ std::vector<std::string> mAvatarNames;
+};
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 135f128692..4068741978 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -36,8 +36,8 @@
// Constants
//
-const bool RADIO_STYLE = true;
-const bool CHECK_STYLE = false;
+constexpr bool RADIO_STYLE = true;
+constexpr bool CHECK_STYLE = false;
//
// Classes
@@ -94,7 +94,7 @@ public:
// LLUICtrl interface
virtual void setValue(const LLSD& value );
virtual LLSD getValue() const;
- bool get() { return (bool)getValue().asBoolean(); }
+ bool get() const { return (bool)getValue().asBoolean(); }
void set(bool value) { setValue(value); }
virtual void setTentative(bool b);
@@ -106,7 +106,7 @@ public:
virtual void onCommit();
// LLCheckBoxCtrl interface
- virtual bool toggle() { return mButton->toggleState(); } // returns new state
+ virtual bool toggle() { return mButton->toggleState(); } // returns new state
void setBtnFocus() { mButton->setFocus(true); }
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index ee1700e009..f3876ef695 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.asString() == value.asString())
+ 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/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 03717da80b..b10ec51f18 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -170,12 +170,14 @@ bool LLCommandManager::load()
if (!parser.readXUI(commands_file, commandsParams))
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Unable to load xml file: " << commands_file << LL_ENDL;
return false;
}
if (!commandsParams.validateBlock())
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Invalid commands file: " << commands_file << LL_ENDL;
return false;
}
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index c6dd401e85..2675d21c22 100644
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -65,21 +65,21 @@ protected:
public:
~LLContainerView();
- /*virtual*/ bool postBuild();
- /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ bool postBuild() override;
+ bool addChild(LLView* view, S32 tab_group = 0) override;
- /*virtual*/ bool handleDoubleClick(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask);
+ bool handleDoubleClick(S32 x, S32 y, MASK mask) override;
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleMouseUp(S32 x, S32 y, MASK mask) override;
- /*virtual*/ void draw();
- /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true);
- /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
+ void draw() override;
+ void reshape(S32 width, S32 height, bool called_from_parent = true) override;
+ LLRect getRequiredRect() override; // Return the height of this object, given the set options.
void setLabel(const std::string& label);
void showLabel(bool show) { mShowLabel = show; }
void setDisplayChildren(bool displayChildren);
- bool getDisplayChildren() { return mDisplayChildren; }
+ bool getDisplayChildren() const { return mDisplayChildren; }
void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;}
private:
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 3effc977db..9c516e23a4 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -112,8 +112,8 @@ public:
virtual bool overlapsScreenChannel() { return mOverlapsScreenChannel && getVisible() && isDocked(); }
virtual void setOverlapsScreenChannel(bool overlaps) { mOverlapsScreenChannel = overlaps; }
- bool getUniqueDocking() { return mUniqueDocking; }
- bool getUseTongue() { return mUseTongue; }
+ bool getUniqueDocking() const { return mUniqueDocking; }
+ bool getUseTongue() const { return mUseTongue; }
void setUseTongue(bool use_tongue) { mUseTongue = use_tongue;}
private:
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 11dbad8c09..1a00c03856 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -156,7 +156,7 @@ void LLDockControl::repositionDockable()
}
}
-bool LLDockControl::isDockVisible()
+bool LLDockControl::isDockVisible() const
{
bool res = true;
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 7e31330713..b6ac9c19dd 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -61,19 +61,19 @@ public:
void off();
void forceRecalculatePosition();
void setDock(LLView* dockWidget);
- LLView* getDock()
+ LLView* getDock() const
{
return mDockWidgetHandle.get();
}
void repositionDockable();
void drawToungue();
- bool isDockVisible();
+ bool isDockVisible() const;
// gets a rect that bounds possible positions for a dockable control (EXT-1111)
void getAllowedRect(LLRect& rect);
- S32 getTongueWidth() { return mDockTongue->getWidth(); }
- S32 getTongueHeight() { return mDockTongue->getHeight(); }
+ S32 getTongueWidth() const { return mDockTongue->getWidth(); }
+ S32 getTongueHeight() const { return mDockTongue->getHeight(); }
private:
virtual void moveDockable();
diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h
index a522e63243..73211d5292 100644
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
@@ -66,7 +66,7 @@ public:
void setMaxTitleWidth(S32 max_width) {mMaxTitleWidth = llmin(max_width, mMaxTitleWidth); }
S32 getMaxTitleWidth() const { return mMaxTitleWidth; }
void setButtonsRect(const LLRect& rect){ mButtonsRect = rect; }
- LLRect getButtonsRect() { return mButtonsRect; }
+ LLRect getButtonsRect() const { return mButtonsRect; }
void setTitleVisible(bool visible);
virtual void setTitle( const std::string& title ) = 0;
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index b9441a9c91..b2c59ce775 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -99,6 +99,7 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
mHelperHandle = pHelperFloater->getHandle();
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())[0]); }, std::placeholders::_2));
+ mHelperCloseConn = pHelperFloater->setCloseCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCloseHelper(ctrl, param); });
}
setHostCtrl(hostctrl_p);
mEmojiCommitCb = cb;
@@ -148,6 +149,16 @@ void LLEmojiHelper::onCommitEmoji(llwchar emoji)
}
}
+void LLEmojiHelper::onCloseHelper(LLUICtrl* ctrl, const LLSD& param)
+{
+ mCloseSignal(ctrl, param);
+}
+
+boost::signals2::connection LLEmojiHelper::setCloseCallback(const commit_signal_t::slot_type& cb)
+{
+ return mCloseSignal.connect(cb);
+}
+
void LLEmojiHelper::setHostCtrl(LLUICtrl* hostctrl_p)
{
const LLUICtrl* pCurHostCtrl = mHostHandle.get();
diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h
index 2834b06061..26840eef94 100644
--- a/indra/llui/llemojihelper.h
+++ b/indra/llui/llemojihelper.h
@@ -51,16 +51,23 @@ public:
// Eventing
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
void onCommitEmoji(llwchar emoji);
+ void onCloseHelper(LLUICtrl* ctrl, const LLSD& param);
+
+ typedef boost::signals2::signal<void(LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
+ boost::signals2::connection setCloseCallback(const commit_signal_t::slot_type& cb);
protected:
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
void setHostCtrl(LLUICtrl* hostctrl_p);
private:
+ commit_signal_t mCloseSignal;
+
LLHandle<LLUICtrl> mHostHandle;
LLHandle<LLFloater> mHelperHandle;
boost::signals2::connection mHostCtrlFocusLostConn;
boost::signals2::connection mHelperCommitConn;
+ boost::signals2::connection mHelperCloseConn;
std::function<void(llwchar)> mEmojiCommitCb;
bool mIsHideDisabled;
};
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
index 686827d94c..685219c9f6 100644
--- a/indra/llui/llfiltereditor.h
+++ b/indra/llui/llfiltereditor.h
@@ -49,7 +49,7 @@ protected:
LLFilterEditor(const Params&);
friend class LLUICtrlFactory;
- /*virtual*/ void handleKeystroke();
+ void handleKeystroke() override;
};
#endif // LL_FILTEREDITOR_H
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index c3db24c987..54f54653e2 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -85,12 +85,12 @@ void LLFlashTimer::stopFlashing()
mCurrentTickCount = 0;
}
-bool LLFlashTimer::isFlashingInProgress()
+bool LLFlashTimer::isFlashingInProgress() const
{
return mIsFlashingInProgress;
}
-bool LLFlashTimer::isCurrentlyHighlighted()
+bool LLFlashTimer::isCurrentlyHighlighted() const
{
return mIsCurrentlyHighlighted;
}
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index b55ce53fc0..4ef70faf2d 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -51,8 +51,8 @@ public:
void startFlashing();
void stopFlashing();
- bool isFlashingInProgress();
- bool isCurrentlyHighlighted();
+ bool isFlashingInProgress() const;
+ bool isCurrentlyHighlighted() const;
/*
* Use this instead of deleting this object.
* The next call to tick() will return true and that will destroy this object.
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 53f39766c6..8178bada42 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -459,6 +459,7 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
, mNoItemsCommentTextbox(NULL)
, mIsConsecutiveSelection(false)
, mKeepSelectionVisibleOnReshape(p.keep_selection_visible_on_reshape)
+ , mFocusOnItemClicked(true)
{
mBorderThickness = getBorderWidth();
@@ -610,7 +611,10 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
return;
}
- setFocus(true);
+ if (mFocusOnItemClicked)
+ {
+ setFocus(true);
+ }
bool select_item = !isSelected(item_pair);
@@ -1337,7 +1341,7 @@ void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string)
}
}
-bool LLFlatListViewEx::getForceShowingUnmatchedItems()
+bool LLFlatListViewEx::getForceShowingUnmatchedItems() const
{
return mForceShowingUnmatchedItems;
}
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 6d75e9f282..6271231183 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -113,7 +113,7 @@ public:
};
// disable traversal when finding widget to hand focus off to
- /*virtual*/ bool canFocusChildren() const { return false; }
+ /*virtual*/ bool canFocusChildren() const override { return false; }
/**
* Connects callback to signal called when Return key is pressed.
@@ -121,15 +121,15 @@ public:
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
- virtual void reshape(S32 width, S32 height, bool called_from_parent = true);
+ virtual void reshape(S32 width, S32 height, bool called_from_parent = true) override;
/** Returns full rect of child panel */
const LLRect& getItemsRect() const;
- LLRect getRequiredRect() { return getItemsRect(); }
+ LLRect getRequiredRect() override { return getItemsRect(); }
/** Returns distance between items */
- const S32 getItemsPad() { return mItemPad; }
+ const S32 getItemsPad() const { return mItemPad; }
/**
* Adds and item and LLSD value associated with it to the list at specified position
@@ -264,13 +264,13 @@ public:
void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
/** Get number of selected items in the list */
- U32 numSelected() const {return static_cast<U32>(mSelectedItemPairs.size()); }
+ U32 numSelected() const { return static_cast<U32>(mSelectedItemPairs.size()); }
/** Get number of (visible) items in the list */
U32 size(const bool only_visible_items = true) const;
/** Removes all items from the list */
- virtual void clear();
+ virtual void clear() override;
/**
* Removes all items that can be detached from the list but doesn't destroy
@@ -294,10 +294,12 @@ public:
void scrollToShowFirstSelectedItem();
- void selectFirstItem ();
- void selectLastItem ();
+ void selectFirstItem();
+ void selectLastItem();
- virtual S32 notify(const LLSD& info) ;
+ virtual S32 notify(const LLSD& info) override;
+
+ void setFocusOnItemClicked(bool b) { mFocusOnItemClicked = b; }
virtual ~LLFlatListView();
@@ -346,8 +348,8 @@ protected:
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
- virtual bool canSelectAll() const;
- virtual void selectAll();
+ virtual bool canSelectAll() const override;
+ virtual void selectAll() override;
virtual bool isSelected(item_pair_t* item_pair) const;
@@ -364,15 +366,15 @@ protected:
*/
void notifyParentItemsRectChanged();
- virtual bool handleKeyHere(KEY key, MASK mask);
+ virtual bool handleKeyHere(KEY key, MASK mask) override;
- virtual bool postBuild();
+ virtual bool postBuild() override;
- virtual void onFocusReceived();
+ virtual void onFocusReceived() override;
- virtual void onFocusLost();
+ virtual void onFocusLost() override;
- virtual void draw();
+ virtual void draw() override;
LLRect getLastSelectedItemRect();
@@ -423,6 +425,8 @@ private:
bool mKeepSelectionVisibleOnReshape;
+ bool mFocusOnItemClicked;
+
/** All pairs of the list */
pairs_list_t mItemPairs;
@@ -478,7 +482,7 @@ public:
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
- bool getForceShowingUnmatchedItems();
+ bool getForceShowingUnmatchedItems() const;
void setForceShowingUnmatchedItems(bool show);
@@ -486,7 +490,7 @@ public:
* Sets up new filter string and filters the list.
*/
void setFilterSubString(const std::string& filter_str, bool notify_parent);
- std::string getFilterSubString() { return mFilterSubString; }
+ std::string getFilterSubString() const { return mFilterSubString; }
/**
* Filters the list, rearranges and notifies parent about shape changes.
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index ff174d8470..fd07b2ec5d 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++)
@@ -2177,7 +2165,7 @@ void LLFloater::setCanDrag(bool can_drag)
}
}
-bool LLFloater::getCanDrag()
+bool LLFloater::getCanDrag() const
{
return mDragHandle->getEnabled();
}
@@ -2287,36 +2275,28 @@ void LLFloater::drawConeToOwner(F32 &context_cone_opacity,
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
{
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
-
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
-
-
gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
+ gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+ gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
+ gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
}
gGL.end();
}
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 9be2240f6f..9e1594bdd2 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -46,24 +46,24 @@ class LLMultiFloater;
class LLFloater;
-const bool RESIZE_YES = true;
-const bool RESIZE_NO = false;
+constexpr bool RESIZE_YES = true;
+constexpr bool RESIZE_NO = false;
-const bool DRAG_ON_TOP = false;
-const bool DRAG_ON_LEFT = true;
+constexpr bool DRAG_ON_TOP = false;
+constexpr bool DRAG_ON_LEFT = true;
-const bool MINIMIZE_YES = true;
-const bool MINIMIZE_NO = false;
+constexpr bool MINIMIZE_YES = true;
+constexpr bool MINIMIZE_NO = false;
-const bool CLOSE_YES = true;
-const bool CLOSE_NO = false;
+constexpr bool CLOSE_YES = true;
+constexpr bool CLOSE_NO = false;
-const bool ADJUST_VERTICAL_YES = true;
-const bool ADJUST_VERTICAL_NO = false;
+constexpr bool ADJUST_VERTICAL_YES = true;
+constexpr bool ADJUST_VERTICAL_NO = false;
-const F32 CONTEXT_CONE_IN_ALPHA = 0.f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_CONE_FADE_TIME = .08f;
+constexpr F32 CONTEXT_CONE_IN_ALPHA = 0.f;
+constexpr F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
+constexpr F32 CONTEXT_CONE_FADE_TIME = .08f;
namespace LLFloaterEnums
{
@@ -228,7 +228,7 @@ public:
/*virtual*/ void setIsChrome(bool is_chrome);
/*virtual*/ void setRect(const LLRect &rect);
void setIsSingleInstance(bool is_single_instance);
- bool getIsSingleInstance() { return mSingleInstance; }
+ bool getIsSingleInstance() const { return mSingleInstance; }
void initFloater(const Params& p);
@@ -274,17 +274,17 @@ public:
static bool isShown(const LLFloater* floater);
static bool isVisible(const LLFloater* floater);
static bool isMinimized(const LLFloater* floater);
- bool isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
+ bool isFirstLook() const { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
virtual bool isFrontmost();
- bool isDependent() { return !mDependeeHandle.isDead(); }
+ bool isDependent() const { return !mDependeeHandle.isDead(); }
void setCanMinimize(bool can_minimize);
void setCanClose(bool can_close);
void setCanTearOff(bool can_tear_off);
virtual void setCanResize(bool can_resize);
void setCanDrag(bool can_drag);
- bool getCanDrag();
+ bool getCanDrag() const;
void setHost(LLMultiFloater* host);
- bool isResizable() const { return mResizable; }
+ bool isResizable() const { return mResizable; }
void setResizeLimits( S32 min_width, S32 min_height );
void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
@@ -347,7 +347,7 @@ public:
virtual void setDocked(bool docked, bool pop_on_undock = true);
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
- bool isTornOff() {return mTornOff;}
+ bool isTornOff() const { return mTornOff; }
void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;}
@@ -377,6 +377,10 @@ public:
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }
+
+ void setAutoFocus(bool focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
+ bool getAutoFocus() const { return mAutoFocus; }
+
protected:
void applyControlsAndPosition(LLFloater* other);
@@ -401,8 +405,6 @@ protected:
void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
const LLRect& getExpandedRect() const { return mExpandedRect; }
- void setAutoFocus(bool focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
- bool getAutoFocus() const { return mAutoFocus; }
LLDragHandle* getDragHandle() const { return mDragHandle; }
void destroy(); // Don't call this directly. You probably want to call closeFloater()
@@ -423,7 +425,6 @@ protected:
private:
void setForeground(bool b); // called only by floaterview
void cleanupHandles(); // remove handles to dead floaters
- void createMinimizeButton();
void buildButtons(const Params& p);
// Images and tooltips are named in the XML, but we want to look them
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index a36072892c..28f6e7c66b 100644
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
@@ -30,7 +30,6 @@
#define LL_LLFLOATERREGLISTENER_H
#include "lleventapi.h"
-#include <string>
class LLSD;
diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h
index 7a49501318..73190fc984 100644
--- a/indra/llui/llflyoutbutton.h
+++ b/indra/llui/llflyoutbutton.h
@@ -54,7 +54,7 @@ protected:
LLFlyoutButton(const Params&);
friend class LLUICtrlFactory;
public:
- virtual void draw();
+ void draw() override;
void setToggleState(bool state);
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 4f3d2328aa..0d7c98294f 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -59,12 +59,6 @@ bool LLFocusableElement::handleUnicodeChar(llwchar uni_char, bool called_from_pa
}
// virtual
-bool LLFocusableElement::handleUnicodeString(char *uni_str, bool editing, bool called_from_parent)
-{
- return FALSE;
-}
-
-// virtual
bool LLFocusableElement::wantsKeyUpKeyDown() const
{
return false;
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 1ca6f50354..89fee5c9f1 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -59,7 +59,6 @@ public:
virtual bool handleKey(KEY key, MASK mask, bool called_from_parent);
virtual bool handleKeyUp(KEY key, MASK mask, bool called_from_parent);
virtual bool handleUnicodeChar(llwchar uni_char, bool called_from_parent);
- virtual bool handleUnicodeString(char *uni_str, bool editing, bool called_from_parent);
/**
* If true this LLFocusableElement wants to receive KEYUP and KEYDOWN messages
@@ -98,7 +97,7 @@ public:
LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; }
bool childHasKeyboardFocus( const LLView* parent ) const;
void removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus );
- bool getKeystrokesOnly() { return mKeystrokesOnly; }
+ bool getKeystrokesOnly() const { return mKeystrokesOnly; }
void setKeystrokesOnly(bool keystrokes_only) { mKeystrokesOnly = keystrokes_only; }
F32 getFocusFlashAmt() const;
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 388dc5b1ac..b664065532 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -28,6 +28,7 @@
#include "llfolderview.h"
#include "llfolderviewmodel.h"
+#include "llcallbacklist.h"
#include "llclipboard.h" // *TODO: remove this once hack below gone.
#include "llkeyboard.h"
#include "lllineeditor.h"
@@ -274,7 +275,11 @@ LLFolderView::~LLFolderView( void )
mRenamer = NULL;
mStatusTextBox = NULL;
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+ if (mPopupMenuHandle.get())
+ {
+ mPopupMenuHandle.get()->die();
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
mPopupMenuHandle.markDead();
mAutoOpenItems.removeAllNodes();
@@ -1095,7 +1100,10 @@ bool LLFolderView::handleKeyHere( KEY key, MASK mask )
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
- LLMenuGL::sMenuContainer->hideMenus();
+ if (LLMenuGL::sMenuContainer->hideMenus())
+ {
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
}
switch( key )
@@ -1340,7 +1348,10 @@ bool LLFolderView::handleUnicodeCharHere(llwchar uni_char)
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
- LLMenuGL::sMenuContainer->hideMenus();
+ if (LLMenuGL::sMenuContainer->hideMenus())
+ {
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
}
//do text search
@@ -1612,7 +1623,11 @@ void LLFolderView::deleteAllChildren()
{
LLUI::getInstance()->removePopup(mRenamer);
}
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+ if (mPopupMenuHandle.get())
+ {
+ mPopupMenuHandle.get()->die();
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
mPopupMenuHandle.markDead();
mScrollContainer = NULL;
mRenameItem = NULL;
@@ -1649,7 +1664,7 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
{
LLRect local_rect = item->getLocalRect();
S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
- S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight();
+ S32 label_height = getLabelFont()->getLineHeight();
// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight();
@@ -1979,9 +1994,24 @@ void LLFolderView::updateMenu()
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->getVisible())
{
- updateMenuOptions(menu);
+ // When fetching folders in bulk or in parts, each callback
+ // cause updateMenu individually, so make sure it gets called
+ // only once per frame, after callbacks are done.
+ // gIdleCallbacks has built in dupplicate protection.
+ gIdleCallbacks.addFunction(onIdleUpdateMenu, this);
+ }
+}
+
+void LLFolderView::onIdleUpdateMenu(void* user_data)
+{
+ LLFolderView* self = (LLFolderView*)user_data;
+ LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get();
+ if (menu)
+ {
+ self->updateMenuOptions(menu);
menu->needsArrange(); // update menu height if needed
}
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, self);
}
bool LLFolderView::isFolderSelected()
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 62ef2a0626..bdce9dec54 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -124,11 +124,11 @@ public:
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
- bool getAllowMultiSelect() { return mAllowMultiSelect; }
- bool getAllowDrag() { return mAllowDrag; }
+ bool getAllowMultiSelect() const { return mAllowMultiSelect; }
+ bool getAllowDrag() const { return mAllowDrag; }
void setSingleFolderMode(bool is_single_mode) { mSingleFolderMode = is_single_mode; }
- bool isSingleFolderMode() { return mSingleFolderMode; }
+ bool isSingleFolderMode() const { return mSingleFolderMode; }
// Close all folders in the view
void closeAllFolders();
@@ -142,7 +142,7 @@ public:
virtual S32 getItemHeight() const;
void arrangeAll() { mArrangeGeneration++; }
- S32 getArrangeGeneration() { return mArrangeGeneration; }
+ S32 getArrangeGeneration() const { return mArrangeGeneration; }
// applies filters to control visibility of items
virtual void filter( LLFolderViewFilter& filter);
@@ -227,27 +227,27 @@ public:
void setShowSelectionContext(bool show) { mShowSelectionContext = show; }
bool getShowSelectionContext();
void setShowSingleSelection(bool show);
- bool getShowSingleSelection() { return mShowSingleSelection; }
- F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
- bool getUseEllipses() { return mUseEllipses; }
- S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
+ bool getShowSingleSelection() const { return mShowSingleSelection; }
+ F32 getSelectionFadeElapsedTime() const { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
+ bool getUseEllipses() const { return mUseEllipses; }
+ S32 getSelectedCount() const { return (S32)mSelectedItems.size(); }
- void update(); // needs to be called periodically (e.g. once per frame)
+ void update(); // needs to be called periodically (e.g. once per frame)
- bool needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
- bool needsAutoRename() { return mNeedsAutoRename; }
+ bool needsAutoSelect() const { return mNeedsAutoSelect && !mAutoSelectOverride; }
+ bool needsAutoRename() const { return mNeedsAutoRename; }
void setNeedsAutoRename(bool val) { mNeedsAutoRename = val; }
void setPinningSelectedItem(bool val) { mPinningSelectedItem = val; }
void setAutoSelectOverride(bool val) { mAutoSelectOverride = val; }
- bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
+ bool showItemLinkOverlays() const { return mShowItemLinkOverlays; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; }
void setForceArrange(bool force) { mForceArrange = force; }
- LLPanel* getParentPanel() { return mParentPanel.get(); }
+ LLPanel* getParentPanel() const { return mParentPanel.get(); }
// DEBUG only
void dumpSelectionInformation();
@@ -255,7 +255,7 @@ public:
void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; }
- bool useLabelSuffix() { return mUseLabelSuffix; }
+ bool useLabelSuffix() const { return mUseLabelSuffix; }
virtual void updateMenu();
void finishRenamingItem( void );
@@ -266,6 +266,7 @@ public:
private:
void updateMenuOptions(LLMenuGL* menu);
void updateRenamerPosition();
+ static void onIdleUpdateMenu(void* user_data);
protected:
LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
@@ -390,7 +391,7 @@ public:
virtual ~LLSelectFirstFilteredItem() {}
virtual void doFolder(LLFolderViewFolder* folder);
virtual void doItem(LLFolderViewItem* item);
- bool wasItemSelected() { return mItemSelected || mFolderSelected; }
+ bool wasItemSelected() const { return mItemSelected || mFolderSelected; }
protected:
bool mItemSelected;
bool mFolderSelected;
@@ -414,6 +415,7 @@ public:
virtual void doItem(LLFolderViewItem* item) {}
void setApply(bool apply);
void clearOpenFolders() { mOpenFolders.clear(); }
+ bool hasOpenFolders() { return !mOpenFolders.empty(); }
protected:
std::set<LLUUID> mOpenFolders;
bool mApply;
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index e4f5664908..6d0cfcba95 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -23,7 +23,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#include "../newview/llviewerprecompiledheaders.h"
+#include "linden_common.h"
#include "llflashtimer.h"
@@ -48,7 +48,6 @@ static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
// statics
std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
-bool LLFolderViewItem::sColorSetInitialized = false;
LLUIColor LLFolderViewItem::sFgColor;
LLUIColor LLFolderViewItem::sHighlightBgColor;
LLUIColor LLFolderViewItem::sFlashBgColor;
@@ -58,6 +57,10 @@ LLUIColor LLFolderViewItem::sFilterBGColor;
LLUIColor LLFolderViewItem::sFilterTextColor;
LLUIColor LLFolderViewItem::sSuffixColor;
LLUIColor LLFolderViewItem::sSearchStatusColor;
+S32 LLFolderViewItem::sTopPad = 0;
+LLUIImagePtr LLFolderViewItem::sFolderArrowImg;
+LLUIImagePtr LLFolderViewItem::sSelectionImg;
+LLFontGL* LLFolderViewItem::sSuffixFont = nullptr;
// only integers can be initialized in header
const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
@@ -83,15 +86,42 @@ LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
return rtn;
}
+
+const LLFontGL* LLFolderViewItem::getLabelFont()
+{
+ if (!pLabelFont)
+ {
+ pLabelFont = getLabelFontForStyle(mLabelStyle);
+ }
+ return pLabelFont;
+}
//static
void LLFolderViewItem::initClass()
{
+ const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+ sTopPad = default_params.item_top_pad;
+ sFolderArrowImg = default_params.folder_arrow_image;
+ sSelectionImg = default_params.selection_image;
+ sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL);
+
+ sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+ sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+ sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+ sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+ sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+ sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+ sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+ sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
}
//static
void LLFolderViewItem::cleanupClass()
{
sFonts.clear();
+ sFolderArrowImg = nullptr;
+ sSelectionImg = nullptr;
+ sSuffixFont = nullptr;
}
@@ -134,6 +164,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mIsItemCut(false),
mCutGeneration(0),
mLabelStyle( LLFontGL::NORMAL ),
+ pLabelFont(nullptr),
mHasVisibleChildren(false),
mLocalIndentation(p.folder_indentation),
mIndentation(0),
@@ -158,20 +189,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mMaxFolderItemOverlap(p.max_folder_item_overlap),
mDoubleClickOverride(p.double_click_override)
{
- if (!sColorSetInitialized)
- {
- sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
- sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
- sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
- sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
- sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
- sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
- sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
- sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
- sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
- sColorSetInitialized = true;
- }
-
if (mViewModelItem)
{
mViewModelItem->setFolderViewItem(this);
@@ -307,6 +324,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()
@@ -319,7 +337,9 @@ void LLFolderViewItem::refresh()
// Very Expensive!
// Can do a number of expensive checks, like checking active motions, wearables or friend list
mLabelStyle = vmi.getLabelStyle();
+ pLabelFont = nullptr; // refresh can be called from a coro, don't use getLabelFontForStyle, coro trips font list tread safety
mLabelSuffix = utf8str_to_wstring(vmi.getLabelSuffix());
+ mSuffixFontBuffer.reset();
}
// Dirty the filter flag of the model from the view (CHUI-849)
@@ -344,6 +364,7 @@ void LLFolderViewItem::refreshSuffix()
// Very Expensive!
// Can do a number of expensive checks, like checking active motions, wearables or friend list
mLabelStyle = vmi->getLabelStyle();
+ pLabelFont = nullptr;
mLabelSuffix = utf8str_to_wstring(vmi->getLabelSuffix());
}
@@ -736,19 +757,17 @@ bool LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
return handled;
}
-void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color)
+void LLFolderViewItem::drawOpenFolderArrow()
{
//--------------------------------------------------------------------------------//
// Draw open folder arrow
//
- const S32 TOP_PAD = default_params.item_top_pad;
if (hasVisibleChildren() || !isFolderComplete())
{
- LLUIImage* arrow_image = default_params.folder_arrow_image;
gl_draw_scaled_rotated_image(
- mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
- mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color);
+ mIndentation, getRect().getHeight() - mArrowSize - mTextPad - sTopPad,
+ mArrowSize, mArrowSize, mControlLabelRotation, sFolderArrowImg->getImage(), sFgColor);
}
}
@@ -764,7 +783,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
/*virtual*/ bool LLFolderViewItem::isFadeItem()
{
- LLClipboard& clipboard = LLClipboard::instance();
+ static const LLClipboard& clipboard = LLClipboard::instance(); // Make it a 'simpleton'?
if (mCutGeneration != clipboard.getGeneration())
{
mCutGeneration = clipboard.getGeneration();
@@ -775,8 +794,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 +804,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 +812,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 +820,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 +909,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);
}
@@ -900,16 +919,14 @@ void LLFolderViewItem::draw()
const bool show_context = (getRoot() ? getRoot()->getShowSelectionContext() : false);
const bool filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : false); // If we have keyboard focus, draw selection filled
- const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- const S32 TOP_PAD = default_params.item_top_pad;
-
- const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+ const LLFontGL* font = getLabelFont();
+ S32 line_height = font->getLineHeight();
getViewModelItem()->update();
- if(!mSingleFolderMode)
+ if (!mSingleFolderMode)
{
- drawOpenFolderArrow(default_params, sFgColor);
+ drawOpenFolderArrow();
}
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
@@ -918,18 +935,19 @@ void LLFolderViewItem::draw()
// Draw open icon
//
const S32 icon_x = mIndentation + mArrowSize + mTextPad;
+ const S32 rect_height = getRect().getHeight();
if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
{
- mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+ mIconOpen->draw(icon_x, rect_height - mIconOpen->getHeight() - sTopPad + 1);
}
else if (mIcon)
{
- mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ mIcon->draw(icon_x, rect_height - mIcon->getHeight() - sTopPad + 1);
}
if (mIconOverlay && getRoot()->showItemLinkOverlays())
{
- mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ mIconOverlay->draw(icon_x, rect_height - mIcon->getHeight() - sTopPad + 1);
}
//--------------------------------------------------------------------------------//
@@ -940,26 +958,24 @@ 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 y = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad;
F32 text_left = (F32)getLabelXPos();
LLWString combined_string = mLabel + mLabelSuffix;
- const LLFontGL* suffix_font = getLabelFontForStyle(LLFontGL::NORMAL);
S32 filter_offset = static_cast<S32>(mViewModelItem->getFilterStringOffset());
if (filter_string_length > 0)
{
- S32 bottom = getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD;
- S32 top = getRect().getHeight() - TOP_PAD;
- if(mLabelSuffix.empty() || (font == suffix_font))
+ S32 bottom = rect_height - line_height - 3 - sTopPad;
+ S32 top = rect_height - sTopPad;
+ if(mLabelSuffix.empty() || (font == sSuffixFont))
{
- S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, static_cast<S32>(mViewModelItem->getFilterStringOffset())) - 2;
- S32 right = left + font->getWidth(combined_string.c_str(), static_cast<S32>(mViewModelItem->getFilterStringOffset()), filter_string_length) + 2;
+ S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, filter_offset) - 2;
+ S32 right = left + font->getWidth(combined_string.c_str(), filter_offset, filter_string_length) + 2;
- LLUIImage* box_image = default_params.selection_image;
- LLRect box_rect(left, top, right, bottom);
- box_image->draw(box_rect, sFilterBGColor);
+ LLRect box_rect(left, top, right, bottom);
+ sSelectionImg->draw(box_rect, sFilterBGColor);
}
else
{
@@ -968,19 +984,17 @@ void LLFolderViewItem::draw()
{
S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, llmin(filter_offset, (S32)mLabel.size()))) - 2;
S32 right = left + (S32)font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length) + 2;
- LLUIImage* box_image = default_params.selection_image;
LLRect box_rect(left, top, right, bottom);
- box_image->draw(box_rect, sFilterBGColor);
+ sSelectionImg->draw(box_rect, sFilterBGColor);
}
S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length;
if(suffix_filter_length > 0)
{
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
- S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2;
- S32 right = left + (S32)suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2;
- LLUIImage* box_image = default_params.selection_image;
+ S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2;
+ S32 right = left + (S32)sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2;
LLRect box_rect(left, top, right, bottom);
- box_image->draw(box_rect, sFilterBGColor);
+ sSelectionImg->draw(box_rect, sFilterBGColor);
}
}
}
@@ -999,9 +1013,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(sSuffixFont, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(),
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ S32_MAX, S32_MAX, &right_x);
}
//--------------------------------------------------------------------------------//
@@ -1009,10 +1023,10 @@ void LLFolderViewItem::draw()
//
if (filter_string_length > 0)
{
- if(mLabelSuffix.empty() || (font == suffix_font))
+ if(mLabelSuffix.empty() || (font == sSuffixFont))
{
F32 match_string_left = text_left + font->getWidthF32(combined_string.c_str(), 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string.c_str(), filter_offset, filter_string_length);
- F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+ F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad;
font->render(combined_string, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
filter_string_length, S32_MAX, &right_x);
@@ -1023,7 +1037,7 @@ void LLFolderViewItem::draw()
if(label_filter_length > 0)
{
F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length);
- F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+ F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad;
font->render(mLabel, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
label_filter_length, S32_MAX, &right_x);
@@ -1033,9 +1047,9 @@ void LLFolderViewItem::draw()
if(suffix_filter_length > 0)
{
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
- F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length);
- F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
- suffix_font->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
+ F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length);
+ F32 yy = (F32)rect_height - sSuffixFont->getLineHeight() - (F32)mTextPad - (F32)sTopPad;
+ sSuffixFont->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
suffix_filter_length, S32_MAX, &right_x);
}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 60cdac3ab9..2ee018a90a 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;
@@ -134,7 +135,6 @@ protected:
LLUIColor mFontHighlightColor;
// For now assuming all colors are the same in derived classes.
- static bool sColorSetInitialized;
static LLUIColor sFgColor;
static LLUIColor sFgDisabledColor;
static LLUIColor sHighlightBgColor;
@@ -154,9 +154,10 @@ protected:
virtual bool isHighlightActive();
virtual bool isFadeItem();
virtual bool isFlashing() { return false; }
- virtual void setFlashState(bool) { }
+ virtual void setFlashState(bool, bool) { }
static LLFontGL* getLabelFontForStyle(U8 style);
+ const LLFontGL* getLabelFont();
bool mIsSelected;
@@ -281,7 +282,7 @@ public:
// Does not need filter update
virtual void refreshSuffix();
- bool isSingleFolderMode() { return mSingleFolderMode; }
+ bool isSingleFolderMode() const { return mSingleFolderMode; }
// LLView functionality
virtual bool handleRightMouseDown( S32 x, S32 y, MASK mask );
@@ -296,9 +297,9 @@ 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 drawOpenFolderArrow();
+ 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,14 @@ public:
private:
static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
+ static S32 sTopPad;
+ static LLUIImagePtr sFolderArrowImg;
+ static LLUIImagePtr sSelectionImg;
+ static LLFontGL* sSuffixFont;
+
+ LLFontVertexBuffer mLabelFontBuffer;
+ LLFontVertexBuffer mSuffixFontBuffer;
+ LLFontGL* pLabelFont{nullptr};
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -406,9 +415,6 @@ public:
// doesn't delete it.
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
- // This function is called by a child that needs to be resorted.
- void resort(LLFolderViewItem* item);
-
void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
// folders can be opened. This will usually be called by internal
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/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 7bf43c22c1..2bea8fb4ed 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -170,7 +170,7 @@ std::string LLKeywords::getAttribute(std::string_view key)
return (it != mAttributes.end()) ? it->second : "";
}
-LLUIColor LLKeywords::getColorGroup(std::string_view key_in)
+LLUIColor LLKeywords::getColorGroup(std::string_view key_in) const
{
std::string color_group = "ScriptText";
if (key_in == "functions")
diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h
index 328561c92a..5892238593 100644
--- a/indra/llui/llkeywords.h
+++ b/indra/llui/llkeywords.h
@@ -111,8 +111,8 @@ public:
~LLKeywords();
void clearLoaded() { mLoaded = false; }
- LLUIColor getColorGroup(std::string_view key_in);
- bool isLoaded() const { return mLoaded; }
+ LLUIColor getColorGroup(std::string_view key_in) const;
+ bool isLoaded() const { return mLoaded; }
void findSegments(std::vector<LLTextSegmentPtr> *seg_list,
const LLWString& text,
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 1c59938f90..fe0591ce4b 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -36,8 +36,8 @@
#include "lliconctrl.h"
#include "boost/foreach.hpp"
-static const F32 MIN_FRACTIONAL_SIZE = 0.00001f;
-static const F32 MAX_FRACTIONAL_SIZE = 1.f;
+static constexpr F32 MIN_FRACTIONAL_SIZE = 0.00001f;
+static constexpr F32 MAX_FRACTIONAL_SIZE = 1.f;
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 8459921c60..9e3536aaff 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -75,9 +75,6 @@ public:
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
/*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true);
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
-
typedef enum e_animate
{
NO_ANIMATE,
@@ -86,7 +83,7 @@ public:
void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE);
void collapsePanel(LLPanel* panel, bool collapsed = true);
- S32 getNumPanels() { return static_cast<S32>(mPanels.size()); }
+ S32 getNumPanels() const { return static_cast<S32>(mPanels.size()); }
void updateLayout();
@@ -190,7 +187,6 @@ public:
bool isCollapsed() const { return mCollapsed;}
void setOrientation(LLView::EOrientation orientation);
- void storeOriginalDim();
void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; }
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index ac7948f735..45dab88e87 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
{
@@ -1031,25 +1050,6 @@ void LLLineEditor::addChar(const llwchar uni_char)
getWindow()->hideCursorUntilMouseMove();
}
-void LLLineEditor::addString(char *s, bool editing)
-{
- if (hasSelection())
- deleteSelection();
- else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) {
- if (!prevalidateInput(mText.getWString()
- .substr(getCursor(), 1)))
- return;
- mText.erase(getCursor(), 1);
- } else if (editing) {
- mText.clear();
- setCursor(0);
- }
- mText.insert(getCursor(), utf8str_to_wstring(s));
- if (editing) setCursor(strlen(s));
- else setCursor(getCursor() + 1);
- getWindow()->hideCursorUntilMouseMove();
-}
-
// Extends the selection box to the new cursor position
void LLLineEditor::extendSelection( S32 new_cursor_pos )
{
@@ -1205,6 +1205,10 @@ void LLLineEditor::deleteSelection()
mText.erase(left_pos, selection_length);
deselect();
setCursor(left_pos);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
}
@@ -1365,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)
@@ -1525,6 +1533,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
mText.assign(*(--mCurrentHistoryLine));
setCursorToEnd();
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -1542,6 +1554,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
mText.assign( *(++mCurrentHistoryLine) );
setCursorToEnd();
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -1704,36 +1720,6 @@ bool LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
return handled;
}
-bool LLLineEditor::handleUnicodeStringHere(char *uni_str, bool editing)
-{
- auto handled = FALSE;
-
- if ((gFocusMgr.getKeyboardFocus() == this)
- && getVisible() && !mReadOnly) {
- handled = TRUE;
- LLLineEditorRollback rollback(this);
-
- addString(uni_str, editing);
-
- mKeystrokeTimer.reset();
- deselect();
- auto need_to_rollback = mPrevalidator
- && !mPrevalidator.validate(mText.getWString());
-
- if (need_to_rollback) {
- rollback.doRollback(this);
- LLUI::getInstance()->reportBadKeystroke();
- mPrevalidator.showLastErrorUsingTimeout();
- }
-
- if (!need_to_rollback && handled) {
- onKeystroke();
- mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
- }
- }
-
- return handled;
-}
bool LLLineEditor::canDoDelete() const
{
@@ -1946,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,
@@ -1968,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,
@@ -1983,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,
@@ -1997,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,
@@ -2157,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,
@@ -2182,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,
@@ -2453,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;
}
@@ -2509,9 +2505,24 @@ void LLLineEditor::resetPreedit()
if (hasPreeditString())
{
const S32 preedit_pos = mPreeditPositions.front();
- mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos);
- mText.insert(preedit_pos, mPreeditOverwrittenWString);
- setCursor(preedit_pos);
+ const S32 end = mPreeditPositions.back();
+ const S32 len = end - preedit_pos;
+ const S32 size = mText.length();
+ if (preedit_pos < size
+ && end <= size
+ && preedit_pos >= 0
+ && len > 0)
+ {
+ mText.erase(preedit_pos, len);
+ mText.insert(preedit_pos, mPreeditOverwrittenWString);
+ setCursor(preedit_pos);
+ }
+ else
+ {
+ LL_WARNS() << "Index out of bounds. Start: " << preedit_pos
+ << ", end:" << end
+ << ", full string length: " << size << LL_ENDL;
+ }
mPreeditWString.clear();
mPreeditOverwrittenWString.clear();
@@ -2557,6 +2568,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 3a39a7363d..7533f76f1d 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"
@@ -133,7 +134,6 @@ public:
/*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
/*virtual*/ bool handleKeyHere(KEY key, MASK mask) override;
/*virtual*/ bool handleUnicodeCharHere(llwchar uni_char) override;
- /*virtual*/ bool handleUnicodeStringHere(char *uni_str, bool editing) override;
/*virtual*/ void onMouseCaptureLost() override;
// LLEditMenuHandler overrides
@@ -301,14 +301,11 @@ public:
void removeChar();
void addChar(const llwchar c);
- void addString(char *s, bool editing);
void setCursorAtLocalPos(S32 local_mouse_x);
S32 findPixelNearestPos(S32 cursor_offset = 0) const;
S32 calcCursorPos(S32 mouse_x);
bool handleSpecialKey(KEY key, MASK mask);
bool handleSelectionKey(KEY key, MASK mask);
- bool handleControlKey(KEY key, MASK mask);
- S32 handleCommitKey(KEY key, MASK mask);
void updateTextPadding();
// Draw the background image depending on enabled/focused state.
@@ -346,6 +343,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.
@@ -441,7 +442,7 @@ private:
mText = ed->getText();
}
- void doRollback( LLLineEditor* ed )
+ void doRollback(LLLineEditor* ed) const
{
ed->mCursorPos = mCursorPos;
ed->mScrollHPos = mScrollHPos;
@@ -452,7 +453,7 @@ private:
ed->mPrevText = mText;
}
- std::string getText() { return mText; }
+ std::string getText() const { return mText; }
private:
std::string mText;
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index a77ae7dae7..3f96b28246 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -65,8 +65,8 @@ public:
boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb );
- /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleKeyHere(KEY key, MASK mask );
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleKeyHere(KEY key, MASK mask) override;
void hideMenu();
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 69ffa9a94f..c11b42a348 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -508,7 +508,7 @@ void LLMenuItemGL::draw( void )
// Highlight if needed
if( ll::ui::SearchableControl::getHighlighted() )
- color = ll::ui::SearchableControl::getHighlightColor();
+ color = ll::ui::SearchableControl::getHighlightFontColor();
// Draw the text on top.
if (mBriefItem)
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 66f84393fe..ff9456acc6 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -439,8 +439,6 @@ protected:
public:
virtual ~LLMenuGL( void );
- void parseChildXML(LLXMLNodePtr child, LLView* parent);
-
// LLView Functionality
/*virtual*/ bool handleUnicodeCharHere( llwchar uni_char );
/*virtual*/ bool handleHover( S32 x, S32 y, MASK mask );
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index a7f9b8b2d9..f53e22c349 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -390,7 +390,7 @@ LLFloater* LLMultiFloater::getActiveFloater()
return (LLFloater*)mTabContainer->getCurrentPanel();
}
-S32 LLMultiFloater::getFloaterCount()
+S32 LLMultiFloater::getFloaterCount() const
{
return mTabContainer->getTabCount();
}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index eb0f917695..e0cd58aa3f 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -66,7 +66,7 @@ public:
virtual LLFloater* getActiveFloater();
virtual bool isFloaterFlashing(LLFloater* floaterp);
- virtual S32 getFloaterCount();
+ virtual S32 getFloaterCount() const;
virtual void setFloaterFlashing(LLFloater* floaterp, bool flashing);
virtual bool closeAllFloaters(); //Returns false if the floater could not be closed due to pending confirmation dialogs
diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
index b2bfc8bc84..af255bcc8f 100644
--- a/indra/llui/llmultislider.h
+++ b/indra/llui/llmultislider.h
@@ -117,10 +117,10 @@ public:
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override;
/*virtual*/ void draw() override;
- S32 getMaxNumSliders() { return mMaxNumSliders; }
- S32 getCurNumSliders() { return static_cast<S32>(mValue.size()); }
- F32 getOverlapThreshold() { return mOverlapThreshold; }
- bool canAddSliders() { return mValue.size() < mMaxNumSliders; }
+ S32 getMaxNumSliders() const { return mMaxNumSliders; }
+ S32 getCurNumSliders() const { return static_cast<S32>(mValue.size()); }
+ F32 getOverlapThreshold() const { return mOverlapThreshold; }
+ bool canAddSliders() const { return mValue.size() < mMaxNumSliders; }
protected:
diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h
index dec6cb48b9..2c2bc5e4d9 100644
--- a/indra/llui/llmultisliderctrl.h
+++ b/indra/llui/llmultisliderctrl.h
@@ -124,10 +124,10 @@ public:
F32 getMinValue() const { return mMultiSlider->getMinValue(); }
F32 getMaxValue() const { return mMultiSlider->getMaxValue(); }
- S32 getMaxNumSliders() { return mMultiSlider->getMaxNumSliders(); }
- S32 getCurNumSliders() { return mMultiSlider->getCurNumSliders(); }
- F32 getOverlapThreshold() { return mMultiSlider->getOverlapThreshold(); }
- bool canAddSliders() { return mMultiSlider->canAddSliders(); }
+ S32 getMaxNumSliders() const { return mMultiSlider->getMaxNumSliders(); }
+ S32 getCurNumSliders() const { return mMultiSlider->getCurNumSliders(); }
+ F32 getOverlapThreshold() const { return mMultiSlider->getOverlapThreshold(); }
+ bool canAddSliders() const { return mMultiSlider->canAddSliders(); }
void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); }
void setLabelColor(const LLUIColor& c) { mTextEnabledColor = c; }
@@ -147,7 +147,6 @@ public:
static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
- static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
private:
void updateText();
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index cd80e7f63f..a05feab1d9 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -614,6 +614,13 @@ void LLNotification::cancel()
LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)
{
LLSD response = LLSD::emptyMap();
+
+ if (!mForm)
+ {
+ LL_WARNS("Notifications") << "Null form when getting response template for notification " << getName() << LL_ENDL;
+ return response;
+ }
+
for (S32 element_idx = 0;
element_idx < mForm->getNumElements();
++element_idx)
@@ -1249,9 +1256,26 @@ LLNotifications::LLNotifications()
LLInstanceTracker<LLNotificationChannel, std::string>::instanceCount();
}
+
+LLNotifications::~LLNotifications()
+{
+ // Clear explicitly, something in ~LLNotifications() crashes so narrowing down suspects
+ pHistoryChannel = nullptr;
+ pExpirationChannel = nullptr;
+ mGlobalStrings.clear();
+ mTemplates.clear();
+ mVisibilityRules.clear();
+ mUniqueNotifications.clear();
+ mListener = nullptr;
+}
+
void LLNotifications::clear()
{
- mDefaultChannels.clear();
+ mDefaultChannels.clear();
+ // At this point mTemplates still gets used by lingering notifications
+ // to do responses (ex: group notice will call forceResponse()), but
+ // since network should be down and everything save, it's questionable
+ // whether it should stay that way
}
// The expiration channel gets all notifications that are cancelled
@@ -1464,6 +1488,13 @@ bool LLNotifications::templateExists(std::string_view name)
void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
{
LLNotificationPtr temp_notify(new LLNotification(params));
+
+ if (!temp_notify->getForm())
+ {
+ LL_WARNS("Notifications") << "Cannot force response for notification with null form: " << (std::string)params.name << LL_ENDL;
+ return;
+ }
+
LLSD response = temp_notify->getResponseTemplate();
LLSD selected_item = temp_notify->getForm()->getElement(option);
@@ -1555,7 +1586,7 @@ bool LLNotifications::loadTemplates()
gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
if (search_paths.empty())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL;
}
@@ -1565,7 +1596,7 @@ bool LLNotifications::loadTemplates()
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1576,7 +1607,7 @@ bool LLNotifications::loadTemplates()
if(!params.validateBlock())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1643,7 +1674,7 @@ bool LLNotifications::loadVisibilityRules()
if(!params.validateBlock())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;
return false;
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 46286457cf..3c8e1e85fa 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -247,7 +247,6 @@ public:
LLNotificationForm(const LLSD& sd);
LLNotificationForm(const std::string& name, const Params& p);
- void fromLLSD(const LLSD& sd);
LLSD asLLSD() const;
S32 getNumElements() { return static_cast<S32>(mFormData.size()); }
@@ -266,8 +265,8 @@ public:
bool getIgnored();
void setIgnored(bool ignored);
- EIgnoreType getIgnoreType() { return mIgnore; }
- std::string getIgnoreMessage() { return mIgnoreMsg; }
+ EIgnoreType getIgnoreType()const { return mIgnore; }
+ std::string getIgnoreMessage() const { return mIgnoreMsg; }
private:
LLSD mFormData;
@@ -887,7 +886,7 @@ class LLNotifications :
{
LLSINGLETON(LLNotifications);
LOG_CLASS(LLNotifications);
- virtual ~LLNotifications() {}
+ virtual ~LLNotifications();
public:
@@ -971,8 +970,6 @@ private:
/*virtual*/ void initSingleton() override;
/*virtual*/ void cleanupSingleton() override;
- void loadPersistentNotifications();
-
bool expirationFilter(LLNotificationPtr pNotification);
bool expirationHandler(const LLSD& payload);
bool uniqueFilter(LLNotificationPtr pNotification);
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/llprogressbar.h b/indra/llui/llprogressbar.h
index 0d5d32cf21..7245bbf1cf 100644
--- a/indra/llui/llprogressbar.h
+++ b/indra/llui/llprogressbar.h
@@ -48,9 +48,9 @@ public:
LLProgressBar(const Params&);
virtual ~LLProgressBar();
- void setValue(const LLSD& value);
+ void setValue(const LLSD& value) override;
- /*virtual*/ void draw();
+ void draw() override;
private:
F32 mPercentDone;
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 4b0f435834..68bf0fd95e 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -61,7 +61,7 @@ public:
void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; }
void setEnableSnapping(bool enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(bool allow) { mAllowDoubleClickSnapping = allow; }
- bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
+ bool canResize() const { return getEnabled() && mMaxSize > mMinSize; }
void setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
void setImagePanel(LLPanel * panelp);
LLPanel * getImagePanel() const;
diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h
index 9cc4123544..caec33405c 100644
--- a/indra/llui/llresizehandle.h
+++ b/indra/llui/llresizehandle.h
@@ -50,10 +50,10 @@ protected:
LLResizeHandle(const LLResizeHandle::Params&);
friend class LLUICtrlFactory;
public:
- virtual void draw();
- virtual bool handleHover(S32 x, S32 y, MASK mask);
- virtual bool handleMouseDown(S32 x, S32 y, MASK mask);
- virtual bool handleMouseUp(S32 x, S32 y, MASK mask);
+ void draw() override;
+ bool handleHover(S32 x, S32 y, MASK mask) override;
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleMouseUp(S32 x, S32 y, MASK mask) override;
void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; }
@@ -71,8 +71,8 @@ private:
const ECorner mCorner;
};
-const S32 RESIZE_HANDLE_HEIGHT = 11;
-const S32 RESIZE_HANDLE_WIDTH = 11;
+constexpr S32 RESIZE_HANDLE_HEIGHT = 11;
+constexpr S32 RESIZE_HANDLE_WIDTH = 11;
#endif // LL_RESIZEHANDLE_H
diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h
index 33ec049a1a..2c39472607 100644
--- a/indra/llui/llrngwriter.h
+++ b/indra/llui/llrngwriter.h
@@ -37,7 +37,7 @@ public:
void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block);
- /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
+ std::string getCurrentElementName() override { return LLStringUtil::null; }
LLRNGWriter();
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..7dded3c0b7 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; }
@@ -104,7 +105,7 @@ public:
virtual const LLSD getAltValue() const;
virtual void setValue(const LLSD& value) { }
virtual void setAltValue(const LLSD& value) { }
- virtual const std::string &getToolTip() const { return mToolTip; }
+ virtual const std::string& getToolTip() const { return mToolTip; }
virtual void setToolTip(const std::string &str) { mToolTip = str; }
virtual bool getVisible() const { return true; }
virtual void setWidth(S32 width) { mWidth = width; }
@@ -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..245339b107 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;
@@ -509,20 +492,18 @@ LLScrollListItem* LLScrollListCtrl::getItem(const LLSD& sd) const
{
std::string string_val = sd.asString();
- 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)
{
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();
}
@@ -3412,7 +3394,7 @@ bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
bool res = false;
- setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red));
+ setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4));
std::string filter_str_lc(filter_str);
LLStringUtil::toLower(filter_str_lc);
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 1f9f26e08b..1f04100306 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -165,7 +165,6 @@ public:
void deleteAllItems() { clearRows(); }
// Sets an array of column descriptors
- void setColumnHeadings(const LLSD& headings);
void sortByColumnIndex(U32 column, bool ascending);
// LLCtrlListInterface functions
@@ -260,11 +259,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,
@@ -317,7 +317,7 @@ public:
void setAllowKeyboardMovement(bool b) { mAllowKeyboardMovement = b; }
void setMaxSelectable(U32 max_selected) { mMaxSelectable = max_selected; }
- S32 getMaxSelectable() { return mMaxSelectable; }
+ S32 getMaxSelectable() const { return mMaxSelectable; }
virtual S32 getScrollPos() const;
@@ -333,7 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
- ContextMenuType getContextMenuType() { return mContextMenuType; }
+ ContextMenuType getContextMenuType() const { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@@ -361,7 +361,6 @@ public:
virtual void fitContents(S32 max_width, S32 max_height);
virtual LLRect getRequiredRect();
- static bool rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row);
LLRect getItemListRect() { return mItemListRect; }
@@ -383,7 +382,6 @@ public:
* then display all items.
*/
void setPageLines(S32 page_lines );
- void setCollapseEmptyColumns(bool collapse);
LLScrollListItem* hitItem(S32 x,S32 y);
virtual void scrollToShowSelected();
@@ -400,7 +398,7 @@ public:
void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
- S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
+ S32 getTotalStaticColumnWidth() const { return mTotalStaticColumnWidth; }
std::string getSortColumnName();
bool getSortAscending() { return mSortColumns.empty() ? true : mSortColumns.back().second; }
@@ -559,6 +557,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/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h
index 119852b763..bae85fe9a5 100644
--- a/indra/llui/llsearchablecontrol.h
+++ b/indra/llui/llsearchablecontrol.h
@@ -43,9 +43,15 @@ namespace ll
virtual ~SearchableControl()
{ }
- const LLColor4& getHighlightColor( ) const
+ const LLColor4& getHighlightBgColor( ) const
{
- static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red);
+ static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4);
+ return highlight_color.get();
+ }
+
+ const LLColor4& getHighlightFontColor() const
+ {
+ static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightFontColor", LLColor4::red4);
return highlight_color.get();
}
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 311377a61f..23ce8fd955 100644
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -132,7 +132,6 @@ public:
static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
- static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
protected:
virtual std::string _getSearchText() const
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 58b38dc630..4ba8c97c63 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -94,7 +94,6 @@ public:
void onEditorCommit(const LLSD& data);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorLostFocus(LLFocusableElement* caller, void *userdata);
- static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
void onUpBtn(const LLSD& data);
void onDownBtn(const LLSD& data);
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 2693243eb1..62c0401869 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -460,7 +460,7 @@ void LLStatBar::draw()
max_value = 0.f;
gGL.color4f(1.f, 0.f, 0.f, 1.f);
- gGL.begin( LLRender::QUADS );
+ gGL.begin(LLRender::TRIANGLES);
const S32 max_frame = llmin(num_frames, num_values);
U32 num_samples = 0;
for (S32 i = 1; i <= max_frame; i++)
@@ -498,6 +498,9 @@ void LLStatBar::draw()
gGL.vertex2f((F32)bar_rect.mRight - offset, max);
gGL.vertex2f((F32)bar_rect.mRight - offset, min);
gGL.vertex2f((F32)bar_rect.mRight - offset - 1, min);
+
+ gGL.vertex2f((F32)bar_rect.mRight - offset, max);
+ gGL.vertex2f((F32)bar_rect.mRight - offset - 1, min);
gGL.vertex2f((F32)bar_rect.mRight - offset - 1, max);
}
else
@@ -505,7 +508,10 @@ void LLStatBar::draw()
gGL.vertex2f(min, (F32)bar_rect.mBottom + offset + 1);
gGL.vertex2f(min, (F32)bar_rect.mBottom + offset);
gGL.vertex2f(max, (F32)bar_rect.mBottom + offset);
- gGL.vertex2f(max, (F32)bar_rect.mBottom + offset + 1 );
+
+ gGL.vertex2f(min, (F32)bar_rect.mBottom + offset + 1);
+ gGL.vertex2f(max, (F32)bar_rect.mBottom + offset);
+ gGL.vertex2f(max, (F32)bar_rect.mBottom + offset + 1);
}
}
gGL.end();
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index c36a138566..bbbf0b3a19 100644
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
@@ -67,7 +67,7 @@ public:
void setStat(const std::string& stat_name);
void setRange(F32 bar_min, F32 bar_max);
- void getRange(F32& bar_min, F32& bar_max) { bar_min = mTargetMinBar; bar_max = mTargetMaxBar; }
+ void getRange(F32& bar_min, F32& bar_max) const { bar_min = mTargetMinBar; bar_max = mTargetMaxBar; }
/*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index d97051247e..0af717d447 100644
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
@@ -36,7 +36,6 @@
#include "llglheaders.h"
#include "lltracerecording.h"
#include "lltracethreadrecorder.h"
-//#include "llviewercontrol.h"
///////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h
index c254821870..6d9e3d1064 100644
--- a/indra/llui/llstatgraph.h
+++ b/indra/llui/llstatgraph.h
@@ -99,9 +99,7 @@ public:
void setMin(const F32 min);
void setMax(const F32 max);
- virtual void draw();
-
- /*virtual*/ void setValue(const LLSD& value);
+ void draw() override;
private:
LLTrace::StatType<LLTrace::CountAccumulator>* mNewStatFloatp;
@@ -133,9 +131,6 @@ private:
};
typedef std::vector<Threshold> threshold_vec_t;
threshold_vec_t mThresholds;
- //S32 mNumThresholds;
- //F32 mThresholds[4];
- //LLColor4 mThresholdColors[4];
};
#endif // LL_LLSTATGRAPH_H
diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h
index b5187f886d..a396773057 100644
--- a/indra/llui/llstatview.h
+++ b/indra/llui/llstatview.h
@@ -29,7 +29,6 @@
#include "llstatbar.h"
#include "llcontainerview.h"
-#include <vector>
class LLStatBar;
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index df4b0ef6a0..7a0e620d61 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -38,11 +38,13 @@ LLStyle::Params::Params()
color("color", LLColor4::black),
readonly_color("readonly_color", LLColor4::black),
selected_color("selected_color", LLColor4::black),
+ highlight_bg_color("highlight_bg_color", LLColor4::green),
alpha("alpha", 1.f),
- font("font", LLFontGL::getFontMonospace()),
+ font("font", LLStyle::getDefaultFont()),
image("image"),
link_href("href"),
- is_link("is_link")
+ is_link("is_link"),
+ draw_highlight_bg("draw_highlight_bg", false)
{}
@@ -51,12 +53,14 @@ LLStyle::LLStyle(const LLStyle::Params& p)
mColor(p.color),
mReadOnlyColor(p.readonly_color),
mSelectedColor(p.selected_color),
+ mHighlightBgColor(p.highlight_bg_color),
mFont(p.font()),
mLink(p.link_href),
mIsLink(p.is_link.isProvided() ? p.is_link : !p.link_href().empty()),
mDropShadow(p.drop_shadow),
mImagep(p.image()),
- mAlpha(p.alpha)
+ mAlpha(p.alpha),
+ mDrawHighlightBg(p.draw_highlight_bg)
{}
void LLStyle::setFont(const LLFontGL* font)
@@ -70,6 +74,11 @@ const LLFontGL* LLStyle::getFont() const
return mFont;
}
+const LLFontGL* LLStyle::getDefaultFont()
+{
+ return LLFontGL::getFontMonospace();
+}
+
void LLStyle::setLinkHREF(const std::string& href)
{
mLink = href;
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index e506895de5..71c3f88109 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -43,15 +43,25 @@ public:
Optional<LLFontGL::ShadowType> drop_shadow;
Optional<LLUIColor> color,
readonly_color,
- selected_color;
+ selected_color,
+ highlight_bg_color;
Optional<F32> alpha;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
Optional<bool> is_link;
+ Optional<bool> draw_highlight_bg;
Params();
};
LLStyle(const Params& p = Params());
+
+ enum EUnderlineLink
+ {
+ UNDERLINE_ALWAYS = 0,
+ UNDERLINE_ON_HOVER,
+ UNDERLINE_NEVER
+ };
+
public:
const LLUIColor& getColor() const { return mColor; }
void setColor(const LLUIColor &color) { mColor = color; }
@@ -72,6 +82,7 @@ public:
void setFont(const LLFontGL* font);
const LLFontGL* getFont() const;
+ static const LLFontGL* getDefaultFont();
const std::string& getLinkHREF() const { return mLink; }
void setLinkHREF(const std::string& href);
@@ -83,6 +94,9 @@ public:
bool isImage() const { return mImagep.notNull(); }
+ bool getDrawHighlightBg() const { return mDrawHighlightBg; }
+ const LLUIColor& getHighlightBgColor() const { return mHighlightBgColor; }
+
bool operator==(const LLStyle &rhs) const
{
return
@@ -90,11 +104,13 @@ public:
&& mColor == rhs.mColor
&& mReadOnlyColor == rhs.mReadOnlyColor
&& mSelectedColor == rhs.mSelectedColor
+ && mHighlightBgColor == rhs.mHighlightBgColor
&& mFont == rhs.mFont
&& mLink == rhs.mLink
&& mImagep == rhs.mImagep
&& mDropShadow == rhs.mDropShadow
- && mAlpha == rhs.mAlpha;
+ && mAlpha == rhs.mAlpha
+ && mDrawHighlightBg == rhs.mDrawHighlightBg;
}
bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); }
@@ -111,11 +127,13 @@ private:
LLUIColor mColor;
LLUIColor mReadOnlyColor;
LLUIColor mSelectedColor;
+ LLUIColor mHighlightBgColor;
const LLFontGL* mFont;
LLPointer<LLUIImage> mImagep;
F32 mAlpha;
bool mVisible;
bool mIsLink;
+ bool mDrawHighlightBg;
};
typedef LLPointer<LLStyle> LLStyleSP;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 595ab0bd2b..5e0985c79c 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1370,17 +1370,17 @@ LLPanel* LLTabContainer::getCurrentPanel()
return NULL;
}
-S32 LLTabContainer::getCurrentPanelIndex()
+S32 LLTabContainer::getCurrentPanelIndex() const
{
return mCurrentTabIdx;
}
-S32 LLTabContainer::getTabCount()
+S32 LLTabContainer::getTabCount() const
{
return static_cast<S32>(mTabList.size());
}
-LLPanel* LLTabContainer::getPanelByIndex(S32 index)
+LLPanel* LLTabContainer::getPanelByIndex(S32 index) const
{
if (index >= 0 && index < (S32)mTabList.size())
{
@@ -1389,7 +1389,7 @@ LLPanel* LLTabContainer::getPanelByIndex(S32 index)
return NULL;
}
-S32 LLTabContainer::getIndexForPanel(LLPanel* panel)
+S32 LLTabContainer::getIndexForPanel(LLPanel* panel) const
{
for (S32 index = 0; index < (S32)mTabList.size(); index++)
{
@@ -1401,7 +1401,7 @@ S32 LLTabContainer::getIndexForPanel(LLPanel* panel)
return -1;
}
-S32 LLTabContainer::getPanelIndexByTitle(std::string_view title)
+S32 LLTabContainer::getPanelIndexByTitle(std::string_view title) const
{
for (S32 index = 0 ; index < (S32)mTabList.size(); index++)
{
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 40f272ffa8..4ac7e73d25 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -182,15 +182,15 @@ public:
void removeTabPanel( LLPanel* child );
void lockTabs(S32 num_tabs = 0);
void unlockTabs();
- S32 getNumLockedTabs() { return mLockedTabCount; }
+ S32 getNumLockedTabs() const { return mLockedTabCount; }
void enableTabButton(S32 which, bool enable);
void deleteAllTabs();
LLPanel* getCurrentPanel();
- S32 getCurrentPanelIndex();
- S32 getTabCount();
- LLPanel* getPanelByIndex(S32 index);
- S32 getIndexForPanel(LLPanel* panel);
- S32 getPanelIndexByTitle(std::string_view title);
+ S32 getCurrentPanelIndex() const;
+ S32 getTabCount() const;
+ LLPanel* getPanelByIndex(S32 index) const;
+ S32 getIndexForPanel(LLPanel* panel) const;
+ S32 getPanelIndexByTitle(std::string_view title) const;
LLPanel* getPanelByName(std::string_view name);
S32 getTotalTabWidth() const;
void setCurrentTabName(const std::string& name);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0aebf7543c..778b253c3c 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -460,6 +460,62 @@ std::vector<LLRect> LLTextBase::getSelectionRects()
return selection_rects;
}
+std::vector<std::pair<LLRect, LLUIColor>> LLTextBase::getHighlightedBgRects()
+{
+ std::vector<std::pair<LLRect, LLUIColor>> highlight_rects;
+
+ LLRect content_display_rect = getVisibleDocumentRect();
+
+ // binary search for line that starts before top of visible buffer
+ line_list_t::const_iterator line_iter =
+ std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
+ line_list_t::const_iterator end_iter =
+ std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
+
+ for (; line_iter != end_iter; ++line_iter)
+ {
+ segment_set_t::iterator segment_iter;
+ S32 segment_offset;
+ getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
+
+ // Use F32 otherwise a string of multiple segments
+ // will accumulate a large error
+ F32 left_precise = (F32)line_iter->mRect.mLeft;
+ F32 right_precise = (F32)line_iter->mRect.mLeft;
+
+ for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
+ {
+ LLTextSegmentPtr segmentp = *segment_iter;
+
+ S32 segment_line_start = segmentp->getStart() + segment_offset;
+ S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
+
+ if (segment_line_start > segment_line_end)
+ break;
+
+ F32 segment_width = 0;
+ S32 segment_height = 0;
+
+ S32 num_chars = segment_line_end - segment_line_start;
+ segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
+ right_precise += segment_width;
+
+ if (segmentp->getStyle()->getDrawHighlightBg())
+ {
+ LLRect selection_rect;
+ selection_rect.mLeft = (S32)left_precise;
+ selection_rect.mRight = (S32)right_precise;
+ selection_rect.mBottom = line_iter->mRect.mBottom;
+ selection_rect.mTop = line_iter->mRect.mTop;
+
+ highlight_rects.push_back(std::pair(selection_rect, segmentp->getStyle()->getHighlightBgColor()));
+ }
+ left_precise += segment_width;
+ }
+ }
+ return highlight_rects;
+}
+
// Draws the black box behind the selected text
void LLTextBase::drawSelectionBackground()
{
@@ -529,6 +585,71 @@ void LLTextBase::drawSelectionBackground()
}
}
+void LLTextBase::drawHighlightedBackground()
+{
+ if (!mLineInfoList.empty())
+ {
+ std::vector<std::pair<LLRect, LLUIColor>> highlight_rects = getHighlightedBgRects();
+
+ if (highlight_rects.empty())
+ return;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLRect content_display_rect = getVisibleDocumentRect();
+
+ for (std::vector<std::pair<LLRect, LLUIColor>>::iterator rect_it = highlight_rects.begin();
+ rect_it != highlight_rects.end(); ++rect_it)
+ {
+ LLRect selection_rect = rect_it->first;
+ const LLColor4& color = rect_it->second;
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
+ gl_rect_2d(selection_rect, color);
+ }
+ }
+}
+
void LLTextBase::drawCursor()
{
F32 alpha = getDrawContext().mAlpha;
@@ -948,7 +1069,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 +1445,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();
@@ -1378,7 +1499,7 @@ void LLTextBase::draw()
// Draw highlighted if needed
if( ll::ui::SearchableControl::getHighlighted() )
{
- const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightColor();
+ const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightBgColor();
LLRect bg_rect = mVisibleTextRect;
if( mScroller )
bg_rect.intersectWith( text_rect );
@@ -1399,6 +1520,7 @@ void LLTextBase::draw()
drawChild(mDocumentView);
}
+ drawHighlightedBackground();
drawSelectionBackground();
drawText();
drawCursor();
@@ -1438,7 +1560,8 @@ void LLTextBase::onVisibilityChange( bool new_visibility )
//virtual
void LLTextBase::setValue(const LLSD& value )
{
- setText(value.asString());
+ static const LLStyle::Params input_params = LLStyle::Params();
+ setText(value.asString(), input_params);
}
//virtual
@@ -2199,20 +2322,20 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
}
-void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
+void LLTextBase::appendTextImpl(const std::string& new_text, const LLStyle::Params& input_params, bool force_slurl)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
LLStyle::Params style_params(getStyleParams());
style_params.overwriteFrom(input_params);
S32 part = (S32)LLTextParser::WHOLE;
- if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
+ if ((mParseHTML || force_slurl) && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
{
S32 start=0,end=0;
LLUrlMatch match;
std::string text = new_text;
while (LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons))
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons, force_slurl))
{
start = match.getStart();
end = match.getEnd()+1;
@@ -2244,7 +2367,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// output the styled Url
- appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly());
+ appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.getUnderline());
bool tooltip_required = !match.getTooltip().empty();
// set the tooltip for the Url label
@@ -2259,7 +2382,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
{
link_params.color = LLColor4::grey;
link_params.readonly_color = LLColor4::grey;
- appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
+ appendAndHighlightTextImpl(label, part, link_params, match.getUnderline());
// set the tooltip for the query part of url
if (tooltip_required)
@@ -2368,6 +2491,34 @@ S32 LLTextBase::removeFirstLine()
return 0;
}
+// virtual
+void LLTextBase::copyContents(const LLTextBase* source)
+{
+ llassert(source);
+ if (!source)
+ return;
+
+ beforeValueChange();
+ deselect();
+
+ mSegments.clear();
+ for (const LLTextSegmentPtr& segp : source->mSegments)
+ {
+ mSegments.emplace(segp->clone(*this));
+ }
+
+ mLineInfoList.clear();
+ for (const line_info& li : mLineInfoList)
+ {
+ mLineInfoList.push_back(line_info(li));
+ }
+
+ getViewModel()->setDisplay(source->getViewModel()->getDisplay());
+
+ onValueChange(0, getLength());
+ needsReflow();
+}
+
void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
{
segment_vec_t segments;
@@ -2399,7 +2550,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, e_underline underline_link)
{
// Save old state
S32 selection_start = mSelectionStart;
@@ -2429,7 +2580,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 || mSkipLinkUnderline)
+ if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline)
{
highlight_params.font.style("NORMAL");
LLStyleConstSP normal_sp(new LLStyle(highlight_params));
@@ -2453,7 +2604,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 segment_start = old_length;
S32 segment_end = old_length + static_cast<S32>(wide_text.size());
LLStyleConstSP sp(new LLStyle(style_params));
- if (underline_on_hover_only || mSkipLinkUnderline)
+ if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline)
{
LLStyle::Params normal_style_params(style_params);
normal_style_params.font.style("NORMAL");
@@ -2487,7 +2638,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, e_underline underline_link)
{
if (new_text.empty())
{
@@ -2502,7 +2653,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, underline_link);
}
appendLineBreakSegment(style_params);
start = pos+1;
@@ -2510,7 +2661,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, underline_link);
}
@@ -2586,6 +2737,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.
@@ -3228,6 +3384,24 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc
LLTextSegment::~LLTextSegment()
{}
+// static
+LLStyleSP LLTextSegment::cloneStyle(LLTextBase& target, const LLStyle* source)
+{
+ // Take most params from target
+ LLStyle::Params params = target.getStyleParams();
+ LLStyle* style = new LLStyle(params);
+
+ // Take some params from source
+ style->setLinkHREF(source->getLinkHREF());
+ if (source->isImage())
+ {
+ style->setImage(source->getImage()->getName());
+ }
+
+ return style;
+}
+
+
bool LLTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; height = 0; return false; }
bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
{
@@ -3280,9 +3454,11 @@ 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();
+ mCanEdit = !mStyle->getDrawHighlightBg();
LLUIImagePtr image = mStyle->getImage();
if (image.notNull())
@@ -3294,7 +3470,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 +3490,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 +3532,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 +3576,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 +3613,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;
}
@@ -3488,6 +3744,13 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
mTooltip = tooltip;
}
+// virtual
+LLTextSegmentPtr LLNormalTextSegment::clone(LLTextBase& target) const
+{
+ LLStyleConstSP sp(cloneStyle(target, mStyle));
+ return new LLNormalTextSegment(sp, mStart, mEnd, target);
+}
+
bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
height = 0;
@@ -3573,6 +3836,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 [" <<
@@ -3606,6 +3878,13 @@ LLLabelTextSegment::LLLabelTextSegment( const LLUIColor& color, S32 start, S32 e
{
}
+// virtual
+LLTextSegmentPtr LLLabelTextSegment::clone(LLTextBase& target) const
+{
+ LLStyleConstSP sp(cloneStyle(target, mStyle));
+ return new LLLabelTextSegment(sp, mStart, mEnd, target);
+}
+
/*virtual*/
const LLWString& LLLabelTextSegment::getWText() const
{
@@ -3630,6 +3909,13 @@ LLEmojiTextSegment::LLEmojiTextSegment(const LLUIColor& color, S32 start, S32 en
{
}
+// virtual
+LLTextSegmentPtr LLEmojiTextSegment::clone(LLTextBase& target) const
+{
+ LLStyleConstSP sp(cloneStyle(target, mStyle));
+ return new LLEmojiTextSegment(sp, mStart, mEnd, target);
+}
+
bool LLEmojiTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
{
if (mTooltip.empty())
@@ -3653,6 +3939,14 @@ LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP s
mHoveredStyle(style),
mNormalStyle(normal_style){}
+// virtual
+LLTextSegmentPtr LLOnHoverChangeableTextSegment::clone(LLTextBase& target) const
+{
+ LLStyleConstSP hsp(cloneStyle(target, mHoveredStyle));
+ LLStyleConstSP nsp(cloneStyle(target, mNormalStyle));
+ return new LLOnHoverChangeableTextSegment(hsp, nsp, mStart, mEnd, target);
+}
+
/*virtual*/
F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)
{
@@ -3692,6 +3986,13 @@ LLInlineViewSegment::~LLInlineViewSegment()
mView->die();
}
+// virtual
+LLTextSegmentPtr LLInlineViewSegment::clone(LLTextBase& target) const
+{
+ llassert_always_msg(false, "NOT SUPPORTED");
+ return nullptr;
+}
+
bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
if (first_char == 0 && num_chars == 0)
@@ -3703,8 +4004,7 @@ bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w
if (mForceNewLine)
{
// Chat, string can't be smaller then font height even if it is empty
- LLStyleSP s(new LLStyle(LLStyle::Params().visible(true)));
- height = s->getFont()->getLineHeight();
+ height = LLStyle::getDefaultFont()->getLineHeight();
return true; // new line
}
@@ -3768,9 +4068,7 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1)
{
- LLStyleSP s( new LLStyle(LLStyle::Params().visible(true)));
-
- mFontHeight = s->getFont()->getLineHeight();
+ mFontHeight = LLStyle::getDefaultFont()->getLineHeight();
}
LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)
{
@@ -3779,6 +4077,14 @@ LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLT
LLLineBreakTextSegment::~LLLineBreakTextSegment()
{
}
+
+// virtual
+LLTextSegmentPtr LLLineBreakTextSegment::clone(LLTextBase& target) const
+{
+ LLLineBreakTextSegment* copy = new LLLineBreakTextSegment(mStart);
+ copy->mFontHeight = mFontHeight;
+ return copy;
+}
bool LLLineBreakTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
width = 0;
@@ -3806,8 +4112,16 @@ LLImageTextSegment::~LLImageTextSegment()
{
}
+// virtual
+LLTextSegmentPtr LLImageTextSegment::clone(LLTextBase& target) const
+{
+ LLStyleConstSP sp(cloneStyle(target, mStyle));
+ return new LLImageTextSegment(sp, mStart, target);
+}
+
static const S32 IMAGE_HPAD = 3;
+// virtual
bool LLImageTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const
{
width = 0;
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 00cf66b134..8ca653acb9 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -30,10 +30,12 @@
#include "v4color.h"
#include "lleditmenuhandler.h"
+#include "llfontvertexbuffer.h"
#include "llspellcheckmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
#include "llpanel.h"
+#include "llurlmatch.h"
#include <string>
#include <vector>
@@ -44,6 +46,7 @@
class LLScrollContainer;
class LLContextMenu;
class LLUrlMatch;
+class LLTextBase;
///
/// A text segment is used to specify a subsection of a text string
@@ -61,6 +64,9 @@ public:
mEnd(end)
{}
virtual ~LLTextSegment();
+ virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); }
+ static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source);
+
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
@@ -127,18 +133,19 @@ public:
LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true);
virtual ~LLNormalTextSegment();
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
/*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*/ bool canEdit() const { return mCanEdit; }
/*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); }
/*virtual*/ LLStyleConstSP getStyle() const { return mStyle; }
/*virtual*/ void setStyle(LLStyleConstSP style) { mStyle = style; }
/*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; }
/*virtual*/ LLKeywordToken* getToken() const { return mToken; }
- /*virtual*/ bool getToolTip( std::string& msg ) const;
/*virtual*/ void setToolTip(const std::string& tooltip);
/*virtual*/ void dump() const;
@@ -149,11 +156,14 @@ 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;
virtual const S32 getLength() const;
+ void setAllowEdit(bool can_edit) { mCanEdit = can_edit; }
+
protected:
class LLTextBase& mEditor;
LLStyleConstSP mStyle;
@@ -161,6 +171,14 @@ protected:
LLKeywordToken* mToken;
std::string mTooltip;
boost::signals2::connection mImageLoadedConnection;
+
+ bool mCanEdit { true };
+
+ // font rendering
+ LLFontVertexBuffer mFontBufferPreSelection;
+ LLFontVertexBuffer mFontBufferSelection;
+ LLFontVertexBuffer mFontBufferPostSelection;
+ S32 mLastGeneration = -1;
};
// This text segment is the same as LLNormalTextSegment, the only difference
@@ -171,6 +189,7 @@ class LLLabelTextSegment : public LLNormalTextSegment
public:
LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
LLLabelTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true);
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
protected:
@@ -185,6 +204,7 @@ class LLEmojiTextSegment : public LLNormalTextSegment
public:
LLEmojiTextSegment(LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor);
LLEmojiTextSegment(const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true);
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const override;
bool canEdit() const override { return false; }
bool handleToolTip(S32 x, S32 y, MASK mask) override;
@@ -195,6 +215,7 @@ class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
{
public:
LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor );
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
protected:
@@ -209,6 +230,7 @@ class LLIndexSegment : public LLTextSegment
{
public:
LLIndexSegment() : LLTextSegment(0, 0) {}
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const { return new LLIndexSegment(); }
};
class LLInlineViewSegment : public LLTextSegment
@@ -226,6 +248,8 @@ public:
LLInlineViewSegment(const Params& p, S32 start, S32 end);
~LLInlineViewSegment();
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
+
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) 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);
@@ -250,6 +274,7 @@ public:
LLLineBreakTextSegment(LLStyleConstSP style,S32 pos);
LLLineBreakTextSegment(S32 pos);
~LLLineBreakTextSegment();
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
@@ -263,6 +288,8 @@ class LLImageTextSegment : public LLTextSegment
public:
LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor);
~LLImageTextSegment();
+ /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const;
+
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const;
F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
@@ -427,11 +454,12 @@ public:
virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style
/*virtual*/ const std::string& getText() const override;
void setMaxTextLength(S32 length) { mMaxTextByteLength = length; }
- S32 getMaxTextLength() { return mMaxTextByteLength; }
+ S32 getMaxTextLength() const { return mMaxTextByteLength; }
// 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());
@@ -465,20 +493,20 @@ public:
LLRect getTextBoundingRect();
LLRect getVisibleDocumentRect() const;
- S32 getVPad() { return mVPad; }
- S32 getHPad() { return mHPad; }
- F32 getLineSpacingMult() { return mLineSpacingMult; }
- S32 getLineSpacingPixels() { return mLineSpacingPixels; } // only for multiline
+ S32 getVPad() const { return mVPad; }
+ S32 getHPad() const { return mHPad; }
+ F32 getLineSpacingMult() const { return mLineSpacingMult; }
+ S32 getLineSpacingPixels() const { return mLineSpacingPixels; } // only for multiline
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, bool round, bool hit_past_end_of_line = true) const;
LLRect getLocalRectFromDocIndex(S32 pos) const;
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; }
+ bool getSkipLinkUnderline() const { return mSkipLinkUnderline; }
void setParseURLs(bool parse_urls) { mParseHTML = parse_urls; }
@@ -492,14 +520,15 @@ public:
void endOfLine();
void startOfDoc();
void endOfDoc();
- void changePage( S32 delta );
- void changeLine( S32 delta );
+ void changePage(S32 delta);
+ void changeLine(S32 delta);
bool scrolledToStart();
bool scrolledToEnd();
const LLFontGL* getFont() const override { return mFont; }
+ virtual void copyContents(const LLTextBase* source);
virtual void appendLineBreakSegment(const LLStyle::Params& style_params);
virtual void appendImageSegment(const LLStyle::Params& style_params);
virtual void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
@@ -582,6 +611,7 @@ protected:
bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const;
};
typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
+ typedef LLStyle::EUnderlineLink e_underline;
// member functions
LLTextBase(const Params &p);
@@ -595,12 +625,13 @@ protected:
virtual void drawSelectionBackground(); // draws the black box behind the selected text
void drawCursor();
void drawText();
+ void drawHighlightedBackground();
// modify contents
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, e_underline underline_link = e_underline::UNDERLINE_ALWAYS);
// manage segments
@@ -648,8 +679,8 @@ protected:
// avatar names are looked up.
void replaceUrl(const std::string &url, const std::string &label, const std::string& icon);
- 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 appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params(), bool force_slurl = false);
+ void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link = e_underline::UNDERLINE_ALWAYS);
S32 normalizeUri(std::string& uri);
protected:
@@ -660,6 +691,7 @@ protected:
}
std::vector<LLRect> getSelectionRects();
+ std::vector<std::pair<LLRect, LLUIColor>> getHighlightedBgRects();
protected:
// text segmentation and flow
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 05af36b71e..9f945d3735 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -159,7 +159,8 @@ LLSD LLTextBox::getValue() const
bool LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
{
mText.setArg(key, text);
- LLTextBase::setText(mText.getString());
+ static const LLStyle::Params input_params = LLStyle::Params();
+ LLTextBase::setText(mText.getString(), input_params);
return true;
}
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index a3cde45cd0..507d8f3ee6 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -46,36 +46,42 @@ protected:
friend class LLUICtrlFactory;
public:
- virtual ~LLTextBox();
+ ~LLTextBox() override;
- /*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);
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleMouseUp(S32 x, S32 y, MASK mask) override;
+ bool handleHover(S32 x, S32 y, MASK mask) override;
- /*virtual*/ void setEnabled(bool enabled);
+ void setEnabled(bool enabled) override;
- /*virtual*/ void setText( const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params() );
+ void setText(const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params()) override;
- void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
- void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
- void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL );
+ void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
+ void setHAlign(LLFontGL::HAlign align) { mHAlign = align; }
+ void setClickedCallback(boost::function<void(void*)> cb, void* userdata = NULL);
- void reshapeToFitText(bool called_from_parent = false);
+ void reshapeToFitText(bool called_from_parent = false);
- S32 getTextPixelWidth();
- S32 getTextPixelHeight();
+ S32 getTextPixelWidth();
+ S32 getTextPixelHeight();
- /*virtual*/ LLSD getValue() const;
- /*virtual*/ bool setTextArg( const std::string& key, const LLStringExplicit& text );
+ LLSD getValue() const override;
+ bool setTextArg(const std::string& key, const LLStringExplicit& text) override;
- void setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; }
+ void setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; }
protected:
- void onUrlLabelUpdated(const std::string &url, const std::string &label);
+ void onUrlLabelUpdated(const std::string& url, const std::string& label);
LLUIString mText;
callback_t mClickedCallback;
bool mShowCursorHand;
+
+protected:
+ virtual std::string _getSearchText() const override
+ {
+ return LLTextBase::_getSearchText() + mText.getString();
+ }
};
// Build time optimization, generate once in .cpp file
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index cbbb164cb2..cfe729be06 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -60,6 +60,7 @@
#include "llurlregistry.h"
#include "lltooltip.h"
#include "llmenugl.h"
+#include "llchatmentionhelper.h"
#include <queue>
#include "llcombobox.h"
@@ -167,50 +168,6 @@ private:
};
///////////////////////////////////////////////////////////////////
-class LLTextEditor::TextCmdAddString : public LLTextBase::TextCmd
-{
-public:
- TextCmdAddString(S32 pos, bool group_with_next, char *str,
- LLTextSegmentPtr segment) :
- TextCmd(pos, group_with_next, segment),
- mWString(utf8str_to_wstring(str)),
- mBlockExtensions(FALSE)
- {
- }
- virtual void blockExtensions()
- {
- mBlockExtensions = TRUE;
- }
- virtual bool canExtend(S32 pos) const
- {
- if (!mSegments.empty()) return FALSE;
-
- return !mBlockExtensions
- && (pos == getPosition() + (S32)mWString.length());
- }
- virtual bool execute(LLTextBase* editor, S32* delta)
- {
- *delta = insert(editor, getPosition(), mWString);
- LLWStringUtil::truncate(mWString, *delta);
- return (*delta != 0);
- }
- virtual S32 undo(LLTextBase* editor)
- {
- remove(editor, getPosition(), mWString.length());
- return getPosition();
- }
- virtual S32 redo(LLTextBase* editor)
- {
- insert(editor, getPosition(), mWString);
- return getPosition() + mWString.length();
- }
-
-private:
- LLWString mWString;
- bool mBlockExtensions;
-};
-
-///////////////////////////////////////////////////////////////////
class LLTextEditor::TextCmdOverwriteChar : public LLTextBase::TextCmd
{
@@ -253,8 +210,15 @@ public:
}
virtual bool execute( LLTextBase* editor, S32* delta )
{
- mWString = editor->getWText().substr(getPosition(), mLen);
- *delta = remove(editor, getPosition(), mLen );
+ try
+ {
+ mWString = editor->getWText().substr(getPosition(), mLen);
+ *delta = remove(editor, getPosition(), mLen);
+ }
+ catch (std::out_of_range&)
+ {
+ return false;
+ }
return (*delta != 0);
}
virtual S32 undo( LLTextBase* editor )
@@ -307,6 +271,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mPrevalidator(p.prevalidator()),
mShowContextMenu(p.show_context_menu),
mShowEmojiHelper(p.show_emoji_helper),
+ mShowChatMentionPicker(false),
mEnableTooltipPaste(p.enable_tooltip_paste),
mPassDelete(false),
mKeepSelectionOnReturn(false)
@@ -751,6 +716,30 @@ void LLTextEditor::handleEmojiCommit(llwchar emoji)
}
}
+void LLTextEditor::handleMentionCommit(std::string name_url)
+{
+ S32 mention_start_pos;
+ if (LLChatMentionHelper::instance().isCursorInNameMention(getWText(), mCursorPos, &mention_start_pos))
+ {
+ remove(mention_start_pos, mCursorPos - mention_start_pos, true);
+ insert(mention_start_pos, utf8str_to_wstring(name_url), false, LLTextSegmentPtr());
+
+ std::string new_text(wstring_to_utf8str(getConvertedText()));
+ clear();
+ appendTextImpl(new_text, LLStyle::Params(), true);
+
+ segment_set_t::const_iterator it = getSegIterContaining(mention_start_pos);
+ if (it != mSegments.end())
+ {
+ setCursorPos((*it)->getEnd() + 1);
+ }
+ else
+ {
+ setCursorPos(mention_start_pos);
+ }
+ }
+}
+
bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
bool handled = false;
@@ -1140,6 +1129,7 @@ void LLTextEditor::removeCharOrTab()
}
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
}
else
{
@@ -1165,6 +1155,7 @@ void LLTextEditor::removeChar()
setCursorPos(mCursorPos - 1);
removeChar(mCursorPos);
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
}
else
{
@@ -1208,18 +1199,6 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc)
return execute(new TextCmdAddChar(pos, false, wc, LLTextSegmentPtr()));
}
-S32 LLTextEditor::addString(S32 pos, char *str)
-{
- if ((wstring_utf8_length(getWText()) + strlen(str))
- > mMaxTextByteLength) {
- make_ui_sound("UISndBadKeystroke");
- return 0;
- }
-
- return execute(new TextCmdAddString(pos, FALSE, str,
- LLTextSegmentPtr()));
-}
-
void LLTextEditor::addChar(llwchar wc)
{
if (!getEnabled())
@@ -1238,6 +1217,7 @@ void LLTextEditor::addChar(llwchar wc)
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
if (!mReadOnly && mAutoreplaceCallback != NULL)
{
@@ -1257,38 +1237,6 @@ void LLTextEditor::addChar(llwchar wc)
}
}
-void LLTextEditor::addString(char *str, bool editing)
-{
- if (!getEnabled())
- return;
- if (hasSelection())
- deleteSelection(TRUE);
- else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode())
- removeChar(mCursorPos);
- else if (editing) {
- clear();
- setCursorPos(0);
- }
-
- setCursorPos(mCursorPos + addString(mCursorPos, str));
-
- if (!mReadOnly && mAutoreplaceCallback != NULL) {
- S32 replacement_start;
- S32 replacement_length;
- LLWString replacement_string;
- S32 new_cursor_pos = mCursorPos;
- mAutoreplaceCallback(replacement_start, replacement_length,
- replacement_string, new_cursor_pos, getWText());
-
- if (replacement_length > 0 || !replacement_string.empty()) {
- remove(replacement_start, replacement_length, true);
- insert(replacement_start, replacement_string, false,
- LLTextSegmentPtr());
- setCursorPos(new_cursor_pos);
- }
- }
-}
-
void LLTextEditor::showEmojiHelper()
{
if (mReadOnly || !mShowEmojiHelper)
@@ -1299,6 +1247,14 @@ void LLTextEditor::showEmojiHelper()
LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, LLStringUtil::null, cb);
}
+void LLTextEditor::hideEmojiHelper()
+{
+ if (mShowEmojiHelper)
+ {
+ LLEmojiHelper::instance().hideHelper(this);
+ }
+}
+
void LLTextEditor::tryToShowEmojiHelper()
{
if (mReadOnly || !mShowEmojiHelper)
@@ -1320,6 +1276,31 @@ void LLTextEditor::tryToShowEmojiHelper()
}
}
+void LLTextEditor::tryToShowMentionHelper()
+{
+ if (mReadOnly || !mShowChatMentionPicker)
+ return;
+
+ S32 mention_start_pos;
+ LLWString text(getWText());
+ if (LLChatMentionHelper::instance().isCursorInNameMention(text, mCursorPos, &mention_start_pos))
+ {
+ const LLRect cursor_rect(getLocalRectFromDocIndex(mention_start_pos));
+ std::string name_part(wstring_to_utf8str(text.substr(mention_start_pos, mCursorPos - mention_start_pos)));
+ name_part.erase(0, 1);
+ auto cb = [this](std::string name_url)
+ {
+ handleMentionCommit(name_url);
+ };
+ LLChatMentionHelper::instance().showHelper(this, cursor_rect.mLeft, cursor_rect.mTop, name_part, cb);
+ }
+ else
+ {
+ LLChatMentionHelper::instance().hideHelper();
+ }
+}
+
+
void LLTextEditor::addLineBreakChar(bool group_together)
{
if( !getEnabled() )
@@ -1946,7 +1927,7 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask )
// not handled and let the parent take care of field movement.
if (KEY_TAB == key && mTabsToNextField)
{
- return false;
+ return mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask);
}
if (mReadOnly && mScroller)
@@ -1957,9 +1938,13 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask )
}
else
{
- if (!mReadOnly && mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask))
+ if (!mReadOnly)
{
- return true;
+ if ((mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask)) ||
+ (mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask)))
+ {
+ return true;
+ }
}
if (mEnableTooltipPaste &&
@@ -2060,24 +2045,6 @@ bool LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
return handled;
}
-bool LLTextEditor::handleUnicodeStringHere(char *uni_str, bool editing)
-{
- auto handled = FALSE;
-
- if (!mReadOnly) {
- addString(uni_str, editing);
- getWindow()->hideCursorUntilMouseMove();
- handled = TRUE;
- }
-
- if (handled) {
- resetCursorBlink();
- deselect();
- onKeyStroke();
- }
-
- return handled;
-}
// virtual
bool LLTextEditor::canDoDelete() const
@@ -3174,3 +3141,21 @@ S32 LLTextEditor::spacesPerTab()
{
return SPACES_PER_TAB;
}
+
+LLWString LLTextEditor::getConvertedText() const
+{
+ LLWString text = getWText();
+ S32 diff = 0;
+ for (auto segment : mSegments)
+ {
+ if (segment && segment->getStyle() && segment->getStyle()->getDrawHighlightBg())
+ {
+ S32 seg_length = segment->getEnd() - segment->getStart();
+ std::string slurl = segment->getStyle()->getLinkHREF();
+
+ text.replace(segment->getStart() + diff, seg_length, utf8str_to_wstring(slurl));
+ diff += (S32)slurl.size() - seg_length;
+ }
+ }
+ return text;
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 47dcadf090..882bb145df 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -95,6 +95,8 @@ public:
void insertEmoji(llwchar emoji);
void handleEmojiCommit(llwchar emoji);
+ void handleMentionCommit(std::string name_url);
+
// mousehandler overrides
virtual bool handleMouseDown(S32 x, S32 y, MASK mask);
virtual bool handleMouseUp(S32 x, S32 y, MASK mask);
@@ -105,7 +107,6 @@ public:
virtual bool handleKeyHere(KEY key, MASK mask );
virtual bool handleUnicodeCharHere(llwchar uni_char);
- virtual bool handleUnicodeStringHere(char *uni_str, bool editing);
virtual void onMouseCaptureLost();
@@ -201,24 +202,24 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
- const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }
bool getShowContextMenu() const { return mShowContextMenu; }
void showEmojiHelper();
+ void hideEmojiHelper();
void setShowEmojiHelper(bool show);
bool getShowEmojiHelper() const { return mShowEmojiHelper; }
void setPassDelete(bool b) { mPassDelete = b; }
+ LLWString getConvertedText() const;
+
protected:
void showContextMenu(S32 x, S32 y);
void drawPreeditMarker();
- void assignEmbedded(const std::string &s);
-
void removeCharOrTab();
void indentSelectedLines( S32 spaces );
@@ -238,7 +239,6 @@ protected:
void autoIndent();
- void findEmbeddedItemSegments(S32 start, S32 end);
void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const;
virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; }
@@ -250,8 +250,6 @@ protected:
// Undoable operations
void addChar(llwchar c); // at mCursorPos
S32 addChar(S32 pos, llwchar wc);
- void addString(char *s, bool editing);
- S32 addString(S32 pos, char *str);
void addLineBreakChar(bool group_together = false);
S32 overwriteChar(S32 pos, llwchar wc);
void removeChar();
@@ -260,6 +258,7 @@ protected:
S32 remove(S32 pos, S32 length, bool group_with_next_op);
void tryToShowEmojiHelper();
+ void tryToShowMentionHelper();
void focusLostHelper();
void updateAllowingLanguageInput();
bool hasPreeditString() const;
@@ -274,6 +273,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
//
@@ -295,6 +296,7 @@ protected:
bool mAutoIndent;
bool mParseOnTheFly;
+ bool mShowChatMentionPicker;
void updateLinkSegments();
void keepSelectionOnReturn(bool keep) { mKeepSelectionOnReturn = keep; }
@@ -305,7 +307,7 @@ private:
// Methods
//
void pasteHelper(bool is_primary);
- void cleanStringForPaste(LLWString & clean_string);
+ void cleanStringForPaste(LLWString& clean_string);
void pasteTextWithLinebreaks(LLWString & clean_string);
void onKeyStroke();
@@ -313,7 +315,6 @@ private:
// Concrete TextCmd sub-classes used by the LLTextEditor base class
class TextCmdInsert;
class TextCmdAddChar;
- class TextCmdAddString;
class TextCmdOverwriteChar;
class TextCmdRemove;
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index c57c979525..5556406fbd 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -68,7 +68,7 @@ public:
void reshape(S32 width, S32 height, bool called_from_parent = true);
void setEnabled(bool enabled);
void setCommandId(const LLCommandId& id) { mId = id; }
- LLCommandId getCommandId() { return mId; }
+ LLCommandId getCommandId() const { return mId; }
void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; }
void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
@@ -256,7 +256,7 @@ public:
// Methods used in loading and saving toolbar settings
void setButtonType(LLToolBarEnums::ButtonType button_type);
- LLToolBarEnums::ButtonType getButtonType() { return mButtonType; }
+ LLToolBarEnums::ButtonType getButtonType() const { return mButtonType; }
command_id_list_t& getCommandsList() { return mButtonCommands; }
void clearCommandsList();
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 86525c2f7e..74f03618cf 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -390,22 +390,22 @@ void LLToolTip::draw()
}
}
-bool LLToolTip::isFading()
+bool LLToolTip::isFading() const
{
return mFadeTimer.getStarted();
}
-F32 LLToolTip::getVisibleTime()
+F32 LLToolTip::getVisibleTime() const
{
return mVisibleTimer.getStarted() ? mVisibleTimer.getElapsedTimeF32() : 0.f;
}
-bool LLToolTip::hasClickCallback()
+bool LLToolTip::hasClickCallback() const
{
return mHasClickCallback;
}
-void LLToolTip::getToolTipMessage(std::string & message)
+void LLToolTip::getToolTipMessage(std::string& message) const
{
if (mTextBox)
{
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 8515504e3b..760acddd6f 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -44,15 +44,15 @@ public:
Params();
};
LLToolTipView(const LLToolTipView::Params&);
- /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMiddleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleScrollWheel( S32 x, S32 y, S32 clicks );
+ bool handleHover(S32 x, S32 y, MASK mask) override;
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleMiddleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleScrollWheel( S32 x, S32 y, S32 clicks ) override;
void drawStickyRect();
- /*virtual*/ void draw();
+ void draw() override;
};
class LLToolTip : public LLPanel
@@ -98,20 +98,20 @@ public:
Params();
};
- /*virtual*/ void draw();
- /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ void setVisible(bool visible);
+ void draw() override;
+ bool handleHover(S32 x, S32 y, MASK mask) override;
+ void onMouseLeave(S32 x, S32 y, MASK mask) override;
+ void setVisible(bool visible) override;
- bool isFading();
- F32 getVisibleTime();
- bool hasClickCallback();
+ bool isFading() const;
+ F32 getVisibleTime() const;
+ bool hasClickCallback() const;
LLToolTip(const Params& p);
virtual void initFromParams(const LLToolTip::Params& params);
- void getToolTipMessage(std::string & message);
- bool isTooltipPastable() { return mIsTooltipPastable; }
+ void getToolTipMessage(std::string & message) const;
+ bool isTooltipPastable() const { return mIsTooltipPastable; }
protected:
void updateTextBox();
diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp
index 8410031653..0c6c5b64e4 100644
--- a/indra/llui/lltrans.cpp
+++ b/indra/llui/lltrans.cpp
@@ -28,12 +28,8 @@
#include "lltrans.h"
-#include "llfasttimer.h" // for call count statistics
#include "llxuiparser.h"
#include "llsd.h"
-#include "llxmlnode.h"
-
-#include <map>
LLTrans::template_map_t LLTrans::sStringTemplates;
LLTrans::template_map_t LLTrans::sDefaultStringTemplates;
@@ -59,7 +55,7 @@ struct StringTable : public LLInitParam::Block<StringTable>
};
//static
-bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& default_args)
+bool LLTrans::parseStrings(LLXMLNodePtr& root, const std::set<std::string>& default_args)
{
std::string xml_filename = "(strings file)";
if (!root->hasName("strings"))
@@ -107,7 +103,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
//static
-bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
+bool LLTrans::parseLanguageStrings(LLXMLNodePtr& root)
{
std::string xml_filename = "(language strings file)";
if (!root->hasName("strings"))
@@ -138,10 +134,6 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
return true;
}
-
-
-static LLTrace::BlockTimerStatHandle FTM_GET_TRANS("Translate string");
-
//static
std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args, bool def_string)
{
@@ -235,7 +227,7 @@ std::string LLTrans::getDefString(std::string_view xml_desc, const LLSD& msg_arg
}
//static
-bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args)
+bool LLTrans::findString(std::string& result, std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
@@ -257,7 +249,7 @@ bool LLTrans::findString(std::string &result, std::string_view xml_desc, const L
}
//static
-bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLSD& msg_args)
+bool LLTrans::findString(std::string& result, std::string_view xml_desc, const LLSD& msg_args)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
@@ -277,7 +269,7 @@ bool LLTrans::findString(std::string &result, std::string_view xml_desc, const L
}
//static
-std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count)
+std::string LLTrans::getCountString(std::string_view language, std::string_view xml_desc, S32 count)
{
// Compute which string identifier to use
const char* form = "";
@@ -337,7 +329,7 @@ std::string LLTrans::getCountString(const std::string& language, const std::stri
args["[COUNT]"] = llformat("%d", count);
// Look up "AgeYearsB" or "AgeWeeksC" including the "form"
- std::string key = llformat("%s%s", xml_desc.c_str(), form);
+ std::string key = llformat("%s%s", xml_desc.data(), form);
return getString(key, args);
}
diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h
index 3492ed0169..c5d01e6f8d 100644
--- a/indra/llui/lltrans.h
+++ b/indra/llui/lltrans.h
@@ -30,10 +30,8 @@
#include <map>
#include <set>
-#include "llpointer.h"
#include "llstring.h"
-
-class LLXMLNode;
+#include "llxmlnode.h"
class LLSD;
@@ -58,17 +56,17 @@ public:
class LLTrans
{
public:
- LLTrans();
+ LLTrans() = default;
/**
* @brief Parses the xml root that holds the strings. Used once on startup
-// *FIXME * @param xml_filename Filename to parse
+ * @param root xml root node to parse
* @param default_args Set of strings (expected to be in the file) to use as default replacement args, e.g. "SECOND_LIFE"
* @returns true if the file was parsed successfully, true if something went wrong
*/
- static bool parseStrings(LLPointer<LLXMLNode> & root, const std::set<std::string>& default_args);
+ static bool parseStrings(LLXMLNodePtr& root, const std::set<std::string>& default_args);
- static bool parseLanguageStrings(LLPointer<LLXMLNode> & root);
+ static bool parseLanguageStrings(LLXMLNodePtr& root);
/**
* @brief Returns a translated string
@@ -80,14 +78,14 @@ public:
static std::string getDefString(std::string_view xml_desc, const LLStringUtil::format_map_t& args);
static std::string getString(std::string_view xml_desc, const LLSD& args, bool def_string = false);
static std::string getDefString(std::string_view xml_desc, const LLSD& args);
- static bool findString(std::string &result, std::string_view xml_desc, const LLStringUtil::format_map_t& args);
- static bool findString(std::string &result, std::string_view xml_desc, const LLSD& args);
+ static bool findString(std::string& result, std::string_view xml_desc, const LLStringUtil::format_map_t& args);
+ static bool findString(std::string& result, std::string_view xml_desc, const LLSD& args);
// Returns translated string with [COUNT] replaced with a number, following
// special per-language logic for plural nouns. For example, some languages
// may have different plurals for 0, 1, 2 and > 2.
// See "AgeWeeksA", "AgeWeeksB", etc. in strings.xml for examples.
- static std::string getCountString(const std::string& language, const std::string& xml_desc, S32 count);
+ static std::string getCountString(std::string_view language, std::string_view xml_desc, S32 count);
/**
* @brief Returns a translated string
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 4af5376a8b..e82af0b96f 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -48,7 +48,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
"Second Life viewer couldn't access some of the files it needs and will be closed."
"\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
"contact https://support.secondlife.com if issue persists after reinstall.";
- LLError::LLUserWarningMsg::show(error_string);
+ LLError::LLUserWarningMsg::show(error_string, LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;
return false;
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 375cd539b7..b2dcb6dc88 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -31,8 +31,6 @@
#include "llrect.h"
#include "llcoord.h"
#include "llcontrol.h"
-#include "llcoord.h"
-#include "llcontrol.h"
#include "llinitparam.h"
#include "llregistry.h"
#include "llrender2dutils.h"
@@ -156,7 +154,7 @@ public:
sanitizeRange();
}
- S32 clamp(S32 input)
+ S32 clamp(S32 input) const
{
if (input < mMin) return mMin;
if (input > mMax) return mMax;
@@ -170,8 +168,8 @@ public:
sanitizeRange();
}
- S32 getMin() { return mMin; }
- S32 getMax() { return mMax; }
+ S32 getMin() const { return mMin; }
+ S32 getMax() const { return mMax; }
bool operator==(const RangeS32& other) const
{
@@ -225,7 +223,7 @@ public:
mValue = clamp(value);
}
- S32 get()
+ S32 get() const
{
return mValue;
}
@@ -255,7 +253,7 @@ public:
static std::string getLanguage(); // static for lldateutil_test compatibility
//helper functions (should probably move free standing rendering helper functions here)
- LLView* getRootView() { return mRootView; }
+ LLView* getRootView() const { return mRootView; }
void setRootView(LLView* view) { mRootView = view; }
/**
* Walk the LLView tree to resolve a path
@@ -298,7 +296,7 @@ public:
LLControlGroup& getControlControlGroup (std::string_view controlname);
F32 getMouseIdleTime() { return mMouseIdleTimer.getElapsedTimeF32(); }
void resetMouseIdleTimer() { mMouseIdleTimer.reset(); }
- LLWindow* getWindow() { return mWindow; }
+ LLWindow* getWindow() const { return mWindow; }
void addPopup(LLView*);
void removePopup(LLView*);
diff --git a/indra/llui/lluiconstants.h b/indra/llui/lluiconstants.h
index 5fdfd37c6e..a317c66008 100644
--- a/indra/llui/lluiconstants.h
+++ b/indra/llui/lluiconstants.h
@@ -28,23 +28,23 @@
#define LL_LLUICONSTANTS_H
// spacing for small font lines of text, like LLTextBoxes
-const S32 LINE = 16;
+constexpr S32 LINE = 16;
// spacing for larger lines of text
-const S32 LINE_BIG = 24;
+constexpr S32 LINE_BIG = 24;
// default vertical padding
-const S32 VPAD = 4;
+constexpr S32 VPAD = 4;
// default horizontal padding
-const S32 HPAD = 4;
+constexpr S32 HPAD = 4;
// Account History, how far to look into past
-const S32 SUMMARY_INTERVAL = 7; // one week
-const S32 SUMMARY_MAX = 8; //
-const S32 DETAILS_INTERVAL = 1; // one day
-const S32 DETAILS_MAX = 30; // one month
-const S32 TRANSACTIONS_INTERVAL = 1;// one day
-const S32 TRANSACTIONS_MAX = 30; // one month
+constexpr S32 SUMMARY_INTERVAL = 7; // one week
+constexpr S32 SUMMARY_MAX = 8; //
+constexpr S32 DETAILS_INTERVAL = 1; // one day
+constexpr S32 DETAILS_MAX = 30; // one month
+constexpr S32 TRANSACTIONS_INTERVAL = 1;// one day
+constexpr S32 TRANSACTIONS_MAX = 30; // one month
#endif
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 8cd9950917..bcaf479b0f 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -39,9 +39,9 @@
#include "llviewmodel.h" // *TODO move dependency to .cpp file
#include "llsearchablecontrol.h"
-const bool TAKE_FOCUS_YES = true;
-const bool TAKE_FOCUS_NO = false;
-const S32 DROP_SHADOW_FLOATER = 5;
+constexpr bool TAKE_FOCUS_YES = true;
+constexpr bool TAKE_FOCUS_NO = false;
+constexpr S32 DROP_SHADOW_FLOATER = 5;
class LLUICtrl
: public LLView, public boost::signals2::trackable
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 75e7e396bc..91221dc7f3 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -184,7 +184,7 @@ fail:
template<class T>
static T* getDefaultWidget(std::string_view name)
{
- typename T::Params widget_params;
+ typename T::Params widget_params{};
widget_params.name = std::string(name);
return create<T>(widget_params);
}
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index bfadeb8428..ab6de16639 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -47,6 +47,12 @@ void LLUIString::assign(const std::string& s)
dirty();
}
+void LLUIString::assign(const LLWString& instring)
+{
+ mOrig = wstring_to_utf8str(instring);
+ dirty();
+}
+
void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
{
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index b9d4ff0ebb..950d4e72c6 100644
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
@@ -61,10 +61,11 @@ public:
LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {}
LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args);
LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); }
- LLUIString(const LLWString& instring) : mArgs(NULL) { insert(0, instring); }
+ LLUIString(const LLWString& instring) : mArgs(NULL) { assign(instring); }
~LLUIString() { delete mArgs; }
void assign(const std::string& instring);
+ void assign(const LLWString& instring);
LLUIString& operator=(const std::string& s) { assign(s); return *this; }
void setArgList(const LLStringUtil::format_map_t& args);
@@ -109,8 +110,8 @@ private:
LLStringUtil::format_map_t* mArgs;
// controls lazy evaluation
- mutable bool mNeedsResult;
- mutable bool mNeedsWResult;
+ mutable bool mNeedsResult { true };
+ mutable bool mNeedsWResult { true };
};
#endif // LL_LLUISTRING_H
diff --git a/indra/llui/llundo.h b/indra/llui/llundo.h
index dc40702be0..990745e530 100644
--- a/indra/llui/llundo.h
+++ b/indra/llui/llundo.h
@@ -42,7 +42,7 @@ public:
LLUndoAction(): mClusterID(0) {};
virtual ~LLUndoAction(){};
private:
- S32 mClusterID;
+ S32 mClusterID;
};
LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count );
@@ -51,8 +51,8 @@ public:
LLUndoAction *getNextAction(bool setClusterBegin = true);
bool undoAction();
bool redoAction();
- bool canUndo() { return (mNextAction != mFirstAction); }
- bool canRedo() { return (mNextAction != mLastAction); }
+ bool canUndo() const { return (mNextAction != mFirstAction); }
+ bool canRedo() const { return (mNextAction != mLastAction); }
void flushActions();
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 0f54b66299..ac9741a7ad 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -45,8 +45,6 @@
class LLUrlAction
{
public:
- LLUrlAction();
-
/// load a Url in the user's preferred web browser
static void openURL(std::string url);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 79d2fcd049..bcd13b7f0b 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -29,7 +29,6 @@
#include "llurlentry.h"
#include "lluictrl.h"
#include "lluri.h"
-#include "llurlmatch.h"
#include "llurlregistry.h"
#include "lluriparser.h"
@@ -48,7 +47,7 @@
// Utility functions
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
-
+LLUUID LLUrlEntryBase::sAgentID(LLUUID::null);
LLUrlEntryBase::LLUrlEntryBase()
{
}
@@ -68,7 +67,7 @@ std::string LLUrlEntryBase::getIcon(const std::string &url)
return mIcon;
}
-LLStyle::Params LLUrlEntryBase::getStyle() const
+LLStyle::Params LLUrlEntryBase::getStyle(const std::string &url) const
{
LLStyle::Params style_params;
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
@@ -221,6 +220,16 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
},
L'\u002F'); // Solidus
+ std::replace_if(wlabel.begin(),
+ wlabel.end(),
+ [](const llwchar& chr)
+ {
+ return // Not a decomposition, but suficiently similar
+ (chr == L'\u04BA') // "Cyrillic Capital Letter Shha"
+ || (chr == L'\u04BB'); // "Cyrillic Small Letter Shha"
+ },
+ L'\u0068'); // "Latin Small Letter H"
+
std::string label = wstring_to_utf8str(wlabel);
if ((label.find(".com") != std::string::npos
|| label.find("www.") != std::string::npos)
@@ -600,15 +609,15 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
- avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
- if (it != mAvatarNameCacheConnections.end())
+ auto range = mAvatarNameCacheConnections.equal_range(id);
+ for (avatar_name_cache_connection_map_t::iterator it = range.first; it != range.second; ++it)
{
if (it->second.connected())
{
it->second.disconnect();
}
- mAvatarNameCacheConnections.erase(it);
}
+ mAvatarNameCacheConnections.erase(range.first, range.second);
std::string label = av_name.getCompleteName();
@@ -621,6 +630,11 @@ LLUUID LLUrlEntryAgent::getID(const std::string &string) const
return LLUUID(getIDStringFromUrl(string));
}
+bool LLUrlEntryAgent::isAgentID(const std::string& url) const
+{
+ return sAgentID == getID(url);
+}
+
std::string LLUrlEntryAgent::getTooltip(const std::string &string) const
{
// return a tooltip corresponding to the URL type instead of the generic one
@@ -657,10 +671,14 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const
return LLTrans::getString("TooltipAgentUrl");
}
-bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const
+LLStyle::EUnderlineLink LLUrlEntryAgent::getUnderline(const std::string& string) const
{
std::string url = getUrl(string);
- return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect");
+ if (LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect"))
+ {
+ return LLStyle::EUnderlineLink::UNDERLINE_ON_HOVER;
+ }
+ return LLStyle::EUnderlineLink::UNDERLINE_ALWAYS;
}
std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
@@ -695,27 +713,19 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
else
{
- avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
- if (it != mAvatarNameCacheConnections.end())
- {
- if (it->second.connected())
- {
- it->second.disconnect();
- }
- mAvatarNameCacheConnections.erase(it);
- }
- mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
+ mAvatarNameCacheConnections.emplace(agent_id, LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)));
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
}
-LLStyle::Params LLUrlEntryAgent::getStyle() const
+LLStyle::Params LLUrlEntryAgent::getStyle(const std::string &url) const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
+ LLStyle::Params style_params = LLUrlEntryBase::getStyle(url);
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+
return style_params;
}
@@ -750,6 +760,10 @@ std::string localize_slapp_label(const std::string& url, const std::string& full
{
return LLTrans::getString("SLappAgentRemoveFriend") + " " + full_name;
}
+ if (LLStringUtil::endsWith(url, "/mention"))
+ {
+ return "@" + full_name;
+ }
return full_name;
}
@@ -761,6 +775,36 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
return mIcon;
}
+///
+/// LLUrlEntryAgentMention Describes a chat mention Url, e.g.,
+/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/mention
+///
+LLUrlEntryAgentMention::LLUrlEntryAgentMention()
+{
+ mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/mention", boost::regex::perl | boost::regex::icase);
+ mMenuName = "menu_url_agent.xml";
+ mIcon = std::string();
+}
+
+LLStyle::EUnderlineLink LLUrlEntryAgentMention::getUnderline(const std::string& string) const
+{
+ return LLStyle::EUnderlineLink::UNDERLINE_NEVER;
+}
+
+LLStyle::Params LLUrlEntryAgentMention::getStyle(const std::string& url) const
+{
+ LLStyle::Params style_params = LLUrlEntryAgent::getStyle(url);
+ style_params.color = LLUIColorTable::instance().getColor("ChatMentionFont");
+ style_params.readonly_color = LLUIColorTable::instance().getColor("ChatMentionFont");
+ style_params.font.style = "NORMAL";
+ style_params.draw_highlight_bg = true;
+
+ LLUUID agent_id(getIDStringFromUrl(url));
+ style_params.highlight_bg_color = LLUIColorTable::instance().getColor((agent_id == sAgentID) ? "ChatSelfMentionHighlight" : "ChatMentionHighlight");
+
+ return style_params;
+}
+
//
// LLUrlEntryAgentName describes a Second Life agent name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
@@ -770,17 +814,17 @@ LLUrlEntryAgentName::LLUrlEntryAgentName()
{}
void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
- const LLAvatarName& av_name)
+ const LLAvatarName& av_name)
{
- avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
- if (it != mAvatarNameCacheConnections.end())
+ auto range = mAvatarNameCacheConnections.equal_range(id);
+ for (avatar_name_cache_connection_map_t::iterator it = range.first; it != range.second; ++it)
{
if (it->second.connected())
{
it->second.disconnect();
}
- mAvatarNameCacheConnections.erase(it);
}
+ mAvatarNameCacheConnections.erase(range.first, range.second);
std::string label = getName(av_name);
// received the agent name from the server - tell our observers
@@ -815,23 +859,14 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
}
else
{
- avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
- if (it != mAvatarNameCacheConnections.end())
- {
- if (it->second.connected())
- {
- it->second.disconnect();
- }
- mAvatarNameCacheConnections.erase(it);
- }
- mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
+ mAvatarNameCacheConnections.emplace(agent_id, LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)));
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
}
-LLStyle::Params LLUrlEntryAgentName::getStyle() const
+LLStyle::Params LLUrlEntryAgentName::getStyle(const std::string &url) const
{
// don't override default colors
return LLStyle::Params().is_link(false);
@@ -967,9 +1002,9 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
-LLStyle::Params LLUrlEntryGroup::getStyle() const
+LLStyle::Params LLUrlEntryGroup::getStyle(const std::string &url) const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
+ LLStyle::Params style_params = LLUrlEntryBase::getStyle(url);
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
return style_params;
@@ -1045,7 +1080,6 @@ std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCal
}
// LLUrlEntryParcel statics.
-LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null);
LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);
LLHost LLUrlEntryParcel::sRegionHost;
bool LLUrlEntryParcel::sDisconnected(false);
@@ -1379,17 +1413,17 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const
return LLUrlEntryBase::getTooltip(string);
}
-bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const
+LLStyle::EUnderlineLink LLUrlEntrySLLabel::getUnderline(const std::string& string) const
{
std::string url = getUrl(string);
- LLUrlMatch match;
+ LLUrlMatch match;
if (LLUrlRegistry::instance().findUrl(url, match))
{
- return match.underlineOnHoverOnly();
+ return match.getUnderline();
}
// unrecognized URL? should not happen
- return LLUrlEntryBase::underlineOnHoverOnly(string);
+ return LLUrlEntryBase::getUnderline(string);
}
//
@@ -1453,7 +1487,7 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC
return getUrl(url);
}
-LLStyle::Params LLUrlEntryNoLink::getStyle() const
+LLStyle::Params LLUrlEntryNoLink::getStyle(const std::string &url) const
{
// Don't render as URL (i.e. no context menu or hand cursor).
return LLStyle::Params().is_link(false);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 84ff278942..6e7d2fc80f 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -85,7 +85,7 @@ public:
virtual std::string getIcon(const std::string &url);
/// Return the style to render the displayed text
- virtual LLStyle::Params getStyle() const;
+ virtual LLStyle::Params getStyle(const std::string &url) const;
/// Given a matched Url, return a tooltip string for the hyperlink
virtual std::string getTooltip(const std::string &string) const { return mTooltip; }
@@ -96,12 +96,14 @@ public:
/// Return the name of a SL location described by this Url, if any
virtual std::string getLocation(const std::string &url) const { return ""; }
- /// Should this link text be underlined only when mouse is hovered over it?
- virtual bool underlineOnHoverOnly(const std::string &string) const { return false; }
+ virtual LLStyle::EUnderlineLink getUnderline(const std::string& string) const { return LLStyle::EUnderlineLink::UNDERLINE_ALWAYS; }
virtual bool isTrusted() const { return false; }
+ virtual bool getSkipProfileIcon(const std::string& string) const { return false; }
+
virtual LLUUID getID(const std::string &string) const { return LLUUID::null; }
+ virtual bool isAgentID(const std::string& url) const { return false; }
bool isLinkDisabled() const;
@@ -109,6 +111,8 @@ public:
virtual bool isSLURLvalid(const std::string &url) const { return true; };
+ static void setAgentID(const LLUUID& id) { sAgentID = id; }
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
@@ -130,6 +134,8 @@ protected:
std::string mMenuName;
std::string mTooltip;
std::multimap<std::string, LLUrlEntryObserver> mObservers;
+
+ static LLUUID sAgentID;
};
///
@@ -224,19 +230,36 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getIcon(const std::string &url);
/*virtual*/ std::string getTooltip(const std::string &string) const;
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
/*virtual*/ LLUUID getID(const std::string &string) const;
- /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
+
+ bool isAgentID(const std::string& url) const;
+
+ LLStyle::EUnderlineLink getUnderline(const std::string& string) const;
+
protected:
/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
- typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ typedef std::multimap<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
///
+/// LLUrlEntryAgentMention Describes a chat mention Url, e.g.,
+/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/mention
+class LLUrlEntryAgentMention : public LLUrlEntryAgent
+{
+public:
+ LLUrlEntryAgentMention();
+
+ LLStyle::Params getStyle(const std::string& url) const;
+ LLStyle::EUnderlineLink getUnderline(const std::string& string) const;
+ bool getSkipProfileIcon(const std::string& string) const { return true; };
+};
+
+///
/// LLUrlEntryAgentName Describes a Second Life agent name Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
/// that displays various forms of user name
@@ -257,14 +280,14 @@ public:
mAvatarNameCacheConnections.clear();
}
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
protected:
// override this to pull out relevant name fields
virtual std::string getName(const LLAvatarName& avatar_name) = 0;
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
- typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ typedef std::multimap<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
@@ -339,7 +362,7 @@ class LLUrlEntryGroup : public LLUrlEntryBase
public:
LLUrlEntryGroup();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
/*virtual*/ LLUUID getID(const std::string &string) const;
private:
void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group);
@@ -411,17 +434,15 @@ public:
// Processes parcel label and triggers notifying observers.
static void processParcelInfo(const LLParcelData& parcel_data);
- // Next 4 setters are used to update agent and viewer connection information
+ // Next setters are used to update agent and viewer connection information
// upon events like user login, viewer disconnect and user changing region host.
// These setters are made public to be accessible from newview and should not be
// used in other cases.
- static void setAgentID(const LLUUID& id) { sAgentID = id; }
static void setSessionID(const LLUUID& id) { sSessionID = id; }
static void setRegionHost(const LLHost& host) { sRegionHost = host; }
static void setDisconnected(bool disconnected) { sDisconnected = disconnected; }
private:
- static LLUUID sAgentID;
static LLUUID sSessionID;
static LLHost sRegionHost;
static bool sDisconnected;
@@ -486,7 +507,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;
+ LLStyle::EUnderlineLink getUnderline(const std::string& string) const;
};
///
@@ -510,7 +531,7 @@ public:
LLUrlEntryNoLink();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
};
///
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index bfa3b167b1..f093934ca9 100644
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -37,8 +37,9 @@ LLUrlMatch::LLUrlMatch() :
mIcon(""),
mMenuName(""),
mLocation(""),
- mUnderlineOnHoverOnly(false),
- mTrusted(false)
+ mUnderline(e_underline::UNDERLINE_ALWAYS),
+ mTrusted(false),
+ mSkipProfileIcon(false)
{
}
@@ -46,7 +47,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std
const std::string& query, const std::string &tooltip,
const std::string &icon, const LLStyle::Params& style,
const std::string &menu, const std::string &location,
- const LLUUID& id, bool underline_on_hover_only, bool trusted)
+ const LLUUID& id, e_underline underline, bool trusted, bool skip_icon)
{
mStart = start;
mEnd = end;
@@ -60,6 +61,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std
mMenuName = menu;
mLocation = location;
mID = id;
- mUnderlineOnHoverOnly = underline_on_hover_only;
+ mUnderline = underline;
mTrusted = trusted;
+ mSkipProfileIcon = skip_icon;
}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index ba822fbda6..418a21f963 100644
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -31,7 +31,6 @@
//#include "linden_common.h"
#include <string>
-#include <vector>
#include "llstyle.h"
///
@@ -80,18 +79,20 @@ public:
/// return the SL location that this Url describes, or "" if none.
std::string getLocation() const { return mLocation; }
- /// Should this link text be underlined only when mouse is hovered over it?
- bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; }
+ typedef LLStyle::EUnderlineLink e_underline;
+ e_underline getUnderline() const { return mUnderline; }
/// Return true if Url is trusted.
bool isTrusted() const { return mTrusted; }
+ bool getSkipProfileIcon() const { return mSkipProfileIcon; }
+
/// 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& query, const std::string &tooltip, const std::string &icon,
const LLStyle::Params& style, const std::string &menu,
const std::string &location, const LLUUID& id,
- bool underline_on_hover_only = false, bool trusted = false);
+ e_underline underline = e_underline::UNDERLINE_ALWAYS, bool trusted = false, bool skip_icon = false);
const LLUUID& getID() const { return mID; }
private:
@@ -106,8 +107,9 @@ private:
std::string mLocation;
LLUUID mID;
LLStyle::Params mStyle;
- bool mUnderlineOnHoverOnly;
+ e_underline mUnderline;
bool mTrusted;
+ bool mSkipProfileIcon;
};
#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index cec1ddfc57..cb101d325d 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -62,6 +62,8 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryAgentUserName());
// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since
// LLUrlEntryAgent is a less specific (catchall for agent urls)
+ mUrlEntryAgentMention = new LLUrlEntryAgentMention();
+ registerUrl(mUrlEntryAgentMention);
registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryChat());
registerUrl(new LLUrlEntryGroup());
@@ -155,7 +157,7 @@ static bool stringHasUrl(const std::string &text)
text.find("@") != std::string::npos);
}
-bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted)
+bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted, bool skip_non_mentions)
{
// avoid costly regexes if there is clearly no URL in the text
if (! stringHasUrl(text))
@@ -176,6 +178,11 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
continue;
}
+ if (skip_non_mentions && (mUrlEntryAgentMention != *it))
+ {
+ continue;
+ }
+
LLUrlEntryBase *url_entry = *it;
U32 start = 0, end = 0;
@@ -233,12 +240,13 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getQuery(url),
match_entry->getTooltip(url),
match_entry->getIcon(url),
- match_entry->getStyle(),
+ match_entry->getStyle(url),
match_entry->getMenuName(),
match_entry->getLocation(url),
match_entry->getID(url),
- match_entry->underlineOnHoverOnly(url),
- match_entry->isTrusted());
+ match_entry->getUnderline(url),
+ match_entry->isTrusted(),
+ match_entry->getSkipProfileIcon(url));
return true;
}
@@ -274,7 +282,9 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.getMenuName(),
match.getLocation(),
match.getID(),
- match.underlineOnHoverOnly());
+ match.getUnderline(),
+ false,
+ match.getSkipProfileIcon());
return true;
}
return false;
@@ -317,3 +327,30 @@ void LLUrlRegistry::setKeybindingHandler(LLKeyBindingToStringHandler* handler)
LLUrlEntryKeybinding *entry = (LLUrlEntryKeybinding*)mUrlEntryKeybinding;
entry->setHandler(handler);
}
+
+bool LLUrlRegistry::containsAgentMention(const std::string& text)
+{
+ // avoid costly regexes if there is clearly no URL in the text
+ if (!stringHasUrl(text))
+ {
+ return false;
+ }
+
+ try
+ {
+ boost::sregex_iterator it(text.begin(), text.end(), mUrlEntryAgentMention->getPattern());
+ boost::sregex_iterator end;
+ for (; it != end; ++it)
+ {
+ if (mUrlEntryAgentMention->isAgentID(it->str()))
+ {
+ return true;
+ }
+ }
+ }
+ catch (boost::regex_error&)
+ {
+ LL_INFOS() << "Regex error for: " << text << LL_ENDL;
+ }
+ return false;
+}
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 64cfec3960..592e422487 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -34,7 +34,6 @@
#include "llstring.h"
#include <string>
-#include <vector>
class LLKeyBindingToStringHandler;
@@ -76,7 +75,7 @@ public:
/// your callback is invoked if the matched Url's label changes in the future
bool findUrl(const std::string &text, LLUrlMatch &match,
const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback,
- bool is_content_trusted = false);
+ bool is_content_trusted = false, bool skip_non_mentions = false);
/// a slightly less efficient version of findUrl for wide strings
bool findUrl(const LLWString &text, LLUrlMatch &match,
@@ -93,6 +92,8 @@ public:
// Set handler for url registry to be capable of parsing and populating keybindings
void setKeybindingHandler(LLKeyBindingToStringHandler* handler);
+ bool containsAgentMention(const std::string& text);
+
private:
std::vector<LLUrlEntryBase *> mUrlEntry;
LLUrlEntryBase* mUrlEntryTrusted;
@@ -102,6 +103,7 @@ private:
LLUrlEntryBase* mUrlEntrySLLabel;
LLUrlEntryBase* mUrlEntryNoLink;
LLUrlEntryBase* mUrlEntryKeybinding;
+ LLUrlEntryBase* mUrlEntryAgentMention;
};
#endif
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index f2a1e16aad..7d6c937b85 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1080,31 +1080,12 @@ bool LLView::handleUnicodeChar(llwchar uni_char, bool called_from_parent)
return handled;
}
-bool LLView::handleUnicodeString(char *uni_str, bool editing, bool called_from_parent)
-{
- auto handled = FALSE;
-
- if (getVisible() && getEnabled() && !handled) {
- handled = handleUnicodeStringHere(uni_str, editing);
- if (handled && LLView::sDebugKeys)
- LL_INFOS() << "Unicode key handled by " << getName() << LL_ENDL;
- }
-
- if (!handled && !called_from_parent && mParentView)
- handled = mParentView->handleUnicodeString(uni_str, editing, FALSE);
-
- return handled;
-}
bool LLView::handleUnicodeCharHere(llwchar uni_char )
{
return false;
}
-bool LLView::handleUnicodeStringHere(char *uni_str, bool editing)
-{
- return FALSE;
-}
bool LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
EDragAndDropType cargo_type, void* cargo_data,
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 876bfafaa3..97212a9d2d 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -54,17 +54,17 @@
class LLSD;
-const U32 FOLLOWS_NONE = 0x00;
-const U32 FOLLOWS_LEFT = 0x01;
-const U32 FOLLOWS_RIGHT = 0x02;
-const U32 FOLLOWS_TOP = 0x10;
-const U32 FOLLOWS_BOTTOM = 0x20;
-const U32 FOLLOWS_ALL = 0x33;
+constexpr U32 FOLLOWS_NONE = 0x00;
+constexpr U32 FOLLOWS_LEFT = 0x01;
+constexpr U32 FOLLOWS_RIGHT = 0x02;
+constexpr U32 FOLLOWS_TOP = 0x10;
+constexpr U32 FOLLOWS_BOTTOM = 0x20;
+constexpr U32 FOLLOWS_ALL = 0x33;
-const bool MOUSE_OPAQUE = true;
-const bool NOT_MOUSE_OPAQUE = false;
+constexpr bool MOUSE_OPAQUE = true;
+constexpr bool NOT_MOUSE_OPAQUE = false;
-const U32 GL_NAME_UI_RESERVED = 2;
+constexpr U32 GL_NAME_UI_RESERVED = 2;
// maintains render state during traversal of UI tree
@@ -241,7 +241,7 @@ public:
void setUseBoundingRect( bool use_bounding_rect );
bool getUseBoundingRect() const;
- ECursorType getHoverCursor() { return mHoverCursor; }
+ ECursorType getHoverCursor() const { return mHoverCursor; }
static F32 getTooltipTimeout();
virtual const std::string getToolTip() const;
@@ -265,7 +265,7 @@ public:
void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; }
S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
- S32 getLastTabGroup() { return mLastTabGroup; }
+ S32 getLastTabGroup() const { return mLastTabGroup; }
bool isInVisibleChain() const;
bool isInEnabledChain() const;
@@ -385,7 +385,6 @@ public:
/* virtual */ bool handleKey(KEY key, MASK mask, bool called_from_parent);
/* virtual */ bool handleKeyUp(KEY key, MASK mask, bool called_from_parent);
/* virtual */ bool handleUnicodeChar(llwchar uni_char, bool called_from_parent);
- /* virtual */ bool handleUnicodeString(char *uni_str, bool editing, bool called_from_parent);
virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
EDragAndDropType cargo_type,
@@ -519,7 +518,6 @@ public:
virtual bool handleKeyHere(KEY key, MASK mask);
virtual bool handleKeyUpHere(KEY key, MASK mask);
virtual bool handleUnicodeCharHere(llwchar uni_char);
- virtual bool handleUnicodeStringHere(char *uni_str, bool editing);
virtual void handleReshape(const LLRect& rect, bool by_user);
virtual void dirtyRect();
diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h
index 1f118a0d20..a4bb748b77 100644
--- a/indra/llui/llviewborder.h
+++ b/indra/llui/llviewborder.h
@@ -92,7 +92,6 @@ public:
private:
void drawOnePixelLines();
void drawTwoPixelLines();
- void drawTextures();
EBevel mBevel;
EStyle mStyle;
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/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
index 9e752e8090..5636c068d8 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -61,7 +61,7 @@ public:
std::string get_xui();
void update_xui(std::string xui);
- bool getLoggingStatus(){return logEvents;};
+ bool getLoggingStatus() const { return logEvents; }
void setEventLoggingOn();
void setEventLoggingOff();
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.
diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h
index 61a78b2398..fbfda04585 100644
--- a/indra/llui/llvirtualtrackball.h
+++ b/indra/llui/llvirtualtrackball.h
@@ -78,20 +78,20 @@ public:
};
- virtual ~LLVirtualTrackball();
- /*virtual*/ bool postBuild();
+ ~LLVirtualTrackball() override;
+ bool postBuild() override;
- virtual bool handleHover(S32 x, S32 y, MASK mask);
- virtual bool handleMouseUp(S32 x, S32 y, MASK mask);
- virtual bool handleMouseDown(S32 x, S32 y, MASK mask);
- virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask);
- virtual bool handleKeyHere(KEY key, MASK mask);
+ bool handleHover(S32 x, S32 y, MASK mask) override;
+ bool handleMouseUp(S32 x, S32 y, MASK mask) override;
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
+ bool handleKeyHere(KEY key, MASK mask) override;
- virtual void draw();
+ void draw() override;
- virtual void setValue(const LLSD& value);
- void setValue(F32 x, F32 y, F32 z, F32 w);
- virtual LLSD getValue() const;
+ void setValue(const LLSD& value) override;
+ void setValue(F32 x, F32 y, F32 z, F32 w);
+ LLSD getValue() const override;
void setRotation(const LLQuaternion &value);
LLQuaternion getRotation() const;
@@ -102,7 +102,6 @@ public:
protected:
friend class LLUICtrlFactory;
LLVirtualTrackball(const Params&);
- void onEditChange();
protected:
LLTextBox* mNLabel;
diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h
index da29188943..ee230cd2f6 100644
--- a/indra/llui/llwindowshade.h
+++ b/indra/llui/llwindowshade.h
@@ -49,7 +49,7 @@ public:
};
void show(LLNotificationPtr);
- /*virtual*/ void draw();
+ void draw() override;
void hide();
bool isShown() const;
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 8fd85a89a1..8cd11b86b3 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -30,7 +30,7 @@
#include "llxmlnode.h"
#include "llfasttimer.h"
-#ifdef LL_USESYSTEMLIBS
+#if 1
#include <expat.h>
#else
#include "expat/expat.h"
diff --git a/indra/llui/llxyvector.h b/indra/llui/llxyvector.h
index bc41213c13..646771f387 100644
--- a/indra/llui/llxyvector.h
+++ b/indra/llui/llxyvector.h
@@ -65,18 +65,18 @@ public:
};
- virtual ~LLXYVector();
- /*virtual*/ bool postBuild();
+ ~LLXYVector() override;
+ bool postBuild() override;
- virtual bool handleHover(S32 x, S32 y, MASK mask);
- virtual bool handleMouseUp(S32 x, S32 y, MASK mask);
- virtual bool handleMouseDown(S32 x, S32 y, MASK mask);
+ bool handleHover(S32 x, S32 y, MASK mask) override;
+ bool handleMouseUp(S32 x, S32 y, MASK mask) override;
+ bool handleMouseDown(S32 x, S32 y, MASK mask) override;
- virtual void draw();
+ void draw() override;
- virtual void setValue(const LLSD& value);
- void setValue(F32 x, F32 y);
- virtual LLSD getValue() const;
+ void setValue(const LLSD& value) override;
+ void setValue(F32 x, F32 y);
+ LLSD getValue() const override;
protected:
friend class LLUICtrlFactory;