Implemented by SL EXT-6722(normal task) - Create modified inventory view for "my outfits" tab in top-level appearance sidebar (tier 1)
llui: - Setting container panel for accordion tab control to dynamically add tabs to accordions. - Added method to dynamically remove accordion tabs. - Added LLIconCtrl image setter. newview: - Class LLOutfitsList - a list of agents's outfits from "My Outfits" inventory category which represents each outfit by an accordion tab with a list of items inside it. - Class LLWearableItemsList - a list of wearable items used in each accordion tab of "My Outfits" tab. - Class LLInventoryItemsList - a base class for LLWearableItemsList that represents inventory items by panels in LLFlatListView. - Class LLPanelInventoryItem - inventory item representation for a flat list. Item icon is set according to item type. - Class LLInventoryCategoriesObserver - an observer used in LLOutfitsList for monitoring changes to "My Outfits" inventory category and updating outfits accordion tabs and list of items for each outfit. Known issues: - Only first outfit tab is displayed in "My Outfits" until this tab is expanded. - Bottom bar buttons and filter field not functioning for "My Outfits" tab since LLOutfitsList still doesn't support selection, filtering and sorting. - "My Outfits" and "Wearing" tabs of "Appearance" side panel might need a common interface to use LLOutfitsList and LLinventoryPanel as tabs in LLPanelOutfitsInventory or "Wearing" tab should be replaces with LLOutfitsList class object i.e. a flat list. On review - https://codereview.productengine.com/secondlife/r/285/ --HG-- branch : product-enginemeow-7.2.2
parent
6b722079c4
commit
2ce7556e53
|
|
@ -332,11 +332,31 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)
|
|||
if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) == getChildList()->end())
|
||||
addChild(accordion_tab);
|
||||
mAccordionTabs.push_back(accordion_tab);
|
||||
|
||||
|
||||
accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, mAccordionTabs.size() - 1) );
|
||||
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(view);
|
||||
if(!accordion_tab)
|
||||
return;
|
||||
|
||||
if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) != getChildList()->end())
|
||||
removeChild(accordion_tab);
|
||||
|
||||
for (std::vector<LLAccordionCtrlTab*>::iterator iter = mAccordionTabs.begin();
|
||||
iter != mAccordionTabs.end(); ++iter)
|
||||
{
|
||||
if (accordion_tab == (*iter))
|
||||
{
|
||||
mAccordionTabs.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::arrangeSinge()
|
||||
{
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public:
|
|||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
void addCollapsibleCtrl(LLView* view);
|
||||
void removeCollapsibleCtrl(LLView* view);
|
||||
void arrange();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -425,6 +425,9 @@ bool LLAccordionCtrlTab::addChild(LLView* child, S32 tab_group)
|
|||
setDisplayChildren(getDisplayChildren());
|
||||
}
|
||||
|
||||
if (!mContainerPanel)
|
||||
mContainerPanel = findContainerView();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
std::string getImageName() const;
|
||||
|
||||
void setColor(const LLColor4& color) { mColor = color; }
|
||||
void setImage(LLPointer<LLUIImage> image) { mImagep = image; }
|
||||
|
||||
private:
|
||||
void setIconImageDrawSize() ;
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ set(viewer_SOURCE_FILES
|
|||
llinventoryclipboard.cpp
|
||||
llinventoryfilter.cpp
|
||||
llinventoryfunctions.cpp
|
||||
llinventoryitemslist.cpp
|
||||
llinventorymodel.cpp
|
||||
llinventorymodelbackgroundfetch.cpp
|
||||
llinventoryobserver.cpp
|
||||
|
|
@ -295,6 +296,7 @@ set(viewer_SOURCE_FILES
|
|||
llnotificationofferhandler.cpp
|
||||
llnotificationscripthandler.cpp
|
||||
llnotificationtiphandler.cpp
|
||||
lloutfitslist.cpp
|
||||
lloutputmonitorctrl.cpp
|
||||
llpanelavatar.cpp
|
||||
llpanelavatartag.cpp
|
||||
|
|
@ -528,6 +530,7 @@ set(viewer_SOURCE_FILES
|
|||
llwaterparamset.cpp
|
||||
llwearable.cpp
|
||||
llwearabledictionary.cpp
|
||||
llwearableitemslist.cpp
|
||||
llwearablelist.cpp
|
||||
llweb.cpp
|
||||
llwind.cpp
|
||||
|
|
@ -756,6 +759,7 @@ set(viewer_HEADER_FILES
|
|||
llinventoryclipboard.h
|
||||
llinventoryfilter.h
|
||||
llinventoryfunctions.h
|
||||
llinventoryitemslist.h
|
||||
llinventorymodel.h
|
||||
llinventorymodelbackgroundfetch.h
|
||||
llinventoryobserver.h
|
||||
|
|
@ -795,6 +799,7 @@ set(viewer_HEADER_FILES
|
|||
llnetmap.h
|
||||
llnotificationhandler.h
|
||||
llnotificationmanager.h
|
||||
lloutfitslist.h
|
||||
lloutputmonitorctrl.h
|
||||
llpanelavatar.h
|
||||
llpanelavatartag.h
|
||||
|
|
@ -1030,6 +1035,7 @@ set(viewer_HEADER_FILES
|
|||
llwaterparamset.h
|
||||
llwearable.h
|
||||
llwearabledictionary.h
|
||||
llwearableitemslist.h
|
||||
llwearablelist.h
|
||||
llweb.h
|
||||
llwind.h
|
||||
|
|
|
|||
|
|
@ -1338,7 +1338,8 @@ public:
|
|||
LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
|
||||
LLPanelOutfitsInventory *outfit_panel =
|
||||
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
|
||||
if (outfit_panel)
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (outfit_panel && outfit_panel->isCOFPanelActive())
|
||||
{
|
||||
outfit_panel->getRootFolder()->clearSelection();
|
||||
outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* @file llinventoryitemslist.cpp
|
||||
* @brief A list of inventory items represented by LLFlatListView.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llinventoryitemslist.h"
|
||||
|
||||
#include "lliconctrl.h"
|
||||
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "lltextutil.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLPanelInventoryItem::LLPanelInventoryItem(LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inventory_type,
|
||||
U32 wearable_type,
|
||||
const std::string &item_name,
|
||||
const std::string &hl)
|
||||
: LLPanel()
|
||||
,mItemName(item_name)
|
||||
,mHighlightedText(hl)
|
||||
,mIcon(NULL)
|
||||
,mTitle(NULL)
|
||||
{
|
||||
mItemIcon = get_item_icon(asset_type, inventory_type, wearable_type, FALSE);
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
|
||||
}
|
||||
|
||||
LLPanelInventoryItem::~LLPanelInventoryItem()
|
||||
{}
|
||||
|
||||
//virtual
|
||||
BOOL LLPanelInventoryItem::postBuild()
|
||||
{
|
||||
mIcon = getChild<LLIconCtrl>("item_icon");
|
||||
mTitle = getChild<LLTextBox>("item_name");
|
||||
|
||||
updateItem();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLPanelInventoryItem::setValue(const LLSD& value)
|
||||
{
|
||||
if (!value.isMap()) return;
|
||||
if (!value.has("selected")) return;
|
||||
childSetVisible("selected_icon", value["selected"]);
|
||||
}
|
||||
|
||||
void LLPanelInventoryItem::updateItem()
|
||||
{
|
||||
if (mItemIcon.notNull())
|
||||
mIcon->setImage(mItemIcon);
|
||||
|
||||
LLTextUtil::textboxSetHighlightedVal(
|
||||
mTitle,
|
||||
LLStyle::Params(),
|
||||
mItemName,
|
||||
mHighlightedText);
|
||||
}
|
||||
|
||||
void LLPanelInventoryItem::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
childSetVisible("hovered_icon", true);
|
||||
|
||||
LLPanel::onMouseEnter(x, y, mask);
|
||||
}
|
||||
|
||||
void LLPanelInventoryItem::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
childSetVisible("hovered_icon", false);
|
||||
|
||||
LLPanel::onMouseLeave(x, y, mask);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLInventoryItemsList::LLInventoryItemsList(const LLFlatListView::Params& p)
|
||||
: LLFlatListView(p)
|
||||
{}
|
||||
|
||||
// virtual
|
||||
LLInventoryItemsList::~LLInventoryItemsList()
|
||||
{}
|
||||
|
||||
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
|
||||
{
|
||||
clear();
|
||||
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
|
||||
iter != item_array.end();
|
||||
iter++)
|
||||
{
|
||||
LLViewerInventoryItem *item = (*iter);
|
||||
|
||||
LLPanelInventoryItem *list_item = new LLPanelInventoryItem(item->getType(),
|
||||
item->getInventoryType(),
|
||||
item->getFlags(),
|
||||
item->getName(),
|
||||
LLStringUtil::null);
|
||||
if (!addItem(list_item, item->getUUID()))
|
||||
{
|
||||
llerrs << "Couldn't add flat item." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @file llinventoryitemslist.h
|
||||
* @brief A list of inventory items represented by LLFlatListView.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLINVENTORYITEMSLIST_H
|
||||
#define LL_LLINVENTORYITEMSLIST_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
#include "llassettype.h"
|
||||
|
||||
#include "llinventorytype.h"
|
||||
|
||||
// newview
|
||||
#include "llflatlistview.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
||||
class LLIconCtrl;
|
||||
class LLTextBox;
|
||||
|
||||
class LLPanelInventoryItem : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelInventoryItem(LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inventory_type,
|
||||
U32 wearable_type,
|
||||
const std::string &item_name,
|
||||
const std::string &hl);
|
||||
virtual ~LLPanelInventoryItem();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
||||
void updateItem();
|
||||
|
||||
void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
private:
|
||||
LLIconCtrl* mIcon;
|
||||
LLTextBox* mTitle;
|
||||
|
||||
LLUIImagePtr mItemIcon;
|
||||
std::string mItemName;
|
||||
std::string mHighlightedText;
|
||||
};
|
||||
|
||||
|
||||
class LLInventoryItemsList : public LLFlatListView
|
||||
{
|
||||
public:
|
||||
virtual ~LLInventoryItemsList();
|
||||
|
||||
void refreshList(const LLInventoryModel::item_array_t item_array);
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLInventoryItemsList(const LLFlatListView::Params& p);
|
||||
};
|
||||
|
||||
#endif //LL_LLINVENTORYITEMSLIST_H
|
||||
|
|
@ -647,3 +647,35 @@ void LLInventoryTransactionObserver::changed(U32 mask)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryCategoriesObserver::changed(U32 mask)
|
||||
{
|
||||
if (!mCategoryMap.size())
|
||||
return;
|
||||
|
||||
for (category_map_t::iterator iter = mCategoryMap.begin();
|
||||
iter != mCategoryMap.end();
|
||||
iter++)
|
||||
{
|
||||
// Inventory category version is used to find out if some changes
|
||||
// to a category have been made.
|
||||
S32 version = gInventory.getCategory((*iter).first)->getVersion();
|
||||
if (version != (*iter).second.mVersion)
|
||||
{
|
||||
// Update category version in map.
|
||||
(*iter).second.mVersion = version;
|
||||
(*iter).second.mCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
|
||||
{
|
||||
S32 version = gInventory.getCategory(cat_id)->getVersion();
|
||||
mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version)));
|
||||
}
|
||||
|
||||
void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id)
|
||||
{
|
||||
mCategoryMap.erase(mCategoryMap.find(cat_id));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,5 +262,40 @@ protected:
|
|||
uuid_vec_t mIncomplete;
|
||||
};
|
||||
|
||||
#endif // LL_LLINVENTORYOBSERVERS_H
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInventoryCategoriesObserver
|
||||
//
|
||||
// This class is used for monitoring a list of inventory categories
|
||||
// and firing a callback when there are changes in any of them.
|
||||
// Categories are identified by their UUIDs.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInventoryCategoriesObserver : public LLInventoryObserver
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void()> callback_t;
|
||||
|
||||
LLInventoryCategoriesObserver() {};
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
void addCategory(const LLUUID& cat_id, callback_t cb);
|
||||
void removeCategory(const LLUUID& cat_id);
|
||||
|
||||
protected:
|
||||
struct LLCategoryData
|
||||
{
|
||||
LLCategoryData(callback_t cb, S32 version)
|
||||
: mCallback(cb)
|
||||
, mVersion(version)
|
||||
{}
|
||||
|
||||
callback_t mCallback;
|
||||
S32 mVersion;
|
||||
};
|
||||
|
||||
typedef std::map<LLUUID, LLCategoryData> category_map_t;
|
||||
typedef category_map_t::value_type category_map_value_t;
|
||||
|
||||
category_map_t mCategoryMap;
|
||||
};
|
||||
|
||||
#endif // LL_LLINVENTORYOBSERVERS_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,265 @@
|
|||
/**
|
||||
* @file lloutfitslist.cpp
|
||||
* @brief List of agent's outfits for My Appearance side panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lloutfitslist.h"
|
||||
|
||||
#include "llaccordionctrl.h"
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llwearableitemslist.h"
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list");
|
||||
|
||||
LLOutfitsList::LLOutfitsList()
|
||||
: LLPanel()
|
||||
, mAccordion(NULL)
|
||||
, mListCommands(NULL)
|
||||
{}
|
||||
|
||||
LLOutfitsList::~LLOutfitsList()
|
||||
{
|
||||
if (gInventory.containsObserver(mCategoriesObserver))
|
||||
{
|
||||
gInventory.removeObserver(mCategoriesObserver);
|
||||
delete mCategoriesObserver;
|
||||
}
|
||||
|
||||
if (gInventory.containsObserver(this))
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLOutfitsList::postBuild()
|
||||
{
|
||||
mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
|
||||
|
||||
mCategoriesObserver = new LLInventoryCategoriesObserver();
|
||||
gInventory.addObserver(mCategoriesObserver);
|
||||
|
||||
gInventory.addObserver(this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLOutfitsList::changed(U32 mask)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
// Start observing changes in "My Outfits" category.
|
||||
const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
|
||||
mCategoriesObserver->addCategory(outfits,
|
||||
boost::bind(&LLOutfitsList::refreshList, this, outfits));
|
||||
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
|
||||
if (!category)
|
||||
return;
|
||||
|
||||
// Fetch "My Outfits" contents and refresh the list to display
|
||||
// initially fetched items. If not all items are fetched now
|
||||
// the observer will refresh the list as soon as the new items
|
||||
// arrive.
|
||||
category->fetch();
|
||||
refreshList(outfits);
|
||||
|
||||
// This observer is used to start the initial outfits fetch
|
||||
// when inventory becomes usable. It is no longer needed because
|
||||
// "My Outfits" category is now observed by
|
||||
// LLInventoryCategoriesObserver.
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void LLOutfitsList::refreshList(const LLUUID& category_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
// Collect all sub-categories of a given category.
|
||||
LLIsType is_category(LLAssetType::AT_CATEGORY);
|
||||
gInventory.collectDescendentsIf(
|
||||
category_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_category);
|
||||
|
||||
uuid_vec_t vnew;
|
||||
|
||||
// Creating a vector of newly collected sub-categories UUIDs.
|
||||
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
|
||||
iter != cat_array.end();
|
||||
iter++)
|
||||
{
|
||||
vnew.push_back((*iter)->getUUID());
|
||||
}
|
||||
|
||||
uuid_vec_t vcur;
|
||||
|
||||
// Creating a vector of currently displayed sub-categories UUIDs.
|
||||
for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
|
||||
iter != mOutfitsMap.end();
|
||||
iter++)
|
||||
{
|
||||
vcur.push_back((*iter).first);
|
||||
}
|
||||
|
||||
// Sorting both vectors to compare.
|
||||
std::sort(vcur.begin(), vcur.end());
|
||||
std::sort(vnew.begin(), vnew.end());
|
||||
|
||||
uuid_vec_t vadded;
|
||||
uuid_vec_t vremoved;
|
||||
|
||||
uuid_vec_t::iterator it;
|
||||
size_t maxsize = llmax(vcur.size(), vnew.size());
|
||||
vadded.resize(maxsize);
|
||||
vremoved.resize(maxsize);
|
||||
|
||||
// what to remove
|
||||
it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
|
||||
vremoved.erase(it, vremoved.end());
|
||||
|
||||
// what to add
|
||||
it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
|
||||
vadded.erase(it, vadded.end());
|
||||
|
||||
// Handle added tabs.
|
||||
for (uuid_vec_t::const_iterator iter = vadded.begin();
|
||||
iter != vadded.end();
|
||||
iter++)
|
||||
{
|
||||
const LLUUID cat_id = (*iter);
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
continue;
|
||||
|
||||
std::string name = cat->getName();
|
||||
|
||||
// *TODO: create accordion tabs and lists from XML.
|
||||
LLAccordionCtrlTab::Params params;
|
||||
params.name(name);
|
||||
params.title(name);
|
||||
params.rect(LLRect(0, 0, 315, 20));
|
||||
params.display_children(false);
|
||||
LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(params);
|
||||
|
||||
mAccordion->addCollapsibleCtrl(tab);
|
||||
|
||||
LLFlatListView::Params list_params;
|
||||
LLWearableItemsList* list = LLUICtrlFactory::create<LLWearableItemsList>(list_params);
|
||||
|
||||
tab->addChild(list, 0);
|
||||
tab->setDisplayChildren(false);
|
||||
|
||||
// Map the new tab with outfit category UUID.
|
||||
mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
|
||||
|
||||
// Start observing the new outfit category.
|
||||
mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id));
|
||||
|
||||
// Fetch the new outfit contents.
|
||||
cat->fetch();
|
||||
|
||||
// Refresh the list of outfit items after fetch().
|
||||
// Further list updates will be triggered by the category observer.
|
||||
list->updateList(cat_id);
|
||||
}
|
||||
|
||||
// Handle removed tabs.
|
||||
for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); iter++)
|
||||
{
|
||||
outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));
|
||||
if (outfits_iter != mOutfitsMap.end())
|
||||
{
|
||||
// An outfit is removed from the list. Do the following:
|
||||
// 1. Remove outfit accordion tab from accordion.
|
||||
mAccordion->removeCollapsibleCtrl(outfits_iter->second);
|
||||
|
||||
// 2. Remove outfit category from observer to stop monitoring its changes.
|
||||
mCategoriesObserver->removeCategory(outfits_iter->first);
|
||||
|
||||
// 3. Remove category UUID to accordion tab mapping.
|
||||
mOutfitsMap.erase(outfits_iter);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
updateOutfitTab(*items_iter);
|
||||
}
|
||||
|
||||
mAccordion->arrange();
|
||||
}
|
||||
|
||||
void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
|
||||
{
|
||||
outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id);
|
||||
if (outfits_iter != mOutfitsMap.end())
|
||||
{
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(category_id);
|
||||
if (!cat)
|
||||
return;
|
||||
|
||||
std::string name = cat->getName();
|
||||
|
||||
// Update tab name with the new category name.
|
||||
LLAccordionCtrlTab* tab = outfits_iter->second;
|
||||
if (tab)
|
||||
{
|
||||
tab->setName(name);
|
||||
}
|
||||
|
||||
// Update tab title with the new category name using textbox
|
||||
// in accordion tab header.
|
||||
LLTextBox* tab_title = tab->findChild<LLTextBox>("dd_textbox");
|
||||
if (tab_title)
|
||||
{
|
||||
tab_title->setText(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitsList::setFilterSubString(const std::string& string)
|
||||
{
|
||||
mFilterSubString = string;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* @file lloutfitslist.h
|
||||
* @brief List of agent's outfits for My Appearance side panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLOUTFITSLIST_H
|
||||
#define LL_LLOUTFITSLIST_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
// newview
|
||||
#include "llinventoryobserver.h"
|
||||
|
||||
class LLAccordionCtrl;
|
||||
class LLAccordionCtrlTab;
|
||||
class LLWearableItemsList;
|
||||
|
||||
class LLOutfitsList : public LLPanel, public LLInventoryObserver
|
||||
{
|
||||
public:
|
||||
LLOutfitsList();
|
||||
virtual ~LLOutfitsList();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/*virtual*/ void changed(U32 mask);
|
||||
|
||||
void refreshList(const LLUUID& category_id);
|
||||
|
||||
// Update tab displaying outfit identified by category_id.
|
||||
void updateOutfitTab(const LLUUID& category_id);
|
||||
|
||||
void setFilterSubString(const std::string& string);
|
||||
|
||||
private:
|
||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
|
||||
LLAccordionCtrl* mAccordion;
|
||||
LLPanel* mListCommands;
|
||||
|
||||
std::string mFilterSubString;
|
||||
|
||||
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
|
||||
typedef outfits_map_t::value_type outfits_map_value_t;
|
||||
outfits_map_t mOutfitsMap;
|
||||
};
|
||||
|
||||
#endif //LL_LLOUTFITSLIST_H
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
#include "lllineeditor.h"
|
||||
#include "llmodaldialog.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llsidepanelappearance.h"
|
||||
#include "llsidetray.h"
|
||||
#include "lltabcontainer.h"
|
||||
|
|
@ -71,7 +72,8 @@ bool LLPanelOutfitsInventory::sShowDebugEditor = false;
|
|||
|
||||
|
||||
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
|
||||
mActivePanel(NULL),
|
||||
mMyOutfitsPanel(NULL),
|
||||
mCurrentOutfitPanel(NULL),
|
||||
mParent(NULL)
|
||||
{
|
||||
mSavedFolderState = new LLSaveFolderState();
|
||||
|
|
@ -145,9 +147,17 @@ void LLPanelOutfitsInventory::setParent(LLSidepanelAppearance* parent)
|
|||
void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
||||
{
|
||||
mFilterSubString = string;
|
||||
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (!isCOFPanelActive())
|
||||
{
|
||||
mMyOutfitsPanel->setFilterSubString(string);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string == "")
|
||||
{
|
||||
mActivePanel->setFilterSubString(LLStringUtil::null);
|
||||
getActivePanel()->setFilterSubString(LLStringUtil::null);
|
||||
|
||||
// re-open folders that were initially open
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
|
|
@ -159,7 +169,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
|
||||
if (mActivePanel->getFilterSubString().empty() && string.empty())
|
||||
if (getActivePanel()->getFilterSubString().empty() && string.empty())
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
|
|
@ -173,7 +183,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
}
|
||||
|
||||
// set new filter string
|
||||
mActivePanel->setFilterSubString(string);
|
||||
getActivePanel()->setFilterSubString(string);
|
||||
}
|
||||
|
||||
void LLPanelOutfitsInventory::onWearButtonClick()
|
||||
|
|
@ -267,6 +277,11 @@ void LLPanelOutfitsInventory::onSave()
|
|||
void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
|
||||
{
|
||||
updateVerbs();
|
||||
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (!isCOFPanelActive())
|
||||
return;
|
||||
|
||||
if (getRootFolder()->needsAutoRename() && items.size())
|
||||
{
|
||||
getRootFolder()->startRenamingSelectedItem();
|
||||
|
|
@ -284,6 +299,10 @@ void LLPanelOutfitsInventory::showEditOutfitPanel()
|
|||
|
||||
LLFolderViewEventListener *LLPanelOutfitsInventory::getCorrectListenerForAction()
|
||||
{
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (!isCOFPanelActive())
|
||||
return NULL;
|
||||
|
||||
LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem();
|
||||
if (!current_item)
|
||||
return NULL;
|
||||
|
|
@ -311,7 +330,7 @@ bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *
|
|||
|
||||
LLFolderView *LLPanelOutfitsInventory::getRootFolder()
|
||||
{
|
||||
return mActivePanel->getRootFolder();
|
||||
return getActivePanel()->getRootFolder();
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -393,7 +412,11 @@ void LLPanelOutfitsInventory::onTrashButtonClick()
|
|||
void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
|
||||
{
|
||||
std::string command_name = userdata.asString();
|
||||
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
|
||||
}
|
||||
updateListCommands();
|
||||
updateVerbs();
|
||||
}
|
||||
|
|
@ -447,21 +470,26 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
|
|||
if (command_name == "delete" || command_name == "remove")
|
||||
{
|
||||
BOOL can_delete = FALSE;
|
||||
LLFolderView* root = getActivePanel()->getRootFolder();
|
||||
if (root)
|
||||
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
std::set<LLUUID> selection_set;
|
||||
root->getSelectionList(selection_set);
|
||||
can_delete = (selection_set.size() > 0);
|
||||
for (std::set<LLUUID>::iterator iter = selection_set.begin();
|
||||
iter != selection_set.end();
|
||||
++iter)
|
||||
LLFolderView* root = getActivePanel()->getRootFolder();
|
||||
if (root)
|
||||
{
|
||||
const LLUUID &item_id = (*iter);
|
||||
LLFolderViewItem *item = root->getItemByID(item_id);
|
||||
can_delete &= item->getListener()->isItemRemovable();
|
||||
std::set<LLUUID> selection_set;
|
||||
root->getSelectionList(selection_set);
|
||||
can_delete = (selection_set.size() > 0);
|
||||
for (std::set<LLUUID>::iterator iter = selection_set.begin();
|
||||
iter != selection_set.end();
|
||||
++iter)
|
||||
{
|
||||
const LLUUID &item_id = (*iter);
|
||||
LLFolderViewItem *item = root->getItemByID(item_id);
|
||||
can_delete &= item->getListener()->isItemRemovable();
|
||||
}
|
||||
return can_delete;
|
||||
}
|
||||
return can_delete;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -517,12 +545,17 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
|
|||
bool LLPanelOutfitsInventory::hasItemsSelected()
|
||||
{
|
||||
bool has_items_selected = false;
|
||||
LLFolderView* root = getActivePanel()->getRootFolder();
|
||||
if (root)
|
||||
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
std::set<LLUUID> selection_set;
|
||||
root->getSelectionList(selection_set);
|
||||
has_items_selected = (selection_set.size() > 0);
|
||||
LLFolderView* root = getActivePanel()->getRootFolder();
|
||||
if (root)
|
||||
{
|
||||
std::set<LLUUID> selection_set;
|
||||
root->getSelectionList(selection_set);
|
||||
has_items_selected = (selection_set.size() > 0);
|
||||
}
|
||||
}
|
||||
return has_items_selected;
|
||||
}
|
||||
|
|
@ -549,74 +582,58 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
|
|||
|
||||
void LLPanelOutfitsInventory::initTabPanels()
|
||||
{
|
||||
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME);
|
||||
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mTabPanels.push_back(cof_panel);
|
||||
mCurrentOutfitPanel = getChild<LLInventoryPanel>(COF_TAB_NAME);
|
||||
mCurrentOutfitPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));
|
||||
|
||||
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
|
||||
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
|
||||
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mTabPanels.push_back(myoutfits_panel);
|
||||
|
||||
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
|
||||
iter != mTabPanels.end();
|
||||
++iter)
|
||||
{
|
||||
LLInventoryPanel *panel = (*iter);
|
||||
panel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, panel, _1, _2));
|
||||
}
|
||||
mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME);
|
||||
|
||||
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
|
||||
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
|
||||
mActivePanel = (LLInventoryPanel*)mAppearanceTabs->getCurrentPanel();
|
||||
}
|
||||
|
||||
void LLPanelOutfitsInventory::onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
|
||||
{
|
||||
if (user_action && items.size() > 0)
|
||||
{
|
||||
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
|
||||
iter != mTabPanels.end();
|
||||
++iter)
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
LLInventoryPanel *panel = (*iter);
|
||||
if (panel == tab_panel)
|
||||
{
|
||||
mActivePanel = panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
panel->getRootFolder()->clearSelection();
|
||||
}
|
||||
onSelectionChange(items, user_action);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentOutfitPanel->getRootFolder()->clearSelection();
|
||||
}
|
||||
}
|
||||
onSelectionChange(items, user_action);
|
||||
}
|
||||
|
||||
void LLPanelOutfitsInventory::onTabChange()
|
||||
{
|
||||
mActivePanel = (LLInventoryPanel*)childGetVisibleTab("appearance_tabs");
|
||||
if (!mActivePanel)
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (isCOFPanelActive())
|
||||
{
|
||||
return;
|
||||
mCurrentOutfitPanel->setFilterSubString(mFilterSubString);
|
||||
}
|
||||
mActivePanel->setFilterSubString(mFilterSubString);
|
||||
else
|
||||
{
|
||||
mMyOutfitsPanel->setFilterSubString(mFilterSubString);
|
||||
}
|
||||
|
||||
updateVerbs();
|
||||
}
|
||||
|
||||
BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const
|
||||
{
|
||||
for(tabpanels_vec_t::const_iterator it = mTabPanels.begin();
|
||||
it != mTabPanels.end();
|
||||
++it)
|
||||
// TODO: add handling "My Outfits" tab.
|
||||
if (mCurrentOutfitPanel == panel)
|
||||
{
|
||||
if (*it == panel)
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
|
||||
{
|
||||
return (getActivePanel()->getName() == COF_TAB_NAME);
|
||||
return (childGetVisibleTab("appearance_tabs")->getName() == COF_TAB_NAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class LLFolderView;
|
|||
class LLFolderViewItem;
|
||||
class LLFolderViewEventListener;
|
||||
class LLInventoryPanel;
|
||||
class LLOutfitsList;
|
||||
class LLSaveFolderState;
|
||||
class LLButton;
|
||||
class LLMenuGL;
|
||||
|
|
@ -88,20 +89,21 @@ private:
|
|||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// tab panels
|
||||
LLInventoryPanel* getActivePanel() { return mActivePanel; }
|
||||
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
|
||||
// TODO: change getActivePanel() to return the active tab instead of returning
|
||||
// a pointer to "Wearing" inventory panel.
|
||||
LLInventoryPanel* getActivePanel() { return mCurrentOutfitPanel; }
|
||||
|
||||
BOOL isTabPanel(LLInventoryPanel *panel) const;
|
||||
|
||||
BOOL isCOFPanelActive() const;
|
||||
|
||||
protected:
|
||||
void initTabPanels();
|
||||
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
void onTabChange();
|
||||
BOOL isCOFPanelActive() const;
|
||||
|
||||
private:
|
||||
LLInventoryPanel* mActivePanel;
|
||||
typedef std::vector<LLInventoryPanel *> tabpanels_vec_t;
|
||||
tabpanels_vec_t mTabPanels;
|
||||
LLOutfitsList* mMyOutfitsPanel;
|
||||
LLInventoryPanel* mCurrentOutfitPanel;
|
||||
|
||||
// tab panels //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -329,8 +329,8 @@ void LLSidepanelAppearance::updateVerbs()
|
|||
|
||||
if (mPanelOutfitsInventory && !is_look_info_visible)
|
||||
{
|
||||
const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
|
||||
mEditBtn->setEnabled(is_correct_type);
|
||||
// const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
|
||||
// mEditBtn->setEnabled(is_correct_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @file llwearableitemslist.cpp
|
||||
* @brief A flat list of wearable items.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llwearableitemslist.h"
|
||||
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
||||
class LLFindOutfitItems : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindOutfitItems() {}
|
||||
virtual ~LLFindOutfitItems() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
};
|
||||
|
||||
bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
if(item)
|
||||
{
|
||||
if((item->getType() == LLAssetType::AT_CLOTHING)
|
||||
|| (item->getType() == LLAssetType::AT_BODYPART)
|
||||
|| (item->getType() == LLAssetType::AT_OBJECT))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
|
||||
|
||||
LLWearableItemsList::LLWearableItemsList(const LLFlatListView::Params& p)
|
||||
: LLInventoryItemsList(p)
|
||||
{}
|
||||
|
||||
// virtual
|
||||
LLWearableItemsList::~LLWearableItemsList()
|
||||
{}
|
||||
|
||||
void LLWearableItemsList::updateList(const LLUUID& category_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
LLFindOutfitItems collector = LLFindOutfitItems();
|
||||
// collectDescendentsIf takes non-const reference:
|
||||
gInventory.collectDescendentsIf(
|
||||
category_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
collector);
|
||||
|
||||
refreshList(item_array);
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file llwearableitemslist.h
|
||||
* @brief A flat list of wearable items.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWEARABLEITEMSLIST_H
|
||||
#define LL_LLWEARABLEITEMSLIST_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
#include "llassettype.h"
|
||||
|
||||
#include "llinventorytype.h"
|
||||
|
||||
// newview
|
||||
#include "llinventoryitemslist.h"
|
||||
|
||||
class LLWearableItemsList : public LLInventoryItemsList
|
||||
{
|
||||
public:
|
||||
virtual ~LLWearableItemsList();
|
||||
|
||||
void updateList(const LLUUID& category_id);
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLWearableItemsList(const LLFlatListView::Params& p);
|
||||
};
|
||||
|
||||
#endif //LL_LLWEARABLEITEMSLIST_H
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="inventory_item"
|
||||
top="0"
|
||||
width="380">
|
||||
<icon
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
image_name="ListItem_Over"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="hovered_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<icon
|
||||
height="20"
|
||||
follows="top|right|left"
|
||||
image_name="ListItem_Select"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="selected_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<icon
|
||||
height="16"
|
||||
follows="top|left"
|
||||
image_name="Inv_Object"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="item_icon"
|
||||
top="0"
|
||||
width="16" />
|
||||
<text
|
||||
follows="left|right"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
allow_html="false"
|
||||
use_ellipses="true"
|
||||
name="item_name"
|
||||
text_color="white"
|
||||
top="4"
|
||||
value="..."
|
||||
width="359" />
|
||||
</panel>
|
||||
|
|
@ -23,20 +23,16 @@
|
|||
tab_position="top"
|
||||
halign="center"
|
||||
width="312">
|
||||
<inventory_panel
|
||||
background_visible="true"
|
||||
background_opaque="true"
|
||||
label="MY OUTFITS"
|
||||
help_topic="my_outfits_tab"
|
||||
allow_multi_select="true"
|
||||
follows="all"
|
||||
border="false"
|
||||
left="0"
|
||||
top="0"
|
||||
width="315"
|
||||
mouse_opaque="true"
|
||||
<panel
|
||||
class="outfits_list"
|
||||
filename="panel_outfits_list.xml"
|
||||
height="490"
|
||||
name="outfitslist_tab"
|
||||
start_folder="My Outfits" />
|
||||
background_visible="true"
|
||||
follows="all"
|
||||
label="MY OUTFITS"
|
||||
layout="topleft"
|
||||
width="315" />
|
||||
<inventory_panel
|
||||
follows="all"
|
||||
background_visible="true"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
background_visible="true"
|
||||
bg_alpha_color="DkGray"
|
||||
border="false"
|
||||
follows="all"
|
||||
height="400"
|
||||
name="Outfits"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0"
|
||||
width="313">
|
||||
<accordion
|
||||
background_visible="true"
|
||||
bg_alpha_color="DkGray2"
|
||||
bg_opaque_color="DkGray2"
|
||||
follows="all"
|
||||
height="400"
|
||||
layout="topleft"
|
||||
left="3"
|
||||
name="outfits_accordion"
|
||||
top="0"
|
||||
width="307">
|
||||
</accordion>
|
||||
</panel>
|
||||
Loading…
Reference in New Issue