EXT-7472 FIXED Open add to outfit panel by (+) button click on unwearable items and by selecting 'Replace' menu item click body part context menu

Main changes:
- Added callback for a '(+) button' to the LLCOFCallbacks and bind it with LLPanelOutfitEdit::onAddWearableClicked
- Created the callback(LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked) for 'Replace' menu item of context menu

Related changes:
- Changed LLFilteredWearableListManager so that it can use different functors (subclasses of LLInventoryCollectFunctor) as a criterion for LLInventoryItemsList filtering. Before it used only LLFindNonLinksByMask filter. Moved LLFindNonLinksByMask from to the llfilteredwearablelist.cpp to the llinventoryfunctions.h
- Created getter 'LLPanelDummyClothingListItem::getWearableType()' for LLPanelDummyClothingListItem
- Made 'add wearables panel' a member of LLPanelOutfitEdit so that not to use findChild each time panel is needed

Reviewed by Igor Borovkov at http://jira.secondlife.com/browse/EXT-7472

--HG--
branch : product-engine
master
Paul Guslisty 2010-05-28 20:10:10 +03:00
parent d2cc5dd0f5
commit d42fd6cf7f
10 changed files with 134 additions and 44 deletions

View File

@ -43,6 +43,8 @@
#include "llmenugl.h"
#include "llviewermenu.h"
#include "llwearableitemslist.h"
#include "llpaneloutfitedit.h"
#include "llsidetray.h"
static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor");
@ -135,8 +137,10 @@ protected:
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
LLUUID selected_id = mUUIDs.back();
registrar.add("BodyPart.Replace", boost::bind(&LLAppearanceMgr::wearItemOnAvatar,
LLAppearanceMgr::getInstance(), selected_id, true, true));
// *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel().
// LLSideTray::getInstance()->getPanel() is rather slow variant
LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit"));
registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));
registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2));
@ -416,6 +420,7 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by
LLWearableType::EType w_type = static_cast<LLWearableType::EType>(type);
LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type);
if(!item_panel) continue;
item_panel->childSetAction("btn_add", mCOFCallbacks.mAddWearable);
mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false);
}
}
@ -435,6 +440,13 @@ bool LLCOFWearables::getSelectedUUIDs(uuid_vec_t& selected_ids)
return selected_ids.size() != 0;
}
LLPanel* LLCOFWearables::getSelectedItem()
{
if (!mLastSelectedList) return NULL;
return mLastSelectedList->getSelectedItem();
}
void LLCOFWearables::clear()
{
mAttachments->clear();

View File

@ -107,6 +107,7 @@ public:
typedef boost::function<void (void*)> cof_callback_t;
cof_callback_t mAddWearable;
cof_callback_t mMoveWearableCloser;
cof_callback_t mMoveWearableFurther;
cof_callback_t mEditWearable;
@ -123,6 +124,8 @@ public:
LLUUID getSelectedUUID();
bool getSelectedUUIDs(uuid_vec_t& selected_ids);
LLPanel* getSelectedItem();
void refresh();
void clear();

View File

@ -37,32 +37,10 @@
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
class LLFindNonLinksByMask : public LLInventoryCollectFunctor
{
public:
LLFindNonLinksByMask(U64 mask)
: mFilterMask(mask)
{}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
{
return true;
}
return false;
}
private:
U64 mFilterMask;
};
//////////////////////////////////////////////////////////////////////////
LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask)
LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)
: mWearableList(list)
, mFilterMask(filter_mask)
, mCollector(collector)
{
llassert(mWearableList);
gInventory.addObserver(this);
@ -84,9 +62,9 @@ void LLFilteredWearableListManager::changed(U32 mask)
populateList();
}
void LLFilteredWearableListManager::setFilterMask(U64 mask)
void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor* collector)
{
mFilterMask = mask;
mCollector = collector;
populateList();
}
@ -94,14 +72,16 @@ void LLFilteredWearableListManager::populateList()
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindNonLinksByMask collector(mFilterMask);
gInventory.collectDescendentsIf(
gInventory.getRootFolderID(),
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
collector);
if(mCollector)
{
gInventory.collectDescendentsIf(
gInventory.getRootFolderID(),
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
*mCollector);
}
// Probably will also need to get items from Library (waiting for reply in EXT-6724).

View File

@ -32,6 +32,7 @@
#ifndef LL_LLFILTEREDWEARABLELIST_H
#define LL_LLFILTEREDWEARABLELIST_H
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
class LLInventoryItemsList;
@ -42,7 +43,7 @@ class LLFilteredWearableListManager : public LLInventoryObserver
LOG_CLASS(LLFilteredWearableListManager);
public:
LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask);
LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector);
~LLFilteredWearableListManager();
/** LLInventoryObserver implementation
@ -51,9 +52,9 @@ public:
/*virtual*/ void changed(U32 mask);
/**
* Sets new filter and applies it immediately
* Sets new collector and applies it immediately
*/
void setFilterMask(U64 mask);
void setFilterCollector(LLInventoryCollectFunctor* collector);
/**
* Populates wearable list with filtered data.
@ -62,7 +63,7 @@ public:
private:
LLInventoryItemsList* mWearableList;
U64 mFilterMask;
LLInventoryCollectFunctor* mCollector;
};
#endif //LL_LLFILTEREDWEARABLELIST_H

View File

@ -372,6 +372,11 @@ bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem
return true;
}
void LLFindWearablesOfType::setType(LLWearableType::EType type)
{
mWearableType = type;
}
///----------------------------------------------------------------------------
/// LLAssetIDMatches
///----------------------------------------------------------------------------

View File

@ -251,6 +251,37 @@ public:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindNonLinksByMask
//
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFindNonLinksByMask : public LLInventoryCollectFunctor
{
public:
LLFindNonLinksByMask(U64 mask)
: mFilterMask(mask)
{}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
{
return true;
}
return false;
}
void setFilterMask(U64 mask)
{
mFilterMask = mask;
}
private:
U64 mFilterMask;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindWearables
//
@ -272,8 +303,10 @@ public:
LLFindWearablesOfType(LLWearableType::EType type) : mWearableType(type) {}
virtual ~LLFindWearablesOfType() {}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
void setType(LLWearableType::EType type);
const LLWearableType::EType mWearableType;
private:
LLWearableType::EType mWearableType;
};
/** Inventory Collector Functions

View File

@ -67,6 +67,7 @@
#include "llsidepanelappearance.h"
#include "lltoggleablemenu.h"
#include "llwearablelist.h"
#include "llwearableitemslist.h"
static LLRegisterPanelClassWrapper<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit");
@ -214,7 +215,10 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()
mCOFObserver(NULL),
mGearMenu(NULL),
mCOFDragAndDropObserver(NULL),
mInitialized(false)
mInitialized(false),
mAddWearablesPanel(NULL),
mWearableListMaskCollector(NULL),
mWearableListTypeCollector(NULL)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
@ -236,6 +240,9 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
delete mCOFObserver;
delete mCOFDragAndDropObserver;
delete mWearableListMaskCollector;
delete mWearableListTypeCollector;
}
BOOL LLPanelOutfitEdit::postBuild()
@ -261,6 +268,7 @@ BOOL LLPanelOutfitEdit::postBuild()
mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this);
mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this);
mCOFWearables->getCOFCallbacks().mDeleteWearable = boost::bind(&LLPanelOutfitEdit::onRemoveFromOutfitClicked, this);
mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true);
@ -268,6 +276,7 @@ BOOL LLPanelOutfitEdit::postBuild()
mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this));
mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel");
mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);
@ -306,9 +315,12 @@ BOOL LLPanelOutfitEdit::postBuild()
save_registar.add("Outfit.SaveAsNew.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_save_outfit.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mWearableListMaskCollector = new LLFindNonLinksByMask(ALL_ITEMS_MASK);
mWearableListTypeCollector = new LLFindWearablesOfType(LLWearableType::WT_NONE);
mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel");
mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list");
mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, ALL_ITEMS_MASK);
mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector);
return TRUE;
}
@ -334,7 +346,8 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
void LLPanelOutfitEdit::toggleAddWearablesPanel()
{
childSetVisible("add_wearables_panel", !childIsVisible("add_wearables_panel"));
BOOL current_visibility = mAddWearablesPanel->getVisible();
mAddWearablesPanel->setVisible(!current_visibility);
}
void LLPanelOutfitEdit::showWearablesFilter()
@ -407,7 +420,9 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)
{
U32 curr_filter_type = type_filter->getCurrentIndex();
mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask);
mWearableListManager->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
mWearableListManager->setFilterCollector(mWearableListMaskCollector);
}
mSavedFolderState->setApply(TRUE);
@ -487,6 +502,25 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)
LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id);
}
void LLPanelOutfitEdit::onAddWearableClicked(void)
{
LLPanelDummyClothingListItem* item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem());
if(item)
{
showFilteredWearableItemsList(item->getWearableType());
}
}
void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id)
{
LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
if (item && item->getType() == LLAssetType::AT_BODYPART)
{
showFilteredWearableItemsList(item->getWearableType());
}
}
void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
{
@ -722,4 +756,11 @@ void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data)
}
}
void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type)
{
mWearableListTypeCollector->setType(type);
mWearableListManager->setFilterCollector(mWearableListTypeCollector);
mAddWearablesPanel->setVisible(TRUE);
}
// EOF

View File

@ -59,6 +59,8 @@ class LLToggleableMenu;
class LLFilterEditor;
class LLFilteredWearableListManager;
class LLMenuGL;
class LLFindNonLinksByMask;
class LLFindWearablesOfType;
class LLPanelOutfitEdit : public LLPanel
{
@ -103,6 +105,8 @@ public:
void onOutfitItemSelectionChange(void);
void onRemoveFromOutfitClicked(void);
void onEditWearableClicked(void);
void onAddWearableClicked(void);
void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id);
void displayCurrentOutfit();
void updateCurrentOutfitName();
@ -129,6 +133,7 @@ private:
void onGearButtonClick(LLUICtrl* clicked_button);
void onGearMenuItemClick(const LLSD& data);
void showFilteredWearableItemsList(LLWearableType::EType type);
LLTextBox* mCurrentOutfitName;
@ -141,6 +146,10 @@ private:
LLButton* mFolderViewBtn;
LLButton* mListViewBtn;
LLToggleableMenu* mSaveMenu;
LLPanel* mAddWearablesPanel;
LLFindNonLinksByMask* mWearableListMaskCollector;
LLFindWearablesOfType* mWearableListTypeCollector;
LLFilteredWearableListManager* mWearableListManager;
LLInventoryItemsList* mWearableItemsList;

View File

@ -251,6 +251,11 @@ BOOL LLPanelDummyClothingListItem::postBuild()
return TRUE;
}
LLWearableType::EType LLPanelDummyClothingListItem::getWearableType() const
{
return mWearableType;
}
LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(LLWearableType::EType w_type)
: LLPanelWearableListItem(NULL)
, mWearableType(w_type)

View File

@ -162,6 +162,7 @@ public:
/*virtual*/ void updateItem();
/*virtual*/ BOOL postBuild();
LLWearableType::EType getWearableType() const;
protected:
LLPanelDummyClothingListItem(LLWearableType::EType w_type);