diff options
Diffstat (limited to 'indra/llui')
45 files changed, 408 insertions, 258 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 53720a6044..f8ef5289db 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -361,6 +361,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) { mStoredOpenCloseState = false; mWasStateStored = false; + mSkipChangesOnNotifyParent = false; mDropdownBGColor = LLColor4::white; LLAccordionCtrlTabHeader::Params headerParams; @@ -691,7 +692,7 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info) mExpandedHeight = height; - if(isExpanded()) + if(isExpanded() && !mSkipChangesOnNotifyParent) { LLRect panel_rect = getRect(); panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), height); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 7a78700e0f..0263bce4be 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -195,6 +195,8 @@ public: void setFitPanel( bool fit ) { mFitPanel = true; } bool getFitParent() const { return mFitPanel; } + void setIgnoreResizeNotification(bool ignore) { mSkipChangesOnNotifyParent = ignore;} + protected: void adjustContainerPanel (const LLRect& child_rect); void adjustContainerPanel (); @@ -235,6 +237,7 @@ private: bool mStoredOpenCloseState; bool mWasStateStored; + bool mSkipChangesOnNotifyParent; bool mSelectionEnabled; diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 58d80e2687..a668ac1ac6 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -48,10 +48,10 @@ class LLClipboard : public LLSingleton<LLClipboard> { -public: - LLClipboard(); + LLSINGLETON(LLClipboard); ~LLClipboard(); +public: // Clears the clipboard void reset(); // Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state) diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index f2f2145953..8cec5e2b24 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -173,6 +173,9 @@ private: class LLCommandManager : public LLSingleton<LLCommandManager> { + LLSINGLETON(LLCommandManager); + ~LLCommandManager(); + public: struct Params : public LLInitParam::Block<Params> { @@ -184,9 +187,6 @@ public: } }; - LLCommandManager(); - ~LLCommandManager(); - U32 commandCount() const; LLCommand * getCommand(U32 commandIndex); LLCommand * getCommand(const LLCommandId& commandId); diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index ac92b19977..99267d978a 100644 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -35,7 +35,9 @@ class LLScrollContainer; struct ContainerViewRegistry : public LLChildRegistry<ContainerViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ContainerViewRegistry); +}; class LLContainerView : public LLView { diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 299f5e42d4..5e00bf7f45 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -105,6 +105,81 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null* return true; } +bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= true*/) +{ + if (!mItemComparator) + { + LL_WARNS_ONCE() << "No comparator specified for inserting FlatListView items." << LL_ENDL; + return false; + } + if (panel_list.size() == 0) + { + return false; + } + + // presort list so that it will be easier to sort elements into mItemPairs + panel_list.sort(ComparatorAdaptor(*mItemComparator)); + + pairs_const_iterator_t new_pair_it = panel_list.begin(); + item_pair_t* new_pair = *new_pair_it; + pairs_iterator_t pair_it = mItemPairs.begin(); + item_pair_t* item_pair = *pair_it; + + // sort panel_list into mItemPars + while (new_pair_it != panel_list.end() && pair_it != mItemPairs.end()) + { + if (!new_pair->first || new_pair->first->getParent() == mItemsPanel) + { + // iterator already used or we are reusing existing panel + new_pair_it++; + new_pair = *new_pair_it; + } + else if (mItemComparator->compare(new_pair->first, item_pair->first)) + { + LLPanel* panel = new_pair->first; + + mItemPairs.insert(pair_it, new_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + else + { + pair_it++; + item_pair = *pair_it; + } + } + + // Add what is left of panel_list into the end of mItemPairs. + for (; new_pair_it != panel_list.end(); ++new_pair_it) + { + item_pair_t* item_pair = *new_pair_it; + LLPanel *panel = item_pair->first; + if (panel && panel->getParent() != mItemsPanel) + { + mItemPairs.push_back(item_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, item_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + } + + if (rearrange) + { + rearrangeItems(); + notifyParentItemsRectChanged(); + } + return true; +} + bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/) { @@ -1289,6 +1364,28 @@ void LLFlatListViewEx::setFilterSubString(const std::string& filter_str) } } +void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action) +{ + if (!item) return; + + // 0 signifies that filter is matched, + // i.e. we don't hide items that don't support 'match_filter' action, separators etc. + if (0 == item->notify(action)) + { + mHasMatchedItems = true; + item->setVisible(true); + } + else + { + // TODO: implement (re)storing of current selection. + if (!mForceShowingUnmatchedItems) + { + selectItem(item, false); + } + item->setVisible(mForceShowingUnmatchedItems); + } +} + void LLFlatListViewEx::filterItems() { typedef std::vector <LLPanel*> item_panel_list_t; @@ -1309,22 +1406,7 @@ void LLFlatListViewEx::filterItems() iter != iter_end; ++iter) { LLPanel* pItem = (*iter); - // 0 signifies that filter is matched, - // i.e. we don't hide items that don't support 'match_filter' action, separators etc. - if (0 == pItem->notify(action)) - { - mHasMatchedItems = true; - pItem->setVisible(true); - } - else - { - // TODO: implement (re)storing of current selection. - if(!mForceShowingUnmatchedItems) - { - selectItem(pItem, false); - } - pItem->setVisible(mForceShowingUnmatchedItems); - } + updateItemVisibility(pItem, action); } sort(); diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 92bf429031..230ea200d8 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -351,6 +351,8 @@ protected: virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange); + bool addItemPairs(pairs_list_t panel_list, bool rearrange = true); + /** * Notify parent about changed size of internal controls with "size_changes" action * @@ -480,6 +482,7 @@ public: * Sets up new filter string and filters the list. */ void setFilterSubString(const std::string& filter_str); + std::string getFilterSubString() { return mFilterSubString; } /** * Filters the list, rearranges and notifies parent about shape changes. @@ -503,6 +506,14 @@ protected: */ void updateNoItemsMessage(const std::string& filter_string); + /** + * Applies visibility acording to action and LLFlatListView settings. + * + * @param item - item we are changing + * @param item - action - parameters to determin visibility from + */ + void updateItemVisibility(LLPanel* item, const LLSD &action); + private: std::string mNoFilteredItemsMsg; std::string mNoItemsMsg; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 4f664a1ccc..3ece1c12bf 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -64,8 +64,6 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; -extern LLControlGroup gSavedSettings; - namespace LLInitParam { void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues() @@ -653,13 +651,7 @@ void LLFloater::openFloater(const LLSD& key) && !getFloaterHost() && (!getVisible() || isMinimized())) { - //Don't play a sound for incoming voice call based upon chat preference setting - bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE); - - if(playSound) - { - make_ui_sound("UISndWindowOpen"); - } + make_ui_sound("UISndWindowOpen"); } //RN: for now, we don't allow rehosting from one multifloater to another diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index f5364f4863..e43974bc52 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -53,14 +53,8 @@ template <typename FUNCTOR_TYPE> class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> > { - friend class LLSingleton<LLFunctorRegistry>; + LLSINGLETON(LLFunctorRegistry); LOG_CLASS(LLFunctorRegistry); -private: - LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") - { - mMap[LOGFUNCTOR] = log_functor; - mMap[DONOTHING] = do_nothing; - } public: typedef FUNCTOR_TYPE ResponseFunctor; @@ -125,6 +119,14 @@ private: }; template <typename FUNCTOR_TYPE> +LLFunctorRegistry<FUNCTOR_TYPE>::LLFunctorRegistry() : + LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") +{ + mMap[LOGFUNCTOR] = log_functor; + mMap[DONOTHING] = do_nothing; +} + +template <typename FUNCTOR_TYPE> class LLFunctorRegistration { public: diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index a245ebe1b9..f772dbc6b4 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -40,7 +40,9 @@ class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack> public: struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry> - {}; + { + LLSINGLETON_EMPTY_CTOR(LayoutStackRegistry); + }; struct Params : public LLInitParam::Block<Params, LLView::Params> { diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index c89e1dac1d..becb45fa79 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -163,6 +163,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) { llassert( mMaxLengthBytes > 0 ); + LLUICtrl::setEnabled(TRUE); + setEnabled(p.enabled); + mScrollTimer.reset(); mTripleClickTimer.reset(); setText(p.default_text()); @@ -218,6 +221,13 @@ LLLineEditor::~LLLineEditor() gFocusMgr.releaseFocusIfNeeded( this ); } +void LLLineEditor::initFromParams(const LLLineEditor::Params& params) +{ + LLUICtrl::initFromParams(params); + LLUICtrl::setEnabled(TRUE); + setEnabled(params.enabled); +} + void LLLineEditor::onFocusReceived() { gEditMenuHandler = this; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index ccbd305a16..88468503df 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -108,6 +108,9 @@ public: Params(); }; + + void initFromParams(const LLLineEditor::Params& params); + protected: LLLineEditor(const Params&); friend class LLUICtrlFactory; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 848367f8a8..8425774d46 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1736,6 +1736,7 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) mJumpKey(p.jump_key), mCreateJumpKeys(p.create_jump_keys), mNeedsArrange(FALSE), + mAlwaysShowMenu(FALSE), mResetScrollPositionOnShow(true), mShortcutPad(p.shortcut_pad) { @@ -3223,20 +3224,23 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->setVisible( TRUE ); - //Do not show menu if all menu items are disabled - BOOL item_enabled = false; - for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin(); - itor != menu->getChildList()->end(); - ++itor) + if(!menu->getAlwaysShowMenu()) { - LLView *menu_item = (*itor); - item_enabled = item_enabled || menu_item->getEnabled(); - } + //Do not show menu if all menu items are disabled + BOOL item_enabled = false; + for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin(); + itor != menu->getChildList()->end(); + ++itor) + { + LLView *menu_item = (*itor); + item_enabled = item_enabled || menu_item->getEnabled(); + } - if(!item_enabled) - { - menu->setVisible( FALSE ); - return; + if(!item_enabled) + { + menu->setVisible( FALSE ); + return; + } } // Save click point for detecting cursor moves before mouse-up. diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 628dedb906..69f7d21513 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -347,7 +347,9 @@ private: // child widget registry struct MenuRegistry : public LLChildRegistry<MenuRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(MenuRegistry); +}; class LLMenuGL @@ -529,6 +531,9 @@ public: void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; } bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; } + void setAlwaysShowMenu(BOOL show) { mAlwaysShowMenu = show; } + BOOL getAlwaysShowMenu() { return mAlwaysShowMenu; } + // add a context menu branch BOOL appendContextSubMenu(LLMenuGL *menu); @@ -570,6 +575,8 @@ private: static LLColor4 sDefaultBackgroundColor; static BOOL sKeyboardMode; + BOOL mAlwaysShowMenu; + LLUIColor mBackgroundColor; BOOL mBgVisible; LLHandle<LLView> mParentMenuItem; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 354add0b82..024332ee65 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -884,9 +884,9 @@ class LLNotifications : public LLSingleton<LLNotifications>, public LLNotificationChannelBase { + LLSINGLETON(LLNotifications); LOG_CLASS(LLNotifications); - friend class LLSingleton<LLNotifications>; public: // Needed to clear up RefCounted things prior to actual destruction @@ -966,8 +966,6 @@ public: bool isVisibleByRules(LLNotificationPtr pNotification); private: - // we're a singleton, so we don't have a public constructor - LLNotifications(); /*virtual*/ void initSingleton(); void loadPersistentNotifications(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c2185f24de..b8f47ef6ba 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -268,8 +268,9 @@ typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; class LLRegisterPanelClass : public LLSingleton< LLRegisterPanelClass > { + LLSINGLETON_EMPTY_CTOR(LLRegisterPanelClass); public: - // reigister with either the provided builder, or the generic templated builder + // register with either the provided builder, or the generic templated builder void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { mPanelClassesNames[tag] = func; diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 8cf72928ff..2c7e7ab13d 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -54,6 +54,7 @@ public: /*virtual*/ void setValue(const LLSD& value); /*virtual*/ BOOL postBuild(); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); LLSD getPayload() { return mPayload; } @@ -224,6 +225,22 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) return TRUE; } +void LLRadioGroup::focusSelectedRadioBtn() +{ + if (mSelectedIndex >= 0) + { + LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex]; + if (radio_item->hasTabStop() && radio_item->getEnabled()) + { + radio_item->focusFirstItem(FALSE, FALSE); + } + } + else if (mRadioButtons[0]->hasTabStop() || hasTabStop()) + { + focusFirstItem(FALSE, FALSE); + } +} + BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask) { BOOL handled = FALSE; @@ -283,19 +300,6 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask) return handled; } -BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask) -{ - // grab focus preemptively, before child button takes mousecapture - // - if (hasTabStop()) - { - focusFirstItem(FALSE, FALSE); - } - - return LLUICtrl::handleMouseDown(x, y, mask); -} - - // Handle one button being clicked. All child buttons must have this // function as their callback function. @@ -466,6 +470,29 @@ BOOL LLRadioCtrl::postBuild() return TRUE; } +BOOL LLRadioCtrl::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // Grab focus preemptively, before button takes mousecapture + if (hasTabStop() && getEnabled()) + { + focusFirstItem(FALSE, FALSE); + } + else + { + // Only currently selected item in group has tab stop as result it is + // unclear how focus should behave on click, just let the group handle + // focus and LLRadioGroup::onClickButton() will set correct state later + // if needed + LLRadioGroup* parent = (LLRadioGroup*)getParent(); + if (parent) + { + parent->focusSelectedRadioBtn(); + } + } + + return LLCheckBoxCtrl::handleMouseDown(x, y, mask); +} + LLRadioCtrl::~LLRadioCtrl() { } diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 8bd5698538..dcb2f43bfe 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -66,8 +66,6 @@ public: virtual BOOL postBuild(); - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleKeyHere(KEY key, MASK mask); void setIndexEnabled(S32 index, BOOL enabled); @@ -75,6 +73,8 @@ public: S32 getSelectedIndex() const { return mSelectedIndex; } // set the index value programatically BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); + // foxus child by index if it can get focus + void focusSelectedRadioBtn(); // Accept and retrieve strings of the radio group control names virtual void setValue(const LLSD& value ); diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h index a652dcd2c0..b19d8d40b8 100644 --- a/indra/llui/llresmgr.h +++ b/indra/llui/llresmgr.h @@ -42,9 +42,9 @@ enum LLLOCALE_ID class LLResMgr : public LLSingleton<LLResMgr> { -public: - LLResMgr(); + LLSINGLETON(LLResMgr); +public: void setLocale( LLLOCALE_ID locale_id ); LLLOCALE_ID getLocale() const { return mLocale; } diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index f64cf43a8e..c4c4d0a136 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -48,7 +48,9 @@ class LLUICtrlFactory; *****************************************************************************/ struct ScrollContainerRegistry : public LLChildRegistry<ScrollContainerRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ScrollContainerRegistry); +}; class LLScrollContainer : public LLUICtrl { diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index db8fdc46b7..1190c5bb94 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -648,7 +648,7 @@ bool LLScrollListCtrl::updateColumnWidths() S32 new_width = 0; if (column->mRelWidth >= 0) { - new_width = (S32)ll_round(column->mRelWidth*mItemListRect.getWidth()); + new_width = (S32)ll_round(column->mRelWidth * (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding)); } else if (column->mDynamicWidth) { @@ -2680,7 +2680,7 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params } if (new_column->mRelWidth >= 0) { - new_column->setWidth((S32)ll_round(new_column->mRelWidth*mItemListRect.getWidth())); + new_column->setWidth((S32)ll_round(new_column->mRelWidth * (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding))); } else if(new_column->mDynamicWidth) { diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp index 0db4281059..5a52600337 100644 --- a/indra/llui/llspellcheck.cpp +++ b/indra/llui/llspellcheck.cpp @@ -161,6 +161,7 @@ void LLSpellChecker::refreshDictionaryMap() } // Load user installed dictionary information + user_filename = user_path + DICT_FILE_USER; llifstream custom_file(user_filename.c_str(), std::ios::binary); if (custom_file.is_open()) { diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h index 4ab80195ea..acac589e43 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -29,16 +29,15 @@ #include "llsingleton.h" #include "llui.h" +#include "llinitdestroyclass.h" #include <boost/signals2.hpp> class Hunspell; class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker> { - friend class LLSingleton<LLSpellChecker>; + LLSINGLETON(LLSpellChecker); friend class LLInitClass<LLSpellChecker>; -protected: - LLSpellChecker(); ~LLSpellChecker(); public: diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 8b1ba406c8..d49e216898 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -153,7 +153,7 @@ F32 clamp_precision(F32 value, S32 decimal_precision) for (S32 i = 0; i < decimal_precision; i++) clamped_value *= 10.0; - clamped_value = ll_round((F32)clamped_value); + clamped_value = ll_round(clamped_value); for (S32 i = 0; i < decimal_precision; i++) clamped_value /= 10.0; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 35f5330a3f..6c8e63442b 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -40,6 +40,7 @@ #include "lltooltip.h" #include "lllocalcliprect.h" #include <iostream> +#include "lltrans.h" // rate at which to update display of value that is rapidly changing const F32 MEAN_VALUE_UPDATE_TIME = 1.f / 4.f; @@ -619,19 +620,19 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re std::string value_str = !llisnan(value) ? llformat("%10.*f %s", decimal_digits, value, label.c_str()) - : "n/a"; + : LLTrans::getString("na"); // Draw the current value. if (mOrientation == HORIZONTAL) { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } else { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } } diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index bc78d3b5fd..af4db7d7ea 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -35,7 +35,9 @@ class LLStatBar; // widget registrars struct StatViewRegistry : public LLChildRegistry<StatViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(StatViewRegistry); +}; class LLStatView : public LLContainerView { diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 701a06a085..1b2f09cff5 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -210,6 +210,7 @@ LLTabContainer::Params::Params() label_pad_left("label_pad_left"), tab_position("tab_position"), hide_tabs("hide_tabs", false), + hide_scroll_arrows("hide_scroll_arrows", false), tab_padding_right("tab_padding_right"), first_tab("first_tab"), middle_tab("middle_tab"), @@ -240,6 +241,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) mPrevArrowBtn(NULL), mNextArrowBtn(NULL), mIsVertical( p.tab_position == LEFT ), + mHideScrollArrows(p.hide_scroll_arrows), // Horizontal Specific mJumpPrevArrowBtn(NULL), mJumpNextArrowBtn(NULL), @@ -409,7 +411,7 @@ void LLTabContainer::draw() setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLSmoothInterpolation::getInterpolant(0.08f))); - BOOL has_scroll_arrows = !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0)); + BOOL has_scroll_arrows = !mHideScrollArrows && !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0)); if (!mIsVertical) { mJumpPrevArrowBtn->setVisible( has_scroll_arrows ); @@ -517,7 +519,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) { static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); + BOOL has_scroll_arrows = !mHideScrollArrows && (getMaxScrollPos() > 0) && !getTabsHidden(); if (has_scroll_arrows) { @@ -591,7 +593,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) { BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); + BOOL has_scroll_arrows = !mHideScrollArrows && (getMaxScrollPos() > 0) && !getTabsHidden(); if (has_scroll_arrows) { @@ -633,7 +635,7 @@ BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) { BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); + BOOL has_scroll_arrows = !mHideScrollArrows && (getMaxScrollPos() > 0) && !getTabsHidden(); S32 local_x = x - getRect().mLeft; S32 local_y = y - getRect().mBottom; @@ -701,7 +703,7 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask) { LLTabTuple* firsttuple = getTab(0); - BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + BOOL has_scroll_arrows = !mHideScrollArrows && (getMaxScrollPos() > 0); LLRect clip; if (mIsVertical) { @@ -826,7 +828,7 @@ BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask) // virtual BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, std::string &tooltip) { - BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + BOOL has_scroll_arrows = !mHideScrollArrows && (getMaxScrollPos() > 0); if(mOpenTabsOnDragAndDrop && !getTabsHidden()) { @@ -1543,7 +1545,7 @@ BOOL LLTabContainer::setTab(S32 which) is_visible = FALSE; } } - else if (getMaxScrollPos() > 0) + else if (!mHideScrollArrows && getMaxScrollPos() > 0) { if( i < getScrollPos() ) { diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 057809dc42..4a5f08f5d3 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -83,6 +83,7 @@ public: label_pad_left; Optional<bool> hide_tabs; + Optional<bool> hide_scroll_arrows; Optional<S32> tab_padding_right; Optional<TabParams> first_tab, @@ -262,6 +263,7 @@ private: S32 mCurrentTabIdx; BOOL mTabsHidden; + BOOL mHideScrollArrows; BOOL mScrolled; LLFrameTimer mScrollTimer; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 20be739286..88a5c3a587 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1522,6 +1522,7 @@ void LLTextBase::reflow() } S32 line_height = 0; + S32 seg_line_offset = line_count; while(seg_iter != mSegments.end()) { @@ -1534,7 +1535,8 @@ void LLTextBase::reflow() S32 character_count = segment->getNumChars(getWordWrap() ? llmax(0, remaining_pixels) : S32_MAX, seg_offset, cur_index - line_start_index, - S32_MAX); + S32_MAX, + line_count - seg_line_offset); S32 segment_width, segment_height; bool force_newline = segment->getDimensions(seg_offset, character_count, segment_width, segment_height); @@ -1597,6 +1599,7 @@ void LLTextBase::reflow() } ++seg_iter; seg_offset = 0; + seg_line_offset = force_newline ? line_count + 1 : line_count; } if (force_newline) { @@ -3065,7 +3068,7 @@ LLTextSegment::~LLTextSegment() bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; return false;} S32 LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; } -S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; } +S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { return 0; } void LLTextSegment::updateLayout(const LLTextBase& editor) {} F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; } bool LLTextSegment::canEdit() const { return false; } @@ -3335,7 +3338,7 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, round); } -S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { const LLWString &text = getWText(); @@ -3352,7 +3355,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin // if no character yet displayed on this line, don't require word wrapping since // we can just move to the next line, otherwise insist on it so we make forward progress - LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0) + LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0) ? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE : LLFontGL::ONLY_WORD_BOUNDARIES; @@ -3490,12 +3493,26 @@ LLInlineViewSegment::~LLInlineViewSegment() bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { - if (first_char == 0 && num_chars == 0) + if (first_char == 0 && num_chars == 0) { - // we didn't fit on a line, the widget will fall on the next line - // so dimensions here are 0 + // We didn't fit on a line or were forced to new string + // the widget will fall on the next line, so width here is 0 width = 0; - height = 0; + + 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(); + + return true; // new line + } + else + { + // height from previous segment in same string will be used, word-wrap + height = 0; + } + } else { @@ -3506,13 +3523,16 @@ bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt return false; } -S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { // if putting a widget anywhere but at the beginning of a line // and the widget doesn't fit or mForceNewLine is true // then return 0 chars for that line, and all characters for the next - if (line_offset != 0 - && (mForceNewLine || num_pixels < mView->getRect().getWidth())) + if (mForceNewLine && line_ind == 0) + { + return 0; + } + else if (line_offset != 0 && num_pixels < mView->getRect().getWidth()) { return 0; } @@ -3565,7 +3585,7 @@ bool LLLineBreakTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& w return true; } -S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { return 1; } @@ -3601,7 +3621,7 @@ bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width return false; } -S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { LLUIImagePtr image = mStyle->getImage(); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3d3a6ca869..c7b6203445 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -64,7 +64,19 @@ public: virtual bool getDimensions(S32 first_char, S32 num_chars, S32& 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) const; + + /** + * Get number of chars that fit into free part of current line. + * + * @param num_pixels - maximum width of rect + * @param segment_offset - symbol in segment we start processing line from + * @param line_offset - symbol in line after which segment starts + * @param max_chars - limit of symbols that will fit in current line + * @param line_ind - index of not word-wrapped string inside segment for multi-line segments. + * Two string separated by word-wrap will have same index. + * @return number of chars that will fit into current line + */ + 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; @@ -116,7 +128,7 @@ public: /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& 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) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool canEdit() const { return true; } /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); } @@ -201,7 +213,7 @@ public: LLInlineViewSegment(const Params& p, S32 start, S32 end); ~LLInlineViewSegment(); /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) 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 false; } @@ -225,7 +237,7 @@ public: LLLineBreakTextSegment(S32 pos); ~LLLineBreakTextSegment(); bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) 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); private: @@ -238,7 +250,7 @@ public: LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor); ~LLImageTextSegment(); bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) 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); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h index 400aeeb8be..3d71e40452 100644 --- a/indra/llui/lltextparser.h +++ b/indra/llui/lltextparser.h @@ -37,14 +37,14 @@ class LLColor4; class LLTextParser : public LLSingleton<LLTextParser> { + LLSINGLETON(LLTextParser); + public: typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType; typedef enum e_highlight_type { PART, ALL } EHighlightType; typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition; typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction; - LLTextParser(); - LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index fad127fc4c..0b1fbe5367 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -129,9 +129,10 @@ public: class LLToolTipMgr : public LLSingleton<LLToolTipMgr> { + LLSINGLETON(LLToolTipMgr); LOG_CLASS(LLToolTipMgr); + public: - LLToolTipMgr(); void show(const LLToolTip::Params& params); void show(const std::string& message); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index f790d8e005..770f13c1c3 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -60,6 +60,7 @@ #include "llflyoutbutton.h" #include "llsearcheditor.h" #include "lltoolbar.h" +#include "llcleanup.h" // for XUIParse #include "llquaternion.h" @@ -208,7 +209,7 @@ void LLUI::initClass(const settings_map_t& settings, void LLUI::cleanupClass() { - LLRender2D::cleanupClass(); + SUBSYSTEM_CLEANUP(LLRender2D); } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c727f75c4f..d7151dbee9 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -344,95 +344,6 @@ private: // Moved LLLocalClipRect to lllocalcliprect.h -class LLCallbackRegistry -{ -public: - typedef boost::signals2::signal<void()> callback_signal_t; - - void registerCallback(const callback_signal_t::slot_type& slot) - { - mCallbacks.connect(slot); - } - - void fireCallbacks() - { - mCallbacks(); - } - -private: - callback_signal_t mCallbacks; -}; - -class LLInitClassList : - public LLCallbackRegistry, - public LLSingleton<LLInitClassList> -{ - friend class LLSingleton<LLInitClassList>; -private: - LLInitClassList() {} -}; - -class LLDestroyClassList : - public LLCallbackRegistry, - public LLSingleton<LLDestroyClassList> -{ - friend class LLSingleton<LLDestroyClassList>; -private: - LLDestroyClassList() {} -}; - -template<typename T> -class LLRegisterWith -{ -public: - LLRegisterWith(boost::function<void ()> func) - { - T::instance().registerCallback(func); - } - - // this avoids a MSVC bug where non-referenced static members are "optimized" away - // even if their constructors have side effects - S32 reference() - { - S32 dummy; - dummy = 0; - return dummy; - } -}; - -template<typename T> -class LLInitClass -{ -public: - LLInitClass() { sRegister.reference(); } - - static LLRegisterWith<LLInitClassList> sRegister; -private: - - static void initClass() - { - LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template<typename T> -class LLDestroyClass -{ -public: - LLDestroyClass() { sRegister.reference(); } - - static LLRegisterWith<LLDestroyClassList> sRegister; -private: - - static void destroyClass() - { - LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass); -template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass); - // useful parameter blocks struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam> { diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 6a7a681d57..44472070cc 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -38,7 +38,8 @@ class LLUIColor; class LLUIColorTable : public LLSingleton<LLUIColorTable> { -LOG_CLASS(LLUIColorTable); + LLSINGLETON_EMPTY_CTOR(LLUIColorTable); + LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster typedef std::map<std::string, LLUIColor> string_color_map_t; diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 99553ee0d2..550bee5c70 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -258,18 +258,25 @@ public: class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->acceptsTextInput(), TRUE); } }; - + template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED > {}; - class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{}; + class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{}; + class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; protected: diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 4cc7da1267..fdefae01b1 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -92,15 +92,27 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa { std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml"); LLXMLNodePtr root_node; + std::vector<std::string> search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, filename); - // Here we're looking for the "en" version, the default-language version - // of the file, rather than the localized version. - std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); - if (!full_filename.empty()) + if (search_paths.empty()) { - LLUICtrlFactory::instance().pushFileName(full_filename); - LLSimpleXUIParser parser; - parser.readXUI(full_filename, block); + return; + } + + // "en" version, the default-language version of the file. + std::string base_filename = search_paths.front(); + if (!base_filename.empty()) + { + LLUICtrlFactory::instance().pushFileName(base_filename); + + if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths)) + { + LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL; + return; + } + LLXUIParser parser; + parser.readXUI(root_node, block, base_filename); LLUICtrlFactory::instance().popFileName(); } } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3ce39c947f..03d946f1b7 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -33,6 +33,8 @@ #include "llxuiparser.h" #include "llstl.h" #include "lldir.h" +#include "llsingleton.h" +#include "llheteromap.h" class LLView; @@ -57,22 +59,24 @@ protected: class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> { -protected: - LLDefaultChildRegistry(){} - friend class LLSingleton<LLDefaultChildRegistry>; + LLSINGLETON_EMPTY_CTOR(LLDefaultChildRegistry); }; // lookup widget name by type class LLWidgetNameRegistry : public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry); +}; // lookup function for generating empty param block by widget type // 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> -//{}; +//{ +// LLSINGLETON(LLDefaultParamBlockRegistry); +//}; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION; @@ -85,31 +89,15 @@ extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getIn class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> { -private: - friend class LLSingleton<LLUICtrlFactory>; - LLUICtrlFactory(); + LLSINGLETON(LLUICtrlFactory); ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter template <typename PARAM_BLOCK, int DUMMY> - class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > + class ParamDefaults { public: - ParamDefaults() - { - // look up template file for this 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; - LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); - mPrototype.fillFrom(params); - } - // recursively fill from base class param block - ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get()); - - } - + ParamDefaults(); const PARAM_BLOCK& get() { return mPrototype; } private: @@ -118,9 +106,10 @@ private: // base case for recursion, there are NO base classes of LLInitParam::BaseBlock template<int DUMMY> - class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> > + class ParamDefaults<LLInitParam::BaseBlock, DUMMY> { public: + ParamDefaults(); const LLInitParam::BaseBlock& get() { return mBaseBlock; } private: LLInitParam::BaseBlock mBaseBlock; @@ -132,7 +121,7 @@ public: template<typename T> static const typename T::Params& getDefaultParams() { - return ParamDefaults<typename T::Params, 0>::instance().get(); + return instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get(); } // Does what you want for LLFloaters and LLPanels @@ -147,7 +136,8 @@ public: template<typename T> static T* create(typename T::Params& params, LLView* parent = NULL) { - params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get()); + params.fillFrom(instance().mParamDefaultsMap.obtain< + ParamDefaults<typename T::Params, 0> >().get()); T* widget = createWidgetImpl<T>(params, parent); if (widget) @@ -295,8 +285,40 @@ private: class LLPanel* mDummyPanel; std::vector<std::string> mFileNames; + + // store ParamDefaults specializations + // Each ParamDefaults specialization used to be an LLSingleton in its own + // right. But the 2016 changes to the LLSingleton mechanism, making + // LLSingleton instances polymorphic, are incompatible with current + // LLInitParam::BaseBlock functionality. (Thanks NickyD for spotting + // that!) Moreover, instances of the private nested ParamDefaults template + // aren't global resources -- which is what LLSingleton is designed for. + // This is simply a cache looked up by type. Its lifespan is tied to + // LLUICtrlFactory. Use LLHeteroMap for this cache. + LLHeteroMap mParamDefaultsMap; }; +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)); + if (param_block_tag) + { // ...and if it exists, back fill values using the most specific template first + PARAM_BLOCK params; + LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); + mPrototype.fillFrom(params); + } + // recursively fill from base class param block + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom( + LLUICtrlFactory::instance().mParamDefaultsMap.obtain< + ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY> >().get()); + +} + +template <int DUMMY> +LLUICtrlFactory::ParamDefaults<LLInitParam::BaseBlock, DUMMY>::ParamDefaults() {} + // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> template<typename T> diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 27a2456deb..05b7a4a9e9 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -764,7 +764,7 @@ LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName() std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name) { - return avatar_name.getCompleteName(); + return avatar_name.getCompleteName(true, true); } // @@ -780,7 +780,7 @@ LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName() std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name) { - return avatar_name.getDisplayName(); + return avatar_name.getDisplayName(true); } // @@ -1377,7 +1377,7 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url) LLUrlEntryEmail::LLUrlEntryEmail() : LLUrlEntryBase() { - mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,6}", + mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,63}", boost::regex::perl | boost::regex::icase); mMenuName = "menu_url_email.xml"; mTooltip = LLTrans::getString("TooltipEmail"); diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 24c3a2b513..efafe543ab 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -62,9 +62,9 @@ void LLUrlRegistryNullCallback(const std::string &url, /// class LLUrlRegistry : public LLSingleton<LLUrlRegistry> { -public: + LLSINGLETON(LLUrlRegistry); ~LLUrlRegistry(); - +public: /// add a new Url handler to the registry (will be freed on destruction) /// optionally force it to the front of the list, making it take /// priority over other regular expression matches for URLs @@ -89,9 +89,6 @@ public: bool isUrl(const LLWString &text); private: - LLUrlRegistry(); - friend class LLSingleton<LLUrlRegistry>; - std::vector<LLUrlEntryBase *> mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; LLUrlEntryBase* mUrlEntryIcon; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 9604e5ce10..89ad8138d8 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1912,6 +1912,7 @@ private: class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> { + LLSINGLETON_EMPTY_CTOR(SortByTabOrder); /*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const { children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup())); @@ -1935,6 +1936,7 @@ const LLViewQuery & LLView::getTabOrderQuery() // This class is only used internally by getFocusRootsQuery below. class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLFocusRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 375efcc3de..d1059d55de 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -44,13 +44,10 @@ class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder> { - - public: - - LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton + LLSINGLETON(LLViewerEventRecorder); ~LLViewerEventRecorder(); - + public: void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); void setMouseLocalCoords(S32 x,S32 y); void setMouseGlobalCoords(S32 x,S32 y); diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 9044c4ff29..21bb1be26f 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -54,31 +54,37 @@ public: class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter> { + LLSINGLETON_EMPTY_CTOR(LLLeavesFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLRootsFilter : public LLQueryFilter, public LLSingleton<LLRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> { + LLSINGLETON_EMPTY_CTOR(LLVisibleFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> { + LLSINGLETON_EMPTY_CTOR(LLEnabledFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> { + LLSINGLETON_EMPTY_CTOR(LLTabStopFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter> { + LLSINGLETON_EMPTY_CTOR(LLCtrlFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index ad2a39cab7..eb0eac8194 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -41,7 +41,9 @@ class LLView; // lookup widget type by name class LLWidgetTypeRegistry : public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry); +}; // global static instance for registering all widget types @@ -51,7 +53,9 @@ typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; class LLChildRegistryRegistry : public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry); +}; class LLXSDWriter : public LLInitParam::Parser { @@ -60,7 +64,7 @@ public: void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } - + /*virtual*/ std::string getCurrentFileName() { return LLStringUtil::null; } LLXSDWriter(); ~LLXSDWriter(); @@ -98,6 +102,7 @@ public: typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); @@ -200,6 +205,7 @@ public: virtual ~LLSimpleXUIParser(); /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index f01178c374..338be1808d 100644..100755 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -31,6 +31,7 @@ #include "llcachename.h" #include "lluuid.h" #include "message.h" +#include "llpounceable.h" #include <string> @@ -165,7 +166,7 @@ LLFontGL* LLFontGL::getFontDefault() char const* const _PREHASH_AgentData = (char *)"AgentData"; char const* const _PREHASH_AgentID = (char *)"AgentID"; -LLMessageSystem* gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // // Stub implementation for LLMessageSystem |