EXT-7676 FIXED Restored fix (47df1b3fd94e) reverted in merge 5b5cc4a8642d with slight modifications.

- Replaced pointers passed to 'Add More' gear menu with LLHandle.
- Removed storing 'Add More' panel sort order from settings because the order is changed each time the panel opens.
- Replaced creating items comparator in LLPanelOutfitEdit::postBuild() with a static comparator in llwearableitemslist.cpp.

Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/826/.

--HG--
branch : product-engine
meow-7.2.2
Sergei Litovchuk 2010-08-02 20:52:17 +03:00
parent 713417aeeb
commit e5b33c31c3
5 changed files with 272 additions and 37 deletions

View File

@ -35,17 +35,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>AddWearableSortOrder</key>
<map>
<key>Comment</key>
<string>Specifies sort order for add wearable panel (0 = name, 1 = date, 2 = by type)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AgentPause</key>
<map>
<key>Comment</key>

View File

@ -86,6 +86,11 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
static const std::string REVERT_BTN("revert_btn");
///////////////////////////////////////////////////////////////////////////////
// LLShopURLDispatcher
///////////////////////////////////////////////////////////////////////////////
class LLShopURLDispatcher
{
public:
@ -145,6 +150,10 @@ std::string LLShopURLDispatcher::resolveURL(LLAssetType::EType asset_type, ESex
return gSavedSettings.getString(setting_name);
}
///////////////////////////////////////////////////////////////////////////////
// LLPanelOutfitEditGearMenu
///////////////////////////////////////////////////////////////////////////////
class LLPanelOutfitEditGearMenu
{
public:
@ -160,7 +169,6 @@ public:
if (menu)
{
populateCreateWearableSubmenus(menu);
menu->buildDrawLabels();
}
return menu;
@ -209,6 +217,147 @@ private:
}
};
///////////////////////////////////////////////////////////////////////////////
// LLAddWearablesGearMenu
///////////////////////////////////////////////////////////////////////////////
class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu>
{
public:
static LLMenuGL* create(LLWearableItemsList* flat_list, LLInventoryPanel* inventory_panel)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
llassert(flat_list);
llassert(inventory_panel);
LLHandle<LLView> flat_list_handle = flat_list->getHandle();
LLHandle<LLPanel> inventory_panel_handle = inventory_panel->getHandle();
registrar.add("AddWearable.Gear.Sort", boost::bind(onSort, flat_list_handle, inventory_panel_handle, _2));
enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list_handle, inventory_panel_handle, _2));
enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel_handle, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
"menu_add_wearable_gear.xml",
LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
return menu;
}
private:
static void onSort(LLHandle<LLView> flat_list_handle,
LLHandle<LLPanel> inventory_panel_handle,
LLSD::String sort_order_str)
{
if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return;
LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get());
LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
if (!flat_list || !inventory_panel) return;
LLWearableItemsList::ESortOrder sort_order;
if ("by_most_recent" == sort_order_str)
{
sort_order = LLWearableItemsList::E_SORT_BY_MOST_RECENT;
}
else if ("by_name" == sort_order_str)
{
sort_order = LLWearableItemsList::E_SORT_BY_NAME;
}
else if ("by_type" == sort_order_str)
{
sort_order = LLWearableItemsList::E_SORT_BY_TYPE_NAME;
}
else
{
llwarns << "Unrecognized sort order action" << llendl;
return;
}
if (inventory_panel->getVisible())
{
inventory_panel->setSortOrder(sort_order);
}
else
{
flat_list->setSortOrder(sort_order);
}
}
static bool onCheck(LLHandle<LLView> flat_list_handle,
LLHandle<LLPanel> inventory_panel_handle,
LLSD::String sort_order_str)
{
if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return false;
LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get());
LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
if (!inventory_panel || !flat_list) return false;
// Inventory panel uses its own sort order independent from
// flat list view so this flag is used to distinguish between
// currently visible "tree" or "flat" representation of inventory.
bool inventory_tree_visible = inventory_panel->getVisible();
if (inventory_tree_visible)
{
U32 sort_order = inventory_panel->getSortOrder();
if ("by_most_recent" == sort_order_str)
{
return LLWearableItemsList::E_SORT_BY_MOST_RECENT & sort_order;
}
else if ("by_name" == sort_order_str)
{
// If inventory panel is not sorted by date then it is sorted by name.
return LLWearableItemsList::E_SORT_BY_MOST_RECENT & ~sort_order;
}
llwarns << "Unrecognized inventory panel sort order" << llendl;
}
else
{
LLWearableItemsList::ESortOrder sort_order = flat_list->getSortOrder();
if ("by_most_recent" == sort_order_str)
{
return LLWearableItemsList::E_SORT_BY_MOST_RECENT == sort_order;
}
else if ("by_name" == sort_order_str)
{
return LLWearableItemsList::E_SORT_BY_NAME == sort_order;
}
else if ("by_type" == sort_order_str)
{
return LLWearableItemsList::E_SORT_BY_TYPE_NAME == sort_order;
}
llwarns << "Unrecognized wearable list sort order" << llendl;
}
return false;
}
static bool onVisible(LLHandle<LLPanel> inventory_panel_handle,
LLSD::String sort_order_str)
{
if (inventory_panel_handle.isDead()) return false;
LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
// Enable sorting by type only for the flat list of items
// because inventory panel doesn't support this kind of sorting.
return ( "by_type" == sort_order_str )
&& ( !inventory_panel || !inventory_panel->getVisible() );
}
};
///////////////////////////////////////////////////////////////////////////////
// LLCOFDragAndDropObserver
///////////////////////////////////////////////////////////////////////////////
class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver
{
public:
@ -244,12 +393,17 @@ void LLCOFDragAndDropObserver::done()
LLAppearanceMgr::instance().updateAppearanceFromCOF();
}
///////////////////////////////////////////////////////////////////////////////
// LLPanelOutfitEdit
///////////////////////////////////////////////////////////////////////////////
LLPanelOutfitEdit::LLPanelOutfitEdit()
: LLPanel(),
mSearchFilter(NULL),
mCOFWearables(NULL),
mInventoryItemsPanel(NULL),
mGearMenu(NULL),
mAddWearablesGearMenu(NULL),
mCOFDragAndDropObserver(NULL),
mInitialized(false),
mAddWearablesPanel(NULL),
@ -284,8 +438,6 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
delete mCOFDragAndDropObserver;
delete mWearableListViewItemsComparator;
while (!mListViewItemTypes.empty()) {
delete mListViewItemTypes.back();
mListViewItemTypes.pop_back();
@ -391,24 +543,11 @@ 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 = getChild<LLWearableItemsList>("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;
@ -462,6 +601,17 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)
showWearablesFilter();
/*
* 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)
*/
mWearableItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_TYPE_NAME);
// Reset mWearableItemsList position to top. See EXT-8180.
mWearableItemsList->goToTop();
}
@ -1063,13 +1213,33 @@ void LLPanelOutfitEdit::resetAccordionState()
void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
{
if(!mGearMenu)
LLMenuGL* menu = NULL;
if (mAddWearablesPanel->getVisible())
{
mGearMenu = LLPanelOutfitEditGearMenu::create();
if (!mAddWearablesGearMenu)
{
mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel);
}
menu = mAddWearablesGearMenu;
}
else
{
if (!mGearMenu)
{
mGearMenu = LLPanelOutfitEditGearMenu::create();
}
menu = mGearMenu;
}
S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight();
LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);
if (!menu) return;
menu->arrangeAndClear(); // update menu height
S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight();
menu->buildDrawLabels();
LLMenuGL::showPopup(clicked_button, menu, 0, menu_y);
}
void LLPanelOutfitEdit::onAddMoreButtonClicked()

View File

@ -43,8 +43,8 @@
#include "llremoteparcelrequest.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
#include "llwearableitemslist.h"
class LLButton;
class LLCOFWearables;
@ -230,9 +230,8 @@ private:
LLComboBox* mListViewFilterCmbBox;
LLFilteredWearableListManager* mWearableListManager;
LLInventoryItemsList* mWearableItemsList;
LLWearableItemsList* mWearableItemsList;
LLPanel* mWearablesListViewPanel;
LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
@ -241,6 +240,7 @@ private:
LLCOFWearables* mCOFWearables;
LLMenuGL* mGearMenu;
LLMenuGL* mAddWearablesGearMenu;
bool mInitialized;
std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;

View File

@ -583,11 +583,28 @@ bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType
return const_it->second.mSortWearableTypeByName;
}
/*virtual*/
bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const
{
time_t date1 = item1->getCreationDate();
time_t date2 = item2->getCreationDate();
if (date1 == date2)
{
return LLWearableItemNameComparator::doCompare(item1, item2);
}
return date1 > date2;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
static LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
static const LLWearableItemTypeNameComparator WEARABLE_TYPE_LAYER_COMPARATOR;
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
static const LLWearableItemCreationDateComparator WEARABLE_CREATION_DATE_COMPARATOR;
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
@ -599,7 +616,7 @@ LLWearableItemsList::Params::Params()
LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
: LLInventoryItemsList(p)
{
setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
setSortOrder(E_SORT_BY_TYPE_LAYER, false);
mIsStandalone = p.standalone;
if (mIsStandalone)
{
@ -699,6 +716,38 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)
ContextMenu::instance().show(this, selected_uuids, x, y);
}
void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now)
{
switch (sort_order)
{
case E_SORT_BY_MOST_RECENT:
setComparator(&WEARABLE_CREATION_DATE_COMPARATOR);
break;
case E_SORT_BY_NAME:
setComparator(&WEARABLE_NAME_COMPARATOR);
break;
case E_SORT_BY_TYPE_LAYER:
setComparator(&WEARABLE_TYPE_LAYER_COMPARATOR);
break;
case E_SORT_BY_TYPE_NAME:
{
WEARABLE_TYPE_NAME_COMPARATOR.setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true);
setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
break;
}
// No "default:" to raise compiler warning
// if we're not handling something
}
mSortOrder = sort_order;
if (sort_now)
{
sort();
}
}
//////////////////////////////////////////////////////////////////////////
/// ContextMenu
//////////////////////////////////////////////////////////////////////////

View File

@ -379,6 +379,19 @@ private:
wearable_type_order_map_t mWearableOrder;
};
/**
* @class LLWearableItemCreationDateComparator
*
* Comparator for sorting wearable list items by creation date (newest go first).
*/
class LLWearableItemCreationDateComparator : public LLWearableItemNameComparator
{
LOG_CLASS(LLWearableItemCreationDateComparator);
protected:
/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const;
};
/**
* @class LLWearableItemsList
*
@ -431,6 +444,14 @@ public:
Params();
};
typedef enum e_sort_order {
// Values should be compatible with InventorySortOrder setting.
E_SORT_BY_NAME = 0,
E_SORT_BY_MOST_RECENT = 1,
E_SORT_BY_TYPE_LAYER = 2,
E_SORT_BY_TYPE_NAME = 3,
} ESortOrder;
virtual ~LLWearableItemsList();
/*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
@ -445,6 +466,10 @@ public:
bool isStandalone() const { return mIsStandalone; }
ESortOrder getSortOrder() const { return mSortOrder; }
void setSortOrder(ESortOrder sort_order, bool sort_now = true);
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLWearableItemsList::Params& p);
@ -453,6 +478,8 @@ protected:
bool mIsStandalone;
bool mWornIndicationEnabled;
ESortOrder mSortOrder;
};
#endif //LL_LLWEARABLEITEMSLIST_H