diff options
Diffstat (limited to 'indra/newview/lloutfitslist.cpp')
-rw-r--r-- | indra/newview/lloutfitslist.cpp | 132 |
1 files changed, 118 insertions, 14 deletions
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 7ebbddca25..8f189a1e9f 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -38,27 +38,63 @@ #include "llaccordionctrl.h" #include "llaccordionctrltab.h" +#include "llagentwearables.h" #include "llappearancemgr.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" +#include "lllistcontextmenu.h" +#include "lltransutil.h" +#include "llviewermenu.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" #include "llwearableitemslist.h" +////////////////////////////////////////////////////////////////////////// + +class OutfitContextMenu : public LLListContextMenu +{ +protected: + /* virtual */ LLContextMenu* createMenu() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + LLUUID selected_id = mUUIDs.front(); + + registrar.add("Outfit.WearReplace", + boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.WearAdd", + boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.TakeOff", + boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); + // *TODO: implement this + // registrar.add("Outfit.Rename", boost::bind()); + // registrar.add("Outfit.Delete", boost::bind()); + + return createFromFile("menu_outfit_tab.xml"); + } +}; + +////////////////////////////////////////////////////////////////////////// + static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list"); LLOutfitsList::LLOutfitsList() : LLPanel() , mAccordion(NULL) , mListCommands(NULL) - , mSelectedList(NULL) { mCategoriesObserver = new LLInventoryCategoriesObserver(); gInventory.addObserver(mCategoriesObserver); gInventory.addObserver(this); + + mOutfitMenu = new OutfitContextMenu(); } LLOutfitsList::~LLOutfitsList() { + delete mOutfitMenu; + if (gInventory.containsObserver(mCategoriesObserver)) { gInventory.removeObserver(mCategoriesObserver); @@ -140,6 +176,8 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); + tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, + _1, _2, _3, cat_id)); tab->setName(name); tab->setTitle(name); @@ -169,6 +207,8 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) // Setting list refresh callback to apply filter on list change. list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1)); + list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); + // Fetch the new outfit contents. cat->fetch(); @@ -198,23 +238,27 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter)); if (outfits_iter != mOutfitsMap.end()) { - // An outfit is removed from the list. Do the following: - // 1. Remove outfit accordion tab from accordion. - mAccordion->removeCollapsibleCtrl(outfits_iter->second); - const LLUUID& outfit_id = outfits_iter->first; + LLAccordionCtrlTab* tab = outfits_iter->second; - // 2. Remove outfit category from observer to stop monitoring its changes. + // An outfit is removed from the list. Do the following: + // 1. Remove outfit category from observer to stop monitoring its changes. mCategoriesObserver->removeCategory(outfit_id); - // 3. Reset selection if selected outfit is being removed. - if (mSelectedOutfitUUID == outfit_id) + // 2. Remove selected lists map entry. + mSelectedListsMap.erase(outfit_id); + + // 3. Reset currently selected outfit id if it is being removed. + if (outfit_id == mSelectedOutfitUUID) { - changeOutfitSelection(NULL, LLUUID()); + mSelectedOutfitUUID = LLUUID(); } // 4. Remove category UUID to accordion tab mapping. mOutfitsMap.erase(outfits_iter); + + // 5. Remove outfit tab from accordion. + mAccordion->removeCollapsibleCtrl(tab); } } @@ -244,6 +288,8 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) void LLOutfitsList::performAction(std::string action) { + if (mSelectedOutfitUUID.isNull()) return; + LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID); if (!cat) return; @@ -328,14 +374,28 @@ void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) { - // Reset selection in previously selected tab - // if a new one is selected. - if (list && mSelectedList && mSelectedList != list) + MASK mask = gKeyboard->currentMask(TRUE); + + // Reset selection in all previously selected tabs except for the current + // if new selection is started. + if (list && !(mask & MASK_CONTROL)) { - mSelectedList->resetSelection(); + for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin(); + iter != mSelectedListsMap.end(); + ++iter) + { + LLWearableItemsList* selected_list = (*iter).second; + if (selected_list != list) + { + selected_list->resetSelection(); + } + } + + // Clear current selection. + mSelectedListsMap.clear(); } - mSelectedList = list; + mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list)); mSelectedOutfitUUID = category_id; } @@ -447,4 +507,48 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) } } +void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); + if(mOutfitMenu && tab && tab->getHeaderVisible() && cat_id.notNull()) + { + S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight(); + if(y >= header_bottom) + { + // Focus tab header to trigger tab selection change. + LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); + if (header) + { + header->setFocus(TRUE); + } + + uuid_vec_t selected_uuids; + selected_uuids.push_back(cat_id); + mOutfitMenu->show(ctrl, selected_uuids, x, y); + } + } +} + +void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ + LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); + if (!list) return; + + uuid_vec_t selected_uuids; + + // Collect seleted items from all selected lists. + for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin(); + iter != mSelectedListsMap.end(); + ++iter) + { + uuid_vec_t uuids; + (*iter).second->getSelectedUUIDs(uuids); + + S32 prev_size = selected_uuids.size(); + selected_uuids.resize(prev_size + uuids.size()); + std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size); + } + + LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y); +} // EOF |