diff options
| -rw-r--r-- | indra/newview/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llinventoryfilter.cpp | 17 | ||||
| -rw-r--r-- | indra/newview/llinventorypanel.cpp | 35 | ||||
| -rw-r--r-- | indra/newview/llinventorypanel.h | 4 | ||||
| -rw-r--r-- | indra/newview/llpanelmaininventory.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitsinventory.cpp | 245 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitsinventory.h | 76 | ||||
| -rw-r--r-- | indra/newview/llsidepanelappearance.cpp | 373 | ||||
| -rw-r--r-- | indra/newview/llsidepanelappearance.h | 102 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_inventory.xml | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_outfits_inventory.xml | 81 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_side_tray.xml | 6 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/sidepanel_appearance.xml | 104 | 
14 files changed, 1026 insertions, 37 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4adef84cd3..e7458529be 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -297,8 +297,6 @@ set(viewer_SOURCE_FILES      llnotify.cpp      lloutputmonitorctrl.cpp      lloverlaybar.cpp -    llpanelappearance.cpp -    llpanelappearancetab.cpp      llpanelavatar.cpp      llpanelavatarrow.cpp      llpanelavatartag.cpp @@ -322,7 +320,6 @@ set(viewer_SOURCE_FILES      llpanellandmedia.cpp      llpanellogin.cpp      llpanellookinfo.cpp -    llpanellooks.cpp      llpanelmaininventory.cpp      llpanelmediasettingsgeneral.cpp      llpanelmediasettingspermissions.cpp @@ -330,6 +327,7 @@ set(viewer_SOURCE_FILES      llpanelmeprofile.cpp      llpanelobject.cpp      llpanelobjectinventory.cpp +    llpaneloutfitsinventory.cpp      llpanelpeople.cpp      llpanelpeoplemenus.cpp      llpanelpermissions.cpp @@ -370,6 +368,7 @@ set(viewer_SOURCE_FILES      llsearchcombobox.cpp      llsearchhistory.cpp      llselectmgr.cpp +    llsidepanelappearance.cpp      llsidepanelinventory.cpp      llsidepanelinventorysubpanel.cpp      llsidepaneliteminfo.cpp @@ -792,8 +791,6 @@ set(viewer_HEADER_FILES      llnotify.h      lloutputmonitorctrl.h      lloverlaybar.h -    llpanelappearance.h -    llpanelappearancetab.h      llpanelavatar.h      llpanelavatarrow.h      llpanelavatartag.h @@ -817,7 +814,6 @@ set(viewer_HEADER_FILES      llpanellandmedia.h      llpanellogin.h      llpanellookinfo.h -    llpanellooks.h      llpanelmaininventory.h      llpanelmediasettingsgeneral.h      llpanelmediasettingspermissions.h @@ -825,6 +821,7 @@ set(viewer_HEADER_FILES      llpanelmeprofile.h      llpanelobject.h      llpanelobjectinventory.h +    llpaneloutfitsinventory.h      llpanelpeople.h      llpanelpeoplemenus.h      llpanelpermissions.h @@ -867,6 +864,7 @@ set(viewer_HEADER_FILES      llsearchcombobox.h      llsearchhistory.h      llselectmgr.h +    llsidepanelappearance.h      llsidepanelinventory.h      llsidepanelinventorysubpanel.h      llsidepaneliteminfo.h diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 80ac9e4085..554f270c02 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -40,7 +40,7 @@  #include "llinventorybridge.h"  #include "llinventoryobserver.h"  #include "llnotifications.h" -#include "llpanelappearance.h" +#include "llsidepanelappearance.h"  #include "llsidetray.h"  #include "llvoavatar.h"  #include "llvoavatarself.h" @@ -530,10 +530,10 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)  							LLAssetType::AT_LINK_FOLDER, link_waiter);  		// Update the current outfit name of the appearance sidepanel. -		LLPanelAppearance* panel_appearance = dynamic_cast<LLPanelAppearance *>(LLSideTray::getInstance()->getPanel("panel_appearance")); +		LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));  		if (panel_appearance)  		{ -			panel_appearance->refreshCurrentLookName(catp->getName()); +			panel_appearance->refreshCurrentOutfitName(catp->getName());  		}  	} diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 3e4b3327db..085c96c93d 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -100,17 +100,18 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)  	bool passed_type = false;  	if (mFilterOps.mFilterForCategories)  	{ -		if (listener->getInventoryType() == LLInventoryType::IT_CATEGORY) +		// Pass if this item is a category of the filter type, or +		// if its parent is a category of the filter type. +		LLUUID uuid = listener->getUUID(); +		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)  		{ -			LLViewerInventoryCategory *cat = gInventory.getCategory(listener->getUUID()); -			if (cat) -			{ -				passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0)); -			} +			const LLInventoryObject *obj = gInventory.getObject(uuid); +			uuid = obj->getParentUUID();  		} -		else +		LLViewerInventoryCategory *cat = gInventory.getCategory(uuid); +		if (cat)  		{ -			passed_type = TRUE; +			passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));  		}  	}  	else diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 7b7090d10d..450ce92412 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -145,23 +145,10 @@ BOOL LLInventoryPanel::postBuild()  	mInventoryObserver = new LLInventoryPanelObserver(this);
  	mInventory->addObserver(mInventoryObserver);
 -	// determine the root folder, if any, so inventory contents show just the children
 -	// of that folder (i.e. not including the folder itself).
 -	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
 -
 -	if ("LIBRARY" == mStartFolderString)
 -	{
 -		mStartFolderID = gInventory.getLibraryRootFolderID();
 -	}
 -	else
 -	{
 -		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
 -	}
 -
  	// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback
  	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection)
  	{
 -		rebuildViewsFor(mStartFolderID);
 +		rebuildViews();
  		mHasInventoryConnection = true;
  		defaultOpenInventory();
  	}
 @@ -268,7 +255,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  	// inventory just initialized, do complete build
  	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
  	{
 -		rebuildViewsFor(mStartFolderID);
 +		rebuildViews();
  		mHasInventoryConnection = true;
  		defaultOpenInventory();
  		return;
 @@ -388,6 +375,24 @@ void LLInventoryPanel::modelChanged(U32 mask)  }
 +void LLInventoryPanel::rebuildViews()
 +{
 +	// Determine the root folder and rebuild the views starting
 +	// at that folder.
 +	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
 +
 +	if ("LIBRARY" == mStartFolderString)
 +	{
 +		mStartFolderID = gInventory.getLibraryRootFolderID();
 +	}
 +	else
 +	{
 +		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
 +	}
 +	
 +	rebuildViewsFor(mStartFolderID);
 +}
 +
  void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
  {
  	LLFolderViewItem* old_view = NULL;
 diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index e398c44105..0ccee337c9 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -162,6 +162,10 @@ public:  	void unSelectAll()	{ mFolders->setSelection(NULL, FALSE, FALSE); }  protected: +	// Destroys the old views, and regenerates them based on the +	// start folder ID. +	void rebuildViews(); +  	// Given the id and the parent, build all of the folder views.  	void rebuildViewsFor(const LLUUID& id);  	virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719 diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index e3b2ab77aa..6c7d434eeb 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -49,7 +49,7 @@  #include "llviewermenu.h"
  #include "llviewertexturelist.h"
 -static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
 +static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory");
  void on_file_loaded_for_save(BOOL success, 
  							 LLViewerFetchedTexture *src_vi,
 diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp new file mode 100644 index 0000000000..2964bbe792 --- /dev/null +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -0,0 +1,245 @@ +/** + * @file llpaneloutfitsinventory.cpp + * @brief Outfits inventory panel + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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 "llpaneloutfitsinventory.h" + +#include "llagent.h" +#include "llbutton.h" +#include "llfloaterreg.h" +#include "lllandmark.h" + +#include "llfloaterworldmap.h" +#include "llfloaterinventory.h" +#include "llfoldervieweventlistener.h" +#include "llinventoryfunctions.h" +#include "llinventorypanel.h" +#include "llsidetray.h" +#include "lltabcontainer.h" +#include "llagentwearables.h" +#include "llviewerjointattachment.h" +#include "llviewerfoldertype.h" +#include "llvoavatarself.h" + +static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); + +LLPanelOutfitsInventory::LLPanelOutfitsInventory() : +	mInventoryPanel(NULL), +	mActionBtn(NULL), +	mWearBtn(NULL), +	mEditBtn(NULL) +{ +	mSavedFolderState = new LLSaveFolderState(); +	mSavedFolderState->setApply(FALSE); + +	// LLUICtrlFactory::getInstance()->buildPanel(this, "panel_outfits_inventory.xml"); +} + +LLPanelOutfitsInventory::~LLPanelOutfitsInventory() +{ +	delete mSavedFolderState; +} + +// virtual +BOOL LLPanelOutfitsInventory::postBuild() +{ +	mInventoryPanel = getChild<LLInventoryPanel>("outfits_list"); +	mInventoryPanel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE); +	mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); +	mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_MY_OUTFITS); +	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2)); +	 +	LLFolderView* root_folder = getRootFolder(); +	root_folder->setReshapeCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2)); +	 +	mWearBtn = getChild<LLButton>("wear_btn"); +	mEditBtn = getChild<LLButton>("edit_btn"); +	mActionBtn = getChild<LLButton>("action_btn"); +	 +	return TRUE; +} + +// virtual +void LLPanelOutfitsInventory::onSearchEdit(const std::string& string) +{ +	if (string == "") +	{ +		mInventoryPanel->setFilterSubString(LLStringUtil::null); + +		// re-open folders that were initially open +		mSavedFolderState->setApply(TRUE); +		getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +		LLOpenFoldersWithSelection opener; +		getRootFolder()->applyFunctorRecursively(opener); +		getRootFolder()->scrollToShowSelection(); +	} + +	gInventory.startBackgroundFetch(); + +	if (mInventoryPanel->getFilterSubString().empty() && string.empty()) +	{ +		// current filter and new filter empty, do nothing +		return; +	} + +	// save current folder open state if no filter currently applied +	if (getRootFolder()->getFilterSubString().empty()) +	{ +		mSavedFolderState->setApply(FALSE); +		getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +	} + +	// set new filter string +	mInventoryPanel->setFilterSubString(string); +} + +void LLPanelOutfitsInventory::onWear() +{ +	LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem(); +	if (!current_item) +		return; + +	LLFolderViewEventListener* listenerp = current_item->getListener(); +	if (getIsCorrectType(listenerp)) +	{ +		listenerp->performAction(NULL, NULL,"replaceoutfit"); +	} +} + +void LLPanelOutfitsInventory::onEdit() +{ +} + +void LLPanelOutfitsInventory::onNew() +{ +	const std::string& outfit_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_OUTFIT); +	LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name); +	getRootFolder()->setSelectionByID(outfit_folder, TRUE); +	getRootFolder()->setNeedsAutoRename(TRUE); +} + +void LLPanelOutfitsInventory::updateVerbs() +{ +	BOOL enabled = FALSE; + +	LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem(); +	if (current_item) +	{ +		LLFolderViewEventListener* listenerp = current_item->getListener(); +		if (getIsCorrectType(listenerp)) +		{ +			enabled = TRUE; +		} +	} + +	if (mWearBtn) +	{ +		mWearBtn->setEnabled(enabled); +	} +	// mEditBtn->setEnabled(enabled); +} + +void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action) +{ +	LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem(); +	if (!current_item) +		return; +	 +	/* +	  LLFolderViewEventListener* listenerp = current_item->getListener(); +	  if (getIsCorrectType(listenerp)) +	  { +	  S32 bottom = 0; +	  LLFolderViewItem* folder = current_item->getParentFolder(); + +	  while ( folder->getParentFolder() != NULL ) +	  { +	  bottom += folder->getRect().mBottom; +	  folder = folder->getParentFolder(); +	  } + +	  LLRect rect = current_item->getRect(); +	  LLRect btn_rect( +	  rect.mRight - mActionBtn->getRect().getWidth(), +	  bottom + rect.mTop, +	  rect.mRight, +	  bottom + rect.mBottom); + +	  mActionBtn->setRect(btn_rect); + +	  if (!mActionBtn->getVisible()) +	  mActionBtn->setVisible(TRUE); +	  } +	  else +	  { +	  if (mActionBtn->getVisible()) +	  mActionBtn->setVisible(FALSE); +	  }  +	*/ + +	updateVerbs(); +} + +void LLPanelOutfitsInventory::onSelectorButtonClicked() +{ +	/* +	  LLFolderViewItem* cur_item = getRootFolder()->getCurSelectedItem(); + +	  LLFolderViewEventListener* listenerp = cur_item->getListener(); +	  if (getIsCorrectType(listenerp)) +	  { +	  LLSD key; +	  key["type"] = "look"; +	  key["id"] = listenerp->getUUID(); + +	  LLSideTray::getInstance()->showPanel("sidepanel_appearance", key); +	  }  +	*/ +} + +bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *listenerp) const +{ +	if (listenerp->getInventoryType() == LLInventoryType::IT_CATEGORY) +	{ +		LLViewerInventoryCategory *cat = gInventory.getCategory(listenerp->getUUID()); +		if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) +		{ +			return true; +		} +	} +	return false; +} + +LLFolderView *LLPanelOutfitsInventory::getRootFolder() +{ +	return mInventoryPanel->getRootFolder(); +} diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h new file mode 100644 index 0000000000..3f837d3635 --- /dev/null +++ b/indra/newview/llpaneloutfitsinventory.h @@ -0,0 +1,76 @@ +/** + * @file llpaneloutfitsinventory.h + * @brief Outfits inventory panel + * class definition + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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_LLPANELOUTFITSINVENTORY_H +#define LL_LLPANELOUTFITSINVENTORY_H + +#include "llpanel.h" +#include "llinventoryobserver.h" + +class LLFolderView; +class LLFolderViewItem; +class LLFolderViewEventListener; +class LLInventoryPanel; +class LLSaveFolderState; +class LLButton; + +class LLPanelOutfitsInventory : public LLPanel +{ +public: +	LLPanelOutfitsInventory(); +	virtual ~LLPanelOutfitsInventory(); + +	/*virtual*/ BOOL postBuild(); +	 +	void onSearchEdit(const std::string& string); +	void onWear(); +	void onEdit(); +	void onNew(); +	void updateVerbs(); + +	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); +	void onSelectorButtonClicked(); + +	LLFolderView* getRootFolder(); + +private: +	bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const; +	LLInventoryPanel*			mInventoryPanel; +	LLSaveFolderState*			mSavedFolderState; + +	LLButton*					mActionBtn; +	LLButton*					mWearBtn; +	LLButton*					mEditBtn; + +}; + +#endif //LL_LLPANELOUTFITSINVENTORY_H diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp new file mode 100644 index 0000000000..d92e404c2c --- /dev/null +++ b/indra/newview/llsidepanelappearance.cpp @@ -0,0 +1,373 @@ +/** + * @file llsidepanelappearance.cpp + * @brief Side Bar "Appearance" panel + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2004-2009, 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 "llsidepanelappearance.h" + +#include "llagent.h" +#include "llagentwearables.h" +#include "llfiltereditor.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" +#include "llpaneleditwearable.h" +#include "llpaneloutfitsinventory.h" +#include "lltextbox.h" +#include "lluictrlfactory.h" +#include "llviewerregion.h" +#include "llvoavatarself.h" +#include "llwearable.h" + +static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance"); + +class LLCurrentlyWornFetchObserver : public LLInventoryFetchObserver +{ +public: +	LLCurrentlyWornFetchObserver(LLSidepanelAppearance *panel) : +		mPanel(panel) +	{} +	~LLCurrentlyWornFetchObserver() {} +	virtual void done() +	{ +		mPanel->inventoryFetched(); +		gInventory.removeObserver(this); +	} +private: +	LLSidepanelAppearance *mPanel; +}; + +LLSidepanelAppearance::LLSidepanelAppearance() : +	LLPanel(), +	mFilterSubString(LLStringUtil::null), +	mFilterEditor(NULL), +	mLookInfo(NULL), +	mCurrLookPanel(NULL) +{ +	//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_appearance.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() +	mFetchWorn = new LLCurrentlyWornFetchObserver(this); +} + +LLSidepanelAppearance::~LLSidepanelAppearance() +{ +} + +// virtual +BOOL LLSidepanelAppearance::postBuild() +{ +	mEditAppearanceBtn = getChild<LLButton>("editappearance_btn"); +	mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this)); + +	mWearBtn = getChild<LLButton>("wear_btn"); +	mWearBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onWearButtonClicked, this)); + +	mEditBtn = getChild<LLButton>("edit_btn"); +	mEditBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditButtonClicked, this)); + +	mNewLookBtn = getChild<LLButton>("newlook_btn"); +	mNewLookBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this)); +	mNewLookBtn->setEnabled(false); + +	mOverflowBtn = getChild<LLButton>("overflow_btn"); + +	mFilterEditor = getChild<LLFilterEditor>("Filter"); +	if (mFilterEditor) +	{ +		mFilterEditor->setCommitCallback(boost::bind(&LLSidepanelAppearance::onFilterEdit, this, _2)); +	} + +	mPanelOutfitsInventory = dynamic_cast<LLPanelOutfitsInventory *>(getChild<LLPanel>("panel_outfits_inventory")); + +	mLookInfo = dynamic_cast<LLPanelLookInfo*>(getChild<LLPanel>("panel_look_info")); +	if (mLookInfo) +	{ +		LLButton* back_btn = mLookInfo->getChild<LLButton>("back_btn"); +		if (back_btn) +		{ +			back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onBackButtonClicked, this)); +		} + +		// *TODO: Assign the action to an appropriate event. +		// mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::toggleMediaPanel, this)); +	} + +	mEditWearable = dynamic_cast<LLPanelEditWearable*>(getChild<LLPanel>("panel_edit_wearable")); +	if (mEditWearable) +	{ +		LLButton* edit_wearable_back_btn = mEditWearable->getChild<LLButton>("back_btn"); +		if (edit_wearable_back_btn) +		{ +			edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this)); +		} +	} + +	mCurrentLookName = getChild<LLTextBox>("currentlook_name"); +	 +	mCurrLookPanel = getChild<LLPanel>("panel_currentlook"); + +	return TRUE; +} + +// virtual +void LLSidepanelAppearance::onOpen(const LLSD& key) +{ +	fetchInventory(); +	refreshCurrentOutfitName(); + +	if(key.size() == 0) +		return; + +	toggleLookInfoPanel(TRUE); +	updateVerbs(); +	 +	mLookInfoType = key["type"].asString(); + +	if (mLookInfoType == "look") +	{ +		LLInventoryCategory *pLook = gInventory.getCategory(key["id"].asUUID()); +		if (pLook) +			mLookInfo->displayLookInfo(pLook); +	} +} + +void LLSidepanelAppearance::onFilterEdit(const std::string& search_string) +{ +	if (mFilterSubString != search_string) +	{ +		mFilterSubString = search_string; + +		// Searches are case-insensitive +		LLStringUtil::toUpper(mFilterSubString); +		LLStringUtil::trimHead(mFilterSubString); + +		mPanelOutfitsInventory->onSearchEdit(mFilterSubString); +	} +} + +void LLSidepanelAppearance::onWearButtonClicked() +{ +	if (mLookInfo->getVisible()) +	{ +	} +	else +	{ +		mPanelOutfitsInventory->onWear(); +	} +} + +void LLSidepanelAppearance::onEditAppearanceButtonClicked() +{ +	if (gAgentWearables.areWearablesLoaded()) +	{ +		gAgent.changeCameraToCustomizeAvatar(); +	} +} + +void LLSidepanelAppearance::onEditButtonClicked() +{ +	toggleLookInfoPanel(FALSE); +	toggleWearableEditPanel(TRUE, NULL); +	/*if (mLookInfo->getVisible()) +	  { +	  } +	  else +	  { +	  mPanelOutfitsInventory->onEdit(); +	  }*/ +} + +void LLSidepanelAppearance::onNewOutfitButtonClicked() +{ +	if (mLookInfo->getVisible()) +	{ +	} +	else +	{ +		mPanelOutfitsInventory->onNew(); +	} +} + + +void LLSidepanelAppearance::onBackButtonClicked() +{ +	toggleLookInfoPanel(FALSE); +} + +void LLSidepanelAppearance::onEditWearBackClicked() +{ +	mEditWearable->saveChanges(); +	toggleWearableEditPanel(FALSE, NULL); +	toggleLookInfoPanel(TRUE); +} + +void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible) +{ +	if (!mLookInfo) +		return; + +	mLookInfo->setVisible(visible); +	mPanelOutfitsInventory->setVisible(!visible); +	mFilterEditor->setVisible(!visible); +	mWearBtn->setVisible(!visible); +	mEditBtn->setVisible(!visible); +	mNewLookBtn->setVisible(!visible); +	mOverflowBtn->setVisible(!visible); +	mCurrLookPanel->setVisible(!visible); +} + +void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) +{ +	if (!wearable) +	{ +		wearable = gAgentWearables.getWearable(WT_SHAPE, 0); +	} +	if (!mEditWearable || !wearable) +	{ +		return; +	} + +	mEditWearable->setVisible(visible); +	mFilterEditor->setVisible(!visible); +	mPanelOutfitsInventory->setVisible(!visible); +} + +void LLSidepanelAppearance::updateVerbs() +{ +	bool is_look_info_visible = mLookInfo->getVisible(); +	mOverflowBtn->setEnabled(false); + +	if (is_look_info_visible) +	{ +	} +	else +	{ +		mPanelOutfitsInventory->updateVerbs(); +	} +} + +void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string name) +{ +	if (name == "") +	{ +		const LLUUID current_outfit_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		// Can't search on AT_OUTFIT since links to categories return AT_CATEGORY for type since they don't +		// return preferred type. +		LLIsType is_category( LLAssetType::AT_CATEGORY );  +		gInventory.collectDescendentsIf(current_outfit_cat, +										cat_array, +										item_array, +										false, +										is_category, +										false); +		for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); +			 iter != item_array.end(); +			 iter++) +		{ +			const LLViewerInventoryItem *item = (*iter); +			const LLViewerInventoryCategory *cat = item->getLinkedCategory(); +			if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) +			{ +				mCurrentLookName->setText(cat->getName()); +				return; +			} +		} +		mCurrentLookName->setText(std::string("")); +	} +	else +	{ +		mCurrentLookName->setText(name); +	} +} + +//static +void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data) +{ +	LLSidepanelAppearance *panel = (LLSidepanelAppearance*) data; +	panel->toggleLookInfoPanel(FALSE); +	panel->toggleWearableEditPanel(TRUE, wearable); +} + +// Fetch currently worn items and only enable the New Look button after everything's been +// fetched.  Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks. +void LLSidepanelAppearance::fetchInventory() +{ + +	mNewLookBtn->setEnabled(false); +	LLInventoryFetchObserver::item_ref_t ids; +	LLUUID item_id; +	for(S32 type = (S32)WT_SHAPE; type < (S32)WT_COUNT; ++type) +	{ +		// MULTI_WEARABLE: +		item_id = gAgentWearables.getWearableItemID((EWearableType)type,0); +		if(item_id.notNull()) +		{ +			ids.push_back(item_id); +		} +	} + +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); +	if( avatar ) +	{ +		for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();  +			 iter != avatar->mAttachmentPoints.end(); ++iter) +		{ +			LLViewerJointAttachment* attachment = iter->second; +			if (!attachment) continue; +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				 attachment_iter != attachment->mAttachedObjects.end(); +				 ++attachment_iter) +			{ +				LLViewerObject* attached_object = (*attachment_iter); +				if (!attached_object) continue; +				const LLUUID& item_id = attached_object->getItemID(); +				if (item_id.isNull()) continue; +				ids.push_back(item_id); +			} +		} +	} + +	mFetchWorn->fetchItems(ids); +	// If no items to be fetched, done will never be triggered. +	// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition. +	if (mFetchWorn->isEverythingComplete()) +	{ +		mFetchWorn->done(); +	} +	else +	{ +		gInventory.addObserver(mFetchWorn); +	} +} + +void LLSidepanelAppearance::inventoryFetched() +{ +	mNewLookBtn->setEnabled(true); +} diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h new file mode 100644 index 0000000000..7be6d2d432 --- /dev/null +++ b/indra/newview/llsidepanelappearance.h @@ -0,0 +1,102 @@ +/**  + * @file llsidepanelappearance.h + * @brief Side Bar "Appearance" panel + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2004-2009, 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_LLSIDEPANELAPPEARANCE_H +#define LL_LLSIDEPANELAPPEARANCE_H + +#include "llpanel.h" +#include "llinventoryobserver.h" + +#include "llinventory.h" +#include "llpanellookinfo.h" + +class LLFilterEditor; +class LLCurrentlyWornFetchObserver; +class LLPanelEditWearable; +class LLWearable; +class LLPanelOutfitsInventory; + +class LLSidepanelAppearance : public LLPanel +{ +public: +	LLSidepanelAppearance(); +	virtual ~LLSidepanelAppearance(); + +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key); + +	void refreshCurrentOutfitName(const std::string name = ""); + +	static void editWearable(LLWearable *wearable, void *data); + +	void fetchInventory(); +	void inventoryFetched(); +private: +	void onFilterEdit(const std::string& search_string); + +	void onEditAppearanceButtonClicked(); +	void onWearButtonClicked(); +	void onEditButtonClicked(); +	void onNewOutfitButtonClicked(); +	void onBackButtonClicked(); +	void onEditWearBackClicked(); +	void toggleLookInfoPanel(BOOL visible); +	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable); + +	void updateVerbs(); + +	LLFilterEditor*			mFilterEditor; +	LLPanelOutfitsInventory* mPanelOutfitsInventory; +	LLPanelLookInfo*		mLookInfo; +	LLPanelEditWearable*	mEditWearable; + +	LLButton*					mEditAppearanceBtn; +	LLButton*					mWearBtn; +	LLButton*					mEditBtn; +	LLButton*					mNewLookBtn; +	LLButton*					mOverflowBtn; +	LLPanel*					mCurrLookPanel; + +	LLTextBox*					mCurrentLookName; + +	// Used to make sure the user's inventory is in memory. +	LLCurrentlyWornFetchObserver* mFetchWorn; + +	// Search string for filtering landmarks and teleport +	// history locations +	std::string					mFilterSubString; + +	// Information type currently shown in Look Information panel +	std::string					mLookInfoType; + +}; + +#endif //LL_LLSIDEPANELAPPEARANCE_H diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml index b48c962413..7cfcac8a9a 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory.xml @@ -30,7 +30,7 @@       name="Fetched">          Fetched      </floater.string> -<panel +    <panel       bottom="560"  	 class="panel_main_inventory"  	 filename="panel_main_inventory.xml" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml new file mode 100644 index 0000000000..f511ec0d6f --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel name="Outfits"  +	  bottom="0"  +	  height="326"  +	  left="0"  +	  width="310" +	  border="true" +	  follows="left|top|right|bottom"> +	 <inventory_panel  +	 	 allow_multi_select="true"  +		 border="true"  +		 bottom="0" +	     follows="left|top|right|bottom"  +		 height="326"  +		 left="0"  +		 mouse_opaque="true" +	     name="outfits_list" +		 width="310" +		 start_folder="My Outfits"/> +	<button bottom="0" +		 halign="center" +		 height="16" +		 label=">" +		 enabled="false" +	     mouse_opaque="false" +		 name="selector" +		 width="20" +		 left="0" +		 visible="false" +	     follows="right|bottom" +		 tool_tip="View outfit properties"/> +    <panel +     background_visible="true" +     bevel_style="none" +     bottom="0" +     follows="left|right|bottom" +     height="30" +     layout="bottomleft" +     left="0" +	 visible="true" +     name="bottom_panel" +     width="310"> +        <button +         follows="bottom|left" +         tool_tip="Show additional options" +         height="18" +         image_disabled="OptionsMenu_Disabled" +         image_selected="OptionsMenu_Press" +         image_unselected="OptionsMenu_Off" +         layout="topleft" +         left="10" +         name="options_gear_btn" +         picture_style="true" +         top="6" +         width="18" /> +        <button +         follows="bottom|left" +         height="18" +         image_selected="AddItem_Press" +         image_unselected="AddItem_Off" +         image_disabled="AddItem_Disabled" +         layout="topleft" +         left_pad="5" +         name="add_btn" +         picture_style="true" +         tool_tip="Add new item" +         width="18" /> +        <dnd_button +         follows="bottom|right" +         height="18" +         image_selected="TrashItem_Press" +         image_unselected="TrashItem_Off" +         layout="topleft" +         right="-5" +         name="trash_btn" +         picture_style="true" +         tool_tip="Remove selected item" +         top="6" +         width="18" /> +    </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index a419a02d75..d02354a647 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -120,9 +120,9 @@      background_visible="true"    >        <panel -        class="panel_appearance" -        name="panel_appearance" -        filename="panel_appearance.xml" +        class="sidepanel_appearance" +        name="sidepanel_appearance" +        filename="sidepanel_appearance.xml"          label="Edit Appearance"          font="SansSerifBold"        /> diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml new file mode 100644 index 0000000000..d87211d432 --- /dev/null +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +	  background_visible="true" +	  follows="all" +	  height="400" +	  label="Appearance" +	  layout="topleft" +	  min_height="350" +	  min_width="240" +	  name="appearance panel" +	  width="333"> +     <string +		 name="looks_tab_title" +		 value="Looks" /> +     <panel +		 left="5" width="320" height="55" +		 background_visible="true" +		 background_opaque="false" +		 bg_alpha_color="0.2 0.2 0.2 1.0" +		 name="panel_currentlook" +		 follows="left|top|right"> +		<text +			 top="-5" width="200" left="5" height="10" follows="left|right|top" +        	 font="SansSerif" text_color="LtGray" word_wrap="true" +        	 mouse_opaque="false" name="currentlook_title"> +					Current Look +    	</text> +  		<text +			 top="-30" left="8" height="10" follows="left|right|top" +      		 font="SansSerifBold" text_color="white" word_wrap="true" +      		 mouse_opaque="false" name="currentlook_name" > +					MyLook +  		</text> +  	    <button +  	     	 follows="left|right|top" +  	     	 font="SansSerif" +  	     	 top="28" right="-105" width="60" height="20" +  	     	 layout="topleft" +  		 	 label="Edit" +  	     	 name="editappearance_btn"/> +	</panel> + +    <filter_editor +  	     follows="left|top|right" +  	     font="SansSerif" +  	     label="Filter" +  	     layout="topleft" +  	     left="15"  +		 width="313" +		 height="20" +  	     name="Filter" /> +    <panel +   	     class="panel_outfits_inventory" +   	     filename="panel_outfits_inventory.xml" + 	     name="panel_outfits_inventory" +  	     follows="all" +  	     height="271" +  	     halign="center" +  	     layout="topleft" +  	     left="10" +  	     top_pad="19" +  	     width="313" /> +    <button +  	     follows="bottom|left" +  	     font="SansSerifSmallBold" +  	     height="25" +  	     label="Wear" +  	     layout="topleft" +  	     left="10" +  	     name="wear_btn" +     	 top_pad="0" +       	 width="80" /> +    <button +    	 follows="bottom|left" +  	     font="SansSerifSmallBold" +  	     height="25" +  	     label="New Look" +  	     layout="topleft" +  	     left_pad="0" +  	     name="newlook_btn" +  	     top_delta="0" +   	     width="90" /> + +	<panel +       	 class="panel_look_info" +       	 filename="panel_look_info.xml" +       	 follows="all" +       	 layout="topleft" +       	 left="0" +       	 name="panel_look_info" +       	 top="-200" +       	 visible="false" /> + +	<panel +	   	 class="panel_edit_wearable" +	   	 filename="panel_edit_wearable.xml" +	   	 follows="all" +	   	 layout="topleft" +	   	 left="0" +	   	 name="panel_edit_wearable" +	   	 top="-200" +	   	 visible="false" +	   	 width="333" /> +</panel> | 
