diff options
| author | Vadim Savchuk <vsavchuk@productengine.com> | 2010-06-17 19:03:57 +0300 | 
|---|---|---|
| committer | Vadim Savchuk <vsavchuk@productengine.com> | 2010-06-17 19:03:57 +0300 | 
| commit | 9f996443604a902e03de87d2d14545b4adffa69c (patch) | |
| tree | 8ebeb38bfe7f09fdcb82173c5d2607242f0d62f5 /indra/newview | |
| parent | 8d2ddff47e973c1692b42081e74dba3ad7745fdd (diff) | |
EXT-7722 Fixed "Add to COF" and "Remove from COF" outfit context menu items to be enabled when appropriate and work properly.
Work on "Take Off - Remove from Current Outfit" and "Wear - Add to Current Outfit" menu options:
- The menu items of the outfit context menu and the My Outfits gear menu are now disabled
  when inappropriate instead of being hidden.
- The menu items get enabled/disabled depending on whether you can wear (take off) anything from the selected outfit.
  (was: depending on whether you're wearing the outfit)
- Changed the way the options work: they now only operate on clothes and attachments.
  "Add to COF" now only adds those body parts that are missing in COF;
  "Remove from COF" doesn't touch body parts at all.
  Without this change both "Add" and "Remove" options would be available simultaneously, because
  any valid outfit contains body parts. I think that would be confusing.
  And you don't expect you body parts to be replaced when doing "Add to COF'. (that's addition, not replacement)
Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/585/
--HG--
branch : product-engine
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 33 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 6 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.h | 1 | ||||
| -rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 30 | ||||
| -rw-r--r-- | indra/newview/llinventoryfunctions.h | 24 | ||||
| -rw-r--r-- | indra/newview/lloutfitslist.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitsinventory.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_outfit_tab.xml | 6 | 
9 files changed, 97 insertions, 42 deletions
| diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index be58a562c0..4e96372da9 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1068,7 +1068,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)  {  	LLInventoryModel::cat_array_t cats;  	LLInventoryModel::item_array_t items; -	LLFindWorn collector; +	LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false);  	gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); @@ -1224,6 +1224,34 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)  	return true;  } +// static +bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) +{ +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_worn); +	return items.size() > 0; +} + +// static +bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id) +{ +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		not_worn); +	return items.size() > 0; +} +  void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)  {  	LLInventoryModel::cat_array_t cats; @@ -1338,9 +1366,12 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	// - Body parts: always include COF contents as a fallback in case any  	// required parts are missing. +	// Preserve body parts from COF if appending.  	LLInventoryModel::item_array_t body_items;  	getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART, false);  	getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART, false); +	if (append) +		reverse(body_items.begin(), body_items.end());  	// Reduce body items to max of one per type.  	removeDuplicateItems(body_items);  	filterWearableItems(body_items, 1); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e42f9f7d6f..8ded32a53d 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -75,6 +75,12 @@ public:  	// Determine whether a given outfit can be removed.  	bool getCanRemoveOutfit(const LLUUID& outfit_cat_id); +	// Determine whether we're wearing any of the outfit contents (excluding body parts). +	static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id); + +	// Determine whether we can add anything (but body parts) from the outfit contents to COF. +	static bool getCanAddToCOF(const LLUUID& outfit_cat_id); +  	// Copy all items in a category.  	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,  									 LLPointer<LLInventoryCallback> cb); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ec367c1746..1881d0d780 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2489,7 +2489,7 @@ void LLFolderBridge::folderOptionsMenu()  			mItems.push_back(std::string("Wear As Ensemble"));  		}  		mItems.push_back(std::string("Remove From Outfit")); -		if (!areAnyContentsWorn(model)) +		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))  		{  			disabled_items.push_back(std::string("Remove From Outfit"));  		} @@ -2514,19 +2514,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv  	return ((item_array.count() > 0) ? TRUE : FALSE );  } -BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const -{ -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t item_array; -	LLFindWorn is_worn; -	model->collectDescendentsIf(mUUID, -								cat_array, -								item_array, -								LLInventoryModel::EXCLUDE_TRASH, -								is_worn); -	return (item_array.size() > 0); -} -  // Flags unused  void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 757808eb93..64d0f8d254 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -295,7 +295,6 @@ protected:  	static void createNewEyes(void* user_data);  	BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck); -	BOOL areAnyContentsWorn(LLInventoryModel* model) const;  	void modifyOutfit(BOOL append);  	void determineFolderType(); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index de24bd92d0..469d1888dd 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -573,6 +573,31 @@ bool LLFindWearables::operator()(LLInventoryCategory* cat,  	return FALSE;  } +LLFindWearablesEx::LLFindWearablesEx(bool is_worn, bool include_body_parts) +:	mIsWorn(is_worn) +,	mIncludeBodyParts(include_body_parts) +{} + +bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ +	LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); +	if (!vitem) return false; + +	// Skip non-wearables. +	if (!vitem->isWearableType() && vitem->getType() != LLAssetType::AT_OBJECT) +	{ +		return false; +	} + +	// Skip body parts if requested. +	if (!mIncludeBodyParts && vitem->getType() == LLAssetType::AT_BODYPART) +	{ +		return false; +	} + +	return (bool) get_is_item_worn(item->getUUID()) == mIsWorn; +} +  bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)  {  	if (!item) return false; @@ -593,11 +618,6 @@ void LLFindWearablesOfType::setType(LLWearableType::EType type)  	mWearableType = type;  } -bool LLFindWorn::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ -	return item && get_is_item_worn(item->getUUID()); -} -  bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item)  {  	if (item) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 93c56e1b8a..1795b54679 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -337,6 +337,21 @@ public:  							LLInventoryItem* item);  }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindWearablesEx +// +// Collects wearables based on given criteria. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFindWearablesEx : public LLInventoryCollectFunctor +{ +public: +	LLFindWearablesEx(bool is_worn, bool include_body_parts = true); +	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +private: +	bool mIncludeBodyParts; +	bool mIsWorn; +}; +  //Inventory collect functor collecting wearables of a specific wearable type  class LLFindWearablesOfType : public LLInventoryCollectFunctor  { @@ -363,15 +378,6 @@ public:  	}  }; -// Find worn items. -class LLFindWorn : public LLInventoryCollectFunctor -{ -public: -	LLFindWorn() {} -	virtual ~LLFindWorn() {} -	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); -}; -  // Collect non-removable folders and items.  class LLFindNonRemovableObjects : public LLInventoryCollectFunctor  { diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 8c6189353e..73c850e1fb 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -102,6 +102,14 @@ protected:  		{  			return get_is_category_renameable(&gInventory, outfit_cat_id);  		} +		else if ("wear_add" == param) +		{ +			return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id); +		} +		else if ("take_off" == param) +		{ +			return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id); +		}  		return true;  	} @@ -119,14 +127,6 @@ protected:  		{  			return !is_worn;  		} -		else if ("wear_add" == param) -		{ -			return !is_worn; -		} -		else if ("take_off" == param) -		{ -			return is_worn; -		}  		else if ("delete" == param)  		{  			return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index e2563efb7d..2405b95e7d 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -191,6 +191,10 @@ private:  		{  			return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id);  		} +		else if ("take_off" == param) +		{ +			return LLAppearanceMgr::getCanRemoveFromCOF(selected_outfit_id); +		}  		return true;  	} @@ -209,10 +213,6 @@ private:  		{  			return !is_worn;  		} -		else if ("take_off" == param) -		{ -			return is_worn; -		}  		return true;  	} diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml index e084216a69..9206969b2f 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -18,6 +18,9 @@       name="wear_add">          <on_click           function="Outfit.WearAdd" /> +        <on_enable +         function="Outfit.OnEnable" +         parameter="wear_add" />          <on_visible           function="Outfit.OnVisible"           parameter="wear_add" /> @@ -28,6 +31,9 @@       name="take_off">          <on_click           function="Outfit.TakeOff" /> +        <on_enable +         function="Outfit.OnEnable" +         parameter="take_off" />          <on_visible           function="Outfit.OnVisible"           parameter="take_off" /> | 
