Sidepanel Appearance refactoring. Work in progress.

1. Changed sidepanel names to have "sidepanel" (e.g. panel_appearance -> sidepanel_appearance)
2. Changed some "Looks" names to "Outfits"
3. Changed LLPanelLooks to LLPanelOutfitsInventory (to match other inventory panel naming)
4. Took out tab from sidepanel_appearance.

--HG--
branch : avatar-pipeline
meow-7.2.2
Loren Shih 2009-11-17 10:36:11 -05:00
parent b88778ca7d
commit 32dccaf3d8
14 changed files with 1026 additions and 37 deletions

View File

@ -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

View File

@ -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());
}
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -30,7 +30,7 @@
name="Fetched">
Fetched
</floater.string>
<panel
<panel
bottom="560"
class="panel_main_inventory"
filename="panel_main_inventory.xml"

View File

@ -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>

View File

@ -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"
/>

View File

@ -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>