merge from PE's viewer-trunk (viewer-public)
commit
dee93e8560
|
|
@ -83,7 +83,7 @@ public:
|
|||
static LLVBOPool sDynamicVBOPool;
|
||||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
|
||||
static BOOL sUseStreamDraw;
|
||||
|
||||
static void initClass(bool use_vbo);
|
||||
|
|
|
|||
|
|
@ -610,8 +610,14 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection();
|
||||
selectItemPair(item_pair, select_item);
|
||||
//no need to do additional commit on selection reset
|
||||
if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(true);
|
||||
|
||||
//only CTRL usage allows to deselect an item, usual clicking on an item cannot deselect it
|
||||
if (mask & MASK_CONTROL)
|
||||
selectItemPair(item_pair, select_item);
|
||||
else
|
||||
selectItemPair(item_pair, true);
|
||||
}
|
||||
|
||||
void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask)
|
||||
|
|
@ -778,6 +784,18 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLFlatListView::scrollToShowFirstSelectedItem()
|
||||
{
|
||||
if (!mSelectedItemPairs.size()) return;
|
||||
|
||||
LLRect selected_rc = mSelectedItemPairs.front()->first->getRect();
|
||||
|
||||
if (selected_rc.isValid())
|
||||
{
|
||||
scrollToShowRect(selected_rc);
|
||||
}
|
||||
}
|
||||
|
||||
LLRect LLFlatListView::getLastSelectedItemRect()
|
||||
{
|
||||
if (!mSelectedItemPairs.size())
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ public:
|
|||
|
||||
bool updateValue(const LLSD& old_value, const LLSD& new_value);
|
||||
|
||||
void scrollToShowFirstSelectedItem();
|
||||
|
||||
void selectFirstItem ();
|
||||
void selectLastItem ();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AddWearableSortOrder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifies sort order for add wearable panel (0 = name, 1 = date, 2 = by type)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AgentPause</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -1785,6 +1785,8 @@ void LLAgent::endAnimationUpdateUI()
|
|||
|
||||
}
|
||||
gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
|
||||
|
||||
LLFloaterCamera::onAvatarEditingAppearance(false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
|
@ -1891,6 +1893,8 @@ void LLAgent::endAnimationUpdateUI()
|
|||
{
|
||||
mPauseRequest = gAgentAvatarp->requestPause();
|
||||
}
|
||||
|
||||
LLFloaterCamera::onAvatarEditingAppearance(true);
|
||||
}
|
||||
|
||||
if (isAgentAvatarValid())
|
||||
|
|
|
|||
|
|
@ -243,6 +243,20 @@ void LLFloaterCamera::resetCameraMode()
|
|||
floater_camera->switchMode(CAMERA_CTRL_MODE_PAN);
|
||||
}
|
||||
|
||||
void LLFloaterCamera::onAvatarEditingAppearance(bool editing)
|
||||
{
|
||||
LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
|
||||
if (!floater_camera) return;
|
||||
|
||||
//camera presets (rear, front, etc.)
|
||||
floater_camera->childSetEnabled("preset_views_list", !editing);
|
||||
floater_camera->childSetEnabled("presets_btn", !editing);
|
||||
|
||||
//camera modes (object view, mouselook view)
|
||||
floater_camera->childSetEnabled("camera_modes_list", !editing);
|
||||
floater_camera->childSetEnabled("avatarview_btn", !editing);
|
||||
}
|
||||
|
||||
void LLFloaterCamera::update()
|
||||
{
|
||||
ECameraControlMode mode = determineMode();
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ public:
|
|||
/** resets current camera mode to orbit mode */
|
||||
static void resetCameraMode();
|
||||
|
||||
/** Called when Avatar is entered/exited editing appearance mode */
|
||||
static void onAvatarEditingAppearance(bool editing);
|
||||
|
||||
/* determines actual mode and updates ui */
|
||||
void update();
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,37 @@ boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(con
|
|||
return mRefreshCompleteSignal.connect(cb);
|
||||
}
|
||||
|
||||
bool LLInventoryItemsList::selectItemByValue(const LLSD& value, bool select)
|
||||
{
|
||||
if (!LLFlatListView::selectItemByValue(value, select) && !value.isUndefined())
|
||||
{
|
||||
mSelectTheseIDs.push_back(value);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLInventoryItemsList::updateSelection()
|
||||
{
|
||||
if(mSelectTheseIDs.empty()) return;
|
||||
|
||||
std::vector<LLSD> cur;
|
||||
getValues(cur);
|
||||
|
||||
for(std::vector<LLSD>::const_iterator cur_id_it = cur.begin(); cur_id_it != cur.end() && !mSelectTheseIDs.empty(); ++cur_id_it)
|
||||
{
|
||||
uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), *cur_id_it);
|
||||
if(select_ids_it != mSelectTheseIDs.end())
|
||||
{
|
||||
selectItemByUUID(*select_ids_it);
|
||||
mSelectTheseIDs.erase(select_ids_it);
|
||||
}
|
||||
}
|
||||
|
||||
scrollToShowFirstSelectedItem();
|
||||
mSelectTheseIDs.clear();
|
||||
}
|
||||
|
||||
void LLInventoryItemsList::doIdle()
|
||||
{
|
||||
if (!mNeedsRefresh) return;
|
||||
|
|
@ -153,6 +184,12 @@ void LLInventoryItemsList::refresh()
|
|||
bool needs_refresh = add_limit_exceeded;
|
||||
setNeedsRefresh(needs_refresh);
|
||||
setForceRefresh(needs_refresh);
|
||||
|
||||
// After list building completed, select items that had been requested to select before list was build
|
||||
if(!needs_refresh)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryItemsList::computeDifference(
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ public:
|
|||
*/
|
||||
void setForceRefresh(bool force_refresh){ mForceRefresh = force_refresh; }
|
||||
|
||||
virtual bool selectItemByValue(const LLSD& value, bool select = true);
|
||||
|
||||
void updateSelection();
|
||||
|
||||
/**
|
||||
* Idle routine used to refresh the list regardless of the current list
|
||||
* visibility, unlike draw() which is called only for the visible list.
|
||||
|
|
@ -104,6 +108,9 @@ protected:
|
|||
private:
|
||||
uuid_vec_t mIDs; // IDs of items that were added in refreshList().
|
||||
// Will be used in refresh() to determine added and removed ids
|
||||
|
||||
uuid_vec_t mSelectTheseIDs; // IDs that will be selected if list is not loaded till now
|
||||
|
||||
bool mNeedsRefresh;
|
||||
|
||||
bool mForceRefresh;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,17 @@ const std::string& LLPanelInventoryListItemBase::getDescription() const
|
|||
return inv_item->getDescription();
|
||||
}
|
||||
|
||||
time_t LLPanelInventoryListItemBase::getCreationDate() const
|
||||
{
|
||||
LLViewerInventoryItem* inv_item = getItem();
|
||||
if (NULL == inv_item)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inv_item->getCreationDate();
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* LLPanelInventoryListItemBase::getItem() const
|
||||
{
|
||||
return gInventory.getItem(mInventoryItemUUID);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,9 @@ public:
|
|||
/** Get the description of a corresponding inventory item */
|
||||
const std::string& getDescription() const;
|
||||
|
||||
/** Get the creation date of a corresponding inventory item */
|
||||
time_t getCreationDate() const;
|
||||
|
||||
/** Get the associated inventory item */
|
||||
LLViewerInventoryItem* getItem() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@
|
|||
#include "lloutfitobserver.h"
|
||||
#include "llcofwearables.h"
|
||||
#include "llfilteredwearablelist.h"
|
||||
#include "llfolderviewitem.h"
|
||||
#include "llinventory.h"
|
||||
#include "llinventoryitemslist.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llui.h"
|
||||
#include "llfloater.h"
|
||||
|
|
@ -85,6 +85,11 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
|
|||
|
||||
static const std::string REVERT_BTN("revert_btn");
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLShopURLDispatcher
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLShopURLDispatcher
|
||||
{
|
||||
public:
|
||||
|
|
@ -144,6 +149,10 @@ std::string LLShopURLDispatcher::resolveURL(LLAssetType::EType asset_type, ESex
|
|||
return gSavedSettings.getString(setting_name);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLPanelOutfitEditGearMenu
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLPanelOutfitEditGearMenu
|
||||
{
|
||||
public:
|
||||
|
|
@ -159,7 +168,6 @@ public:
|
|||
if (menu)
|
||||
{
|
||||
populateCreateWearableSubmenus(menu);
|
||||
menu->buildDrawLabels();
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
|
@ -208,6 +216,131 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLAddWearablesGearMenu
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu>
|
||||
{
|
||||
public:
|
||||
static LLMenuGL* create(LLWearableItemsList* flat_list, LLInventoryPanel* inventory_panel)
|
||||
{
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
|
||||
|
||||
llassert(flat_list);
|
||||
llassert(inventory_panel);
|
||||
|
||||
registrar.add("AddWearable.Gear.Sort", boost::bind(onSort, flat_list, inventory_panel, _2));
|
||||
enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list, inventory_panel, _2));
|
||||
enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel, _2));
|
||||
|
||||
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
|
||||
"menu_add_wearable_gear.xml",
|
||||
LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private:
|
||||
static void onSort(LLWearableItemsList* flat_list,
|
||||
LLInventoryPanel* inventory_panel,
|
||||
LLSD::String sort_order_str)
|
||||
{
|
||||
if (!flat_list || !inventory_panel) return;
|
||||
|
||||
LLWearableItemsList::ESortOrder sort_order;
|
||||
|
||||
if ("by_most_recent" == sort_order_str)
|
||||
{
|
||||
sort_order = LLWearableItemsList::E_SORT_BY_MOST_RECENT;
|
||||
}
|
||||
else if ("by_name" == sort_order_str)
|
||||
{
|
||||
sort_order = LLWearableItemsList::E_SORT_BY_NAME;
|
||||
}
|
||||
else if ("by_type" == sort_order_str)
|
||||
{
|
||||
sort_order = LLWearableItemsList::E_SORT_BY_TYPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unrecognized sort order action" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (inventory_panel->getVisible())
|
||||
{
|
||||
inventory_panel->setSortOrder(sort_order);
|
||||
}
|
||||
else
|
||||
{
|
||||
flat_list->setSortOrder(sort_order);
|
||||
gSavedSettings.setU32("AddWearableSortOrder", sort_order);
|
||||
}
|
||||
}
|
||||
|
||||
static bool onCheck(LLWearableItemsList* flat_list,
|
||||
LLInventoryPanel* inventory_panel,
|
||||
LLSD::String sort_order_str)
|
||||
{
|
||||
if (!inventory_panel || !flat_list) return false;
|
||||
|
||||
// Inventory panel uses its own sort order independent from
|
||||
// flat list view so this flag is used to distinguish between
|
||||
// currently visible "tree" or "flat" representation of inventory.
|
||||
bool inventory_tree_visible = inventory_panel->getVisible();
|
||||
|
||||
if (inventory_tree_visible)
|
||||
{
|
||||
U32 sort_order = inventory_panel->getSortOrder();
|
||||
|
||||
if ("by_most_recent" == sort_order_str)
|
||||
{
|
||||
return LLWearableItemsList::E_SORT_BY_MOST_RECENT & sort_order;
|
||||
}
|
||||
else if ("by_name" == sort_order_str)
|
||||
{
|
||||
// If inventory panel is not sorted by date then it is sorted by name.
|
||||
return LLWearableItemsList::E_SORT_BY_MOST_RECENT & ~sort_order;
|
||||
}
|
||||
llwarns << "Unrecognized inventory panel sort order" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLWearableItemsList::ESortOrder sort_order = flat_list->getSortOrder();
|
||||
|
||||
if ("by_most_recent" == sort_order_str)
|
||||
{
|
||||
return LLWearableItemsList::E_SORT_BY_MOST_RECENT == sort_order;
|
||||
}
|
||||
else if ("by_name" == sort_order_str)
|
||||
{
|
||||
return LLWearableItemsList::E_SORT_BY_NAME == sort_order;
|
||||
}
|
||||
else if ("by_type" == sort_order_str)
|
||||
{
|
||||
return LLWearableItemsList::E_SORT_BY_TYPE == sort_order;
|
||||
}
|
||||
llwarns << "Unrecognized wearable list sort order" << llendl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool onVisible(LLInventoryPanel* inventory_panel,
|
||||
LLSD::String sort_order_str)
|
||||
{
|
||||
// Enable sorting by type only for the flat list of items
|
||||
// because inventory panel doesn't support this kind of sorting.
|
||||
return ( "by_type" == sort_order_str )
|
||||
&& ( !inventory_panel || !inventory_panel->getVisible() );
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLCOFDragAndDropObserver
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver
|
||||
{
|
||||
public:
|
||||
|
|
@ -243,12 +376,17 @@ void LLCOFDragAndDropObserver::done()
|
|||
LLAppearanceMgr::instance().updateAppearanceFromCOF();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LLPanelOutfitEdit
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLPanelOutfitEdit::LLPanelOutfitEdit()
|
||||
: LLPanel(),
|
||||
mSearchFilter(NULL),
|
||||
mCOFWearables(NULL),
|
||||
mInventoryItemsPanel(NULL),
|
||||
mGearMenu(NULL),
|
||||
mAddWearablesGearMenu(NULL),
|
||||
mCOFDragAndDropObserver(NULL),
|
||||
mInitialized(false),
|
||||
mAddWearablesPanel(NULL),
|
||||
|
|
@ -326,7 +464,9 @@ BOOL LLPanelOutfitEdit::postBuild()
|
|||
|
||||
childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
|
||||
childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesFolderView, this), NULL);
|
||||
childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL);
|
||||
childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL);
|
||||
childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL);
|
||||
childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
|
||||
childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
|
||||
childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
|
||||
|
|
@ -387,10 +527,11 @@ BOOL LLPanelOutfitEdit::postBuild()
|
|||
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
|
||||
|
||||
mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");
|
||||
mWearableItemsList = getChild<LLInventoryItemsList>("list_view");
|
||||
mWearableItemsList = getChild<LLWearableItemsList>("list_view");
|
||||
mWearableItemsList->setCommitOnSelectionChange(true);
|
||||
mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));
|
||||
mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
|
||||
mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder"));
|
||||
|
||||
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
|
||||
return TRUE;
|
||||
|
|
@ -474,9 +615,7 @@ void LLPanelOutfitEdit::showWearablesListView()
|
|||
{
|
||||
if(switchPanels(mInventoryItemsPanel, mWearablesListViewPanel))
|
||||
{
|
||||
mFolderViewBtn->setToggleState(FALSE);
|
||||
mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());
|
||||
mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign());
|
||||
updateWearablesPanelVerbButtons();
|
||||
updateFiltersVisibility();
|
||||
}
|
||||
mListViewBtn->setToggleState(TRUE);
|
||||
|
|
@ -486,9 +625,7 @@ void LLPanelOutfitEdit::showWearablesFolderView()
|
|||
{
|
||||
if(switchPanels(mWearablesListViewPanel, mInventoryItemsPanel))
|
||||
{
|
||||
mListViewBtn->setToggleState(FALSE);
|
||||
mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());
|
||||
mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign());
|
||||
updateWearablesPanelVerbButtons();
|
||||
updateFiltersVisibility();
|
||||
}
|
||||
mFolderViewBtn->setToggleState(TRUE);
|
||||
|
|
@ -999,13 +1136,33 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch
|
|||
|
||||
void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
|
||||
{
|
||||
if(!mGearMenu)
|
||||
LLMenuGL* menu = NULL;
|
||||
|
||||
if (mAddWearablesPanel->getVisible())
|
||||
{
|
||||
mGearMenu = LLPanelOutfitEditGearMenu::create();
|
||||
if (!mAddWearablesGearMenu)
|
||||
{
|
||||
mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel);
|
||||
}
|
||||
|
||||
menu = mAddWearablesGearMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mGearMenu)
|
||||
{
|
||||
mGearMenu = LLPanelOutfitEditGearMenu::create();
|
||||
}
|
||||
|
||||
menu = mGearMenu;
|
||||
}
|
||||
|
||||
S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight();
|
||||
LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);
|
||||
if (!menu) return;
|
||||
|
||||
menu->arrangeAndClear(); // update menu height
|
||||
S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight();
|
||||
menu->buildDrawLabels();
|
||||
LLMenuGL::showPopup(clicked_button, menu, 0, menu_y);
|
||||
}
|
||||
|
||||
void LLPanelOutfitEdit::onAddMoreButtonClicked()
|
||||
|
|
@ -1085,6 +1242,67 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
|
|||
// return selected_id;
|
||||
}
|
||||
|
||||
void LLPanelOutfitEdit::updateWearablesPanelVerbButtons()
|
||||
{
|
||||
if(mWearablesListViewPanel->getVisible())
|
||||
{
|
||||
mFolderViewBtn->setToggleState(FALSE);
|
||||
mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());
|
||||
mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign());
|
||||
}
|
||||
else if(mInventoryItemsPanel->getVisible())
|
||||
{
|
||||
mListViewBtn->setToggleState(FALSE);
|
||||
mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());
|
||||
mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelOutfitEdit::saveListSelection()
|
||||
{
|
||||
if(mWearablesListViewPanel->getVisible())
|
||||
{
|
||||
std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
|
||||
|
||||
if(!selected_ids.size()) return;
|
||||
|
||||
mWearableItemsList->resetSelection();
|
||||
|
||||
for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
|
||||
{
|
||||
mWearableItemsList->selectItemByUUID(*item_id, true);
|
||||
}
|
||||
mWearableItemsList->scrollToShowFirstSelectedItem();
|
||||
}
|
||||
else if(mInventoryItemsPanel->getVisible())
|
||||
{
|
||||
std::vector<LLUUID> selected_ids;
|
||||
mWearableItemsList->getSelectedUUIDs(selected_ids);
|
||||
|
||||
if(!selected_ids.size()) return;
|
||||
|
||||
mInventoryItemsPanel->clearSelection();
|
||||
LLFolderView* root = mInventoryItemsPanel->getRootFolder();
|
||||
|
||||
if(!root) return;
|
||||
|
||||
for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
|
||||
{
|
||||
LLFolderViewItem* item = root->getItemByID(*item_id);
|
||||
if (!item) continue;
|
||||
|
||||
LLFolderViewFolder* parent = item->getParentFolder();
|
||||
if(parent)
|
||||
{
|
||||
parent->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
|
||||
}
|
||||
mInventoryItemsPanel->getRootFolder()->changeSelection(item, TRUE);
|
||||
}
|
||||
mInventoryItemsPanel->getRootFolder()->scrollToShowSelection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPanelOutfitEdit::onCOFChanged()
|
||||
{
|
||||
//the panel is only updated when is visible to a user
|
||||
|
|
@ -1093,5 +1311,4 @@ void LLPanelOutfitEdit::onCOFChanged()
|
|||
update();
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@
|
|||
#include "llremoteparcelrequest.h"
|
||||
#include "llinventory.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryitemslist.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llwearableitemslist.h"
|
||||
|
||||
class LLButton;
|
||||
class LLCOFWearables;
|
||||
|
|
@ -140,6 +140,12 @@ public:
|
|||
void showWearablesListView();
|
||||
void showWearablesFolderView();
|
||||
|
||||
/**
|
||||
* Method preserves selection while switching between folder/list view modes
|
||||
*/
|
||||
void saveListSelection();
|
||||
|
||||
void updateWearablesPanelVerbButtons();
|
||||
void updateFiltersVisibility();
|
||||
|
||||
void onFolderViewFilterCommitted(LLUICtrl* ctrl);
|
||||
|
|
@ -218,7 +224,7 @@ private:
|
|||
LLComboBox* mListViewFilterCmbBox;
|
||||
|
||||
LLFilteredWearableListManager* mWearableListManager;
|
||||
LLInventoryItemsList* mWearableItemsList;
|
||||
LLWearableItemsList* mWearableItemsList;
|
||||
LLPanel* mWearablesListViewPanel;
|
||||
|
||||
LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
|
||||
|
|
@ -228,6 +234,7 @@ private:
|
|||
|
||||
LLCOFWearables* mCOFWearables;
|
||||
LLMenuGL* mGearMenu;
|
||||
LLMenuGL* mAddWearablesGearMenu;
|
||||
bool mInitialized;
|
||||
std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
|
||||
|
||||
|
|
|
|||
|
|
@ -537,11 +537,27 @@ LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparato
|
|||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const
|
||||
{
|
||||
time_t date1 = item1->getCreationDate();
|
||||
time_t date2 = item2->getCreationDate();
|
||||
|
||||
if (date1 == date2)
|
||||
{
|
||||
return LLWearableItemNameComparator::doCompare(item1, item2);
|
||||
}
|
||||
|
||||
return date1 > date2;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
|
||||
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
|
||||
static const LLWearableItemCreationDateComparator WEARABLE_CREATION_DATE_COMPARATOR;
|
||||
|
||||
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
|
||||
|
||||
|
|
@ -553,7 +569,7 @@ LLWearableItemsList::Params::Params()
|
|||
LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
|
||||
: LLInventoryItemsList(p)
|
||||
{
|
||||
setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
|
||||
setSortOrder(E_SORT_BY_TYPE, false);
|
||||
mIsStandalone = p.standalone;
|
||||
if (mIsStandalone)
|
||||
{
|
||||
|
|
@ -653,6 +669,32 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)
|
|||
ContextMenu::instance().show(this, selected_uuids, x, y);
|
||||
}
|
||||
|
||||
void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now)
|
||||
{
|
||||
switch (sort_order)
|
||||
{
|
||||
case E_SORT_BY_MOST_RECENT:
|
||||
setComparator(&WEARABLE_CREATION_DATE_COMPARATOR);
|
||||
break;
|
||||
case E_SORT_BY_NAME:
|
||||
setComparator(&WEARABLE_NAME_COMPARATOR);
|
||||
break;
|
||||
case E_SORT_BY_TYPE:
|
||||
setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
|
||||
break;
|
||||
|
||||
// No "default:" to raise compiler warning
|
||||
// if we're not handling something
|
||||
}
|
||||
|
||||
mSortOrder = sort_order;
|
||||
|
||||
if (sort_now)
|
||||
{
|
||||
sort();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// ContextMenu
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -336,6 +336,19 @@ private:
|
|||
static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLWearableItemCreationDateComparator
|
||||
*
|
||||
* Comparator for sorting wearable list items by creation date (newest go first).
|
||||
*/
|
||||
class LLWearableItemCreationDateComparator : public LLWearableItemNameComparator
|
||||
{
|
||||
LOG_CLASS(LLWearableItemCreationDateComparator);
|
||||
|
||||
protected:
|
||||
/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLWearableItemsList
|
||||
*
|
||||
|
|
@ -388,6 +401,13 @@ public:
|
|||
Params();
|
||||
};
|
||||
|
||||
typedef enum e_sort_order {
|
||||
// Values should be compatible with InventorySortOrder setting.
|
||||
E_SORT_BY_NAME = 0,
|
||||
E_SORT_BY_MOST_RECENT = 1,
|
||||
E_SORT_BY_TYPE = 2,
|
||||
} ESortOrder;
|
||||
|
||||
virtual ~LLWearableItemsList();
|
||||
|
||||
/*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
|
||||
|
|
@ -402,6 +422,10 @@ public:
|
|||
|
||||
bool isStandalone() const { return mIsStandalone; }
|
||||
|
||||
ESortOrder getSortOrder() const { return mSortOrder; }
|
||||
|
||||
void setSortOrder(ESortOrder sort_order, bool sort_now = true);
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLWearableItemsList(const LLWearableItemsList::Params& p);
|
||||
|
|
@ -410,6 +434,8 @@ protected:
|
|||
|
||||
bool mIsStandalone;
|
||||
bool mWornIndicationEnabled;
|
||||
|
||||
ESortOrder mSortOrder;
|
||||
};
|
||||
|
||||
#endif //LL_LLWEARABLEITEMSLIST_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<menu
|
||||
layout="topleft"
|
||||
name="Add Wearable Gear Menu">
|
||||
<menu_item_check
|
||||
label="Sort by Most Recent"
|
||||
layout="topleft"
|
||||
name="sort_by_most_recent">
|
||||
<on_check
|
||||
function="AddWearable.Gear.Check"
|
||||
parameter="by_most_recent" />
|
||||
<on_click
|
||||
function="AddWearable.Gear.Sort"
|
||||
parameter="by_most_recent" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Sort by Name"
|
||||
layout="topleft"
|
||||
name="sort_by_name">
|
||||
<on_check
|
||||
function="AddWearable.Gear.Check"
|
||||
parameter="by_name" />
|
||||
<on_click
|
||||
function="AddWearable.Gear.Sort"
|
||||
parameter="by_name" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Sort by Type"
|
||||
layout="topleft"
|
||||
name="sort_by_type">
|
||||
<on_check
|
||||
function="AddWearable.Gear.Check"
|
||||
parameter="by_type" />
|
||||
<on_click
|
||||
function="AddWearable.Gear.Sort"
|
||||
parameter="by_type" />
|
||||
<on_visible
|
||||
function="AddWearable.Gear.Visible"
|
||||
parameter="by_type" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
Loading…
Reference in New Issue