From 2696e375097c2e45102bede0e7d33175feea080b Mon Sep 17 00:00:00 2001
From: Igor Borovkov <iborovkov@productengine.com>
Date: Tue, 27 Apr 2010 15:23:07 +0300
Subject: [PATCH] partial implementation of EXT-6723 Create specialized view of
 inventory for "clothing" accordion tab of outfit editor

Initial implementation (no sorting, no grayed items from Base outfit)

Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/322

--HG--
branch : product-engine
---
 indra/newview/CMakeLists.txt                  |   2 +
 indra/newview/llcofwearables.cpp              | 153 ++++++++++++++++++
 indra/newview/llcofwearables.h                |  66 ++++++++
 indra/newview/llpaneloutfitedit.cpp           | 123 +++-----------
 indra/newview/llpaneloutfitedit.h             |   6 +-
 .../default/xui/en/panel_cof_wearables.xml    |  65 ++++++++
 .../default/xui/en/panel_outfit_edit.xml      |  29 ++--
 7 files changed, 320 insertions(+), 124 deletions(-)
 create mode 100644 indra/newview/llcofwearables.cpp
 create mode 100644 indra/newview/llcofwearables.h
 create mode 100644 indra/newview/skins/default/xui/en/panel_cof_wearables.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 99ba356d9e0..70fc692a89f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -104,6 +104,7 @@ set(viewer_SOURCE_FILES
     llclassifiedinfo.cpp
     llclassifiedstatsresponder.cpp
     llcloud.cpp
+    llcofwearables.cpp
     llcolorswatch.cpp
     llcommanddispatcherlistener.cpp
     llcommandhandler.cpp
@@ -614,6 +615,7 @@ set(viewer_HEADER_FILES
     llclassifiedinfo.h
     llclassifiedstatsresponder.h
     llcloud.h
+    llcofwearables.h
     llcolorswatch.h
     llcommanddispatcherlistener.h
     llcommandhandler.h
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
new file mode 100644
index 00000000000..f0442ee3f64
--- /dev/null
+++ b/indra/newview/llcofwearables.cpp
@@ -0,0 +1,153 @@
+/** 
+ * @file llcofwearables.cpp
+ * @brief LLCOFWearables displayes wearables from the current outfit split into three lists (attachments, clothing and body parts)
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llcofwearables.h"
+
+#include "llappearancemgr.h"
+#include "llinventory.h"
+#include "llinventoryitemslist.h"
+#include "llinventoryfunctions.h"
+
+static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables");
+
+const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
+
+
+LLCOFWearables::LLCOFWearables() : LLPanel(),
+	mAttachments(NULL),
+	mClothing(NULL),
+	mBodyParts(NULL),
+	mLastSelectedList(NULL)
+{
+};
+
+
+// virtual
+BOOL LLCOFWearables::postBuild()
+{
+	mAttachments = getChild<LLFlatListView>("list_attachments");
+	mClothing = getChild<LLFlatListView>("list_clothing");
+	mBodyParts = getChild<LLFlatListView>("list_body_parts");
+
+
+	//selection across different list/tabs is not supported
+	mAttachments->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mAttachments));
+	mClothing->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mClothing));
+	mBodyParts->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mBodyParts));
+	
+	mAttachments->setCommitOnSelectionChange(true);
+	mClothing->setCommitOnSelectionChange(true);
+	mBodyParts->setCommitOnSelectionChange(true);
+
+	return LLPanel::postBuild();
+}
+
+void LLCOFWearables::onSelectionChange(LLFlatListView* selected_list)
+{
+	if (!selected_list) return;
+
+	if (selected_list != mLastSelectedList)
+	{
+		if (selected_list != mAttachments) mAttachments->resetSelection(true);
+		if (selected_list != mClothing) mClothing->resetSelection(true);
+		if (selected_list != mBodyParts) mBodyParts->resetSelection(true);
+
+		mLastSelectedList = selected_list;
+	}
+
+	onCommit();
+}
+
+void LLCOFWearables::refresh()
+{
+	clear();
+
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	
+	gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
+	if (items.empty()) return;
+
+	for (U32 i = 0; i < items.size(); ++i)
+	{
+		LLViewerInventoryItem* item = items.get(i);
+		if (!item) continue;
+
+		LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
+		if (!item_panel) continue;
+
+		switch (item->getType())
+		{
+			case LLAssetType::AT_OBJECT:
+				mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
+				break;
+
+			case LLAssetType::AT_BODYPART:
+				mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
+				break;
+
+			case LLAssetType::AT_CLOTHING:
+				mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
+				break;
+
+			default: break;
+		}
+	}
+
+	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
+	mClothing->notify(REARRANGE);
+	
+	mBodyParts->sort(); //*TODO by name
+	mBodyParts->notify(REARRANGE);
+}
+
+
+LLUUID LLCOFWearables::getSelectedUUID()
+{
+	if (!mLastSelectedList) return LLUUID::null;
+	
+	return mLastSelectedList->getSelectedUUID();
+}
+
+void LLCOFWearables::clear()
+{
+	mAttachments->clear();
+	mClothing->clear();
+	mBodyParts->clear();
+}
+
+//EOF
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
new file mode 100644
index 00000000000..58d67ed32f8
--- /dev/null
+++ b/indra/newview/llcofwearables.h
@@ -0,0 +1,66 @@
+/** 
+ * @file llcofwearables.h
+ * @brief LLCOFWearables displayes wearables from the current outfit split into three lists (attachments, clothing and body parts)
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCOFWEARABLES_H
+#define LL_LLCOFWEARABLES_H
+
+#include "llpanel.h"
+
+class LLFlatListView;
+
+class LLCOFWearables : public LLPanel
+{
+public:
+	LLCOFWearables();
+	virtual ~LLCOFWearables() {};
+
+	/*virtual*/ BOOL postBuild();
+	
+	LLUUID getSelectedUUID();
+
+	void refresh();
+	void clear();
+
+protected:
+
+	void onSelectionChange(LLFlatListView* selected_list);
+
+	LLFlatListView* mAttachments;
+	LLFlatListView* mClothing;
+	LLFlatListView* mBodyParts;
+
+	LLFlatListView* mLastSelectedList;
+
+};
+
+
+#endif
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index ae181e2819b..dbccd243dad 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -38,6 +38,7 @@
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
+#include "llcofwearables.h"
 #include "llfilteredwearablelist.h"
 #include "llinventory.h"
 #include "llinventoryitemslist.h"
@@ -121,9 +122,15 @@ class LLLookFetchObserver : public LLInventoryFetchDescendentsObserver
 
 
 LLPanelOutfitEdit::LLPanelOutfitEdit()
-:	LLPanel(), mCurrentOutfitID(), mFetchLook(NULL), mSearchFilter(NULL),
-mLookContents(NULL), mInventoryItemsPanel(NULL), mAddToOutfitBtn(NULL),
-mRemoveFromOutfitBtn(NULL), mLookObserver(NULL)
+:	LLPanel(), 
+	mCurrentOutfitID(),
+	mFetchLook(NULL),
+	mSearchFilter(NULL),
+	mCOFWearables(NULL),
+	mInventoryItemsPanel(NULL),
+	mAddToOutfitBtn(NULL),
+	mRemoveFromOutfitBtn(NULL),
+	mLookObserver(NULL)
 {
 	mSavedFolderState = new LLSaveFolderState();
 	mSavedFolderState->setApply(FALSE);
@@ -171,9 +178,8 @@ BOOL LLPanelOutfitEdit::postBuild()
 	childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
 	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL);
 
-	mLookContents = getChild<LLScrollListCtrl>("look_items_list");
-	mLookContents->sortByColumn("look_item_sort", TRUE);
-	mLookContents->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
+	mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
+	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
 
 	mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
 	mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);
@@ -206,15 +212,6 @@ BOOL LLPanelOutfitEdit::postBuild()
 	childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));
 	childSetEnabled("add_to_outfit_btn", false);
 
-	mUpBtn = getChild<LLButton>("up_btn");
-	mUpBtn->setEnabled(TRUE);
-	mUpBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onUpClicked, this));
-	
-	//*TODO rename mLookContents to mOutfitContents
-	mLookContents = getChild<LLScrollListCtrl>("look_items_list");
-	mLookContents->sortByColumn("look_item_sort", TRUE);
-	mLookContents->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
-
 	mRemoveFromOutfitBtn = getChild<LLButton>("remove_from_outfit_btn");
 	mRemoveFromOutfitBtn->setEnabled(FALSE);
 	mRemoveFromOutfitBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onRemoveFromOutfitClicked, this));
@@ -245,7 +242,10 @@ BOOL LLPanelOutfitEdit::postBuild()
 
 void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
 {
-	LLViewerInventoryItem* wearable_to_move = gInventory.getItem(mLookContents->getSelectionInterface()->getCurrentID());
+	LLUUID item_id = mCOFWearables->getSelectedUUID();
+	if (item_id.isNull()) return;
+	
+	LLViewerInventoryItem* wearable_to_move = gInventory.getItem(item_id);
 	LLAppearanceMgr::getInstance()->moveWearable(wearable_to_move, closer_to_body);
 
 	//*TODO why not to listen to inventory?
@@ -374,7 +374,7 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)
 
 void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
 {
-	LLUUID id_to_remove = mLookContents->getSelectionInterface()->getCurrentID();
+	LLUUID id_to_remove = mCOFWearables->getSelectedUUID();
 	
 	LLAppearanceMgr::getInstance()->removeItemFromAvatar(id_to_remove);
 
@@ -384,41 +384,9 @@ void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
 }
 
 
-void LLPanelOutfitEdit::onUpClicked(void)
-{
-	LLUUID inv_id = mLookContents->getSelectionInterface()->getCurrentID();
-	if (inv_id.isNull())
-	{
-		//nothing selected, do nothing
-		return;
-	}
-
-	LLViewerInventoryItem *link_item = gInventory.getItem(inv_id);
-	if (!link_item)
-	{
-		llwarns << "could not find inventory item based on currently worn link." << llendl;
-		return;
-	}
-
-
-	LLUUID asset_id = link_item->getAssetUUID();
-	if (asset_id.isNull())
-	{
-		llwarns << "inventory link has null Asset ID. could not get object reference" << llendl;
-	}
-
-	static const std::string empty = "";
-	LLWearableList::instance().getAsset(asset_id,
-										empty,	// don't care about wearable name
-										link_item->getActualType(),
-										LLSidepanelAppearance::editWearable,
-										(void*)getParentUICtrl());
-}
-
-
 void LLPanelOutfitEdit::onEditWearableClicked(void)
 {
-	LLUUID id_to_edit = mLookContents->getSelectionInterface()->getCurrentID();
+	LLUUID id_to_edit = mCOFWearables->getSelectedUUID();
 	LLViewerInventoryItem * item_to_edit = gInventory.getItem(id_to_edit);
 
 	if (item_to_edit)
@@ -491,29 +459,11 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView
 
 void LLPanelOutfitEdit::onOutfitItemSelectionChange(void)
 {	
-	LLScrollListItem* item = mLookContents->getLastSelectedItem();
-	if (!item)
-		return;
+	LLUUID item_id = mCOFWearables->getSelectedUUID();
 
-	LLRect item_rect;
-	mLookContents->localRectToOtherView(item->getRect(), &item_rect, this);
+	//*TODO show Edit Wearable Button
 
-	// TODO button(and item list) should be removed (when new widget is ready)
-	LLRect btn_rect = mEditWearableBtn->getRect();
-	btn_rect.set(item_rect.mRight - btn_rect.getWidth(), item_rect.mTop, item_rect.mRight, item_rect.mBottom);
-	
-	mEditWearableBtn->setShape(btn_rect);
-	sendChildToFront(mEditWearableBtn);
-	
-	mEditWearableBtn->setEnabled(TRUE);
-	if (!mEditWearableBtn->getVisible())
-	{
-		mEditWearableBtn->setVisible(TRUE);
-	}
-
-
-	const LLUUID& id_item_to_remove = item->getUUID();
-	LLViewerInventoryItem* item_to_remove = gInventory.getItem(id_item_to_remove);
+	LLViewerInventoryItem* item_to_remove = gInventory.getItem(item_id);
 	if (!item_to_remove) return;
 
 	switch (item_to_remove->getType())
@@ -534,34 +484,7 @@ void LLPanelOutfitEdit::changed(U32 mask)
 
 void LLPanelOutfitEdit::lookFetched(void)
 {
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-
-	// collectDescendentsIf takes non-const reference:
-	LLFindCOFValidItems is_cof_valid;
-	gInventory.collectDescendentsIf(mCurrentOutfitID,
-									cat_array,
-									item_array,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_cof_valid);
-	for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
-		 iter != item_array.end();
-		 iter++)
-	{
-		const LLViewerInventoryItem *item = (*iter);
-		
-		LLSD row;
-		row["id"] = item->getUUID();
-		LLSD& columns = row["columns"];
-		columns[0]["column"] = "look_item";
-		columns[0]["type"] = "text";
-		columns[0]["value"] = item->getName();
-		columns[1]["column"] = "look_item_sort";
-		columns[1]["type"] = "text"; // TODO: multi-wearable sort "type" should go here.
-		columns[1]["value"] = item->LLInventoryItem::getDescription();
-		
-		mLookContents->addElement(row);
-	}
+	mCOFWearables->refresh();
 
 	updateVerbs();
 }
@@ -570,8 +493,6 @@ void LLPanelOutfitEdit::updateLookInfo()
 {	
 	if (getVisible())
 	{
-		mLookContents->clearRows();
-
 		mFetchLook->setFetchID(mCurrentOutfitID);
 		mFetchLook->startFetch();
 		if (mFetchLook->isFinished())
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index b6f121d4846..21fa8492899 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -45,6 +45,7 @@
 #include "llinventorymodel.h"
 
 class LLButton;
+class LLCOFWearables;
 class LLTextBox;
 class LLInventoryCategory;
 class LLInventoryLookObserver;
@@ -102,7 +103,6 @@ class LLPanelOutfitEdit : public LLPanel
 	void onOutfitItemSelectionChange(void);
 	void onRemoveFromOutfitClicked(void);
 	void onEditWearableClicked(void);
-	void onUpClicked(void);
 
 	void displayCurrentOutfit();
 	
@@ -118,14 +118,12 @@ class LLPanelOutfitEdit : public LLPanel
 	LLUUID				mCurrentOutfitID;
 
 	LLTextBox*			mCurrentOutfitName;
-	LLScrollListCtrl*	mLookContents;
 	LLInventoryPanel*	mInventoryItemsPanel;
 	LLFilterEditor*		mSearchFilter;
 	LLSaveFolderState*	mSavedFolderState;
 	std::string			mSearchString;
 	LLButton*			mAddToOutfitBtn;
 	LLButton*			mRemoveFromOutfitBtn;
-	LLButton*			mUpBtn;
 	LLButton*			mEditWearableBtn;
 	LLToggleableMenu*	mSaveMenu;
 
@@ -134,6 +132,8 @@ class LLPanelOutfitEdit : public LLPanel
 	LLLookFetchObserver*		mFetchLook;
 	LLInventoryLookObserver*	mLookObserver;
 	std::vector<LLLookItemType> mLookItemTypes;
+
+	LLCOFWearables*		mCOFWearables;
 };
 
 #endif // LL_LLPANELOUTFITEDIT_H
diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
new file mode 100644
index 00000000000..01c7ae61d24
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bg_alpha_color="DkGray"
+ border="false"
+ bottom="0"
+ follows="all"
+ height="200"
+ left="0"
+ name="cof_wearables"
+ width="313">
+    <accordion
+     follows="all"
+     height="373"
+     layout="topleft"
+     left="3"
+     top="0"
+     name="cof_wearables_accordion"
+     background_visible="true"
+     bg_alpha_color="DkGray2"
+     width="307">
+        <accordion_tab
+         layout="topleft"
+         name="tab_attachments"
+         title="Attachments">
+            <flat_list_view
+             allow_select="true"
+             follows="all"
+             height="150"
+             layout="topleft"
+             left="0"
+             name="list_attachments"
+             top="0"
+             width="307" />
+        </accordion_tab>
+        <accordion_tab
+         layout="topleft"
+         name="tab_clothing"
+         title="Clothing">
+            <flat_list_view
+             allow_select="true"
+             follows="all"
+             height="150"
+             layout="topleft"
+             left="0"
+             name="list_clothing"
+             top="0"
+             width="307" />
+        </accordion_tab>
+        <accordion_tab
+         layout="topleft"
+         name="tab_body_parts"
+         title="Body Parts">
+            <flat_list_view
+             allow_select="true"
+             follows="all"
+             height="150"
+             layout="topleft"
+             left="0"
+             name="list_body_parts"
+             top="0"
+             width="307" />
+        </accordion_tab>
+    </accordion>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index 314d2389ae0..73181392c9d 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -149,29 +149,18 @@
          auto_resize="true"
          user_resize="true">
 
-            <scroll_list
-             width="300"
-             column_padding="0"
-             draw_heading="false"
-             draw_stripes="false"
+            <!-- List containing items from the COF and Base outfit -->
+            <panel
+             background_visible="false"
+             class="cof_wearables"
+             filename="panel_cof_wearables.xml"
              follows="left|top|right|bottom"
+             height="193"
              layout="topleft"
-             name="look_items_list"
-             search_column="1"
-             sort_column="2"
              left="0"
-             height="193"
-             top="0">
-                <scroll_list.columns
-                 label="Look Item"
-                 name="look_item"
-                 width="285" />
-                <scroll_list.columns
-                 label="Outfit Item Sort"
-                 width="0"
-                 sort_column="look_item_sort"
-                 name="look_item_sort" />
-            </scroll_list>
+             name="cof_wearables_list"
+             top="0"
+             width="300" /> 
 
           <panel
              background_visible="true"
-- 
GitLab