summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorVadim Savchuk <vsavchuk@productengine.com>2010-06-17 19:03:57 +0300
committerVadim Savchuk <vsavchuk@productengine.com>2010-06-17 19:03:57 +0300
commit9f996443604a902e03de87d2d14545b4adffa69c (patch)
tree8ebeb38bfe7f09fdcb82173c5d2607242f0d62f5 /indra/newview
parent8d2ddff47e973c1692b42081e74dba3ad7745fdd (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.cpp33
-rw-r--r--indra/newview/llappearancemgr.h6
-rw-r--r--indra/newview/llinventorybridge.cpp15
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventoryfunctions.cpp30
-rw-r--r--indra/newview/llinventoryfunctions.h24
-rw-r--r--indra/newview/lloutfitslist.cpp16
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp8
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_tab.xml6
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" />