diff options
| author | Sergei Litovchuk <slitovchuk@productengine.com> | 2010-08-02 20:52:17 +0300 | 
|---|---|---|
| committer | Sergei Litovchuk <slitovchuk@productengine.com> | 2010-08-02 20:52:17 +0300 | 
| commit | 74ed51e77d7a44b845dcc12d1d7ad6a426caaa2d (patch) | |
| tree | e30c6541f88013fe4fb822dca028b9bf1df7485b | |
| parent | b8b7a61e9e732b16a56ae0bec3b9098ccfd28292 (diff) | |
EXT-7676 FIXED Restored fix (47df1b3fd94e) reverted in merge 5b5cc4a8642d with slight modifications.
- Replaced pointers passed to 'Add More' gear menu with LLHandle.
- Removed storing 'Add More' panel sort order from settings because the order is changed each time the panel opens.
- Replaced creating items comparator in LLPanelOutfitEdit::postBuild() with a static comparator in llwearableitemslist.cpp.
Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/826/.
--HG--
branch : product-engine
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 212 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitedit.h | 6 | ||||
| -rw-r--r-- | indra/newview/llwearableitemslist.cpp | 53 | ||||
| -rw-r--r-- | indra/newview/llwearableitemslist.h | 27 | 
5 files changed, 272 insertions, 37 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ce22db97b4..bbf3f4fc75 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -35,17 +35,6 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>AddWearableSortOrder</key> -    <map> -      <key>Comment</key> -      <string>Specifies sort order for add wearable panel (0 = name, 1 = date, 2 = by type)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>U32</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>AgentPause</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 17e7965ab7..c7ac4af14c 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -86,6 +86,11 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;  static const std::string REVERT_BTN("revert_btn"); + +/////////////////////////////////////////////////////////////////////////////// +// LLShopURLDispatcher +/////////////////////////////////////////////////////////////////////////////// +  class LLShopURLDispatcher  {  public: @@ -145,6 +150,10 @@ std::string LLShopURLDispatcher::resolveURL(LLAssetType::EType asset_type, ESex  	return gSavedSettings.getString(setting_name);  } +/////////////////////////////////////////////////////////////////////////////// +// LLPanelOutfitEditGearMenu +/////////////////////////////////////////////////////////////////////////////// +  class LLPanelOutfitEditGearMenu  {  public: @@ -160,7 +169,6 @@ public:  		if (menu)  		{  			populateCreateWearableSubmenus(menu); -			menu->buildDrawLabels();  		}  		return menu; @@ -209,6 +217,147 @@ private:  	}  }; +/////////////////////////////////////////////////////////////////////////////// +// LLAddWearablesGearMenu +/////////////////////////////////////////////////////////////////////////////// + +class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu> +{ +public: +	static LLMenuGL* create(LLWearableItemsList* flat_list, LLInventoryPanel* inventory_panel) +	{ +		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + +		llassert(flat_list); +		llassert(inventory_panel); + +		LLHandle<LLView> flat_list_handle = flat_list->getHandle(); +		LLHandle<LLPanel> inventory_panel_handle = inventory_panel->getHandle(); + +		registrar.add("AddWearable.Gear.Sort", boost::bind(onSort, flat_list_handle, inventory_panel_handle, _2)); +		enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list_handle, inventory_panel_handle, _2)); +		enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel_handle, _2)); + +		LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( +			"menu_add_wearable_gear.xml", +			LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + +		return menu; +	} + +private: +	static void onSort(LLHandle<LLView> flat_list_handle, +					   LLHandle<LLPanel> inventory_panel_handle, +					   LLSD::String sort_order_str) +	{ +		if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return; + +		LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get()); +		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get()); + +		if (!flat_list || !inventory_panel) return; + +		LLWearableItemsList::ESortOrder	sort_order; + +		if ("by_most_recent" == sort_order_str) +		{ +			sort_order = LLWearableItemsList::E_SORT_BY_MOST_RECENT; +		} +		else if ("by_name" == sort_order_str) +		{ +			sort_order = LLWearableItemsList::E_SORT_BY_NAME; +		} +		else if ("by_type" == sort_order_str) +		{ +			sort_order = LLWearableItemsList::E_SORT_BY_TYPE_NAME; +		} +		else +		{ +			llwarns << "Unrecognized sort order action" << llendl; +			return; +		} + +		if (inventory_panel->getVisible()) +		{ +			inventory_panel->setSortOrder(sort_order); +		} +		else +		{ +			flat_list->setSortOrder(sort_order); +		} +	} + +	static bool onCheck(LLHandle<LLView> flat_list_handle, +						LLHandle<LLPanel> inventory_panel_handle, +						LLSD::String sort_order_str) +	{ +		if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return false; + +		LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get()); +		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get()); + +		if (!inventory_panel || !flat_list) return false; + +		// Inventory panel uses its own sort order independent from +		// flat list view so this flag is used to distinguish between +		// currently visible "tree" or "flat" representation of inventory. +		bool inventory_tree_visible = inventory_panel->getVisible(); + +		if (inventory_tree_visible) +		{ +			U32 sort_order = inventory_panel->getSortOrder(); + +			if ("by_most_recent" == sort_order_str) +			{ +				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & sort_order; +			} +			else if ("by_name" == sort_order_str) +			{ +				// If inventory panel is not sorted by date then it is sorted by name. +				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & ~sort_order; +			} +			llwarns << "Unrecognized inventory panel sort order" << llendl; +		} +		else +		{ +			LLWearableItemsList::ESortOrder	sort_order = flat_list->getSortOrder(); + +			if ("by_most_recent" == sort_order_str) +			{ +				return LLWearableItemsList::E_SORT_BY_MOST_RECENT == sort_order; +			} +			else if ("by_name" == sort_order_str) +			{ +				return LLWearableItemsList::E_SORT_BY_NAME == sort_order; +			} +			else if ("by_type" == sort_order_str) +			{ +				return LLWearableItemsList::E_SORT_BY_TYPE_NAME == sort_order; +			} +			llwarns << "Unrecognized wearable list sort order" << llendl; +		} +		return false; +	} + +	static bool onVisible(LLHandle<LLPanel> inventory_panel_handle, +						  LLSD::String sort_order_str) +	{ +		if (inventory_panel_handle.isDead()) return false; + +		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get()); + +		// Enable sorting by type only for the flat list of items +		// because inventory panel doesn't support this kind of sorting. +		return ( "by_type" == sort_order_str ) +				&&	( !inventory_panel || !inventory_panel->getVisible() ); +	} +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLCOFDragAndDropObserver +/////////////////////////////////////////////////////////////////////////////// +  class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver  {  public: @@ -244,12 +393,17 @@ void LLCOFDragAndDropObserver::done()  	LLAppearanceMgr::instance().updateAppearanceFromCOF();  } +/////////////////////////////////////////////////////////////////////////////// +// LLPanelOutfitEdit +/////////////////////////////////////////////////////////////////////////////// +  LLPanelOutfitEdit::LLPanelOutfitEdit()  :	LLPanel(),   	mSearchFilter(NULL),  	mCOFWearables(NULL),  	mInventoryItemsPanel(NULL),  	mGearMenu(NULL), +	mAddWearablesGearMenu(NULL),  	mCOFDragAndDropObserver(NULL),  	mInitialized(false),  	mAddWearablesPanel(NULL), @@ -284,8 +438,6 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  	delete mCOFDragAndDropObserver; -	delete mWearableListViewItemsComparator; -  	while (!mListViewItemTypes.empty()) {  		delete mListViewItemTypes.back();  		mListViewItemTypes.pop_back(); @@ -391,24 +543,11 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); -	/* -	 * By default AT_CLOTHING are sorted by (in in MY OUTFITS): -	 *  - by type (types order determined in LLWearableType::EType) -	 *  - each LLWearableType::EType by outer layer on top -	 * -	 * In Add More panel AT_CLOTHING should be sorted in a such way: -	 *  - by type (types order determined in LLWearableType::EType) -	 *  - each LLWearableType::EType by name (EXT-8205) -	*/ -	mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator(); -	mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true); -  	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel"); -	mWearableItemsList = getChild<LLInventoryItemsList>("list_view"); +	mWearableItemsList = getChild<LLWearableItemsList>("list_view");  	mWearableItemsList->setCommitOnSelectionChange(true);  	mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));  	mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); -	mWearableItemsList->setComparator(mWearableListViewItemsComparator);  	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));  	return TRUE; @@ -462,6 +601,17 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)  		showWearablesFilter(); +		/* +		 * By default AT_CLOTHING are sorted by (in in MY OUTFITS): +		 *  - by type (types order determined in LLWearableType::EType) +		 *  - each LLWearableType::EType by outer layer on top +		 * +		 * In Add More panel AT_CLOTHING should be sorted in a such way: +		 *  - by type (types order determined in LLWearableType::EType) +		 *  - each LLWearableType::EType by name (EXT-8205) +		*/ +		mWearableItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_TYPE_NAME); +  		// Reset mWearableItemsList position to top. See EXT-8180.  		mWearableItemsList->goToTop();  	} @@ -1063,13 +1213,33 @@ void LLPanelOutfitEdit::resetAccordionState()  void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)  { -	if(!mGearMenu) +	LLMenuGL* menu = NULL; + +	if (mAddWearablesPanel->getVisible())  	{ -		mGearMenu = LLPanelOutfitEditGearMenu::create(); +		if (!mAddWearablesGearMenu) +		{ +			mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); +		} + +		menu = mAddWearablesGearMenu; +	} +	else +	{ +		if (!mGearMenu) +		{ +			mGearMenu = LLPanelOutfitEditGearMenu::create(); +		} + +		menu = mGearMenu;  	} -	S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight(); -	LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y); +	if (!menu) return; + +	menu->arrangeAndClear(); // update menu height +	S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight(); +	menu->buildDrawLabels(); +	LLMenuGL::showPopup(clicked_button, menu, 0, menu_y);  }  void LLPanelOutfitEdit::onAddMoreButtonClicked() diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index b3394e45a3..0b6926b83e 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -43,8 +43,8 @@  #include "llremoteparcelrequest.h"  #include "llinventory.h"  #include "llinventoryfunctions.h" -#include "llinventoryitemslist.h"  #include "llinventorymodel.h" +#include "llwearableitemslist.h"  class LLButton;  class LLCOFWearables; @@ -230,9 +230,8 @@ private:  	LLComboBox*			mListViewFilterCmbBox;  	LLFilteredWearableListManager* 	mWearableListManager; -	LLInventoryItemsList* 			mWearableItemsList; +	LLWearableItemsList* 			mWearableItemsList;  	LLPanel*						mWearablesListViewPanel; -	LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;  	LLCOFDragAndDropObserver* mCOFDragAndDropObserver; @@ -241,6 +240,7 @@ private:  	LLCOFWearables*		mCOFWearables;  	LLMenuGL*			mGearMenu; +	LLMenuGL*			mAddWearablesGearMenu;  	bool				mInitialized;  	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 34f6fbebd6..c9130b56b4 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -583,11 +583,28 @@ bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType  	return const_it->second.mSortWearableTypeByName;  } + +/*virtual*/ +bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const +{ +	time_t date1 = item1->getCreationDate(); +	time_t date2 = item2->getCreationDate(); + +	if (date1 == date2) +	{ +		return LLWearableItemNameComparator::doCompare(item1, item2); +	} + +	return date1 > date2; +}  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// -static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR; +static LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR; +static const LLWearableItemTypeNameComparator WEARABLE_TYPE_LAYER_COMPARATOR; +static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR; +static const LLWearableItemCreationDateComparator WEARABLE_CREATION_DATE_COMPARATOR;  static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list"); @@ -599,7 +616,7 @@ LLWearableItemsList::Params::Params()  LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)  :	LLInventoryItemsList(p)  { -	setComparator(&WEARABLE_TYPE_NAME_COMPARATOR); +	setSortOrder(E_SORT_BY_TYPE_LAYER, false);  	mIsStandalone = p.standalone;  	if (mIsStandalone)  	{ @@ -699,6 +716,38 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)  	ContextMenu::instance().show(this, selected_uuids, x, y);  } +void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now) +{ +	switch (sort_order) +	{ +	case E_SORT_BY_MOST_RECENT: +		setComparator(&WEARABLE_CREATION_DATE_COMPARATOR); +		break; +	case E_SORT_BY_NAME: +		setComparator(&WEARABLE_NAME_COMPARATOR); +		break; +	case E_SORT_BY_TYPE_LAYER: +		setComparator(&WEARABLE_TYPE_LAYER_COMPARATOR); +		break; +	case E_SORT_BY_TYPE_NAME: +	{ +		WEARABLE_TYPE_NAME_COMPARATOR.setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true); +		setComparator(&WEARABLE_TYPE_NAME_COMPARATOR); +		break; +	} + +	// No "default:" to raise compiler warning +	// if we're not handling something +	} + +	mSortOrder = sort_order; + +	if (sort_now) +	{ +		sort(); +	} +} +  //////////////////////////////////////////////////////////////////////////  /// ContextMenu  ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 2e720d13bb..81f1cd1b40 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -380,6 +380,19 @@ private:  };  /** + * @class LLWearableItemCreationDateComparator + * + * Comparator for sorting wearable list items by creation date (newest go first). + */ +class LLWearableItemCreationDateComparator : public LLWearableItemNameComparator +{ +	LOG_CLASS(LLWearableItemCreationDateComparator); + +protected: +	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const; +}; + +/**   * @class LLWearableItemsList   *   * A flat list of wearable inventory items. @@ -431,6 +444,14 @@ public:  		Params();  	}; +	typedef enum e_sort_order { +		// Values should be compatible with InventorySortOrder setting. +		E_SORT_BY_NAME			= 0, +		E_SORT_BY_MOST_RECENT	= 1, +		E_SORT_BY_TYPE_LAYER	= 2, +		E_SORT_BY_TYPE_NAME 	= 3, +	} ESortOrder; +  	virtual ~LLWearableItemsList();  	/*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); @@ -445,6 +466,10 @@ public:  	bool isStandalone() const { return mIsStandalone; } +	ESortOrder getSortOrder() const { return mSortOrder; } + +	void setSortOrder(ESortOrder sort_order, bool sort_now = true); +  protected:  	friend class LLUICtrlFactory;  	LLWearableItemsList(const LLWearableItemsList::Params& p); @@ -453,6 +478,8 @@ protected:  	bool mIsStandalone;  	bool mWornIndicationEnabled; + +	ESortOrder		mSortOrder;  };  #endif //LL_LLWEARABLEITEMSLIST_H | 
