summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Borovkov <iborovkov@productengine.com>2010-04-28 17:47:08 +0300
committerIgor Borovkov <iborovkov@productengine.com>2010-04-28 17:47:08 +0300
commitf9a120e8983a72b6de2f146acec55e079255b70e (patch)
tree4dabbf42f91339dcf68feb5b94fa630509a2d55e
parent8e0a73f0edea77c6fac4303a5a77a72f1db4a233 (diff)
partial implementation of EXT-6723 Create specialized view of inventory for "clothing" accordion tab of outfit editor
- added grouping clothing items by wearable type (shirt, jeans etc.) - added sorting clothing items by wearing order in groups - added separators between items of the same wearable type (lists: clothing, body parts) - added list specific button bars - partially added dummy items for missing wearable types in the COF (clothing list) Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/322 --HG-- branch : product-engine
-rw-r--r--indra/newview/llappearancemgr.cpp10
-rw-r--r--indra/newview/llappearancemgr.h12
-rw-r--r--indra/newview/llcofwearables.cpp149
-rw-r--r--indra/newview/llcofwearables.h10
-rw-r--r--indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml36
-rw-r--r--indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml37
-rw-r--r--indra/newview/skins/default/xui/en/panel_cof_wearables.xml1
7 files changed, 227 insertions, 28 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 5586b3cd4d..e93e29ecde 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1092,7 +1092,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
}
//preparing the list of wearables in the correct order for LLAgentWearables
- std::sort(wear_items.begin(), wear_items.end(), sort_by_description);
+ sortItemsByActualDescription(wear_items);
+
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
@@ -1910,6 +1911,13 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
return result;
}
+//static
+void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_t& items)
+{
+ if (items.size() < 2) return;
+
+ std::sort(items.begin(), items.end(), sort_by_description);
+}
//#define DUMP_CAT_VERBOSE
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index a308a3efa9..516dada39d 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -48,6 +48,8 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
friend class LLSingleton<LLAppearanceMgr>;
public:
+ typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
+
void updateAppearanceFromCOF();
bool needToSaveCOF();
void updateCOF(const LLUUID& category, bool append = false);
@@ -143,17 +145,17 @@ public:
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
+ static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items);
+
+ //Divvy items into arrays by wearable type
+ static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
+
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
private:
- typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
-
- //Divvy items into arrays by wearable type
- static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
-
//Check ordering information on wearables stored in links' descriptions and update if it is invalid
void updateClothingOrderingInfo();
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index f0442ee3f6..e21644e119 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -94,47 +94,139 @@ void LLCOFWearables::refresh()
clear();
LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
+ LLInventoryModel::item_array_t cof_items;
+
+ gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, cof_items, LLInventoryModel::EXCLUDE_TRASH);
+
+ populateAttachmentsAndBodypartsLists(cof_items);
+
+
+ LLAppearanceMgr::wearables_by_type_t clothing_by_type(WT_COUNT);
+ LLAppearanceMgr::getInstance()->divvyWearablesByType(cof_items, clothing_by_type);
- gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
- if (items.empty()) return;
+ populateClothingList(clothing_by_type);
+}
+
- for (U32 i = 0; i < items.size(); ++i)
+void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items)
+{
+ for (U32 i = 0; i < cof_items.size(); ++i)
{
- LLViewerInventoryItem* item = items.get(i);
+ LLViewerInventoryItem* item = cof_items.get(i);
if (!item) continue;
+ const LLAssetType::EType item_type = item->getType();
+ if (item_type == LLAssetType::AT_CLOTHING) continue;
+
LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
if (!item_panel) continue;
- switch (item->getType())
+ if (item_type == LLAssetType::AT_OBJECT)
{
- case LLAssetType::AT_OBJECT:
- mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
- break;
+ mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
+ }
+ else if (item_type == LLAssetType::AT_BODYPART)
+ {
+ mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
+ addWearableTypeSeparator(mBodyParts);
+ }
+ }
+
+ if (mAttachments->size())
+ {
+ mAttachments->sort(); //*TODO by Name
+ mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false)
+ }
- case LLAssetType::AT_BODYPART:
- mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
- break;
+ if (mBodyParts->size())
+ {
+ mBodyParts->sort(); //*TODO by name
+ }
+
+ addListButtonBar(mBodyParts, "panel_bodyparts_list_button_bar.xml");
+ mBodyParts->notify(REARRANGE);
+}
+
+
+void LLCOFWearables::populateClothingList(LLAppearanceMgr::wearables_by_type_t& clothing_by_type)
+{
+ llassert(clothing_by_type.size() == WT_COUNT);
+
+ addListButtonBar(mClothing, "panel_clothing_list_button_bar.xml");
+
+ for (U32 type = WT_SHIRT; type < WT_COUNT; ++type)
+ {
+ U32 size = clothing_by_type[type].size();
+ if (!size) continue;
+
+ LLAppearanceMgr::sortItemsByActualDescription(clothing_by_type[type]);
+
+ for (U32 i = 0; i < size; i++)
+ {
+ LLViewerInventoryItem* item = clothing_by_type[type][i];
- case LLAssetType::AT_CLOTHING:
- mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
- break;
+ LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
+ if (!item_panel) continue;
- default: break;
+ mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
}
+
+ addWearableTypeSeparator(mClothing);
}
- mAttachments->sort(); //*TODO by Name
- mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false)
-
- mClothing->sort(); //*TODO by actual inventory item description
+ addClothingTypesDummies(clothing_by_type);
+
mClothing->notify(REARRANGE);
+}
+
+void LLCOFWearables::addListButtonBar(LLFlatListView* list, std::string xml_filename)
+{
+ llassert(list);
+ llassert(xml_filename.length());
- mBodyParts->sort(); //*TODO by name
- mBodyParts->notify(REARRANGE);
+ LLPanel::Params params;
+ LLPanel* button_bar = LLUICtrlFactory::create<LLPanel>(params);
+ LLUICtrlFactory::instance().buildPanel(button_bar, xml_filename);
+
+ LLRect rc = button_bar->getRect();
+ button_bar->reshape(list->getItemsRect().getWidth(), rc.getHeight());
+
+ list->addItem(button_bar, LLUUID::null, ADD_TOP, false);
}
+//adding dummy items for missing wearable types
+void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by_type_t& clothing_by_type)
+{
+ llassert(clothing_by_type.size() == WT_COUNT);
+
+ for (U32 type = WT_SHIRT; type < WT_COUNT; type++)
+ {
+ U32 size = clothing_by_type[type].size();
+ if (size) continue;
+
+ //*TODO create dummy item panel
+
+ //*TODO add dummy item panel -> mClothing->addItem(dummy_item_panel, item->getUUID(), ADD_BOTTOM, false);
+
+ addWearableTypeSeparator(mClothing);
+ }
+}
+
+void LLCOFWearables::addWearableTypeSeparator(LLFlatListView* list)
+{
+ llassert(list);
+
+ static LLXMLNodePtr separator_xml_node = getXMLNode("panel_wearable_type_separator.xml");
+ if (separator_xml_node->isNull()) return;
+
+ LLPanel* separator = LLUICtrlFactory::defaultBuilder<LLPanel>(separator_xml_node, NULL, NULL);
+
+ LLRect rc = separator->getRect();
+ rc.setOriginAndSize(0, 0, list->getItemsRect().getWidth(), rc.getHeight());
+ separator->setRect(rc);
+
+ list->addItem(separator, LLUUID::null, ADD_BOTTOM, false);
+}
LLUUID LLCOFWearables::getSelectedUUID()
{
@@ -150,4 +242,17 @@ void LLCOFWearables::clear()
mBodyParts->clear();
}
+LLXMLNodePtr LLCOFWearables::getXMLNode(std::string xml_filename)
+{
+ LLXMLNodePtr xmlNode = NULL;
+ bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, xmlNode);
+ if (!success)
+ {
+ llwarning("Failed to read xml", 0);
+ return NULL;
+ }
+
+ return xmlNode;
+}
+
//EOF
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 58d67ed32f..28d58887da 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -34,6 +34,8 @@
#define LL_LLCOFWEARABLES_H
#include "llpanel.h"
+#include "llinventorymodel.h"
+#include "llappearancemgr.h"
class LLFlatListView;
@@ -52,8 +54,16 @@ public:
protected:
+ void populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items);
+ void populateClothingList(LLAppearanceMgr::wearables_by_type_t& clothing_by_type);
+
+ void addListButtonBar(LLFlatListView* list, std::string xml_filename);
+ void addClothingTypesDummies(const LLAppearanceMgr::wearables_by_type_t& clothing_by_type);
+ void addWearableTypeSeparator(LLFlatListView* list);
void onSelectionChange(LLFlatListView* selected_list);
+ LLXMLNodePtr LLCOFWearables::getXMLNode(std::string xml_filename);
+
LLFlatListView* mAttachments;
LLFlatListView* mClothing;
LLFlatListView* mBodyParts;
diff --git a/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml
new file mode 100644
index 0000000000..9d19b89a61
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+
+<panel
+ follows="left|right|top"
+ height="35"
+ layout="topleft"
+ left="0"
+ name="clothing_list_button_bar_panel"
+ top="0"
+ visible="true"
+ width="300">
+ <button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ label="Switch"
+ layout="topleft"
+ left="5"
+ name="switch_btn"
+ top="5"
+ width="45" />
+ <button
+ follows="top|right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ label="Shop >"
+ layout="topleft"
+ right="-5"
+ name="bodyparts_shop_btn"
+ top="5"
+ width="61" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml
new file mode 100644
index 0000000000..2359719c2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+
+<panel
+ follows="left|right|top"
+ height="35"
+ layout="topleft"
+ left="0"
+ name="clothing_list_button_bar_panel"
+ top="0"
+ visible="true"
+ width="500">
+ <button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ is_toggle="true"
+ label="Add +"
+ layout="topleft"
+ left="5"
+ name="add_btn"
+ top="5"
+ width="45" />
+ <button
+ follows="top|right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ label="Shop >"
+ layout="topleft"
+ right="-5"
+ name="clothing_shop_btn"
+ top="5"
+ width="61" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
index 01c7ae61d2..d8a8dbbea4 100644
--- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
@@ -14,6 +14,7 @@
height="373"
layout="topleft"
left="3"
+ single_expansion="true"
top="0"
name="cof_wearables_accordion"
background_visible="true"