EXT-8205 FIXED (Items in \"Add more\" panel are not sorted by name)

- Modified LLWearableItemTypeNameComparator so that it can be more reusable and adjustable
- Set LLWearableItemTypeNameComparator for WearableItemsList ('List view' of 'Add More' panel) due to sort clothings by name
- Modified and applied patch form https://codereview.productengine.com/secondlife/r/620/diff/2/#index_header. This patch was discarded because specification was changed

Reviewed by Mike Antipov and Vadim Savchuk at https://codereview.productengine.com/secondlife/r/765/

--HG--
branch : product-engine
master
Paul Guslisty 2010-07-21 17:03:00 +03:00
parent 576e70aab2
commit 258f67cd02
4 changed files with 141 additions and 35 deletions

View File

@ -283,6 +283,8 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
delete mCOFDragAndDropObserver;
delete mWearableListViewItemsComparator;
while (!mListViewItemTypes.empty()) {
delete mListViewItemTypes.back();
mListViewItemTypes.pop_back();
@ -386,11 +388,24 @@ 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->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;

View File

@ -64,6 +64,7 @@ class LLMenuGL;
class LLFindNonLinksByMask;
class LLFindWearablesOfType;
class LLSaveOutfitComboBtn;
class LLWearableItemTypeNameComparator;
class LLPanelOutfitEdit : public LLPanel
{
@ -222,6 +223,7 @@ private:
LLFilteredWearableListManager* mWearableListManager;
LLInventoryItemsList* mWearableItemsList;
LLPanel* mWearablesListViewPanel;
LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
LLCOFDragAndDropObserver* mCOFDragAndDropObserver;

View File

@ -465,6 +465,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name):
mOrderPriority(order_priority),
mSortAssetTypeByName(sort_asset_by_name),
mSortWearableTypeByName(sort_wearable_by_name)
{
}
LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
{
// By default the sort order conforms the order by spec of MY OUTFITS items list:
// 1. CLOTHING - sorted by name
// 2. OBJECT - sorted by type
// 3. BODYPART - sorted by name
mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANK_2, true, true);
mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
}
void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type, LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
{
mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name);
}
/*virtual*/
bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
{
@ -493,7 +516,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
return item_type_order1 < item_type_order2;
}
if (item_type_order1 & TLO_SORTABLE_BY_NAME)
if (sortAssetTypeByName(item_type1))
{
// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART
// we can compare them by name.
@ -505,38 +528,61 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
if (item_wearable_type1 != item_wearable_type2)
{
// If items are of different clothing types they are compared
// by clothing types order determined in LLWearableType::EType.
// If items are of different LLWearableType::EType types they are compared
// by LLWearableType::EType. types order determined in LLWearableType::EType.
return item_wearable_type1 < item_wearable_type2;
}
else
{
// If both items are of the same clothing type they are compared
// by description and place in reverse order i.e. outer layer item
// on top.
// by description and place in reverse order (i.e. outer layer item
// on top) OR by name
if(sortWearableTypeByName(item_type1))
{
return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2);
}
return wearable_item1->getDescription() > wearable_item2->getDescription();
}
}
// static
LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type)
LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const
{
switch (item_type)
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
if(const_it == mWearableOrder.end())
{
case LLAssetType::AT_OBJECT:
return TLO_ATTACHMENT;
case LLAssetType::AT_CLOTHING:
return TLO_CLOTHING;
case LLAssetType::AT_BODYPART:
return TLO_BODYPART;
default:
return TLO_UNKNOWN;
llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
return ORDER_RANK_UNKNOWN;
}
return const_it->second.mOrderPriority;
}
bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const
{
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
if(const_it == mWearableOrder.end())
{
llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
return true;
}
return const_it->second.mSortAssetTypeByName;
}
bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
{
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
if(const_it == mWearableOrder.end())
{
llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
return true;
}
return const_it->second.mSortWearableTypeByName;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

View File

@ -307,33 +307,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
LOG_CLASS(LLWearableItemTypeNameComparator);
public:
LLWearableItemTypeNameComparator() {};
LLWearableItemTypeNameComparator();
virtual ~LLWearableItemTypeNameComparator() {};
enum ETypeListOrder
{
ORDER_RANK_1 = 1,
ORDER_RANK_2,
ORDER_RANK_3,
ORDER_RANK_UNKNOWN
};
void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
protected:
/**
* Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following:
* - Attachments (abc order)
* - Clothing
* - by type (types order determined in LLWearableType::EType)
* - outer layer on top
* - Body Parts (abc order),
* "false" otherwise.
* All information about sort order is stored in mWearableOrder map
*
* mWearableOrder : KYES VALUES
* [LLAssetType] [struct LLWearableTypeOrder]
*
*---------------------------------------------------------------------------------------------
* I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
* For example by spec in MY OUTFITS the order is:
* 1. AT_CLOTHING (ORDER_RANK_1)
* 2. AT_OBJECT (ORDER_RANK_2)
* 3. AT_BODYPART (ORDER_RANK_3)
*
* II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
* For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
* 1. AT_OBJECTS (abc order)
* 2. AT_CLOTHINGS
* - by type (types order determined in LLWearableType::EType)
* - outer layer on top
* 3. AT_BODYPARTS (abc order)
*---------------------------------------------------------------------------------------------
*
* For each LLAssetType (KEYS in mWearableOrder) the information about:
*
* I. ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
*
* II. whether items of this LLAssetType type should be ordered
* by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
*
* III.whether items of LLWearableType type within this LLAssetType
* should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName)
*
* holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).
*/
/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
private:
enum ETypeListOrder
{
TLO_CLOTHING = 0x01,
TLO_ATTACHMENT = 0x02,
TLO_BODYPART = 0x04,
TLO_UNKNOWN = 0x08,
TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN
struct LLWearableTypeOrder
{
ETypeListOrder mOrderPriority;
bool mSortAssetTypeByName;
bool mSortWearableTypeByName;
LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name);
LLWearableTypeOrder(){};
};
static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const;
bool sortAssetTypeByName(LLAssetType::EType item_type) const;
bool sortWearableTypeByName(LLAssetType::EType item_type) const;
typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t;
wearable_type_order_map_t mWearableOrder;
};
/**