diff options
| -rw-r--r-- | indra/llui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llui/llaccordionctrltab.cpp | 51 | ||||
| -rw-r--r-- | indra/llui/llaccordionctrltab.h | 6 | ||||
| -rw-r--r-- | indra/newview/llavatarlist.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llavatarlistitem.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llgrouplist.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llinventoryitemslist.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llinventoryitemslist.h | 19 | ||||
| -rw-r--r-- | indra/newview/lloutfitslist.cpp | 131 | ||||
| -rw-r--r-- | indra/newview/lloutfitslist.h | 11 | ||||
| -rw-r--r-- | indra/newview/llpanelteleporthistory.cpp | 2 | 
11 files changed, 212 insertions, 55 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 3ecab90756..88a1652671 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -101,6 +101,7 @@ set(llui_SOURCE_FILES      lluictrlfactory.cpp      lluiimage.cpp      lluistring.cpp +    lluitextutil.cpp      llundo.cpp      llurlaction.cpp      llurlentry.cpp @@ -197,6 +198,7 @@ set(llui_HEADER_FILES      llui.h      lluiimage.h      lluistring.h +    lluitextutil.h      llundo.h      llurlaction.h      llurlentry.h diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 596da782ce..0db2dca615 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -32,12 +32,13 @@  #include "linden_common.h" -#include "lluictrl.h" -#include "llscrollbar.h"  #include "llaccordionctrltab.h" -#include "lllocalcliprect.h" +#include "lllocalcliprect.h" +#include "llscrollbar.h"  #include "lltextbox.h" +#include "lluictrl.h" +#include "lluitextutil.h"  static const std::string DD_BUTTON_NAME = "dd_button";  static const std::string DD_TEXTBOX_NAME = "dd_textbox"; @@ -72,7 +73,8 @@ public:  	virtual BOOL postBuild(); -	void	setTitle(const std::string& title); +	std::string getTitle(); +	void	setTitle(const std::string& title, const std::string& hl);  	virtual void onMouseEnter(S32 x, S32 y, MASK mask);  	virtual void onMouseLeave(S32 x, S32 y, MASK mask); @@ -146,10 +148,28 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::postBuild()  	return TRUE;  } -void	LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title) +std::string LLAccordionCtrlTab::LLAccordionCtrlTabHeader::getTitle()  {  	if(mHeaderTextbox) -		mHeaderTextbox->setText(title); +	{ +		return mHeaderTextbox->getText(); +	} +	else +	{ +		return LLStringUtil::null; +	} +} + +void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title, const std::string& hl) +{ +	if(mHeaderTextbox) +	{ +		LLTextUtil::textboxSetHighlightedVal( +			mHeaderTextbox, +			LLStyle::Params(), +			title, +			hl); +	}  }  void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw() @@ -436,12 +456,25 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)  	addChild(panel,0);  } -void LLAccordionCtrlTab::setTitle(const std::string& title) +std::string LLAccordionCtrlTab::getTitle() +{ +	LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); +	if (header) +	{ +		return header->getTitle(); +	} +	else +	{ +		return LLStringUtil::null; +	} +} + +void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& hl)  {  	LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);  	if (header)  	{ -		header->setTitle(title); +		header->setTitle(title, hl);  	}  } @@ -903,5 +936,3 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)  	}  	return LLUICtrl::handleToolTip(x, y, mask);  } - - diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index de254ed3eb..f5b7fd0af6 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -113,8 +113,10 @@ public:  	void		setAccordionView(LLView* panel);  	LLView*		getAccordionView() { return mContainerPanel; }; -	// Set text in LLAccordionCtrlTabHeader -	void setTitle(const std::string& title); +	std::string getTitle(); + +	// Set text and highlight substring in LLAccordionCtrlTabHeader +	void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null);  	boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);  	boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index dfb213716c..47ec5270c3 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -316,9 +316,7 @@ void LLAvatarList::refresh()  		}  		// Send refresh_complete signal. -		std::vector<LLSD> cur_values; -		getValues(cur_values); -		mRefreshCompleteSignal(this, LLSD((S32)cur_values.size())); +		mRefreshCompleteSignal(this, LLSD((S32)size(false)));  	}  	// Commit if we've added/removed items. diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 2a51eeacfc..656274cb7a 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -36,12 +36,13 @@  #include "llavataractions.h"  #include "llavatarlistitem.h" +#include "llbutton.h"  #include "llfloaterreg.h" +#include "lluitextutil.h" +  #include "llagent.h" -#include "lloutputmonitorctrl.h"  #include "llavatariconctrl.h" -#include "lltextutil.h" -#include "llbutton.h" +#include "lloutputmonitorctrl.h"  bool LLAvatarListItem::sStaticInitialized = false;  S32 LLAvatarListItem::sLeftPadding = 0; diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 5efd99b939..3224ac6d9b 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -40,12 +40,12 @@  #include "llmenugl.h"  #include "lltextbox.h"  #include "lltrans.h" +#include "lluitextutil.h"  // newview  #include "llagent.h"  #include "llgroupactions.h"  #include "llfloaterreg.h" -#include "lltextutil.h"  #include "llviewercontrol.h"	// for gSavedSettings  #include "llviewermenu.h"		// for gMenuHolder  #include "llvoiceclient.h" diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index f48e7b3966..2d1d401cd4 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -40,11 +40,13 @@  // llcommon  #include "llcommonutils.h" +// llui  #include "lliconctrl.h" +#include "lluitextutil.h" +#include "llcallbacklist.h"  #include "llinventoryfunctions.h"  #include "llinventorymodel.h" -#include "lltextutil.h"  #include "lltrans.h"  //////////////////////////////////////////////////////////////////////////////// @@ -320,6 +322,7 @@ LLInventoryItemsList::Params::Params()  LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p)  :	LLFlatListViewEx(p)  ,	mNeedsRefresh(false) +,	mPrevVisibility(false)  {  	// TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView  	// but reset to true in all derived classes. This settings might need to @@ -327,6 +330,8 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p  	setCommitOnSelectionChange(true);  	setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems")); + +	gIdleCallbacks.addFunction(idle, this);  }  // virtual @@ -344,12 +349,31 @@ void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item  	mNeedsRefresh = true;  } -void LLInventoryItemsList::draw() +boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb)  { -	LLFlatListViewEx::draw(); -	if(mNeedsRefresh) +	return mRefreshCompleteSignal.connect(cb); +} + +void LLInventoryItemsList::doIdle() +{ +	bool cur_visibility = getVisible(); +	if(cur_visibility != mPrevVisibility || mNeedsRefresh)  	{  		refresh(); + +		mRefreshCompleteSignal(this, LLSD()); + +		mPrevVisibility = getVisible(); +	} +} + +//static +void LLInventoryItemsList::idle(void* user_data) +{ +	LLInventoryItemsList* self = static_cast<LLInventoryItemsList*>(user_data); +	if ( self ) +	{	// Do the real idle +		self->doIdle();  	}  } diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 6e74330df2..60cccc0f4f 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -212,14 +212,23 @@ public:  	void refreshList(const LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array); +	boost::signals2::connection setRefreshCompleteCallback(const commit_signal_t::slot_type& cb); +  	/** -	 * Let list know items need to be refreshed in next draw() +	 * Let list know items need to be refreshed in next doIdle()  	 */  	void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }  	bool getNeedsRefresh(){ return mNeedsRefresh; } -	/*virtual*/ void draw(); +	/** +	 * Idle routine used to refresh the list regardless of the current list +	 * visibility, unlike draw() which is called only for the visible list. +	 * This is needed for example to filter items of the list hidden by closed +	 * accordion tab. +	 */ +	void	doIdle();						// Real idle routine +	static void idle(void* user_data);		// static glue to doIdle()  protected:  	friend class LLUICtrlFactory; @@ -229,7 +238,7 @@ protected:  	/**  	 * Refreshes list items, adds new items and removes deleted items.  -	 * Called from draw() until all new items are added, , +	 * Called from doIdle() until all new items are added,  	 * maximum 50 items can be added during single call.  	 */  	void refresh(); @@ -249,6 +258,10 @@ private:  	uuid_vec_t mIDs; // IDs of items that were added in refreshList().  					 // Will be used in refresh() to determine added and removed ids  	bool mNeedsRefresh; + +	bool mPrevVisibility; + +	commit_signal_t mRefreshCompleteSignal;  };  #endif //LL_LLINVENTORYITEMSLIST_H diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 18bd610dd9..12d5203429 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -169,6 +169,9 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  		// Setting list commit callback to monitor currently selected wearable item.  		list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1)); +		// Setting list refresh callback to apply filter on list change. +		list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onWearableItemsListRefresh, this, _1)); +  		// Fetch the new outfit contents.  		cat->fetch(); @@ -244,35 +247,9 @@ void LLOutfitsList::performAction(std::string action)  void LLOutfitsList::setFilterSubString(const std::string& string)  { -	mFilterSubString = string; +	applyFilter(string); -	for (outfits_map_t::iterator -			 iter = mOutfitsMap.begin(), -			 iter_end = mOutfitsMap.end(); -		 iter != iter_end; ++iter) -	{ -		LLAccordionCtrlTab* tab = iter->second; -		if (tab) -		{ -			LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*> (tab->getAccordionView()); -			if (list) -			{ -				list->setFilterSubString(mFilterSubString); -			} - -			if(!mFilterSubString.empty()) -			{ -				//store accordion tab state when filter is not empty -				tab->notifyChildren(LLSD().with("action","store_state")); -				tab->setDisplayChildren(true); -			} -			else -			{ -				//restore accordion state after all those accodrion tab manipulations -				tab->notifyChildren(LLSD().with("action","restore_state")); -			} -		} -	} +	mFilterSubString = string;  }  ////////////////////////////////////////////////////////////////////////// @@ -350,4 +327,102 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI  	mSelectedOutfitUUID = category_id;  } +void LLOutfitsList::onWearableItemsListRefresh(LLUICtrl* ctrl) +{ +	if (!ctrl || mFilterSubString.empty()) +		return; + +	for (outfits_map_t::iterator +			 iter = mOutfitsMap.begin(), +			 iter_end = mOutfitsMap.end(); +		 iter != iter_end; ++iter) +	{ +		LLAccordionCtrlTab* tab = iter->second; +		if (tab) continue; + +		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); +		if (list != ctrl) continue; + +		std::string title = tab->getTitle(); +		LLStringUtil::toUpper(title); + +		std::string cur_filter = mFilterSubString; +		LLStringUtil::toUpper(cur_filter); + +		if (std::string::npos == title.find(cur_filter)) +		{ +			// hide tab if its title doesn't pass filter +			// and it has no visible items +			tab->setVisible(list->size() != 0); +		} +		else +		{ +			tab->setTitle(tab->getTitle(), cur_filter); +		} +	} +} + +void LLOutfitsList::applyFilter(const std::string& new_filter_substring) +{ +	for (outfits_map_t::iterator +			 iter = mOutfitsMap.begin(), +			 iter_end = mOutfitsMap.end(); +		 iter != iter_end; ++iter) +	{ +		LLAccordionCtrlTab* tab = iter->second; +		if (!tab) continue; + +		bool more_restrictive = mFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, mFilterSubString.size()).compare(mFilterSubString); + +		// Restore tab visibility in case of less restrictive filter +		// to compare it with updated string if it was previously hidden. +		if (!more_restrictive) +		{ +			tab->setVisible(TRUE); +		} + +		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); +		if (list) +		{ +			list->setFilterSubString(new_filter_substring); +		} + +		if(mFilterSubString.empty() && !new_filter_substring.empty()) +		{ +			//store accordion tab state when filter is not empty +			tab->notifyChildren(LLSD().with("action","store_state")); +		} + +		if (!new_filter_substring.empty()) +		{ +			tab->setDisplayChildren(true); + +			std::string title = tab->getTitle(); +			LLStringUtil::toUpper(title); + +			std::string cur_filter = new_filter_substring; +			LLStringUtil::toUpper(cur_filter); + +			if (std::string::npos == title.find(cur_filter)) +			{ +				// hide tab if its title doesn't pass filter +				// and it has no visible items +				tab->setVisible(list->size() != 0); +			} +			else +			{ +				tab->setTitle(tab->getTitle(), cur_filter); +			} +		} +		else +		{ +			// restore tab title when filter is empty +			tab->setTitle(tab->getTitle()); + +			//restore accordion state after all those accodrion tab manipulations +			tab->notifyChildren(LLSD().with("action","restore_state")); +		} +	} +} +  // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index d86cf5a703..bcb393b12a 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -94,6 +94,17 @@ private:  	 */  	void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); +	/** +	 * Called upon list refresh event to update tab visibility depending on +	 * the results of applying filter to the title and list items of the tab. +	 */ +	void onWearableItemsListRefresh(LLUICtrl* ctrl); + +	/** +	 * Highlights filtered items and hides tabs which haven't passed filter. +	 */ +	void applyFilter(const std::string& new_filter_substring); +  	LLInventoryCategoriesObserver* 	mCategoriesObserver;  	LLAccordionCtrl*				mAccordion; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index e8b6c6bfe5..4dd03e04a9 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -38,7 +38,7 @@  #include "llsidetray.h"  #include "llworldmap.h"  #include "llteleporthistorystorage.h" -#include "lltextutil.h" +#include "lluitextutil.h"  #include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  | 
