summaryrefslogtreecommitdiff
path: root/indra/newview/lloutfitslist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lloutfitslist.cpp')
-rw-r--r--indra/newview/lloutfitslist.cpp1022
1 files changed, 556 insertions, 466 deletions
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 5c7792b0df..0f5f7aebf8 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -5,21 +5,21 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -37,6 +37,7 @@
#include "llappearancemgr.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
+#include "llinspecttexture.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llmenubutton.h"
@@ -56,42 +57,42 @@ static const LLOutfitTabNameComparator OUTFIT_TAB_NAME_COMPARATOR;
/*virtual*/
bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const
{
- std::string name1 = tab1->getTitle();
- std::string name2 = tab2->getTitle();
+ std::string name1 = tab1->getTitle();
+ std::string name2 = tab2->getTitle();
return (LLStringUtil::compareDict(name1, name2) < 0);
}
-struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params>
+struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLOutfitAccordionCtrlTab::Params>
{
- Mandatory<LLWearableItemsList::Params> wearable_list;
+ Mandatory<LLWearableItemsList::Params> wearable_list;
- outfit_accordion_tab_params()
- : wearable_list("wearable_items_list")
- {}
+ outfit_accordion_tab_params()
+ : wearable_list("wearable_items_list")
+ {}
};
const outfit_accordion_tab_params& get_accordion_tab_params()
{
- static outfit_accordion_tab_params tab_params;
- static bool initialized = false;
- if (!initialized)
- {
- initialized = true;
+ static outfit_accordion_tab_params tab_params;
+ static bool initialized = false;
+ if (!initialized)
+ {
+ initialized = true;
- LLXMLNodePtr xmlNode;
- if (LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode))
- {
- LLXUIParser parser;
- parser.readXUI(xmlNode, tab_params, "outfit_accordion_tab.xml");
- }
- else
- {
- LL_WARNS() << "Failed to read xml of Outfit's Accordion Tab from outfit_accordion_tab.xml" << LL_ENDL;
- }
- }
+ LLXMLNodePtr xmlNode;
+ if (LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode))
+ {
+ LLXUIParser parser;
+ parser.readXUI(xmlNode, tab_params, "outfit_accordion_tab.xml");
+ }
+ else
+ {
+ LL_WARNS() << "Failed to read xml of Outfit's Accordion Tab from outfit_accordion_tab.xml" << LL_ENDL;
+ }
+ }
- return tab_params;
+ return tab_params;
}
@@ -100,8 +101,8 @@ static LLPanelInjector<LLOutfitsList> t_outfits_list("outfits_list");
LLOutfitsList::LLOutfitsList()
: LLOutfitListBase()
, mAccordion(NULL)
- , mListCommands(NULL)
- , mItemSelected(false)
+ , mListCommands(NULL)
+ , mItemSelected(false)
{
}
@@ -109,10 +110,10 @@ LLOutfitsList::~LLOutfitsList()
{
}
-BOOL LLOutfitsList::postBuild()
+bool LLOutfitsList::postBuild()
{
- mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
- mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
+ mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
+ mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
return LLOutfitListBase::postBuild();
}
@@ -128,11 +129,11 @@ void LLOutfitsList::onOpen(const LLSD& info)
LLOutfitListBase::onOpen(info);
- LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
- if (!selected_tab) return;
+ LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
+ if (!selected_tab) return;
- // Pass focus to the selected outfit tab.
- selected_tab->showAndFocusHeader();
+ // Pass focus to the selected outfit tab.
+ selected_tab->showAndFocusHeader();
}
@@ -144,7 +145,8 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
std::string name = cat->getName();
outfit_accordion_tab_params tab_params(get_accordion_tab_params());
- LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
+ tab_params.cat_id = cat_id;
+ LLOutfitAccordionCtrlTab *tab = LLUICtrlFactory::create<LLOutfitAccordionCtrlTab>(tab_params);
if (!tab) return;
LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
wearable_list->setShape(tab->getLocalRect());
@@ -188,7 +190,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1));
// Setting list refresh callback to apply filter on list change.
- list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
+ list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onRefreshComplete, this, _1));
list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
@@ -199,19 +201,17 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
// Further list updates will be triggered by the category observer.
list->updateList(cat_id);
- // If filter is currently applied we store the initial tab state and
- // open it to show matched items if any.
- if (!sFilterSubString.empty())
+ // If filter is currently applied we store the initial tab state.
+ if (!getFilterSubString().empty())
{
tab->notifyChildren(LLSD().with("action", "store_state"));
- tab->setDisplayChildren(true);
// Setting mForceRefresh flag will make the list refresh its contents
// even if it is not currently visible. This is required to apply the
// filter to the newly added list.
list->setForceRefresh(true);
- list->setFilterSubString(sFilterSubString);
+ list->setFilterSubString(getFilterSubString(), false);
}
}
@@ -220,27 +220,27 @@ void LLOutfitsList::updateRemovedCategory(LLUUID cat_id)
outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat_id);
if (outfits_iter != mOutfitsMap.end())
{
- const LLUUID& outfit_id = outfits_iter->first;
- LLAccordionCtrlTab* tab = outfits_iter->second;
+ const LLUUID& outfit_id = outfits_iter->first;
+ LLAccordionCtrlTab* tab = outfits_iter->second;
- // 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);
+ // 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);
- // 2. Remove the outfit from selection.
- deselectOutfit(outfit_id);
+ // 2. Remove the outfit from selection.
+ deselectOutfit(outfit_id);
- // 3. Remove category UUID to accordion tab mapping.
- mOutfitsMap.erase(outfits_iter);
+ // 3. Remove category UUID to accordion tab mapping.
+ mOutfitsMap.erase(outfits_iter);
- // 4. Remove outfit tab from accordion.
- mAccordion->removeCollapsibleCtrl(tab);
+ // 4. Remove outfit tab from accordion.
+ mAccordion->removeCollapsibleCtrl(tab);
- // kill removed tab
- if (tab != NULL)
- {
- tab->die();
- }
+ // kill removed tab
+ if (tab != NULL)
+ {
+ tab->die();
+ }
}
}
@@ -253,174 +253,166 @@ void LLOutfitsList::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
mOutfitsMap[prev_id]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor"));
}
if (mOutfitsMap[base_id])
- {
- mOutfitsMap[base_id]->setTitleFontStyle("BOLD");
- mOutfitsMap[base_id]->setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor"));
- }
+ {
+ mOutfitsMap[base_id]->setTitleFontStyle("BOLD");
+ mOutfitsMap[base_id]->setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor"));
+ }
}
void LLOutfitsList::onListSelectionChange(LLUICtrl* ctrl)
{
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
- if (!list) return;
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
+ if (!list) return;
- LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID());
- if (!item) return;
+ LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID());
+ if (!item) return;
- ChangeOutfitSelection(list, item->getParentUUID());
+ ChangeOutfitSelection(list, item->getParentUUID());
}
void LLOutfitListBase::performAction(std::string action)
{
- if (mSelectedOutfitUUID.isNull()) return;
+ if (mSelectedOutfitUUID.isNull()) return;
- LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);
- if (!cat) return;
+ LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);
+ if (!cat) return;
- if ("replaceoutfit" == action)
- {
- LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE );
- }
- else if ("addtooutfit" == action)
- {
- LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE );
- }
- else if ("rename_outfit" == action)
- {
- LLAppearanceMgr::instance().renameOutfit(mSelectedOutfitUUID);
- }
+ if ("replaceoutfit" == action)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory( cat, false, false );
+ }
+ else if ("addtooutfit" == action)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory( cat, false, true );
+ }
+ else if ("rename_outfit" == action)
+ {
+ LLAppearanceMgr::instance().renameOutfit(mSelectedOutfitUUID);
+ }
}
void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
{
- for (outfits_map_t::iterator iter = mOutfitsMap.begin();
- iter != mOutfitsMap.end();
- ++iter)
- {
- if (outfit_uuid == iter->first)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if (!tab) continue;
-
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
- if (!list) continue;
-
- tab->setFocus(TRUE);
- ChangeOutfitSelection(list, outfit_uuid);
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ if (outfit_uuid == iter->first)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if (!tab) continue;
- tab->changeOpenClose(false);
- }
- }
-}
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (!list) continue;
-// virtual
-void LLOutfitsList::setFilterSubString(const std::string& string)
-{
- applyFilter(string);
+ tab->setFocus(true);
+ ChangeOutfitSelection(list, outfit_uuid);
- sFilterSubString = string;
+ tab->changeOpenClose(false);
+ }
+ }
}
// virtual
bool LLOutfitListBase::isActionEnabled(const LLSD& userdata)
{
- if (mSelectedOutfitUUID.isNull()) return false;
+ if (mSelectedOutfitUUID.isNull()) return false;
- const std::string command_name = userdata.asString();
- if (command_name == "delete")
- {
+ const std::string command_name = userdata.asString();
+ if (command_name == "delete")
+ {
return !hasItemSelected() && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID);
- }
- if (command_name == "rename")
- {
- return get_is_category_renameable(&gInventory, mSelectedOutfitUUID);
- }
- if (command_name == "save_outfit")
- {
- 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 == "wear")
- {
- if (gAgentWearables.isCOFChangeInProgress())
- {
- return false;
- }
-
- if (hasItemSelected())
- {
- return canWearSelected();
- }
-
- // outfit selected
- return LLAppearanceMgr::instance().getCanReplaceCOF(mSelectedOutfitUUID);
- }
- if (command_name == "take_off")
- {
- // Enable "Take Off" if any of selected items can be taken off
- // or the selected outfit contains items that can be taken off.
- return ( hasItemSelected() && canTakeOffSelected() )
- || ( !hasItemSelected() && LLAppearanceMgr::getCanRemoveFromCOF(mSelectedOutfitUUID) );
- }
-
- if (command_name == "wear_add")
- {
- // *TODO: do we ever get here?
- return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
- }
-
- return false;
+ }
+ if (command_name == "rename")
+ {
+ return get_is_category_renameable(&gInventory, mSelectedOutfitUUID);
+ }
+ if (command_name == "save_outfit")
+ {
+ 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 == "wear")
+ {
+ if (gAgentWearables.isCOFChangeInProgress())
+ {
+ return false;
+ }
+
+ if (hasItemSelected())
+ {
+ return canWearSelected();
+ }
+
+ // outfit selected
+ return LLAppearanceMgr::instance().getCanReplaceCOF(mSelectedOutfitUUID);
+ }
+ if (command_name == "take_off")
+ {
+ // Enable "Take Off" if any of selected items can be taken off
+ // or the selected outfit contains items that can be taken off.
+ return ( hasItemSelected() && canTakeOffSelected() )
+ || ( !hasItemSelected() && LLAppearanceMgr::getCanRemoveFromCOF(mSelectedOutfitUUID) );
+ }
+
+ if (command_name == "wear_add")
+ {
+ // *TODO: do we ever get here?
+ return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
+ }
+
+ return false;
}
void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
{
- // Collect selected items from all selected lists.
- for (wearables_lists_map_t::const_iterator iter = mSelectedListsMap.begin();
- iter != mSelectedListsMap.end();
- ++iter)
- {
- uuid_vec_t uuids;
- (*iter).second->getSelectedUUIDs(uuids);
+ // Collect selected items from all selected lists.
+ for (wearables_lists_map_t::const_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);
- }
+ auto prev_size = selected_uuids.size();
+ selected_uuids.resize(prev_size + uuids.size());
+ std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size);
+ }
}
void LLOutfitsList::onCollapseAllFolders()
{
- for (outfits_map_t::iterator iter = mOutfitsMap.begin();
- iter != mOutfitsMap.end();
- ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if(tab && tab->isExpanded())
- {
- tab->changeOpenClose(true);
- }
- }
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if(tab && tab->isExpanded())
+ {
+ tab->changeOpenClose(true);
+ }
+ }
}
void LLOutfitsList::onExpandAllFolders()
{
- for (outfits_map_t::iterator iter = mOutfitsMap.begin();
- iter != mOutfitsMap.end();
- ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if(tab && !tab->isExpanded())
- {
- tab->changeOpenClose(false);
- }
- }
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if(tab && !tab->isExpanded())
+ {
+ tab->changeOpenClose(false);
+ }
+ }
}
bool LLOutfitsList::hasItemSelected()
{
- return mItemSelected;
+ return mItemSelected;
}
//////////////////////////////////////////////////////////////////////////
@@ -430,305 +422,285 @@ bool LLOutfitsList::hasItemSelected()
void LLOutfitsList::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name)
{
outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat->getUUID());
- if (outfits_iter != mOutfitsMap.end())
- {
- // Update tab name with the new category name.
- LLAccordionCtrlTab* tab = outfits_iter->second;
- if (tab)
- {
- tab->setName(name);
- tab->setTitle(name);
- }
- }
+ if (outfits_iter != mOutfitsMap.end())
+ {
+ // Update tab name with the new category name.
+ LLAccordionCtrlTab* tab = outfits_iter->second;
+ if (tab)
+ {
+ tab->setName(name);
+ tab->setTitle(name);
+ }
+ }
}
void LLOutfitsList::resetItemSelection(LLWearableItemsList* list, const LLUUID& category_id)
{
- list->resetSelection();
- mItemSelected = false;
- signalSelectionOutfitUUID(category_id);
+ list->resetSelection();
+ mItemSelected = false;
+ signalSelectionOutfitUUID(category_id);
}
void LLOutfitsList::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
{
- MASK mask = gKeyboard->currentMask(TRUE);
+ 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))
- {
- 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();
- }
- }
+ // Reset selection in all previously selected tabs except for the current
+ // if new selection is started.
+ if (list && !(mask & MASK_CONTROL))
+ {
+ 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();
- }
+ // Clear current selection.
+ mSelectedListsMap.clear();
+ }
- mItemSelected = list && (list->getSelectedItem() != NULL);
+ mItemSelected = list && (list->getSelectedItem() != NULL);
- mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));
+ mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));
}
void LLOutfitsList::deselectOutfit(const LLUUID& category_id)
{
- // Remove selected lists map entry.
- mSelectedListsMap.erase(category_id);
-
+ // Remove selected lists map entry.
+ mSelectedListsMap.erase(category_id);
+
LLOutfitListBase::deselectOutfit(category_id);
}
void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID& category_id)
{
- // Try restoring outfit selection after filtering.
- if (mAccordion->getSelectedTab() == tab)
- {
- signalSelectionOutfitUUID(category_id);
- }
+ // Try restoring outfit selection after filtering.
+ if (mAccordion->getSelectedTab() == tab)
+ {
+ signalSelectionOutfitUUID(category_id);
+ }
}
-void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
+void LLOutfitsList::onRefreshComplete(LLUICtrl* ctrl)
{
- if (!ctrl || sFilterSubString.empty())
- return;
+ if (!ctrl || getFilterSubString().empty())
+ return;
- for (outfits_map_t::iterator
- iter = mOutfitsMap.begin(),
- iter_end = mOutfitsMap.end();
- iter != iter_end; ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if (!tab) continue;
+ for (outfits_map_t::iterator
+ iter = mOutfitsMap.begin(),
+ iter_end = mOutfitsMap.end();
+ iter != iter_end; ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if (!tab) continue;
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
- if (list != ctrl) continue;
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (list != ctrl) continue;
- applyFilterToTab(iter->first, tab, sFilterSubString);
- }
+ applyFilterToTab(iter->first, tab, getFilterSubString());
+ }
}
-void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
+// virtual
+void LLOutfitsList::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
{
- mAccordion->setFilterSubString(new_filter_substring);
-
- for (outfits_map_t::iterator
- iter = mOutfitsMap.begin(),
- iter_end = mOutfitsMap.end();
- iter != iter_end; ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if (!tab) continue;
+ mAccordion->setFilterSubString(new_string);
- bool more_restrictive = sFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, sFilterSubString.size()).compare(sFilterSubString);
+ outfits_map_t::iterator iter = mOutfitsMap.begin(), iter_end = mOutfitsMap.end();
+ while (iter != iter_end)
+ {
+ const LLUUID& category_id = iter->first;
+ LLAccordionCtrlTab* tab = iter++->second;
+ if (!tab) continue;
- // Restore tab visibility in case of less restrictive filter
- // to compare it with updated string if it was previously hidden.
- if (!more_restrictive)
- {
- tab->setVisible(TRUE);
- }
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (list)
+ {
+ list->setFilterSubString(new_string, tab->getDisplayChildren());
+ }
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
- if (list)
- {
- list->setFilterSubString(new_filter_substring);
- }
+ if (old_string.empty())
+ {
+ // Store accordion tab state when filter is not empty
+ tab->notifyChildren(LLSD().with("action", "store_state"));
+ }
- if(sFilterSubString.empty() && !new_filter_substring.empty())
- {
- //store accordion tab state when filter is not empty
- tab->notifyChildren(LLSD().with("action","store_state"));
- }
+ if (!new_string.empty())
+ {
+ applyFilterToTab(category_id, tab, new_string);
+ }
+ else
+ {
+ tab->setVisible(true);
- if (!new_filter_substring.empty())
- {
- applyFilterToTab(iter->first, tab, new_filter_substring);
- }
- else
- {
- // restore tab title when filter is empty
- tab->setTitle(tab->getTitle());
+ // Restore tab title when filter is empty
+ tab->setTitle(tab->getTitle());
- //restore accordion state after all those accodrion tab manipulations
- tab->notifyChildren(LLSD().with("action","restore_state"));
+ // Restore accordion state after all those accodrion tab manipulations
+ tab->notifyChildren(LLSD().with("action", "restore_state"));
- // Try restoring the tab selection.
- restoreOutfitSelection(tab, iter->first);
- }
- }
+ // Try restoring the tab selection.
+ restoreOutfitSelection(tab, category_id);
+ }
+ }
- mAccordion->arrange();
+ mAccordion->arrange();
}
void LLOutfitsList::applyFilterToTab(
- const LLUUID& category_id,
- LLAccordionCtrlTab* tab,
- const std::string& filter_substring)
-{
- if (!tab) return;
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
- if (!list) return;
-
- std::string title = tab->getTitle();
- LLStringUtil::toUpper(title);
-
- std::string cur_filter = filter_substring;
- LLStringUtil::toUpper(cur_filter);
-
- tab->setTitle(tab->getTitle(), cur_filter);
-
- if (std::string::npos == title.find(cur_filter))
- {
- // hide tab if its title doesn't pass filter
- // and it has no visible items
- tab->setVisible(list->hasMatchedItems());
-
- // remove title highlighting because it might
- // have been previously highlighted by less restrictive filter
- tab->setTitle(tab->getTitle());
-
- // Remove the tab from selection.
- deselectOutfit(category_id);
- }
- else
- {
- // Try restoring the tab selection.
- restoreOutfitSelection(tab, category_id);
- }
-
- if (tab->getVisible())
- {
- // Open tab if it has passed the filter.
- tab->setDisplayChildren(true);
- }
- else
- {
- // Set force refresh flag to refresh not visible list
- // when some changes occur in it.
- list->setForceRefresh(true);
- }
+ const LLUUID& category_id,
+ LLAccordionCtrlTab* tab,
+ const std::string& filter_substring)
+{
+ if (!tab) return;
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (!list) return;
+
+ std::string title = tab->getTitle();
+ LLStringUtil::toUpper(title);
+
+ std::string cur_filter = filter_substring;
+ LLStringUtil::toUpper(cur_filter);
+
+ tab->setTitle(tab->getTitle(), cur_filter);
+
+ if (std::string::npos == title.find(cur_filter))
+ {
+ // Hide tab if its title doesn't pass filter
+ // and it has no matched items
+ tab->setVisible(list->hasMatchedItems());
+
+ // Remove title highlighting because it might
+ // have been previously highlighted by less restrictive filter
+ tab->setTitle(tab->getTitle());
+
+ // Remove the tab from selection.
+ deselectOutfit(category_id);
+ }
+ else
+ {
+ // Try restoring the tab selection.
+ restoreOutfitSelection(tab, category_id);
+ }
}
bool LLOutfitsList::canWearSelected()
{
- if (!isAgentAvatarValid())
- {
- return false;
- }
+ if (!isAgentAvatarValid())
+ {
+ return false;
+ }
- uuid_vec_t selected_items;
- getSelectedItemsUUIDs(selected_items);
- S32 nonreplacable_objects = 0;
+ uuid_vec_t selected_items;
+ getSelectedItemsUUIDs(selected_items);
+ S32 nonreplacable_objects = 0;
- for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
- {
- const LLUUID& id = *it;
+ for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
+ {
+ const LLUUID& id = *it;
- // Check whether the item is worn.
- if (!get_can_item_be_worn(id))
- {
- return false;
- }
+ // Check whether the item is worn.
+ if (!get_can_item_be_worn(id))
+ {
+ return false;
+ }
- const LLViewerInventoryItem* item = gInventory.getItem(id);
- if (!item)
- {
- return false;
- }
+ const LLViewerInventoryItem* item = gInventory.getItem(id);
+ if (!item)
+ {
+ return false;
+ }
- if (item->getType() == LLAssetType::AT_OBJECT)
- {
- nonreplacable_objects++;
- }
- }
+ if (item->getType() == LLAssetType::AT_OBJECT)
+ {
+ nonreplacable_objects++;
+ }
+ }
- // All selected items can be worn. But do we have enough space for them?
- return nonreplacable_objects == 0 || gAgentAvatarp->canAttachMoreObjects(nonreplacable_objects);
+ // All selected items can be worn. But do we have enough space for them?
+ return nonreplacable_objects == 0 || gAgentAvatarp->canAttachMoreObjects(nonreplacable_objects);
}
void LLOutfitsList::wearSelectedItems()
{
- uuid_vec_t selected_uuids;
- getSelectedItemsUUIDs(selected_uuids);
+ uuid_vec_t selected_uuids;
+ getSelectedItemsUUIDs(selected_uuids);
- if(selected_uuids.empty())
- {
- return;
- }
+ if(selected_uuids.empty())
+ {
+ return;
+ }
- wear_multiple(selected_uuids, false);
+ wear_multiple(selected_uuids, false);
}
void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
{
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
- if (!list) return;
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
+ if (!list) return;
- uuid_vec_t selected_uuids;
+ uuid_vec_t selected_uuids;
- getSelectedItemsUUIDs(selected_uuids);
+ getSelectedItemsUUIDs(selected_uuids);
- LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);
+ LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);
}
void LLOutfitsList::onCOFChanged()
{
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
-
- // Collect current COF items
- gInventory.collectDescendents(
- LLAppearanceMgr::instance().getCOF(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH);
-
- uuid_vec_t vnew;
- uuid_vec_t vadded;
- uuid_vec_t vremoved;
-
- // From gInventory we get the UUIDs of links that are currently in COF.
- // These links UUIDs are not the same UUIDs that we have in each wearable items list.
- // So we collect base items' UUIDs to find them or links that point to them in wearable
- // items lists and update their worn state there.
- for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
- iter != item_array.end();
- ++iter)
- {
- vnew.push_back((*iter)->getLinkedUUID());
- }
-
- // We need to update only items that were added or removed from COF.
- LLCommonUtils::computeDifference(vnew, mCOFLinkedItems, vadded, vremoved);
-
- // Store the ids of items currently linked from COF.
- mCOFLinkedItems = vnew;
-
- for (outfits_map_t::iterator iter = mOutfitsMap.begin();
- iter != mOutfitsMap.end();
- ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if (!tab) continue;
-
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
- if (!list) continue;
-
- // Append removed ids to added ids because we should update all of them.
- vadded.reserve(vadded.size() + vremoved.size());
- vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
-
- // Every list updates the labels of changed items or
- // the links that point to these items.
- list->updateChangedItems(vadded);
- }
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+
+ // Collect current COF items
+ gInventory.collectDescendents(
+ LLAppearanceMgr::instance().getCOF(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ uuid_vec_t vnew;
+ uuid_vec_t vadded;
+ uuid_vec_t vremoved;
+
+ // From gInventory we get the UUIDs of links that are currently in COF.
+ // These links UUIDs are not the same UUIDs that we have in each wearable items list.
+ // So we collect base items' UUIDs to find them or links that point to them in wearable
+ // items lists and update their worn state there.
+ LLInventoryModel::item_array_t::const_iterator array_iter = item_array.begin(), array_end = item_array.end();
+ while (array_iter < array_end)
+ {
+ vnew.push_back((*(array_iter++))->getLinkedUUID());
+ }
+
+ // We need to update only items that were added or removed from COF.
+ LLCommonUtils::computeDifference(vnew, mCOFLinkedItems, vadded, vremoved);
+
+ // Store the ids of items currently linked from COF.
+ mCOFLinkedItems = vnew;
+
+ // Append removed ids to added ids because we should update all of them.
+ vadded.reserve(vadded.size() + vremoved.size());
+ vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
+ vremoved.clear();
+
+ outfits_map_t::iterator map_iter = mOutfitsMap.begin(), map_end = mOutfitsMap.end();
+ while (map_iter != map_end)
+ {
+ LLAccordionCtrlTab* tab = (map_iter++)->second;
+ if (!tab) continue;
+
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (!list) continue;
+
+ // Every list updates the labels of changed items or
+ // the links that point to these items.
+ list->updateChangedItems(vadded);
+ }
}
void LLOutfitsList::getCurrentCategories(uuid_vec_t& vcur)
@@ -757,7 +729,7 @@ void LLOutfitsList::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUI
LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header");
if (header)
{
- header->setFocus(TRUE);
+ header->setFocus(true);
}
uuid_vec_t selected_uuids;
@@ -774,10 +746,10 @@ LLOutfitListGearMenuBase* LLOutfitsList::createGearMenu()
bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)
{
- if(!tab || !tab->getHeaderVisible()) return false;
+ if(!tab || !tab->getHeaderVisible()) return false;
- S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();
- return y >= header_bottom;
+ S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();
+ return y >= header_bottom;
}
LLOutfitListBase::LLOutfitListBase()
@@ -820,7 +792,7 @@ void LLOutfitListBase::onOpen(const LLSD& info)
// Start observing changes in "My Outfits" category.
mCategoriesObserver->addCategory(outfits,
- boost::bind(&LLOutfitListBase::refreshList, this, outfits));
+ boost::bind(&LLOutfitListBase::observerCallback, this, outfits));
//const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
// Start observing changes in Current Outfit category.
@@ -835,14 +807,23 @@ void LLOutfitListBase::onOpen(const LLSD& info)
// arrive.
category->fetch();
refreshList(outfits);
- highlightBaseOutfit();
mIsInitialized = true;
}
}
+void LLOutfitListBase::observerCallback(const LLUUID& category_id)
+{
+ const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
+ mChangedItems.insert(changed_items.begin(), changed_items.end());
+ refreshList(category_id);
+}
+
void LLOutfitListBase::refreshList(const LLUUID& category_id)
{
+ bool wasNull = mRefreshListState.CategoryUUID.isNull();
+ mRefreshListState.CategoryUUID.setNull();
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
@@ -855,51 +836,109 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
LLInventoryModel::EXCLUDE_TRASH,
is_category);
- uuid_vec_t vadded;
- uuid_vec_t vremoved;
+ // Memorize item names for each UUID
+ std::map<LLUUID, std::string> names;
+ for (const LLPointer<LLViewerInventoryCategory>& cat : cat_array)
+ {
+ names.emplace(std::make_pair(cat->getUUID(), cat->getName()));
+ }
- // Create added and removed items vectors.
- computeDifference(cat_array, vadded, vremoved);
+ // Fill added and removed items vectors.
+ mRefreshListState.Added.clear();
+ mRefreshListState.Removed.clear();
+ computeDifference(cat_array, mRefreshListState.Added, mRefreshListState.Removed);
+ // Sort added items vector by item name.
+ std::sort(mRefreshListState.Added.begin(), mRefreshListState.Added.end(),
+ [names](const LLUUID& a, const LLUUID& b)
+ {
+ return LLStringUtil::compareDict(names.at(a), names.at(b)) < 0;
+ });
+ // Initialize iterators for added and removed items vectors.
+ mRefreshListState.AddedIterator = mRefreshListState.Added.begin();
+ mRefreshListState.RemovedIterator = mRefreshListState.Removed.begin();
+
+ LL_INFOS() << "added: " << mRefreshListState.Added.size() <<
+ ", removed: " << mRefreshListState.Removed.size() <<
+ ", changed: " << gInventory.getChangedIDs().size() <<
+ LL_ENDL;
+
+ mRefreshListState.CategoryUUID = category_id;
+ if (wasNull)
+ {
+ gIdleCallbacks.addFunction(onIdle, this);
+ }
+}
+
+// static
+void LLOutfitListBase::onIdle(void* userdata)
+{
+ LLOutfitListBase* self = (LLOutfitListBase*)userdata;
+
+ self->onIdleRefreshList();
+}
+
+void LLOutfitListBase::onIdleRefreshList()
+{
+ if (mRefreshListState.CategoryUUID.isNull())
+ return;
+
+ const F64 MAX_TIME = 0.05f;
+ F64 curent_time = LLTimer::getTotalSeconds();
+ const F64 end_time = curent_time + MAX_TIME;
// Handle added tabs.
- for (uuid_vec_t::const_iterator iter = vadded.begin();
- iter != vadded.end();
- ++iter)
+ while (mRefreshListState.AddedIterator < mRefreshListState.Added.end())
{
- const LLUUID cat_id = (*iter);
+ const LLUUID cat_id = (*mRefreshListState.AddedIterator++);
updateAddedCategory(cat_id);
+
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
}
+ mRefreshListState.Added.clear();
+ mRefreshListState.AddedIterator = mRefreshListState.Added.end();
// Handle removed tabs.
- for (uuid_vec_t::const_iterator iter = vremoved.begin(); iter != vremoved.end(); ++iter)
+ while (mRefreshListState.RemovedIterator < mRefreshListState.Removed.end())
{
- const LLUUID cat_id = (*iter);
+ const LLUUID cat_id = (*mRefreshListState.RemovedIterator++);
updateRemovedCategory(cat_id);
+
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
}
+ mRefreshListState.Removed.clear();
+ mRefreshListState.RemovedIterator = mRefreshListState.Removed.end();
// Get changed items from inventory model and update outfit tabs
// which might have been renamed.
- const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
- for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
- items_iter != changed_items.end();
- ++items_iter)
+ while (!mChangedItems.empty())
{
+ std::set<LLUUID>::const_iterator items_iter = mChangedItems.begin();
LLViewerInventoryCategory *cat = gInventory.getCategory(*items_iter);
- if (!cat)
- {
- LLInventoryObject* obj = gInventory.getObject(*items_iter);
- if(!obj || (obj->getType() != LLAssetType::AT_CATEGORY))
- {
- return;
- }
- cat = (LLViewerInventoryCategory*)obj;
- }
- std::string name = cat->getName();
+ mChangedItems.erase(items_iter);
+ // Links aren't supposed to be allowed here, check only cats
+ if (cat)
+ {
+ std::string name = cat->getName();
updateChangedCategoryName(cat, name);
}
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
+ }
+
sortOutfits();
+ highlightBaseOutfit();
+
+ gIdleCallbacks.deleteFunction(onIdle, this);
+ mRefreshListState.CategoryUUID.setNull();
+
+ LL_INFOS() << "done" << LL_ENDL;
}
void LLOutfitListBase::computeDifference(
@@ -936,7 +975,6 @@ void LLOutfitListBase::highlightBaseOutfit()
mHighlightedOutfitUUID = base_id;
onHighlightBaseOutfit(base_id, prev_id);
}
-
}
void LLOutfitListBase::removeSelected()
@@ -982,7 +1020,7 @@ void LLOutfitListBase::ChangeOutfitSelection(LLWearableItemsList* list, const LL
signalSelectionOutfitUUID(category_id);
}
-BOOL LLOutfitListBase::postBuild()
+bool LLOutfitListBase::postBuild()
{
mGearMenu = createGearMenu();
@@ -990,7 +1028,7 @@ BOOL LLOutfitListBase::postBuild()
menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenuBase::updateItemsVisibility, mGearMenu));
menu_gear_btn->setMenu(mGearMenu->getMenu());
- return TRUE;
+ return true;
}
void LLOutfitListBase::collapseAllFolders()
@@ -1028,6 +1066,8 @@ LLContextMenu* LLOutfitContextMenu::createMenu()
registrar.add("Outfit.Edit", boost::bind(editOutfit));
registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
registrar.add("Outfit.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList));
+ registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitContextMenu::onThumbnail, this, selected_id));
+ registrar.add("Outfit.Save", boost::bind(&LLOutfitContextMenu::onSave, this, selected_id));
enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2));
enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2));
@@ -1092,6 +1132,31 @@ void LLOutfitContextMenu::renameOutfit(const LLUUID& outfit_cat_id)
LLAppearanceMgr::instance().renameOutfit(outfit_cat_id);
}
+void LLOutfitContextMenu::onThumbnail(const LLUUID &outfit_cat_id)
+{
+ if (outfit_cat_id.notNull())
+ {
+ LLSD data(outfit_cat_id);
+ LLFloaterReg::showInstance("change_item_thumbnail", data);
+ }
+}
+
+void LLOutfitContextMenu::onSave(const LLUUID &outfit_cat_id)
+{
+ if (outfit_cat_id.notNull())
+ {
+ LLNotificationsUtil::add("ConfirmOverwriteOutfit", LLSD(), LLSD(),
+ [outfit_cat_id](const LLSD &notif, const LLSD &resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ LLAppearanceMgr::getInstance()->onOutfitFolderCreated(outfit_cat_id, true);
+ }
+ });
+ }
+}
+
LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
: mOutfitList(olist),
mMenu(NULL)
@@ -1110,6 +1175,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
registrar.add("Gear.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, mOutfitList));
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
+ registrar.add("Gear.Save", boost::bind(&LLOutfitListGearMenuBase::onSave, this));
registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this));
registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this));
@@ -1135,8 +1201,7 @@ void LLOutfitListGearMenuBase::onUpdateItemsVisibility()
if (!mMenu) return;
bool have_selection = getSelectedOutfitID().notNull();
- mMenu->setItemVisible("sepatator1", have_selection);
- mMenu->setItemVisible("sepatator2", have_selection);
+ mMenu->setItemVisible("wear_separator", have_selection);
mMenu->arrangeAndClear(); // update menu height
}
@@ -1167,7 +1232,7 @@ void LLOutfitListGearMenuBase::onWear()
if (selected_outfit)
{
LLAppearanceMgr::instance().wearInventoryCategory(
- selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
+ selected_outfit, /*copy=*/ false, /*append=*/ false);
}
}
@@ -1181,6 +1246,20 @@ void LLOutfitListGearMenuBase::onAdd()
}
}
+void LLOutfitListGearMenuBase::onSave()
+{
+ const LLUUID &selected_id = getSelectedOutfitID();
+ LLNotificationsUtil::add("ConfirmOverwriteOutfit", LLSD(), LLSD(),
+ [selected_id](const LLSD &notif, const LLSD &resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ LLAppearanceMgr::getInstance()->onOutfitFolderCreated(selected_id, true);
+ }
+ });
+}
+
void LLOutfitListGearMenuBase::onTakeOff()
{
// Take off selected outfit.
@@ -1234,15 +1313,6 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
return false;
}
- // *TODO This condition leads to menu item behavior inconsistent with
- // "Wear" button behavior and should be modified or removed.
- bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
-
- if ("wear" == param)
- {
- return !is_worn;
- }
-
return true;
}
@@ -1268,12 +1338,32 @@ LLOutfitListGearMenu::~LLOutfitListGearMenu()
void LLOutfitListGearMenu::onUpdateItemsVisibility()
{
if (!mMenu) return;
- mMenu->setItemVisible("expand", TRUE);
- mMenu->setItemVisible("collapse", TRUE);
- mMenu->setItemVisible("thumbnail", FALSE); // Never visible?
- mMenu->setItemVisible("sepatator3", FALSE);
- mMenu->setItemVisible("sort_folders_by_name", FALSE);
+ mMenu->setItemVisible("expand", true);
+ mMenu->setItemVisible("collapse", true);
+ mMenu->setItemVisible("thumbnail", getSelectedOutfitID().notNull());
+ mMenu->setItemVisible("sepatator3", false);
+ mMenu->setItemVisible("sort_folders_by_name", false);
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
}
+bool LLOutfitAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
+{
+ if (y >= getLocalRect().getHeight() - getHeaderHeight())
+ {
+ LLSD params;
+ params["inv_type"] = LLInventoryType::IT_CATEGORY;
+ params["thumbnail_id"] = gInventory.getCategory(mFolderID)->getThumbnailUUID();
+ params["item_id"] = mFolderID;
+
+ LLToolTipMgr::instance().show(LLToolTip::Params()
+ .message(getToolTip())
+ .sticky_rect(calcScreenRect())
+ .delay_time(LLView::getTooltipTimeout())
+ .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1))
+ .create_params(params));
+ return true;
+ }
+
+ return LLAccordionCtrlTab::handleToolTip(x, y, mask);
+}
// EOF