diff options
| author | Jonathan "Geenz" Goodman <geenz@lindenlab.com> | 2026-05-19 18:51:02 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-19 18:51:02 -0400 |
| commit | 6d4c4c029ce43aa413266135829cd2bc00001890 (patch) | |
| tree | 209ae880aba5ac777d524bdc557ed166b466347f /indra/llui | |
| parent | 5c500ccf407f0b5a0b253b98dd4bd3f33f643aba (diff) | |
| parent | 115686ca0f962da9ec5dbcdbe54a4cb6c86302bb (diff) | |
Merge pull request #5369 from secondlife/release/2026.02
Release/2026.02
Diffstat (limited to 'indra/llui')
46 files changed, 264 insertions, 119 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 828bfb289b..fa9de1eb09 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -39,7 +39,7 @@ static const std::string DD_BUTTON_NAME = "dd_button"; static const std::string DD_TEXTBOX_NAME = "dd_textbox"; static const std::string DD_HEADER_NAME = "dd_header"; -static const S32 HEADER_HEIGHT = 23; +static const S32 HEADER_HEIGHT = 25; static const S32 HEADER_IMAGE_LEFT_OFFSET = 5; static const S32 HEADER_TEXT_LEFT_OFFSET = 30; static const F32 AUTO_OPEN_TIME = 1.f; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 0048c44189..7f209c60a7 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -85,6 +85,7 @@ LLButton::Params::Params() image_top_pad("image_top_pad"), image_bottom_pad("image_bottom_pad"), imgoverlay_label_space("imgoverlay_label_space", 1), + image_overlay_right_delta("image_overlay_right_delta", 0), label_color("label_color"), label_color_selected("label_color_selected"), // requires is_toggle true label_color_disabled("label_color_disabled"), @@ -109,6 +110,8 @@ LLButton::Params::Params() commit_on_capture_lost("commit_on_capture_lost", false), display_pressed_state("display_pressed_state", true), use_draw_context_alpha("use_draw_context_alpha", true), + draw_focus_border("draw_focus_border", true), + hover_hand_cursor("hover_hand_cursor", false), badge("badge"), handle_right_mouse("handle_right_mouse"), held_down_delay("held_down_delay"), @@ -158,6 +161,7 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlayTopPad(p.image_top_pad), mImageOverlayBottomPad(p.image_bottom_pad), mImgOverlayLabelSpace(p.imgoverlay_label_space), + mImageOverlayRightDelta(p.image_overlay_right_delta), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), mDropShadowedText(p.label_shadow), @@ -179,6 +183,8 @@ LLButton::LLButton(const LLButton::Params& p) mMouseUpSignal(NULL), mHeldDownSignal(NULL), mUseDrawContextAlpha(p.use_draw_context_alpha), + mDrawFocusBorder(p.draw_focus_border), + mHoverHandCursor(p.hover_hand_cursor), mHandleRightMouse(p.handle_right_mouse), mFlashingTimer(NULL) { @@ -653,7 +659,7 @@ bool LLButton::handleHover(S32 x, S32 y, MASK mask) } // We only handle the click if the click both started and ended within us - getWindow()->setCursor(UI_CURSOR_ARROW); + getWindow()->setCursor(mHoverHandCursor ? UI_CURSOR_HAND : UI_CURSOR_ARROW); LL_DEBUGS("UserInput") << "hover handled by " << getName() << LL_ENDL; } return true; @@ -840,10 +846,9 @@ void LLButton::draw() label_color = ll::ui::SearchableControl::getHighlightFontColor(); // overlay with keyboard focus border - if (hasFocus()) + if (hasFocus() && mDrawFocusBorder) { - F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); - drawBorder(imagep, gFocusMgr.getFocusColor() % alpha, ll_round(lerp(1.f, 3.f, lerp_amt))); + drawBorder(imagep, gFocusMgr.getFocusColor() % alpha, gFocusMgr.getFocusFlashWidth()); } if (use_glow_effect) @@ -930,6 +935,17 @@ void LLButton::draw() } overlay_color.mV[VALPHA] *= alpha; + if (mImageOverlayRightDelta > 0) + { + mImageOverlay->draw(getRect().getWidth() - overlay_width - mImageOverlayRightDelta, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + } + else + { + switch(mImageOverlayAlignment) { case LLFontGL::LEFT: @@ -964,6 +980,7 @@ void LLButton::draw() // draw nothing break; } + } } // Draw label diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index f530eceb4b..0d1a28ee31 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -110,6 +110,7 @@ public: //image overlay paddings Optional<S32> image_top_pad; Optional<S32> image_bottom_pad; + Optional<S32> image_overlay_right_delta; /** * Space between image_overlay and label @@ -132,7 +133,9 @@ public: Optional<F32> hover_glow_amount; Optional<TimeIntervalParam> held_down_delay; - Optional<bool> use_draw_context_alpha; + Optional<bool> use_draw_context_alpha, + draw_focus_border, + hover_hand_cursor; Optional<LLBadge::Params> badge; @@ -366,12 +369,16 @@ protected: S32 mImageOverlayBottomPad; bool mUseDrawContextAlpha; + bool mDrawFocusBorder; + bool mHoverHandCursor; /* * Space between image_overlay and label */ S32 mImgOverlayLabelSpace; + S32 mImageOverlayRightDelta; + F32 mHoverGlowStrength; F32 mCurGlowStrength; diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h index 3115606d91..69b80db1e8 100644 --- a/indra/llui/llcallbackmap.h +++ b/indra/llui/llcallbackmap.h @@ -27,9 +27,11 @@ #ifndef LLCALLBACKMAP_H #define LLCALLBACKMAP_H -#include <map> +#include "llstl.h" + #include <string> #include <functional> +#include <unordered_map> class LLCallbackMap { @@ -37,7 +39,7 @@ public: // callback definition. typedef std::function<void* (void* data)> callback_t; - typedef std::map<std::string, LLCallbackMap> map_t; + typedef std::unordered_map<std::string, LLCallbackMap> map_t; typedef map_t::iterator map_iter_t; typedef map_t::const_iterator map_const_iter_t; diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 91e6f281da..ca512a9883 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -67,6 +67,10 @@ LLConsole::LLConsole(const LLConsole::Params& p) { setFontSize(p.font_size_index); } + if (mFont == nullptr) + { + setFontSize(0); // sans-serif + } mFadeTime = mLinePersistTime - FADE_DURATION; setMaxLines(LLUI::getInstance()->mSettingGroups["config"]->getS32("ConsoleMaxLines")); } @@ -79,6 +83,13 @@ void LLConsole::setLinePersistTime(F32 seconds) void LLConsole::reshape(S32 width, S32 height, bool called_from_parent) { + if (mFont == nullptr) + { + // not initialized yet + LL_WARNS() << "LLConsole::reshape called before font is set" << LL_ENDL; + return; + } + S32 new_width = llmax(50, llmin(getRect().getWidth(), width)); S32 new_height = llmax(mFont->getLineHeight() + 15, llmin(getRect().getHeight(), height)); diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 15536178ab..b3b47084c5 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -59,7 +59,9 @@ LLDragHandle::LLDragHandle(const LLDragHandle::Params& p) mMaxTitleWidth( 0 ), mForeground( true ), mDragHighlightColor(p.drag_highlight_color()), - mDragShadowColor(p.drag_shadow_color()) + mDragShadowColor(p.drag_shadow_color()), + mFont(p.font), + mLabelVPad(p.label_vpad()) { static LLUICachedControl<S32> snap_margin ("SnapMargin", 0); @@ -98,14 +100,13 @@ void LLDragHandleTop::setTitle(const std::string& title) } else { - const LLFontGL* font = LLFontGL::getFontSansSerif(); LLTextBox::Params params; params.name("Drag Handle Title"); params.rect(getRect()); params.initial_value(trimmed_title); - params.font(font); + params.font(mFont); params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); - params.font_shadow(LLFontGL::DROP_SHADOW_SOFT); + params.font_shadow(LLFontGL::NO_SHADOW); params.use_ellipses = true; params.parse_urls = false; //cancel URL replacement in floater title mTitleBox = LLUICtrlFactory::create<LLTextBox> (params); @@ -236,7 +237,6 @@ void LLDragHandleLeft::draw() void LLDragHandleTop::reshapeTitleBox() { - static LLUICachedControl<S32> title_vpad("UIFloaterTitleVPad", 0); if( ! mTitleBox) { return; @@ -248,7 +248,7 @@ void LLDragHandleTop::reshapeTitleBox() LLRect title_rect; title_rect.setLeftTopAndSize( LEFT_PAD, - getRect().getHeight() - title_vpad, + getRect().getHeight() - mLabelVPad, title_width, title_height); diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 73211d5292..f768839749 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -43,13 +43,17 @@ public: : public LLInitParam::Block<Params, LLView::Params> { Optional<std::string> label; + Optional<S32> label_vpad; Optional<LLUIColor> drag_highlight_color; Optional<LLUIColor> drag_shadow_color; + Optional<const LLFontGL*> font; Params() : label("label"), + label_vpad("label_vpad", 7), drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), - drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) + drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")), + font("font", LLFontGL::getFontSansSerif()) { changeDefault(mouse_opaque, true); changeDefault(follows.flags, FOLLOWS_ALL); @@ -82,6 +86,8 @@ protected: protected: LLTextBox* mTitleBox; + const LLFontGL* mFont; + S32 mLabelVPad; private: LLRect mButtonsRect; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 52a5e3dbd6..9361358ced 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -183,8 +183,10 @@ LLFloater::Params::Params() show_title("show_title", true), auto_close("auto_close", false), positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), + header_font("header_font", LLFontGL::getFontSansSerif()), header_height("header_height", 0), legacy_header_height("legacy_header_height", 0), + header_vpad("header_vpad", 7), close_image("close_image"), restore_image("restore_image"), minimize_image("minimize_image"), @@ -239,7 +241,7 @@ void LLFloater::initClass() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), // intentionally do not pass params here, see initFromParams @@ -293,7 +295,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool)); memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*)); - addDragHandle(); + addDragHandle(p); addResizeCtrls(); initFromParams(p); @@ -336,7 +338,7 @@ void LLFloater::initFloater(const Params& p) } } -void LLFloater::addDragHandle() +void LLFloater::addDragHandle(const LLFloater::Params& floater_params) { if (!mDragHandle) { @@ -346,6 +348,8 @@ void LLFloater::addDragHandle() p.name("drag"); p.follows.flags(FOLLOWS_ALL); p.label(mTitle); + p.font(floater_params.header_font); + p.label_vpad(floater_params.header_vpad); mDragHandle = LLUICtrlFactory::create<LLDragHandleLeft>(p); } else // drag on top @@ -354,6 +358,8 @@ void LLFloater::addDragHandle() p.name("Drag Handle"); p.follows.flags(FOLLOWS_ALL); p.label(mTitle); + p.font(floater_params.header_font); + p.label_vpad(floater_params.header_vpad); mDragHandle = LLUICtrlFactory::create<LLDragHandleTop>(p); } addChild(mDragHandle); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 9e1594bdd2..bda2531b43 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -172,8 +172,10 @@ public: Optional<LLFloaterEnums::EOpenPositioning> positioning; + Optional<const LLFontGL*> header_font; Optional<S32> header_height, - legacy_header_height; // HACK see initFromXML() + legacy_header_height, // HACK see initFromXML() + header_vpad; Optional<F32> rel_x, rel_y; @@ -442,7 +444,7 @@ private: bool offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index); void addResizeCtrls(); void layoutResizeCtrls(); - void addDragHandle(); + void addDragHandle(const LLFloater::Params& p); void layoutDragHandle(); // repair layout static void updateActiveFloaterTransparency(); diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index a818e72f59..c18495ce71 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -40,9 +40,9 @@ LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList; LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap; LLFloaterReg::build_map_t LLFloaterReg::sBuildMap; -std::map<std::string, std::string, std::less<>> LLFloaterReg::sGroupMap; +LLFloaterReg::group_map_t LLFloaterReg::sGroupMap; bool LLFloaterReg::sBlockShowFloaters = false; -std::set<std::string, std::less<>> LLFloaterReg::sAlwaysShowableList; +LLFloaterReg::always_showable_t LLFloaterReg::sAlwaysShowableList; static LLFloaterRegListener sFloaterRegListener; @@ -96,11 +96,8 @@ LLFloater* LLFloaterReg::getLastFloaterCascading() candidate_rect.mTop = 100000; LLFloater* candidate_floater = NULL; - std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end(); - for( ; it != it_end; ++it) + for (const auto& [floater_name, group_name] : sGroupMap) { - const std::string& group_name = it->second; - instance_list_t& instances = sInstanceMap[group_name]; for (LLFloater* inst : instances) @@ -604,17 +601,11 @@ U32 LLFloaterReg::getVisibleFloaterInstanceCount() { U32 count = 0; - std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end(); - for( ; it != it_end; ++it) + for (const auto& [floater_name, group_name] : sGroupMap) { - const std::string& group_name = it->second; - instance_list_t& instances = sInstanceMap[group_name]; - - for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter) + for (LLFloater* inst : instances) { - LLFloater* inst = *iter; - if (inst->getVisible() && !inst->isMinimized()) { count++; diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index 24d1476dda..71a11b6f42 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -29,9 +29,11 @@ /// llcommon #include "llrect.h" #include "llsd.h" +#include "llstl.h" #include <functional> #include <list> +#include <unordered_set> //******************************************************* // @@ -51,26 +53,29 @@ public: // 2) We can change the key of a floater without altering the list. typedef std::list<LLFloater*> instance_list_t; typedef const instance_list_t const_instance_list_t; - typedef std::map<std::string, instance_list_t, std::less<>> instance_map_t; + typedef std::unordered_map<std::string, instance_list_t, ll::string_hash, std::equal_to<>> instance_map_t; struct BuildData { LLFloaterBuildFunc mFunc; std::string mFile; }; - typedef std::map<std::string, BuildData, std::less<>> build_map_t; + typedef std::unordered_map<std::string, BuildData, ll::string_hash, std::equal_to<>> build_map_t; private: friend class LLFloaterRegListener; static instance_list_t sNullInstanceList; static instance_map_t sInstanceMap; static build_map_t sBuildMap; - static std::map<std::string, std::string, std::less<>> sGroupMap; + + using group_map_t = std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>>; + static group_map_t sGroupMap; static bool sBlockShowFloaters; /** * Defines list of floater names that can be shown despite state of sBlockShowFloaters. */ - static std::set<std::string, std::less<>> sAlwaysShowableList; + using always_showable_t = std::unordered_set<std::string, ll::string_hash, std::equal_to<>>; + static always_showable_t sAlwaysShowableList; public: // Registration diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 7544a44478..ce0e8036e7 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -464,6 +464,11 @@ F32 LLFocusMgr::getFocusFlashAmt() const return clamp_rescale(mFocusFlashTimer.getElapsedTimeF32(), 0.f, FOCUS_FADE_TIME, 1.f, 0.f); } +S32 LLFocusMgr::getFocusFlashWidth() const +{ + return ll_round(lerp(1.f, 2.f, getFocusFlashAmt())); +} + LLColor4 LLFocusMgr::getFocusColor() const { static LLUIColor focus_color_cached = LLUIColorTable::instance().getColor("FocusColor"); diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 89fee5c9f1..2e2293196b 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -101,7 +101,7 @@ public: void setKeystrokesOnly(bool keystrokes_only) { mKeystrokesOnly = keystrokes_only; } F32 getFocusFlashAmt() const; - S32 getFocusFlashWidth() const { return ll_round(lerp(1.f, 3.f, getFocusFlashAmt())); } + S32 getFocusFlashWidth() const; LLColor4 getFocusColor() const; void triggerFocusFlash(); bool getAppHasFocus() const { return mAppHasFocus; } diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 878f1cb856..fcc1964bd6 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -28,6 +28,7 @@ #include "llflashtimer.h" #include "linden_common.h" +#include "llapp.h" #include "llfolderviewitem.h" #include "llfolderview.h" #include "llfolderviewmodel.h" @@ -158,9 +159,11 @@ LLFolderViewItem::Params::Params() icon_width("icon_width", 0), text_pad("text_pad", 0), text_pad_right("text_pad_right", 0), + text_pad_top("text_pad_top", 1), single_folder_mode("single_folder_mode", false), double_click_override("double_click_override", false), arrow_size("arrow_size", 0), + arrow_pad_top("arrow_pad_top", 1), max_folder_item_overlap("max_folder_item_overlap", 0) { } @@ -200,7 +203,9 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mIconWidth(p.icon_width), mTextPad(p.text_pad), mTextPadRight(p.text_pad_right), + mTextPadTop(p.text_pad_top), mArrowSize(p.arrow_size), + mArrowPadTop(p.arrow_pad_top), mSingleFolderMode(p.single_folder_mode), mMaxFolderItemOverlap(p.max_folder_item_overlap), mDoubleClickOverride(p.double_click_override) @@ -810,7 +815,7 @@ void LLFolderViewItem::drawOpenFolderArrow() if (hasVisibleChildren() || !isFolderComplete()) { gl_draw_scaled_rotated_image( - mIndentation, getRect().getHeight() - mArrowSize - mTextPad - sTopPad, + mIndentation, getRect().getHeight() - mArrowSize - mArrowPadTop - sTopPad, mArrowSize, mArrowSize, mControlLabelRotation, sFolderArrowImg->getImage(), sFgColor); } } @@ -1044,7 +1049,7 @@ void LLFolderViewItem::draw() S32 filter_string_length = mViewModelItem->hasFilterStringMatch() ? (S32)mViewModelItem->getFilterStringSize() : 0; F32 right_x = 0; - F32 y = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; + F32 y = (F32)rect_height - line_height - (F32)mTextPadTop - (F32)sTopPad; F32 text_left = (F32)getLabelXPos(); LLWString combined_string = mLabel + mLabelSuffix; @@ -1123,7 +1128,7 @@ void LLFolderViewItem::draw() 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)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; + F32 yy = (F32)rect_height - line_height - (F32)mTextPadTop - (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); @@ -1134,7 +1139,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)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; + F32 yy = (F32)rect_height - line_height - (F32)mTextPadTop - (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); @@ -1145,7 +1150,7 @@ void LLFolderViewItem::draw() { 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())) + 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; + F32 yy = (F32)rect_height - sSuffixFont->getLineHeight() - (F32)mTextPadTop - (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); @@ -1884,6 +1889,11 @@ void LLFolderViewFolder::updateHasFavorites(bool new_childs_value) void LLFolderViewFolder::onIdleUpdateFavorites(void* data) { LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data); + if (gDisconnected || !self) + { + return; + } + if (self->mFavoritesDirtyFlags == FAVORITE_CLEANUP) { // parent or child already processed the update, clean the callback @@ -2359,9 +2369,10 @@ bool LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) { // navigating is going to destroy views and change children // delay it untill handleDoubleClick processing is complete - doOnIdleOneTime([this]() - { - getViewModelItem()->navigateToFolder(false); + LLPointer<LLFolderViewModelItem> view_model_item = getViewModelItem(); + doOnIdleOneTime([view_model_item]() mutable + {; + view_model_item->navigateToFolder(false); }); } return true; diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 23d794bf26..258a806b91 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -73,7 +73,9 @@ public: icon_width, text_pad, text_pad_right, + text_pad_top, arrow_size, + arrow_pad_top, max_folder_item_overlap; Optional<bool> single_folder_mode, double_click_override; @@ -117,7 +119,9 @@ protected: mIconWidth, mTextPad, mTextPadRight, + mTextPadTop, mArrowSize, + mArrowPadTop, mMaxFolderItemOverlap; F32 mControlLabelRotation; diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index 953963b683..40a3e439a6 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -29,8 +29,9 @@ #define LL_LLFUNCTORREGISTRY_H #include <string> -#include <map> +#include <unordered_map> +#include "llstring.h" #include "llsd.h" #include "llsingleton.h" @@ -56,7 +57,7 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> > public: typedef FUNCTOR_TYPE ResponseFunctor; - typedef typename std::map<std::string, FUNCTOR_TYPE> FunctorMap; + typedef typename std::unordered_map<std::string, FUNCTOR_TYPE, ll::string_hash, std::equal_to<>> FunctorMap; bool registerFunctor(const std::string& name, ResponseFunctor f) { diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index 5892238593..53b5435324 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -194,7 +194,7 @@ protected: token_list_t mLineTokenList; token_list_t mDelimiterTokenList; - typedef std::map<std::string, std::string, std::less<>> element_attributes_t; + typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> element_attributes_t; typedef element_attributes_t::const_iterator attribute_iterator_t; element_attributes_t mAttributes; std::string getAttribute(std::string_view key); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index fe0591ce4b..1dc80671cc 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -48,17 +48,21 @@ static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layo LLLayoutPanel::Params::Params() : expanded_min_dim("expanded_min_dim", 0), min_dim("min_dim", -1), + max_dim("max_dim", -1), user_resize("user_resize", false), auto_resize("auto_resize", true) { addSynonym(min_dim, "min_width"); addSynonym(min_dim, "min_height"); + addSynonym(max_dim, "max_width"); + addSynonym(max_dim, "max_height"); } LLLayoutPanel::LLLayoutPanel(const Params& p) : LLPanel(p), mExpandedMinDim(p.expanded_min_dim.isProvided() ? p.expanded_min_dim : p.min_dim), mMinDim(p.min_dim), + mMaxDim(p.max_dim), mAutoResize(p.auto_resize), mUserResize(p.user_resize), mCollapsed(false), @@ -75,6 +79,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) { mVisibleAmt = 0.f; } + setMaxDim(mMaxDim); } void LLLayoutPanel::initFromParams(const Params& p) @@ -113,6 +118,8 @@ S32 LLLayoutPanel::getTargetDim() const void LLLayoutPanel::setTargetDim(S32 value) { + value = llmin(value, mMaxDim); + LLRect new_rect(getRect()); if (mOrientation == LLLayoutStack::HORIZONTAL) { @@ -145,6 +152,7 @@ void LLLayoutPanel::setOrientation( LLView::EOrientation orientation ) setMinDim(layout_dim); } mTargetDim = llmax(layout_dim, getMinDim()); + mTargetDim = llmin(mTargetDim, mMaxDim); } void LLLayoutPanel::setVisible( bool visible ) @@ -167,6 +175,7 @@ void LLLayoutPanel::reshape( S32 width, S32 height, bool called_from_parent /*= if (!mIgnoreReshape && !mAutoResize) { mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; + mTargetDim = llmin(mTargetDim, mMaxDim); LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent()); if (stackp) { @@ -439,6 +448,7 @@ void LLLayoutStack::updateLayout() F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute); panelp->mTargetDim += delta; + panelp->mTargetDim = llmin(panelp->mTargetDim, panelp->mMaxDim); remaining_space -= delta; } } @@ -455,6 +465,7 @@ void LLLayoutStack::updateLayout() { S32 space_for_panel = remaining_space > 0 ? 1 : -1; panelp->mTargetDim += space_for_panel; + panelp->mTargetDim = llmin(panelp->mTargetDim, panelp->mMaxDim); remaining_space -= space_for_panel; } } diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 9e3536aaff..4c78c8a289 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -140,7 +140,8 @@ public: struct Params : public LLInitParam::Block<Params, LLPanel::Params> { Optional<S32> expanded_min_dim, - min_dim; + min_dim, + max_dim; Optional<bool> user_resize, auto_resize; @@ -164,6 +165,8 @@ public: S32 getMinDim() const { return llmax(0, mMinDim); } void setMinDim(S32 value) { mMinDim = value; } + void setMaxDim(S32 value) { mMaxDim = value < 0 ? S32_MAX : value; } + S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : getMinDim(); } void setExpandedMinDim(S32 value) { mExpandedMinDim = value; } @@ -198,6 +201,7 @@ protected: S32 mExpandedMinDim; S32 mMinDim; + S32 mMaxDim; bool mCollapsed; F32 mVisibleAmt; F32 mCollapseAmt; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index b534c8d4e8..9a88083a5d 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -97,6 +97,7 @@ LLLineEditor::Params::Params() ignore_tab("ignore_tab", true), is_password("is_password", false), allow_emoji("allow_emoji", true), + draw_focus_border("draw_focus_border", true), cursor_color("cursor_color"), use_bg_color("use_bg_color", false), bg_color("bg_color"), @@ -122,6 +123,7 @@ LLLineEditor::Params::Params() LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) : LLUICtrl(p), + mDefaultText(p.default_text), mMaxLengthBytes(p.max_length.bytes), mMaxLengthChars(p.max_length.chars), mCursorPos( 0 ), @@ -146,6 +148,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mIgnoreTab( p.ignore_tab ), mDrawAsterixes( p.is_password ), mAllowEmoji( p.allow_emoji ), + mDrawFocusBorder(p.draw_focus_border), mSpellCheck( p.spellcheck ), mSpellCheckStart(-1), mSpellCheckEnd(-1), @@ -1794,7 +1797,7 @@ void LLLineEditor::drawBackground() if (!image) return; // optionally draw programmatic border - if (has_focus) + if (has_focus && mDrawFocusBorder) { LLColor4 tmp_color = gFocusMgr.getFocusColor(); tmp_color.setAlpha(alpha); @@ -1954,12 +1957,11 @@ void LLLineEditor::draw() width = llmin(width, mTextRightEdge - ll_round(rendered_pixels_right)); 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 += mFontBufferSelection.render( mGLFont, mText, mScrollHPos + rendered_text, rendered_pixels_right, text_bottom, - tmp_color, + LLColor4::black, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 3f762822ee..fd248edda3 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -95,7 +95,8 @@ public: show_label_focused, is_password, allow_emoji, - use_bg_color; + use_bg_color, + draw_focus_border; // colors Optional<LLUIColor> cursor_color, @@ -202,6 +203,7 @@ public: void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; } const std::string& getLabel() { return mLabel.getString(); } + void setDefaultText() { setText(mDefaultText); } void setText(const LLStringExplicit &new_text); const std::string& getText() const override { return mText.getString(); } @@ -347,6 +349,7 @@ protected: LLFontVertexBuffer mFontBufferSelection; LLFontVertexBuffer mFontBufferPostSelection; LLFontVertexBuffer mFontBufferLabel; + std::string mDefaultText; 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. @@ -409,6 +412,7 @@ protected: bool mAllowEmoji; bool mUseBgColor; + bool mDrawFocusBorder; LLWString mPreeditWString; LLWString mPreeditOverwrittenWString; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 6ba31c251e..3b21ed8f47 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -73,7 +73,7 @@ S32 MENU_BAR_WIDTH = 410; /// Local function declarations, constants, enums, and typedefs ///============================================================================ -const S32 LABEL_BOTTOM_PAD_PIXELS = 2; +const S32 LABEL_BOTTOM_PAD_PIXELS = 1; const U32 LEFT_PAD_PIXELS = 3; const U32 LEFT_WIDTH_PIXELS = 15; @@ -519,21 +519,25 @@ void LLMenuItemGL::draw( void ) } else { + // Munus are all of the same size, so fixed offset works here, + // but it won't work if somebody decides to use different font + // todo: adjust logic to work of rect and font height + F32 y = (F32)MENU_ITEM_PADDING / 2.f; if( !mDrawBoolLabel.empty() ) { - mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color, + mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, false ); } - mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color, + mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, false ); if( !mDrawAccelLabel.empty() ) { - mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color, + mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, y, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, false ); } if( !mDrawBranchLabel.empty() ) { - mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color, + mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, y, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, false ); } } @@ -1638,6 +1642,9 @@ void LLMenuItemBranchDownGL::draw( void ) { color = mDisabledColor.get(); } + // Munus are all of the same size, so fixed offset works here, + // but it won't work if somebody decides to use different font + // todo: adjust logic to work of rect and font height getFont()->render( mLabel.getWString(), 0, (F32)getRect().getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color, LLFontGL::HCENTER, LLFontGL::BOTTOM, LLFontGL::NORMAL); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 0ffe6cff5e..56475a2d8d 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1424,6 +1424,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN // this function is called once at construction time, after the object is constructed. void LLNotifications::initSingleton() { + LL_PROFILE_ZONE_SCOPED; loadTemplates(); loadVisibilityRules(); createDefaultChannels(); @@ -1436,6 +1437,8 @@ void LLNotifications::cleanupSingleton() void LLNotifications::createDefaultChannels() { + LL_PROFILE_ZONE_SCOPED; + LL_INFOS("Notifications") << "Generating default notification channels" << LL_ENDL; // now construct the various channels AFTER loading the notifications, // because the history channel is going to rewrite the stored notifications file @@ -1578,6 +1581,8 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path bool LLNotifications::loadTemplates() { + LL_PROFILE_ZONE_SCOPED; + LL_INFOS("Notifications") << "Reading notifications template" << LL_ENDL; // Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it // output all relevant pathnames instead of just the ones from the most @@ -1663,6 +1668,8 @@ bool LLNotifications::loadTemplates() bool LLNotifications::loadVisibilityRules() { + LL_PROFILE_ZONE_SCOPED; + const std::string xml_filename = "notification_visibility.xml"; // Note that here we're looking for the "en" version, the default // language, rather than the most localized version of this file. diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index d56c459560..ea1cb7f638 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -93,6 +93,7 @@ #include "llinitparam.h" #include "llinstancetracker.h" #include "llmortician.h" +#include "llmutex.h" #include "llnotificationptr.h" #include "llpointer.h" #include "llrefcount.h" @@ -945,7 +946,7 @@ public: typedef std::vector<std::string> TemplateNames; TemplateNames getTemplateNames() const; // returns a list of notification names - typedef std::map<std::string, LLNotificationTemplatePtr, std::less<>> TemplateMap; + typedef std::unordered_map<std::string, LLNotificationTemplatePtr, ll::string_hash, std::equal_to<>> TemplateMap; TemplateMap::const_iterator templatesBegin() { return mTemplates.begin(); } TemplateMap::const_iterator templatesEnd() { return mTemplates.end(); } @@ -991,7 +992,7 @@ private: LLNotificationMap mUniqueNotifications; - typedef std::map<std::string, std::string, std::less<>> GlobalStringMap; + typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> GlobalStringMap; GlobalStringMap mGlobalStrings; bool mIgnoreAllNotifications; diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index fe861dc719..a928997c7d 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -250,7 +250,7 @@ private: LLButton* mDefaultBtn; LLUIString mLabel; - typedef std::map<std::string, std::string, std::less<>> ui_string_map_t; + typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> ui_string_map_t; ui_string_map_t mUIStrings; @@ -292,7 +292,7 @@ public: } private: - typedef std::map< std::string, LLPanelClassCreatorFunc, std::less<>> param_name_map_t; + typedef std::unordered_map<std::string, LLPanelClassCreatorFunc, ll::string_hash, std::equal_to<>> param_name_map_t; param_name_map_t mPanelClassesNames; }; diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 2aff434612..1dbd9f5b0c 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -67,7 +67,7 @@ protected: LLSD mPayload; // stores data that this item represents in the radio group }; -static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); +static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams), "radio_item"); LLRadioGroup::Params::Params() : allow_deselect("allow_deselect"), diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 1b4008cff2..5b0d2315c1 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -94,7 +94,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam: block.inspectBlock(*this); // add includes for all possible children - const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const std::type_index& type = *LLWidgetTypeRegistry::instance().getValue(type_name); const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add include declarations for all valid children diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index a4510d1fc2..b5ba466750 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -39,7 +39,7 @@ const S32 MIN_COLUMN_WIDTH = 20; // defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params), "scroll_column_header"); //--------------------------------------------------------------------------- // LLScrollColumnHeader diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index b459c67dad..558ce6a7fd 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3185,6 +3185,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS if (cell_p.width.isProvided()) { new_column.width.pixel_width = cell_p.width; + new_column.width.pixel_width.choose(); } addColumn(new_column); columnp = mColumns[column]; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 5e0985c79c..27f1dcb03d 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -483,7 +483,7 @@ void LLTabContainer::draw() tuple->mButton->setVisible( true ); } - S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos(); + S32 max_scroll_visible = getVisibleTabCount() - getMaxScrollPos() + getScrollPos(); S32 idx = 0; for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { @@ -1380,6 +1380,20 @@ S32 LLTabContainer::getTabCount() const return static_cast<S32>(mTabList.size()); } +S32 LLTabContainer::getVisibleTabCount() const +{ + S32 visible_count = 0; + for (tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr) + { + const LLTabTuple* pTT = *itr; + if (pTT->mVisible) + { + visible_count++; + } + } + return visible_count; +} + LLPanel* LLTabContainer::getPanelByIndex(S32 index) const { if (index >= 0 && index < (S32)mTabList.size()) @@ -2109,6 +2123,14 @@ void LLTabContainer::updateMaxScrollPos() S32 tab_space = 0; S32 available_space = 0; tab_space = mTotalTabWidth; + for(tuple_list_t::const_iterator tab_it = mTabList.begin(); tab_it != mTabList.end(); ++tab_it) + { + const LLTabTuple* tuple = *tab_it; + if (!tuple->mVisible) + { + tab_space -= tuple->mButton->getRect().getWidth(); + } + } available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_tab_h_pad); if( tab_space > available_space ) @@ -2118,7 +2140,7 @@ void LLTabContainer::updateMaxScrollPos() available_width_with_arrows -= tabcntr_tab_partial_width; S32 running_tab_width = 0; - setMaxScrollPos(getTabCount()); + setMaxScrollPos(getVisibleTabCount()); for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it) { running_tab_width += (*tab_it)->mButton->getRect().getWidth(); @@ -2129,7 +2151,7 @@ void LLTabContainer::updateMaxScrollPos() setMaxScrollPos(getMaxScrollPos()-1); } // in case last tab doesn't actually fit on screen, make it the last scrolling position - setMaxScrollPos(llmin(getMaxScrollPos(), getTabCount() - 1)); + setMaxScrollPos(llmin(getMaxScrollPos(), getVisibleTabCount() - 1)); no_scroll = false; } } @@ -2202,3 +2224,16 @@ void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) updateMaxScrollPos(); } + +bool LLTabContainer::getTabVisibility(const LLPanel* panel) const +{ + for (tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr) + { + LLTabTuple const* pTT = *itr; + if (pTT->mTabPanel == panel) + { + return pTT->mVisible; + } + } + return false; +} diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 4ac7e73d25..3095e641f8 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -188,6 +188,7 @@ public: LLPanel* getCurrentPanel(); S32 getCurrentPanelIndex() const; S32 getTabCount() const; + S32 getVisibleTabCount() const; LLPanel* getPanelByIndex(S32 index) const; S32 getIndexForPanel(LLPanel* panel) const; S32 getPanelIndexByTitle(std::string_view title) const; @@ -225,6 +226,7 @@ public: S32 getMaxTabWidth() const { return mMaxTabWidth; } void setTabVisibility( LLPanel const *aPanel, bool ); + bool getTabVisibility(const LLPanel* panel) const; void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 2079ff17fc..5882c1edbb 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -51,6 +51,9 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds const S32 CURSOR_THICKNESS = 2; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. +constexpr F32 FOCUSED_SELECTION_BG_ALPHA = 1; +constexpr F32 UNFOCUSED_SELECTION_BG_ALPHA = 0.7f; + LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) : mDocIndexStart(index_start), mDocIndexEnd(index_end), @@ -129,7 +132,7 @@ struct LLTextBase::line_end_compare // // register LLTextBase::Params under name "textbase" -static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params), "textbase"); LLTextBase::LineSpacingParams::LineSpacingParams() : multiple("multiple", 1.f), @@ -529,7 +532,7 @@ void LLTextBase::drawSelectionBackground() // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mSelectedBGColor; - F32 alpha = hasFocus() ? 0.7f : 0.3f; + F32 alpha = hasFocus() ? FOCUSED_SELECTION_BG_ALPHA : UNFOCUSED_SELECTION_BG_ALPHA; alpha *= getDrawContext().mAlpha; LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3ab5e905e3..35477bdea9 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -408,6 +408,7 @@ public: /*virtual*/ void setColor(const LLUIColor& c) override; virtual void setReadOnlyColor(const LLUIColor& c); /*virtual*/ void onVisibilityChange(bool new_visibility) override; + void setBgReadOnlyColor(const LLUIColor& c) { mReadOnlyBgColor = c; } /*virtual*/ void setValue(const LLSD& value) override; /*virtual*/ LLTextViewModel* getViewModel() const override; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index fcdf3782ae..7689b93374 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -581,7 +581,7 @@ S32 LLTextEditor::indentLine( S32 pos, S32 spaces ) LLWString wtext = getWText(); if (wtext[pos] == ' ') { - delta_spaces += remove( pos, 1, false ); + delta_spaces -= remove( pos, 1, false ); } } } diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 74f03618cf..c5b1b5ba1d 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params), "inspector"); // // LLToolTip diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h index c5d01e6f8d..4dba4c5c3e 100644 --- a/indra/llui/lltrans.h +++ b/indra/llui/lltrans.h @@ -125,7 +125,7 @@ public: } private: - typedef std::map<std::string, LLTransTemplate, std::less<>> template_map_t; + typedef std::unordered_map<std::string, LLTransTemplate, ll::string_hash, std::equal_to<>> template_map_t; static template_map_t sStringTemplates; static template_map_t sDefaultStringTemplates; static LLStringUtil::format_map_t sDefaultArgs; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 38d5720556..0056e73cce 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -65,7 +65,6 @@ // for XUIParse #include "llquaternion.h" -#include <boost/tokenizer.hpp> #include <boost/algorithm/string/find_iterator.hpp> #include <boost/algorithm/string/finder.hpp> @@ -157,6 +156,7 @@ mWindow(NULL), // set later in startup mRootView(NULL), mHelpImpl(NULL) { + LL_PROFILE_ZONE_SCOPED; LLRender2D::createInstance(image_provider); LLSpellChecker::createInstance(); diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 2ef64baaf6..091e0ab1cf 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -114,7 +114,7 @@ class LLUI : public LLSimpleton<LLUI> { LOG_CLASS(LLUI); public: - typedef std::map<std::string, LLControlGroup*, std::less<> > settings_map_t; + typedef std::unordered_map<std::string, LLControlGroup*, ll::string_hash, std::equal_to<>> settings_map_t; LLUI(const settings_map_t &settings, LLImageProviderInterface* image_provider, diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index a792cb8103..7a4f72fe4f 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -198,8 +198,8 @@ LLUIColor LLUIColorTable::getColor(std::string_view name, const LLColor4& defaul // update user color, loaded colors are parsed on initialization void LLUIColorTable::setColor(std::string_view name, const LLColor4& color) { - auto it = mUserSetColors.lower_bound(name); - if(it != mUserSetColors.end() && !(mUserSetColors.key_comp()(name, it->first))) + auto it = mUserSetColors.find(name); + if(it != mUserSetColors.end()) { it->second = color; } @@ -330,9 +330,8 @@ void LLUIColorTable::clearTable(string_color_map_t& table) // if the color already exists it changes the color void LLUIColorTable::setColor(std::string_view name, const LLColor4& color, string_color_map_t& table) { - string_color_map_t::iterator it = table.lower_bound(name); - if(it != table.end() - && !(table.key_comp()(name, it->first))) + string_color_map_t::iterator it = table.find(name); + if(it != table.end()) { it->second = color; } diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 0c6286e5eb..aff6f59db6 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -27,7 +27,7 @@ #ifndef LL_LLUICOLORTABLE_H_ #define LL_LLUICOLORTABLE_H_ -#include <map> +#include <unordered_map> #include "llinitparam.h" #include "llsingleton.h" @@ -42,7 +42,7 @@ class LLUIColorTable : public LLSingleton<LLUIColorTable> LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster - typedef std::map<std::string, LLUIColor, std::less<>> string_color_map_t; + typedef std::unordered_map<std::string, LLUIColor, ll::string_hash, std::equal_to<>> string_color_map_t; public: struct ColorParams : LLInitParam::ChoiceBlock<ColorParams> diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 05461edd82..9a27049d37 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -80,7 +80,7 @@ LLUICtrl::Params::Params() mouseenter_callback("mouseenter_callback"), mouseleave_callback("mouseleave_callback"), control_name("control_name"), - font("font", LLFontGL::getFontEmojiMedium()), + font("font", LLFontGL::getFontEmojiSmall()), font_halign("halign"), font_valign("valign"), length("length"), // ignore LLXMLNode cruft diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 9abccfd9a0..33ffc3dfc6 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -253,7 +253,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() // adds a widget and its param block to various registries //static -void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name) +void LLUICtrlFactory::registerWidget(std::type_index widget_type, std::type_index param_block_type, const std::string& name) { // associate parameter block type with template .xml file std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type); diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index fc069c078f..f44b4ba4dc 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -65,7 +65,7 @@ class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> // lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> +: public LLRegistrySingleton<std::type_index, std::string, LLWidgetNameRegistry> { LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry); }; @@ -74,7 +74,7 @@ class LLWidgetNameRegistry // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry -//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry> +//: public LLRegistrySingleton<std::type_index, empty_param_block_func_t, LLDefaultParamBlockRegistry> //{ // LLSINGLETON(LLDefaultParamBlockRegistry); //}; @@ -202,7 +202,7 @@ private: static void copyName(LLXMLNodePtr src, LLXMLNodePtr dest); // helper function for adding widget type info to various registries - static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag); + static void registerWidget(std::type_index widget_type, std::type_index param_block_type, const std::string& tag); static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block); @@ -290,7 +290,7 @@ template <typename PARAM_BLOCK, int DUMMY> LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults() { // look up template file for this param block... - const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); + const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(typeid(PARAM_BLOCK)); if (param_block_tag) { // ...and if it exists, back fill values using the most specific template first PARAM_BLOCK params; @@ -314,12 +314,12 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator : LLChildRegistry<DERIVED>::StaticRegistrar(tag, func == nullptr ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func) { // add this widget to various registries - LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag); + LLUICtrlFactory::instance().registerWidget(typeid(T), typeid(typename T::Params), tag); // since registry_t depends on T, do this in line here // TODO: uncomment this for schema generation //typedef typename T::child_registry_t registry_t; - //LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance()); + //LLChildRegistryRegistry::instance().defaultRegistrar().add(typeid(T), registry_t::instance()); } #endif //LLUICTRLFACTORY_H diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index d53fd6eb91..68ca61681c 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -149,7 +149,7 @@ void LLViewBorder::drawOnePixelLines() top_color = gFocusMgr.getFocusColor(); bottom_color = top_color; - LLUI::setLineWidth(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt())); + LLUI::setLineWidth(lerp(1.f, 2.f, gFocusMgr.getFocusFlashAmt())); } S32 left = 0; diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 8fd85a89a1..71ce2afdbd 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -602,7 +602,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui"); // add includes for all possible children - const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const std::type_index& type = *LLWidgetTypeRegistry::instance().getValue(type_name); const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add choices for valid children @@ -1459,7 +1459,7 @@ void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int void LLSimpleXUIParser::characterData(const char *s, int len) { - mTextContents += std::string(s, len); + mTextContents.append(s, len); } void LLSimpleXUIParser::startElement(const char *name, const char **atts) @@ -1480,24 +1480,24 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts) mOutputStack.back().second++; S32 num_tokens_pushed = 0; - std::string child_name(name); + std::string_view child_name(name); if (mOutputStack.back().second == 1) { // root node for this block - mScope.push_back(child_name); + mScope.emplace_back(child_name); } else { // compound attribute if (child_name.find(".") == std::string::npos) { - mNameStack.push_back(std::make_pair(child_name, true)); + mNameStack.emplace_back(child_name, true); num_tokens_pushed++; - mScope.push_back(child_name); + mScope.emplace_back(child_name); } else { // parse out "dotted" name into individual tokens - tokenizer name_tokens(child_name, sep); + tokenizer name_tokens(std::string(child_name), sep); tokenizer::iterator name_token_it = name_tokens.begin(); if(name_token_it == name_tokens.end()) @@ -1603,8 +1603,8 @@ bool LLSimpleXUIParser::processText() LLStringUtil::trim(mTextContents); if (!mTextContents.empty()) { - mNameStack.push_back(std::make_pair(std::string("value"), true)); - mCurAttributeValueBegin = mTextContents.c_str(); + mNameStack.emplace_back("value", true); + mCurAttributeValueBegin = std::move(mTextContents); mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); mNameStack.pop_back(); } @@ -1648,12 +1648,12 @@ bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr) bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - if (!strcmp(self.mCurAttributeValueBegin, "true")) + if (!strcmp(self.mCurAttributeValueBegin.c_str(), "true")) { *((bool*)val_ptr) = true; return true; } - else if (!strcmp(self.mCurAttributeValueBegin, "false")) + else if (!strcmp(self.mCurAttributeValueBegin.c_str(), "false")) { *((bool*)val_ptr) = false; return true; @@ -1665,56 +1665,56 @@ bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr) bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - *((std::string*)val_ptr) = self.mCurAttributeValueBegin; + *((std::string*)val_ptr) = std::move(self.mCurAttributeValueBegin); return true; } bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U8*)val_ptr)]).full; } bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S8*)val_ptr)]).full; } bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U16*)val_ptr)]).full; } bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S16*)val_ptr)]).full; } bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U32*)val_ptr)]).full; } bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S32*)val_ptr)]).full; } bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(*(F32*)val_ptr)]).full; } bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr) { LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); - return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full; + return parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(*(F64*)val_ptr)]).full; } bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr) @@ -1722,7 +1722,7 @@ bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr) LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); LLColor4 value; - if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + if (parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) { *(LLColor4*)(val_ptr) = value; return true; @@ -1736,7 +1736,7 @@ bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr) LLColor4 value; LLUIColor* colorp = (LLUIColor*)val_ptr; - if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + if (parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) { colorp->set(value); return true; @@ -1749,7 +1749,7 @@ bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr) LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); LLUUID temp_id; // LLUUID::set is destructive, so use temporary value - if (temp_id.set(std::string(self.mCurAttributeValueBegin))) + if (temp_id.set(self.mCurAttributeValueBegin)) { *(LLUUID*)(val_ptr) = temp_id; return true; diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index 2179ae54d3..3cc564772e 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -40,7 +40,7 @@ class LLView; // lookup widget type by name class LLWidgetTypeRegistry -: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> +: public LLRegistrySingleton<std::string, std::type_index, LLWidgetTypeRegistry> { LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry); }; @@ -52,7 +52,7 @@ typedef std::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; class LLChildRegistryRegistry -: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> +: public LLRegistrySingleton<std::type_index, widget_registry_t, LLChildRegistryRegistry> { LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry); }; @@ -247,7 +247,7 @@ private: S32 mCurReadDepth; std::string mCurFileName; std::string mTextContents; - const char* mCurAttributeValueBegin; + std::string mCurAttributeValueBegin; std::vector<S32> mTokenSizeStack; std::vector<std::string> mScope; std::vector<bool> mEmptyLeafNode; |
