summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoren Shih <seraph@lindenlab.com>2009-11-23 15:25:31 -0500
committerLoren Shih <seraph@lindenlab.com>2009-11-23 15:25:31 -0500
commitfc1860bcc6bab4b538692662db2da4be1def5af4 (patch)
tree2452ea008050749c15be1dcd2b7f392ef499e796
parent0c3bd94da9ba2244613b6c1f1f0e4ce9723c46d3 (diff)
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-pipeline
-rw-r--r--indra/newview/llfolderview.cpp6
-rw-r--r--indra/newview/llinventorypanel.cpp61
-rw-r--r--indra/newview/llinventorypanel.h8
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp69
-rw-r--r--indra/newview/llpaneloutfitsinventory.h22
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml33
6 files changed, 153 insertions, 46 deletions
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 955bc64e05..c9c4c76da4 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -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");
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 327a735f78..e4dd70cdd1 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -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)
+ }
+ else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
{
- // This item exists outside the inventory's hierarchy, so don't add it.
+ // 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).
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 0ccee337c9..41f393c660 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -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;
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index c4bde369db..2550962d76 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -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;
+}
+
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 4d903a389b..902a5caab8 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -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 //
////////////////////////////////////////////////////////////////////////////////
};
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index f511ec0d6f..d805209bf5 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -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"