diff options
author | Igor Borovkov <iborovkov@productengine.com> | 2010-04-27 15:23:07 +0300 |
---|---|---|
committer | Igor Borovkov <iborovkov@productengine.com> | 2010-04-27 15:23:07 +0300 |
commit | 2696e375097c2e45102bede0e7d33175feea080b (patch) | |
tree | f2ed4f9aa520c2ca98b18fed9474d5bdc7655ba2 /indra | |
parent | c233b2cf99aaacfc4dac1638394a67905eb51c9a (diff) |
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
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llcofwearables.cpp | 153 | ||||
-rw-r--r-- | indra/newview/llcofwearables.h | 66 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 123 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitedit.h | 6 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_cof_wearables.xml | 65 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_outfit_edit.xml | 29 |
7 files changed, 320 insertions, 124 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 99ba356d9e..70fc692a89 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -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 diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp new file mode 100644 index 0000000000..f0442ee3f6 --- /dev/null +++ b/indra/newview/llcofwearables.cpp @@ -0,0 +1,153 @@ +/** + * @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 diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h new file mode 100644 index 0000000000..58d67ed32f --- /dev/null +++ b/indra/newview/llcofwearables.h @@ -0,0 +1,66 @@ +/** + * @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 diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index ae181e2819..dbccd243da 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -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 @@ private: 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()) diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index b6f121d484..21fa849289 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -45,6 +45,7 @@ #include "llinventorymodel.h" class LLButton; +class LLCOFWearables; class LLTextBox; class LLInventoryCategory; class LLInventoryLookObserver; @@ -102,7 +103,6 @@ public: void onOutfitItemSelectionChange(void); void onRemoveFromOutfitClicked(void); void onEditWearableClicked(void); - void onUpClicked(void); void displayCurrentOutfit(); @@ -118,14 +118,12 @@ private: 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 @@ private: LLLookFetchObserver* mFetchLook; LLInventoryLookObserver* mLookObserver; std::vector<LLLookItemType> mLookItemTypes; + + LLCOFWearables* mCOFWearables; }; #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml new file mode 100644 index 0000000000..01c7ae61d2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -0,0 +1,65 @@ +<?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> 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 314d2389ae..73181392c9 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -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" |