diff options
author | Loren Shih <seraph@lindenlab.com> | 2009-11-23 15:25:31 -0500 |
---|---|---|
committer | Loren Shih <seraph@lindenlab.com> | 2009-11-23 15:25:31 -0500 |
commit | fc1860bcc6bab4b538692662db2da4be1def5af4 (patch) | |
tree | 2452ea008050749c15be1dcd2b7f392ef499e796 | |
parent | 0c3bd94da9ba2244613b6c1f1f0e4ce9723c46d3 (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.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.cpp | 61 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.h | 8 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitsinventory.cpp | 69 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitsinventory.h | 22 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_outfits_inventory.xml | 33 |
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" |