Skip to content
Snippets Groups Projects
Commit 2696e375 authored by Igor Borovkov's avatar Igor Borovkov
Browse files

partial implementation of EXT-6723 Create specialized view of inventory for...

partial implementation of EXT-6723 Create specialized view of inventory for "clothing" accordion tab of outfit editor

Initial implementation (no sorting, no grayed items from Base outfit)

Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/322

--HG--
branch : product-engine
parent c233b2cf
No related branches found
No related tags found
No related merge requests found
......@@ -104,6 +104,7 @@ set(viewer_SOURCE_FILES
llclassifiedinfo.cpp
llclassifiedstatsresponder.cpp
llcloud.cpp
llcofwearables.cpp
llcolorswatch.cpp
llcommanddispatcherlistener.cpp
llcommandhandler.cpp
......@@ -614,6 +615,7 @@ set(viewer_HEADER_FILES
llclassifiedinfo.h
llclassifiedstatsresponder.h
llcloud.h
llcofwearables.h
llcolorswatch.h
llcommanddispatcherlistener.h
llcommandhandler.h
......
/**
* @file llcofwearables.cpp
* @brief LLCOFWearables displayes wearables from the current outfit split into three lists (attachments, clothing and body parts)
*
* $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 "llcofwearables.h"
#include "llappearancemgr.h"
#include "llinventory.h"
#include "llinventoryitemslist.h"
#include "llinventoryfunctions.h"
static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables");
const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachments(NULL),
mClothing(NULL),
mBodyParts(NULL),
mLastSelectedList(NULL)
{
};
// virtual
BOOL LLCOFWearables::postBuild()
{
mAttachments = getChild<LLFlatListView>("list_attachments");
mClothing = getChild<LLFlatListView>("list_clothing");
mBodyParts = getChild<LLFlatListView>("list_body_parts");
//selection across different list/tabs is not supported
mAttachments->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mAttachments));
mClothing->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mClothing));
mBodyParts->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mBodyParts));
mAttachments->setCommitOnSelectionChange(true);
mClothing->setCommitOnSelectionChange(true);
mBodyParts->setCommitOnSelectionChange(true);
return LLPanel::postBuild();
}
void LLCOFWearables::onSelectionChange(LLFlatListView* selected_list)
{
if (!selected_list) return;
if (selected_list != mLastSelectedList)
{
if (selected_list != mAttachments) mAttachments->resetSelection(true);
if (selected_list != mClothing) mClothing->resetSelection(true);
if (selected_list != mBodyParts) mBodyParts->resetSelection(true);
mLastSelectedList = selected_list;
}
onCommit();
}
void LLCOFWearables::refresh()
{
clear();
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
if (items.empty()) return;
for (U32 i = 0; i < items.size(); ++i)
{
LLViewerInventoryItem* item = items.get(i);
if (!item) continue;
LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
if (!item_panel) continue;
switch (item->getType())
{
case LLAssetType::AT_OBJECT:
mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
break;
case LLAssetType::AT_BODYPART:
mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
break;
case LLAssetType::AT_CLOTHING:
mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
break;
default: break;
}
}
mAttachments->sort(); //*TODO by Name
mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false)
mClothing->sort(); //*TODO by actual inventory item description
mClothing->notify(REARRANGE);
mBodyParts->sort(); //*TODO by name
mBodyParts->notify(REARRANGE);
}
LLUUID LLCOFWearables::getSelectedUUID()
{
if (!mLastSelectedList) return LLUUID::null;
return mLastSelectedList->getSelectedUUID();
}
void LLCOFWearables::clear()
{
mAttachments->clear();
mClothing->clear();
mBodyParts->clear();
}
//EOF
/**
* @file llcofwearables.h
* @brief LLCOFWearables displayes wearables from the current outfit split into three lists (attachments, clothing and body parts)
*
* $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_LLCOFWEARABLES_H
#define LL_LLCOFWEARABLES_H
#include "llpanel.h"
class LLFlatListView;
class LLCOFWearables : public LLPanel
{
public:
LLCOFWearables();
virtual ~LLCOFWearables() {};
/*virtual*/ BOOL postBuild();
LLUUID getSelectedUUID();
void refresh();
void clear();
protected:
void onSelectionChange(LLFlatListView* selected_list);
LLFlatListView* mAttachments;
LLFlatListView* mClothing;
LLFlatListView* mBodyParts;
LLFlatListView* mLastSelectedList;
};
#endif
......@@ -38,6 +38,7 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llcofwearables.h"
#include "llfilteredwearablelist.h"
#include "llinventory.h"
#include "llinventoryitemslist.h"
......@@ -121,9 +122,15 @@ class LLLookFetchObserver : public LLInventoryFetchDescendentsObserver
LLPanelOutfitEdit::LLPanelOutfitEdit()
: LLPanel(), mCurrentOutfitID(), mFetchLook(NULL), mSearchFilter(NULL),
mLookContents(NULL), mInventoryItemsPanel(NULL), mAddToOutfitBtn(NULL),
mRemoveFromOutfitBtn(NULL), mLookObserver(NULL)
: LLPanel(),
mCurrentOutfitID(),
mFetchLook(NULL),
mSearchFilter(NULL),
mCOFWearables(NULL),
mInventoryItemsPanel(NULL),
mAddToOutfitBtn(NULL),
mRemoveFromOutfitBtn(NULL),
mLookObserver(NULL)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
......@@ -171,9 +178,8 @@ BOOL LLPanelOutfitEdit::postBuild()
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);
mLookContents->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);
......@@ -206,15 +212,6 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));
childSetEnabled("add_to_outfit_btn", false);
mUpBtn = getChild<LLButton>("up_btn");
mUpBtn->setEnabled(TRUE);
mUpBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onUpClicked, this));
//*TODO rename mLookContents to mOutfitContents
mLookContents = getChild<LLScrollListCtrl>("look_items_list");
mLookContents->sortByColumn("look_item_sort", TRUE);
mLookContents->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
mRemoveFromOutfitBtn = getChild<LLButton>("remove_from_outfit_btn");
mRemoveFromOutfitBtn->setEnabled(FALSE);
mRemoveFromOutfitBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onRemoveFromOutfitClicked, this));
......@@ -245,7 +242,10 @@ BOOL LLPanelOutfitEdit::postBuild()
void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
{
LLViewerInventoryItem* wearable_to_move = gInventory.getItem(mLookContents->getSelectionInterface()->getCurrentID());
LLUUID item_id = mCOFWearables->getSelectedUUID();
if (item_id.isNull()) return;
LLViewerInventoryItem* wearable_to_move = gInventory.getItem(item_id);
LLAppearanceMgr::getInstance()->moveWearable(wearable_to_move, closer_to_body);
//*TODO why not to listen to inventory?
......@@ -374,7 +374,7 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)
void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
{
LLUUID id_to_remove = mLookContents->getSelectionInterface()->getCurrentID();
LLUUID id_to_remove = mCOFWearables->getSelectedUUID();
LLAppearanceMgr::getInstance()->removeItemFromAvatar(id_to_remove);
......@@ -384,41 +384,9 @@ void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
}
void LLPanelOutfitEdit::onUpClicked(void)
{
LLUUID inv_id = mLookContents->getSelectionInterface()->getCurrentID();
if (inv_id.isNull())
{
//nothing selected, do nothing
return;
}
LLViewerInventoryItem *link_item = gInventory.getItem(inv_id);
if (!link_item)
{
llwarns << "could not find inventory item based on currently worn link." << llendl;
return;
}
LLUUID asset_id = link_item->getAssetUUID();
if (asset_id.isNull())
{
llwarns << "inventory link has null Asset ID. could not get object reference" << llendl;
}
static const std::string empty = "";
LLWearableList::instance().getAsset(asset_id,
empty, // don't care about wearable name
link_item->getActualType(),
LLSidepanelAppearance::editWearable,
(void*)getParentUICtrl());
}
void LLPanelOutfitEdit::onEditWearableClicked(void)
{
LLUUID id_to_edit = mLookContents->getSelectionInterface()->getCurrentID();
LLUUID id_to_edit = mCOFWearables->getSelectedUUID();
LLViewerInventoryItem * item_to_edit = gInventory.getItem(id_to_edit);
if (item_to_edit)
......@@ -491,29 +459,11 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView
void LLPanelOutfitEdit::onOutfitItemSelectionChange(void)
{
LLScrollListItem* item = mLookContents->getLastSelectedItem();
if (!item)
return;
LLUUID item_id = mCOFWearables->getSelectedUUID();
LLRect item_rect;
mLookContents->localRectToOtherView(item->getRect(), &item_rect, this);
//*TODO show Edit Wearable Button
// TODO button(and item list) should be removed (when new widget is ready)
LLRect btn_rect = mEditWearableBtn->getRect();
btn_rect.set(item_rect.mRight - btn_rect.getWidth(), item_rect.mTop, item_rect.mRight, item_rect.mBottom);
mEditWearableBtn->setShape(btn_rect);
sendChildToFront(mEditWearableBtn);
mEditWearableBtn->setEnabled(TRUE);
if (!mEditWearableBtn->getVisible())
{
mEditWearableBtn->setVisible(TRUE);
}
const LLUUID& id_item_to_remove = item->getUUID();
LLViewerInventoryItem* item_to_remove = gInventory.getItem(id_item_to_remove);
LLViewerInventoryItem* item_to_remove = gInventory.getItem(item_id);
if (!item_to_remove) return;
switch (item_to_remove->getType())
......@@ -534,34 +484,7 @@ void LLPanelOutfitEdit::changed(U32 mask)
void LLPanelOutfitEdit::lookFetched(void)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
// collectDescendentsIf takes non-const reference:
LLFindCOFValidItems is_cof_valid;
gInventory.collectDescendentsIf(mCurrentOutfitID,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_cof_valid);
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
iter != item_array.end();
iter++)
{
const LLViewerInventoryItem *item = (*iter);
LLSD row;
row["id"] = item->getUUID();
LLSD& columns = row["columns"];
columns[0]["column"] = "look_item";
columns[0]["type"] = "text";
columns[0]["value"] = item->getName();
columns[1]["column"] = "look_item_sort";
columns[1]["type"] = "text"; // TODO: multi-wearable sort "type" should go here.
columns[1]["value"] = item->LLInventoryItem::getDescription();
mLookContents->addElement(row);
}
mCOFWearables->refresh();
updateVerbs();
}
......@@ -570,8 +493,6 @@ void LLPanelOutfitEdit::updateLookInfo()
{
if (getVisible())
{
mLookContents->clearRows();
mFetchLook->setFetchID(mCurrentOutfitID);
mFetchLook->startFetch();
if (mFetchLook->isFinished())
......
......@@ -45,6 +45,7 @@
#include "llinventorymodel.h"
class LLButton;
class LLCOFWearables;
class LLTextBox;
class LLInventoryCategory;
class LLInventoryLookObserver;
......@@ -102,7 +103,6 @@ class LLPanelOutfitEdit : public LLPanel
void onOutfitItemSelectionChange(void);
void onRemoveFromOutfitClicked(void);
void onEditWearableClicked(void);
void onUpClicked(void);
void displayCurrentOutfit();
......@@ -118,14 +118,12 @@ class LLPanelOutfitEdit : public LLPanel
LLUUID mCurrentOutfitID;
LLTextBox* mCurrentOutfitName;
LLScrollListCtrl* mLookContents;
LLInventoryPanel* mInventoryItemsPanel;
LLFilterEditor* mSearchFilter;
LLSaveFolderState* mSavedFolderState;
std::string mSearchString;
LLButton* mAddToOutfitBtn;
LLButton* mRemoveFromOutfitBtn;
LLButton* mUpBtn;
LLButton* mEditWearableBtn;
LLToggleableMenu* mSaveMenu;
......@@ -134,6 +132,8 @@ class LLPanelOutfitEdit : public LLPanel
LLLookFetchObserver* mFetchLook;
LLInventoryLookObserver* mLookObserver;
std::vector<LLLookItemType> mLookItemTypes;
LLCOFWearables* mCOFWearables;
};
#endif // LL_LLPANELOUTFITEDIT_H
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
background_visible="true"
bg_alpha_color="DkGray"
border="false"
bottom="0"
follows="all"
height="200"
left="0"
name="cof_wearables"
width="313">
<accordion
follows="all"
height="373"
layout="topleft"
left="3"
top="0"
name="cof_wearables_accordion"
background_visible="true"
bg_alpha_color="DkGray2"
width="307">
<accordion_tab
layout="topleft"
name="tab_attachments"
title="Attachments">
<flat_list_view
allow_select="true"
follows="all"
height="150"
layout="topleft"
left="0"
name="list_attachments"
top="0"
width="307" />
</accordion_tab>
<accordion_tab
layout="topleft"
name="tab_clothing"
title="Clothing">
<flat_list_view
allow_select="true"
follows="all"
height="150"
layout="topleft"
left="0"
name="list_clothing"
top="0"
width="307" />
</accordion_tab>
<accordion_tab
layout="topleft"
name="tab_body_parts"
title="Body Parts">
<flat_list_view
allow_select="true"
follows="all"
height="150"
layout="topleft"
left="0"
name="list_body_parts"
top="0"
width="307" />
</accordion_tab>
</accordion>
</panel>
......@@ -149,29 +149,18 @@
auto_resize="true"
user_resize="true">
<scroll_list
width="300"
column_padding="0"
draw_heading="false"
draw_stripes="false"
<!-- List containing items from the COF and Base outfit -->
<panel
background_visible="false"
class="cof_wearables"
filename="panel_cof_wearables.xml"
follows="left|top|right|bottom"
height="193"
layout="topleft"
name="look_items_list"
search_column="1"
sort_column="2"
left="0"
height="193"
top="0">
<scroll_list.columns
label="Look Item"
name="look_item"
width="285" />
<scroll_list.columns
label="Outfit Item Sort"
width="0"
sort_column="look_item_sort"
name="look_item_sort" />
</scroll_list>
name="cof_wearables_list"
top="0"
width="300" />
<panel
background_visible="true"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment