summaryrefslogtreecommitdiff
path: root/indra/newview/llpaneloutfitsinventory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpaneloutfitsinventory.cpp')
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp261
1 files changed, 225 insertions, 36 deletions
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index a7e8f497d9..5563214407 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -42,6 +42,7 @@
#include "llfloaterworldmap.h"
#include "llfloaterinventory.h"
#include "llfoldervieweventlistener.h"
+#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
@@ -49,7 +50,9 @@
#include "lllineeditor.h"
#include "llmodaldialog.h"
#include "llnotificationsutil.h"
+#include "lloutfitobserver.h"
#include "lloutfitslist.h"
+#include "llsaveoutfitcombobtn.h"
#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "lltabcontainer.h"
@@ -69,20 +72,190 @@ static const std::string COF_TAB_NAME = "cof_tab";
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
+class LLOutfitListGearMenu
+{
+public:
+ LLOutfitListGearMenu(LLOutfitsList* olist)
+ : mOutfitList(olist),
+ mMenu(NULL)
+ {
+ llassert_always(mOutfitList);
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this));
+ registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this));
+ registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
+ registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this));
+ registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
+
+ enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
+ enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
+
+ mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
+ "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ llassert(mMenu);
+ }
+
+ LLMenuGL* getMenu() { return mMenu; }
+
+ void show(LLView* spawning_view)
+ {
+ if (!mMenu) return;
+
+ updateItemsVisibility();
+ mMenu->buildDrawLabels();
+ mMenu->updateParent(LLMenuGL::sMenuContainer);
+ S32 menu_x = 0;
+ S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight();
+ LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y);
+ }
+
+ void updateItemsVisibility()
+ {
+ if (!mMenu) return;
+
+ bool have_selection = getSelectedOutfitID().notNull();
+ mMenu->setItemVisible("sepatator1", have_selection);
+ mMenu->setItemVisible("sepatator2", have_selection);
+ mMenu->arrangeAndClear(); // update menu height
+ }
+
+private:
+ const LLUUID& getSelectedOutfitID()
+ {
+ return mOutfitList->getSelectedOutfitUUID();
+ }
+
+ LLViewerInventoryCategory* getSelectedOutfit()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.isNull())
+ {
+ return NULL;
+ }
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
+ return cat;
+ }
+
+ void onWear()
+ {
+ LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
+ if (selected_outfit)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory(
+ selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
+ }
+ }
+
+ void onTakeOff()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
+ }
+ }
+
+ void onRename()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
+ }
+ }
+
+ void onDelete()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ remove_category(&gInventory, selected_outfit_id);
+ }
+ }
+
+ void onCreate(const LLSD& data)
+ {
+ LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
+ if (type == LLWearableType::WT_NONE)
+ {
+ llwarns << "Invalid wearable type" << llendl;
+ return;
+ }
+
+ LLAgentWearables::createWearable(type, true);
+ }
+
+ bool onEnable(LLSD::String param)
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
+ {
+ return false;
+ }
+
+ if ("rename" == param)
+ {
+ return get_is_category_renameable(&gInventory, selected_outfit_id);
+ }
+ else if ("delete" == param)
+ {
+ return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id);
+ }
+
+ return true;
+ }
+
+ bool onVisible(LLSD::String param)
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
+ {
+ return false;
+ }
+
+ bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
+
+ if ("wear" == param)
+ {
+ return !is_worn;
+ }
+ else if ("take_off" == param)
+ {
+ return is_worn;
+ }
+
+ return true;
+ }
+
+ LLOutfitsList* mOutfitList;
+ LLMenuGL* mMenu;
+};
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mMyOutfitsPanel(NULL),
mCurrentOutfitPanel(NULL),
mParent(NULL),
+ mGearMenu(NULL),
mInitialized(false)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
+ gAgentWearables.addLoadingStartedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoading, this));
+
+ LLOutfitObserver& observer = LLOutfitObserver::instance();
+ observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
+ observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
+ observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
}
LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
{
+ delete mGearMenu;
delete mSavedFolderState;
}
@@ -101,6 +274,8 @@ BOOL LLPanelOutfitsInventory::postBuild()
LLInventoryModelBackgroundFetch::instance().start(outfits_cat);
}
+ mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true));
+
return TRUE;
}
@@ -208,7 +383,6 @@ void LLPanelOutfitsInventory::onWearButtonClick()
if (!isCOFPanelActive())
{
mMyOutfitsPanel->performAction("replaceoutfit");
- setWearablesLoading(true);
}
else
{
@@ -371,9 +545,8 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
{
mListCommands = getChild<LLPanel>("bottom_panel");
- mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this));
+ mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this));
mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
- mListCommands->childSetAction("make_outfit_btn", boost::bind(&LLPanelOutfitsInventory::onAddButtonClick, this));
mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
@@ -383,45 +556,28 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
, _7 // EAcceptance* accept
));
- mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_outfit_gear.xml",
- gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mGearMenu = new LLOutfitListGearMenu(mMyOutfitsPanel);
}
void LLPanelOutfitsInventory::updateListCommands()
{
bool trash_enabled = isActionEnabled("delete");
bool wear_enabled = isActionEnabled("wear");
- bool make_outfit_enabled = isActionEnabled("make_outfit");
+ bool wear_visible = !isCOFPanelActive();
+ bool make_outfit_enabled = isActionEnabled("save_outfit");
mListCommands->childSetEnabled("trash_btn", trash_enabled);
mListCommands->childSetEnabled("wear_btn", wear_enabled);
- mListCommands->childSetVisible("wear_btn", wear_enabled);
- mListCommands->childSetEnabled("make_outfit_btn", make_outfit_enabled);
+ mListCommands->childSetVisible("wear_btn", wear_visible);
+ mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
}
-void LLPanelOutfitsInventory::onGearButtonClick()
+void LLPanelOutfitsInventory::showGearMenu()
{
- showActionMenu(mMenuGearDefault,"options_gear_btn");
-}
+ if (!mGearMenu) return;
-void LLPanelOutfitsInventory::onAddButtonClick()
-{
- onSave();
-}
-
-void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
-{
- if (menu)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLView* spawning_view = getChild<LLView> (spawning_view_name);
- S32 menu_x, menu_y;
- //show menu in co-ordinates of panel
- spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
- menu_y += menu->getRect().getHeight();
- LLMenuGL::showPopup(this, menu, menu_x, menu_y);
- }
+ LLView* spawning_view = getChild<LLView>("options_gear_btn");
+ mGearMenu->show(spawning_view);
}
void LLPanelOutfitsInventory::onTrashButtonClick()
@@ -432,11 +588,25 @@ void LLPanelOutfitsInventory::onTrashButtonClick()
void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
- // TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
+ else // "My Outfits" tab active
+ {
+ if (command_name == "delete")
+ {
+ const LLUUID& selected_outfit_id = mMyOutfitsPanel->getSelectedOutfitUUID();
+ if (selected_outfit_id.notNull())
+ {
+ remove_category(&gInventory, selected_outfit_id);
+ }
+ }
+ else
+ {
+ llwarns << "Unrecognized action" << llendl;
+ }
+ }
updateListCommands();
updateVerbs();
}
@@ -491,7 +661,6 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
{
BOOL can_delete = FALSE;
- // TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
LLFolderView* root = getActivePanel()->getRootFolder();
@@ -507,10 +676,15 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
LLFolderViewItem *item = root->getItemByID(item_id);
can_delete &= item->getListener()->isItemRemovable();
}
- return can_delete;
}
}
- return FALSE;
+ else // "My Outfits" tab active
+ {
+ const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID();
+ can_delete = LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit);
+ }
+
+ return can_delete;
}
if (command_name == "remove_link")
{
@@ -545,10 +719,14 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
{
return FALSE;
}
+ return hasItemsSelected();
}
- if (command_name == "make_outfit")
+ if (command_name == "save_outfit")
{
- return TRUE;
+ bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();
+ bool outfit_dirty =LLAppearanceMgr::getInstance()->isOutfitDirty();
+ // allow save only if outfit isn't locked and is dirty
+ return !outfit_locked && outfit_dirty;
}
if (command_name == "edit" ||
@@ -564,7 +742,6 @@ bool LLPanelOutfitsInventory::hasItemsSelected()
{
bool has_items_selected = false;
- // TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
LLFolderView* root = getActivePanel()->getRootFolder();
@@ -574,6 +751,10 @@ bool LLPanelOutfitsInventory::hasItemsSelected()
has_items_selected = (selection_set.size() > 0);
}
}
+ else // My Outfits Tab is active
+ {
+ has_items_selected = mMyOutfitsPanel->getSelectedOutfitUUID().notNull();
+ }
return has_items_selected;
}
@@ -604,6 +785,7 @@ void LLPanelOutfitsInventory::initTabPanels()
mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));
mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME);
+ mMyOutfitsPanel->addSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
@@ -635,6 +817,7 @@ void LLPanelOutfitsInventory::onTabChange()
else
{
mMyOutfitsPanel->setFilterSubString(mFilterSubString);
+ mMyOutfitsPanel->onOpen(LLSD());
}
updateVerbs();
@@ -671,6 +854,12 @@ void LLPanelOutfitsInventory::onWearablesLoaded()
setWearablesLoading(false);
}
+void LLPanelOutfitsInventory::onWearablesLoading()
+{
+ setWearablesLoading(true);
+}
+
+// static
LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()
{
static LLSidepanelAppearance* panel_appearance =