EXT-2705 : Create accordion panel to show COF contents
Also made several infrastructure improvements that help inventory panels defer generating their folders/views until after inventory has been loaded up. This was pretty haphazard before. --HG-- branch : avatar-pipelinemeow-7.2.2
parent
0c3bd94da9
commit
fc1860bcc6
|
|
@ -2014,6 +2014,12 @@ static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
|
|||
// Main idle routine
|
||||
void LLFolderView::doIdle()
|
||||
{
|
||||
// Don't do anything until the inventory is loaded up.
|
||||
if (!gInventory.isInventoryUsable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLFastTimer t2(FTM_INVENTORY);
|
||||
|
||||
BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
|
||||
|
|
|
|||
|
|
@ -96,6 +96,11 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
|
|||
setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor"));
|
||||
setBackgroundVisible(TRUE);
|
||||
setBackgroundOpaque(TRUE);
|
||||
|
||||
if (mStartFolderString != "")
|
||||
{
|
||||
mBuildDefaultHierarchy = false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLInventoryPanel::postBuild()
|
||||
|
|
@ -148,7 +153,7 @@ BOOL LLInventoryPanel::postBuild()
|
|||
// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback
|
||||
if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection)
|
||||
{
|
||||
rebuildViews();
|
||||
generateViews();
|
||||
mHasInventoryConnection = true;
|
||||
defaultOpenInventory();
|
||||
}
|
||||
|
|
@ -253,9 +258,9 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
|||
bool handled = false;
|
||||
|
||||
// inventory just initialized, do complete build
|
||||
if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
|
||||
if ((mask & LLInventoryObserver::ADD) && mInventory->isInventoryUsable() && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
|
||||
{
|
||||
rebuildViews();
|
||||
generateViews();
|
||||
mHasInventoryConnection = true;
|
||||
defaultOpenInventory();
|
||||
return;
|
||||
|
|
@ -367,10 +372,14 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
|||
}
|
||||
|
||||
|
||||
void LLInventoryPanel::rebuildViews()
|
||||
void LLInventoryPanel::generateViews()
|
||||
{
|
||||
// Determine the root folder and rebuild the views starting
|
||||
// at that folder.
|
||||
|
||||
// Blow away the entire previous UI tree.
|
||||
mFolders->getRoot()->destroyView();
|
||||
|
||||
// Determine the root folder in case specified, and
|
||||
// build the views starting with that folder.
|
||||
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
|
||||
|
||||
if ("LIBRARY" == mStartFolderString)
|
||||
|
|
@ -381,16 +390,14 @@ void LLInventoryPanel::rebuildViews()
|
|||
{
|
||||
mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
|
||||
}
|
||||
|
||||
llinfos << this << " Generating views for start folder " << mStartFolderString << llendl;
|
||||
rebuildViewsFor(mStartFolderID);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
|
||||
{
|
||||
LLFolderViewItem* old_view = NULL;
|
||||
|
||||
// get old LLFolderViewItem
|
||||
old_view = mFolders->getItemByID(id);
|
||||
// Destroy the old view for this ID so we can rebuild it
|
||||
LLFolderViewItem* old_view = mFolders->getItemByID(id);
|
||||
if (old_view && id.notNull())
|
||||
{
|
||||
old_view->destroyView();
|
||||
|
|
@ -409,14 +416,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
|||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id);
|
||||
if (id == mStartFolderID)
|
||||
parent_folder = mFolders;
|
||||
|
||||
if (!parent_folder)
|
||||
{
|
||||
// This item exists outside the inventory's hierarchy, so don't add it.
|
||||
parent_folder = mFolders;
|
||||
}
|
||||
else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
|
||||
{
|
||||
// This item exists outside the inventory's hierarchy,
|
||||
// so don't add it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (objectp->getName() == "My Inventory")
|
||||
{
|
||||
llinfos << this << " Adding MyInventory for start folder " << mStartFolderString << llendl;
|
||||
}
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE ||
|
||||
objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
|
|
@ -520,19 +533,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
|||
// bit of a hack to make sure the inventory is open.
|
||||
void LLInventoryPanel::defaultOpenInventory()
|
||||
{
|
||||
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
|
||||
if (preferred_type != LLFolderType::FT_NONE)
|
||||
if (mStartFolderString != "")
|
||||
{
|
||||
const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type);
|
||||
mFolders->openFolder(top_level_folder_name);
|
||||
mFolders->openFolder(mStartFolderString);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the first child (it should be "My Inventory") and
|
||||
// open it up by name (just to make sure the first child is actually a folder).
|
||||
LLView* first_child = mFolders->getFirstChild();
|
||||
const std::string& first_child_name = first_child->getName();
|
||||
mFolders->openFolder(first_child_name);
|
||||
if (first_child)
|
||||
{
|
||||
const std::string& first_child_name = first_child->getName();
|
||||
mFolders->openFolder(first_child_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -640,13 +654,6 @@ void LLInventoryPanel::openAllFolders()
|
|||
mFolders->arrangeAll();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::openDefaultFolderForType(LLFolderType::EType type)
|
||||
{
|
||||
LLUUID category_id = mInventory->findCategoryUUIDForType(type);
|
||||
LLOpenFolderByID opener(category_id);
|
||||
mFolders->applyFunctorRecursively(opener);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
|
||||
{
|
||||
// Don't select objects in COF (e.g. to prevent refocus when items are worn).
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ public:
|
|||
|
||||
// Call this method to set the selection.
|
||||
void openAllFolders();
|
||||
void openDefaultFolderForType(LLFolderType::EType);
|
||||
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
|
||||
void clearSelection();
|
||||
|
|
@ -161,16 +160,17 @@ public:
|
|||
void openSelected();
|
||||
void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); }
|
||||
|
||||
protected:
|
||||
private:
|
||||
// Destroys the old views, and regenerates them based on the
|
||||
// start folder ID.
|
||||
void rebuildViews();
|
||||
void generateViews();
|
||||
|
||||
// Given the id and the parent, build all of the folder views.
|
||||
void rebuildViewsFor(const LLUUID& id);
|
||||
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
|
||||
void defaultOpenInventory(); // open the first level of inventory
|
||||
protected:
|
||||
void defaultOpenInventory(); // open the first level of inventory
|
||||
|
||||
LLInventoryModel* mInventory;
|
||||
LLInventoryObserver* mInventoryObserver;
|
||||
BOOL mAllowMultiSelect;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
|
||||
|
||||
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
|
||||
mInventoryPanel(NULL),
|
||||
mActivePanel(NULL),
|
||||
mParent(NULL)
|
||||
{
|
||||
mSavedFolderState = new LLSaveFolderState();
|
||||
|
|
@ -74,12 +74,8 @@ LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
|
|||
// virtual
|
||||
BOOL LLPanelOutfitsInventory::postBuild()
|
||||
{
|
||||
mInventoryPanel = getChild<LLInventoryPanel>("outfits_list");
|
||||
mInventoryPanel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
|
||||
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_MY_OUTFITS);
|
||||
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2));
|
||||
|
||||
initAccordionPanels();
|
||||
initListCommandsHandlers();
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -102,7 +98,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
{
|
||||
if (string == "")
|
||||
{
|
||||
mInventoryPanel->setFilterSubString(LLStringUtil::null);
|
||||
mActivePanel->setFilterSubString(LLStringUtil::null);
|
||||
|
||||
// re-open folders that were initially open
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
|
|
@ -114,7 +110,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
|
||||
gInventory.startBackgroundFetch();
|
||||
|
||||
if (mInventoryPanel->getFilterSubString().empty() && string.empty())
|
||||
if (mActivePanel->getFilterSubString().empty() && string.empty())
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
|
|
@ -128,7 +124,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
}
|
||||
|
||||
// set new filter string
|
||||
mInventoryPanel->setFilterSubString(string);
|
||||
mActivePanel->setFilterSubString(string);
|
||||
}
|
||||
|
||||
void LLPanelOutfitsInventory::onWear()
|
||||
|
|
@ -207,7 +203,7 @@ bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *
|
|||
|
||||
LLFolderView *LLPanelOutfitsInventory::getRootFolder()
|
||||
{
|
||||
return mInventoryPanel->getRootFolder();
|
||||
return mActivePanel->getRootFolder();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -349,3 +345,56 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
|
|||
// List Commands //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Accordion //
|
||||
|
||||
void LLPanelOutfitsInventory::initAccordionPanels()
|
||||
{
|
||||
mAccordionPanels.resize(2);
|
||||
|
||||
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_accordionpanel");
|
||||
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
|
||||
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mAccordionPanels[0] = myoutfits_panel;
|
||||
mActivePanel = myoutfits_panel;
|
||||
|
||||
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_accordionpanel");
|
||||
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mAccordionPanels[1] = cof_panel;
|
||||
|
||||
for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin();
|
||||
iter != mAccordionPanels.end();
|
||||
++iter)
|
||||
{
|
||||
LLInventoryPanel *panel = (*iter);
|
||||
panel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onAccordionSelectionChange, this, panel, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelOutfitsInventory::onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
|
||||
{
|
||||
if (user_action && items.size() > 0)
|
||||
{
|
||||
for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin();
|
||||
iter != mAccordionPanels.end();
|
||||
++iter)
|
||||
{
|
||||
LLInventoryPanel *panel = (*iter);
|
||||
if (panel == accordion_panel)
|
||||
{
|
||||
mActivePanel = panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
panel->getRootFolder()->clearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
onSelectionChange(items, user_action);
|
||||
}
|
||||
|
||||
LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel()
|
||||
{
|
||||
return mActivePanel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ public:
|
|||
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
void onSelectorButtonClicked();
|
||||
|
||||
LLInventoryPanel* getActivePanel() { return mInventoryPanel; }
|
||||
|
||||
// If a compatible listener type is selected, then return a pointer to that.
|
||||
// Otherwise, return NULL.
|
||||
LLFolderViewEventListener* getCorrectListenerForAction();
|
||||
|
|
@ -74,9 +72,25 @@ protected:
|
|||
|
||||
private:
|
||||
LLSidepanelAppearance* mParent;
|
||||
LLInventoryPanel* mInventoryPanel;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Accordion //
|
||||
LLInventoryPanel* getActivePanel();
|
||||
|
||||
protected:
|
||||
void initAccordionPanels();
|
||||
void onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
|
||||
private:
|
||||
LLInventoryPanel* mActivePanel;
|
||||
typedef std::vector<LLInventoryPanel *> accordionpanels_vec_t;
|
||||
accordionpanels_vec_t mAccordionPanels;
|
||||
|
||||
// Accordion //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// List Commands //
|
||||
|
|
@ -95,7 +109,7 @@ private:
|
|||
LLPanel* mListCommands;
|
||||
LLMenuGL* mMenuGearDefault;
|
||||
LLMenuGL* mMenuAdd;
|
||||
// //
|
||||
// List Commands //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,18 @@
|
|||
width="310"
|
||||
border="true"
|
||||
follows="left|top|right|bottom">
|
||||
<accordion
|
||||
follows="left|top|right|bottom"
|
||||
height="315"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="outfits_accordion"
|
||||
top="2"
|
||||
width="310">
|
||||
<accordion_tab
|
||||
layout="topleft"
|
||||
name="tab_outfits"
|
||||
title="Outfits bar">
|
||||
<inventory_panel
|
||||
allow_multi_select="true"
|
||||
border="true"
|
||||
|
|
@ -14,9 +26,28 @@
|
|||
height="326"
|
||||
left="0"
|
||||
mouse_opaque="true"
|
||||
name="outfits_list"
|
||||
name="outfitslist_accordionpanel"
|
||||
width="310"
|
||||
start_folder="My Outfits"/>
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
layout="topleft"
|
||||
name="tab_cof"
|
||||
title="Current Outfit bar">
|
||||
<inventory_panel
|
||||
allow_multi_select="true"
|
||||
border="true"
|
||||
bottom="0"
|
||||
follows="left|top|right|bottom"
|
||||
height="326"
|
||||
left="0"
|
||||
mouse_opaque="true"
|
||||
name="cof_accordionpanel"
|
||||
width="310"
|
||||
start_folder="Current Outfit"/>
|
||||
</accordion_tab>
|
||||
</accordion>
|
||||
|
||||
<button bottom="0"
|
||||
halign="center"
|
||||
height="16"
|
||||
|
|
|
|||
Loading…
Reference in New Issue