summaryrefslogtreecommitdiff
path: root/indra/newview/llcofwearables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llcofwearables.cpp')
-rw-r--r--indra/newview/llcofwearables.cpp164
1 files changed, 161 insertions, 3 deletions
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 7c4ceb3458..ee366f4e3c 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -35,10 +35,16 @@
#include "llcofwearables.h"
#include "llagentdata.h"
+#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
+#include "lllistcontextmenu.h"
+#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");
@@ -49,14 +55,132 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
+//////////////////////////////////////////////////////////////////////////
+
+class CofAttachmentContextMenu : public LLListContextMenu
+{
+protected:
+
+ /*virtual*/ LLContextMenu* createMenu()
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
+ registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
+
+ return createFromFile("menu_cof_attachment.xml");
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+class CofClothingContextMenu : public LLListContextMenu
+{
+protected:
+
+ /*virtual*/ LLContextMenu* createMenu()
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ LLUUID selected_id = mUUIDs.back();
+ functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
+
+ registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
+ registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false));
+ registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true));
+ registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
+
+ enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2));
+
+ return createFromFile("menu_cof_clothing.xml");
+ }
+
+ bool onEnable(const LLSD& data)
+ {
+ std::string param = data.asString();
+ LLUUID selected_id = mUUIDs.back();
+
+ if ("move_up" == param)
+ {
+ return gAgentWearables.canMoveWearable(selected_id, false);
+ }
+ else if ("move_down" == param)
+ {
+ return gAgentWearables.canMoveWearable(selected_id, true);
+ }
+ else if ("edit" == param)
+ {
+ return gAgentWearables.isWearableModifiable(selected_id);
+ }
+ return true;
+ }
+
+ // We don't use LLAppearanceMgr::moveWearable() directly because
+ // the item may be invalidated between setting the callback and calling it.
+ static bool moveWearable(const LLUUID& item_id, bool closer_to_body)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ return LLAppearanceMgr::instance().moveWearable(item, closer_to_body);
+ }
+
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+class CofBodyPartContextMenu : public LLListContextMenu
+{
+protected:
+
+ /*virtual*/ LLContextMenu* createMenu()
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ LLUUID selected_id = mUUIDs.back();
+
+ // *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));
+
+ return createFromFile("menu_cof_body_part.xml");
+ }
+
+ bool onEnable(const LLSD& data)
+ {
+ std::string param = data.asString();
+ LLUUID selected_id = mUUIDs.back();
+
+ if ("edit" == param)
+ {
+ return gAgentWearables.isWearableModifiable(selected_id);
+ }
+
+ return true;
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////
+
LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachments(NULL),
mClothing(NULL),
mBodyParts(NULL),
mLastSelectedList(NULL)
{
+ mClothingMenu = new CofClothingContextMenu();
+ mAttachmentMenu = new CofAttachmentContextMenu();
+ mBodyPartMenu = new CofBodyPartContextMenu();
};
+LLCOFWearables::~LLCOFWearables()
+{
+ delete mClothingMenu;
+ delete mAttachmentMenu;
+ delete mBodyPartMenu;
+}
// virtual
BOOL LLCOFWearables::postBuild()
@@ -65,6 +189,9 @@ BOOL LLCOFWearables::postBuild()
mClothing = getChild<LLFlatListView>("list_clothing");
mBodyParts = getChild<LLFlatListView>("list_body_parts");
+ mClothing->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mClothingMenu));
+ mAttachments->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mAttachmentMenu));
+ mBodyParts->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mBodyPartMenu));
//selection across different list/tabs is not supported
mAttachments->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mAttachments));
@@ -185,13 +312,15 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel
LLPanelClothingListItem* LLCOFWearables::buildClothingListItem(LLViewerInventoryItem* item, bool first, bool last)
{
llassert(item);
-
+ if (!item) return NULL;
LLPanelClothingListItem* item_panel = LLPanelClothingListItem::create(item);
if (!item_panel) return NULL;
//updating verbs
//we don't need to use permissions of a link but of an actual/linked item
if (item->getLinkedItem()) item = item->getLinkedItem();
+ llassert(item);
+ if (!item) return NULL;
bool allow_modify = item->getPermissions().allowModifyBy(gAgentID);
@@ -217,14 +346,15 @@ LLPanelClothingListItem* LLCOFWearables::buildClothingListItem(LLViewerInventory
LLPanelBodyPartsListItem* LLCOFWearables::buildBodypartListItem(LLViewerInventoryItem* item)
{
llassert(item);
-
+ if (!item) return NULL;
LLPanelBodyPartsListItem* item_panel = LLPanelBodyPartsListItem::create(item);
if (!item_panel) return NULL;
//updating verbs
//we don't need to use permissions of a link but of an actual/linked item
if (item->getLinkedItem()) item = item->getLinkedItem();
-
+ llassert(item);
+ if (!item) return NULL;
bool allow_modify = item->getPermissions().allowModifyBy(gAgentID);
item_panel->setShowLockButton(!allow_modify);
item_panel->setShowEditButton(allow_modify);
@@ -293,6 +423,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);
}
}
@@ -304,6 +435,21 @@ LLUUID LLCOFWearables::getSelectedUUID()
return mLastSelectedList->getSelectedUUID();
}
+bool LLCOFWearables::getSelectedUUIDs(uuid_vec_t& selected_ids)
+{
+ if (!mLastSelectedList) return false;
+
+ mLastSelectedList->getSelectedUUIDs(selected_ids);
+ return selected_ids.size() != 0;
+}
+
+LLPanel* LLCOFWearables::getSelectedItem()
+{
+ if (!mLastSelectedList) return NULL;
+
+ return mLastSelectedList->getSelectedItem();
+}
+
void LLCOFWearables::clear()
{
mAttachments->clear();
@@ -311,4 +457,16 @@ void LLCOFWearables::clear()
mBodyParts->clear();
}
+void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)
+{
+ if(menu)
+ {
+ uuid_vec_t selected_uuids;
+ if(getSelectedUUIDs(selected_uuids))
+ {
+ menu->show(ctrl, selected_uuids, x, y);
+ }
+ }
+}
+
//EOF