summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfilteredwearablelist.cpp113
-rw-r--r--indra/newview/llfilteredwearablelist.h70
-rw-r--r--indra/newview/llinventoryitemslist.cpp96
-rw-r--r--indra/newview/llinventoryitemslist.h34
-rw-r--r--indra/newview/llpaneloutfitedit.cpp14
-rw-r--r--indra/newview/llpaneloutfitedit.h6
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml24
8 files changed, 344 insertions, 15 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c372edbea1..bfb5798909 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -142,6 +142,7 @@ set(viewer_SOURCE_FILES
llfavoritesbar.cpp
llfeaturemanager.cpp
llfilepicker.cpp
+ llfilteredwearablelist.cpp
llfirstuse.cpp
llflexibleobject.cpp
llfloaterabout.cpp
@@ -651,6 +652,7 @@ set(viewer_HEADER_FILES
llfavoritesbar.h
llfeaturemanager.h
llfilepicker.h
+ llfilteredwearablelist.h
llfirstuse.h
llflexibleobject.h
llfloaterabout.h
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
new file mode 100644
index 0000000000..01d3c3f22e
--- /dev/null
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -0,0 +1,113 @@
+/**
+ * @file llfilteredwearablelist.cpp
+ * @brief Functionality for showing filtered wearable flat list
+ *
+ * $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 "llfilteredwearablelist.h"
+
+// newview
+#include "llinventoryfunctions.h"
+#include "llinventoryitemslist.h"
+#include "llinventorymodel.h"
+
+class LLFindItemsByMask : public LLInventoryCollectFunctor
+{
+public:
+ LLFindItemsByMask(U64 mask)
+ : mFilterMask(mask)
+ {}
+
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ if(item)
+ {
+ if( mFilterMask & (1LL << item->getInventoryType()) )
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+private:
+ U64 mFilterMask;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask)
+: mWearableList(list)
+, mFilterMask(filter_mask)
+{
+ llassert(mWearableList);
+ gInventory.addObserver(this);
+ gInventory.fetchDescendentsOf(gInventory.getRootFolderID());
+}
+
+LLFilteredWearableListManager::~LLFilteredWearableListManager()
+{
+ gInventory.removeObserver(this);
+}
+
+void LLFilteredWearableListManager::changed(U32 mask)
+{
+ if(!gInventory.isInventoryUsable())
+ {
+ return;
+ }
+
+ populateList();
+}
+
+void LLFilteredWearableListManager::setFilterMask(U64 mask)
+{
+ mFilterMask = mask;
+ populateList();
+}
+
+void LLFilteredWearableListManager::populateList()
+{
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ LLFindItemsByMask collector(mFilterMask);
+
+ gInventory.collectDescendentsIf(
+ gInventory.getRootFolderID(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH,
+ collector);
+
+ // Probably will also need to get items from Library (waiting for reply in EXT-6724).
+
+ mWearableList->refreshList(item_array);
+}
+
+// EOF
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
new file mode 100644
index 0000000000..3f42833bb4
--- /dev/null
+++ b/indra/newview/llfilteredwearablelist.h
@@ -0,0 +1,70 @@
+/**
+ * @file llfilteredwearablelist.h
+ * @brief Functionality for showing filtered wearable flat list
+ *
+ * $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_LLFILTEREDWEARABLELIST_H
+#define LL_LLFILTEREDWEARABLELIST_H
+
+#include "llinventoryobserver.h"
+
+class LLInventoryItemsList;
+
+// Class that fills LLInventoryItemsList with filtered data.
+class LLFilteredWearableListManager : public LLInventoryObserver
+{
+ LOG_CLASS(LLFilteredWearableListManager);
+public:
+
+ LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask);
+ ~LLFilteredWearableListManager();
+
+ /** LLInventoryObserver implementation
+ *
+ */
+ /*virtual*/ void changed(U32 mask);
+
+ /**
+ * Sets new filter and applies it immediately
+ */
+ void setFilterMask(U64 mask);
+
+ /**
+ * Populates wearable list with filtered data.
+ */
+ void populateList();
+
+private:
+ LLInventoryItemsList* mWearableList;
+ U64 mFilterMask;
+};
+
+#endif //LL_LLFILTEREDWEARABLELIST_H
+
+// EOF
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 9489e0f2e4..9f54b86607 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -33,6 +33,9 @@
#include "llinventoryitemslist.h"
+// llcommon
+#include "llcommonutils.h"
+
#include "lliconctrl.h"
#include "llinventoryfunctions.h"
@@ -112,6 +115,7 @@ void LLPanelInventoryItem::onMouseLeave(S32 x, S32 y, MASK mask)
LLInventoryItemsList::LLInventoryItemsList(const LLFlatListView::Params& p)
: LLFlatListView(p)
+, mNeedsRefresh(false)
{}
// virtual
@@ -120,22 +124,88 @@ LLInventoryItemsList::~LLInventoryItemsList()
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
{
- clear();
+ getIDs().clear();
+ LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
+ for( ; item_array.end() != it; ++it)
+ {
+ getIDs().push_back((*it)->getUUID());
+ }
+ mNeedsRefresh = true;
+}
- for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
- iter != item_array.end();
- iter++)
+void LLInventoryItemsList::draw()
+{
+ LLFlatListView::draw();
+ if(mNeedsRefresh)
{
- LLViewerInventoryItem *item = (*iter);
-
- LLPanelInventoryItem *list_item = new LLPanelInventoryItem(item->getType(),
- item->getInventoryType(),
- item->getFlags(),
- item->getName(),
- LLStringUtil::null);
- if (!addItem(list_item, item->getUUID()))
+ refresh();
+ }
+}
+
+void LLInventoryItemsList::refresh()
+{
+ static const unsigned ADD_LIMIT = 50;
+
+ uuid_vec_t added_items;
+ uuid_vec_t removed_items;
+
+ computeDifference(getIDs(), added_items, removed_items);
+
+ bool add_limit_exceeded = false;
+ unsigned nadded = 0;
+
+ uuid_vec_t::const_iterator it = added_items.begin();
+ for( ; added_items.end() != it; ++it)
+ {
+ if(nadded >= ADD_LIMIT)
{
- llerrs << "Couldn't add flat item." << llendl;
+ add_limit_exceeded = true;
+ break;
}
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ addNewItem(item);
+ ++nadded;
+ }
+
+ it = removed_items.begin();
+ for( ; removed_items.end() != it; ++it)
+ {
+ removeItemByUUID(*it);
}
+
+ bool needs_refresh = add_limit_exceeded;
+ setNeedsRefresh(needs_refresh);
+}
+
+void LLInventoryItemsList::computeDifference(
+ const uuid_vec_t& vnew,
+ uuid_vec_t& vadded,
+ uuid_vec_t& vremoved)
+{
+ uuid_vec_t vcur;
+ {
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
+
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
+
+ LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
}
+
+void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)
+{
+ llassert(item);
+
+ LLPanelInventoryItem *list_item = new LLPanelInventoryItem(item->getType(),
+ item->getInventoryType(), item->getFlags(), item->getName(), LLStringUtil::null);
+
+ if (!addItem(list_item, item->getUUID()))
+ {
+ llwarns << "Couldn't add flat list item." << llendl;
+ llassert(!"Couldn't add flat list item.");
+ }
+}
+
+// EOF
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index bba739dbbf..0ca4146867 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -80,9 +80,43 @@ public:
void refreshList(const LLInventoryModel::item_array_t item_array);
+ /**
+ * Let list know items need to be refreshed in next draw()
+ */
+ void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
+
+ bool getNeedsRefresh(){ return mNeedsRefresh; }
+
+ /*virtual*/ void draw();
+
protected:
friend class LLUICtrlFactory;
LLInventoryItemsList(const LLFlatListView::Params& p);
+
+ uuid_vec_t& getIDs() { return mIDs; }
+
+ /**
+ * Refreshes list items, adds new items and removes deleted items.
+ * Called from draw() until all new items are added, ,
+ * maximum 50 items can be added during single call.
+ */
+ void refresh();
+
+ /**
+ * Compute difference between new items and current items, fills 'vadded' with added items,
+ * 'vremoved' with removed items. See LLCommonUtils::computeDifference
+ */
+ void computeDifference(const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+
+ /**
+ * Add an item to the list
+ */
+ void addNewItem(LLViewerInventoryItem* item);
+
+private:
+ uuid_vec_t mIDs; // IDs of items that were added in refreshList().
+ // Will be used in refresh() to determine added and removed ids
+ bool mNeedsRefresh;
};
#endif //LL_LLINVENTORYITEMSLIST_H
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index ce17e1d624..e139cb31d6 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -38,7 +38,9 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llfilteredwearablelist.h"
#include "llinventory.h"
+#include "llinventoryitemslist.h"
#include "llviewercontrol.h"
#include "llui.h"
#include "llfloater.h"
@@ -164,6 +166,7 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetCommitCallback("add_btn", boost::bind(&LLPanelOutfitEdit::showAddWearablesPanel, this), NULL);
childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
+ childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL);
mLookContents = getChild<LLScrollListCtrl>("look_items_list");
mLookContents->sortByColumn("look_item_sort", TRUE);
@@ -229,6 +232,9 @@ BOOL LLPanelOutfitEdit::postBuild()
save_registar.add("Outfit.SaveAsNew.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_save_outfit.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mWearableListManager = new LLFilteredWearableListManager(
+ getChild<LLInventoryItemsList>("filtered_wearables_list"), ALL_ITEMS_MASK);
+
return TRUE;
}
@@ -242,6 +248,11 @@ void LLPanelOutfitEdit::showWearablesFilter()
childSetVisible("filter_combobox_panel", childGetValue("filter_button"));
}
+void LLPanelOutfitEdit::showFilteredWearablesPanel()
+{
+ childSetVisible("filtered_wearables_panel", !childIsVisible("filtered_wearables_panel"));
+}
+
void LLPanelOutfitEdit::saveOutfit(bool as_new)
{
if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
@@ -275,6 +286,7 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)
{
U32 curr_filter_type = type_filter->getCurrentIndex();
mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask);
+ mWearableListManager->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
}
mSavedFolderState->setApply(TRUE);
@@ -577,4 +589,4 @@ void LLPanelOutfitEdit::displayCurrentOutfit()
updateLookInfo();
}
-
+// EOF
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 69e8016534..308ee23115 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -55,6 +55,7 @@ class LLScrollListCtrl;
class LLToggleableMenu;
class LLLookFetchObserver;
class LLFilterEditor;
+class LLFilteredWearableListManager;
class LLPanelOutfitEdit : public LLPanel
{
@@ -88,6 +89,7 @@ public:
void showAddWearablesPanel();
void showWearablesFilter();
+ void showFilteredWearablesPanel();
void saveOutfit(bool as_new = false);
void showSaveMenu();
@@ -122,7 +124,9 @@ private:
LLButton* mUpBtn;
LLButton* mEditWearableBtn;
LLToggleableMenu* mSaveMenu;
-
+
+ LLFilteredWearableListManager* mWearableListManager;
+
LLLookFetchObserver* mFetchLook;
LLInventoryLookObserver* mLookObserver;
std::vector<LLLookItemType> mLookItemTypes;
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index c77e4e8d5e..b1f0ff15cb 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -342,6 +342,30 @@
width="300"/>
<panel
+ name="filtered_wearables_panel"
+ background_opaque="true"
+ background_visible="true"
+ layout="topleft"
+ follows="left|top|right|bottom"
+ border="false"
+ height="155"
+ left="0"
+ mouse_opaque="false"
+ width="300"
+ top_delta="0"
+ visible="false">
+ <wearable_items_list
+ name="filtered_wearables_list"
+ allow_select="true"
+ layout="topleft"
+ follows="all"
+ width="300"
+ height="155"
+ left="0"
+ top="0" />
+ </panel>
+
+ <panel
background_visible="true"
bevel_style="none"
follows="left|right|bottom"