From 32dccaf3d89b40b711d69088a3e390119c7efc7f Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 17 Nov 2009 10:36:11 -0500 Subject: 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 --- indra/newview/llsidepanelappearance.cpp | 373 ++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 indra/newview/llsidepanelappearance.cpp (limited to 'indra/newview/llsidepanelappearance.cpp') 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 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("editappearance_btn"); + mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this)); + + mWearBtn = getChild("wear_btn"); + mWearBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onWearButtonClicked, this)); + + mEditBtn = getChild("edit_btn"); + mEditBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditButtonClicked, this)); + + mNewLookBtn = getChild("newlook_btn"); + mNewLookBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this)); + mNewLookBtn->setEnabled(false); + + mOverflowBtn = getChild("overflow_btn"); + + mFilterEditor = getChild("Filter"); + if (mFilterEditor) + { + mFilterEditor->setCommitCallback(boost::bind(&LLSidepanelAppearance::onFilterEdit, this, _2)); + } + + mPanelOutfitsInventory = dynamic_cast(getChild("panel_outfits_inventory")); + + mLookInfo = dynamic_cast(getChild("panel_look_info")); + if (mLookInfo) + { + LLButton* back_btn = mLookInfo->getChild("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(getChild("panel_edit_wearable")); + if (mEditWearable) + { + LLButton* edit_wearable_back_btn = mEditWearable->getChild("back_btn"); + if (edit_wearable_back_btn) + { + edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this)); + } + } + + mCurrentLookName = getChild("currentlook_name"); + + mCurrLookPanel = getChild("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); +} -- cgit v1.2.3 From 53beee9e0837865163ff700df4b8d452135da9eb Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 17 Nov 2009 13:00:26 -0500 Subject: EXT-2569 : Separate out LLPanelOutfitsInventory so it's more modular versus being coupled with LLSidepanelAppearance EXT-2561 : Add standard bottom panel (gear menu, add button, trash icon) Added gear menu and standardized the code. (someday, will create a subclass to share the functionality across panels) Make LLPanelOutfitsInventory more modular, e.g. it no longer knows about the Wear/Edit buttons. --HG-- branch : avatar-pipeline --- indra/newview/llsidepanelappearance.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'indra/newview/llsidepanelappearance.cpp') diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index d92e404c2c..aeab3e2876 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -103,6 +103,7 @@ BOOL LLSidepanelAppearance::postBuild() } mPanelOutfitsInventory = dynamic_cast(getChild("panel_outfits_inventory")); + mPanelOutfitsInventory->setParent(this); mLookInfo = dynamic_cast(getChild("panel_look_info")); if (mLookInfo) @@ -172,10 +173,7 @@ void LLSidepanelAppearance::onFilterEdit(const std::string& search_string) void LLSidepanelAppearance::onWearButtonClicked() { - if (mLookInfo->getVisible()) - { - } - else + if (!mLookInfo->getVisible()) { mPanelOutfitsInventory->onWear(); } @@ -204,10 +202,7 @@ void LLSidepanelAppearance::onEditButtonClicked() void LLSidepanelAppearance::onNewOutfitButtonClicked() { - if (mLookInfo->getVisible()) - { - } - else + if (!mLookInfo->getVisible()) { mPanelOutfitsInventory->onNew(); } @@ -262,12 +257,16 @@ void LLSidepanelAppearance::updateVerbs() bool is_look_info_visible = mLookInfo->getVisible(); mOverflowBtn->setEnabled(false); - if (is_look_info_visible) + if (!is_look_info_visible) { + const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL); + mEditBtn->setEnabled(is_correct_type); + mWearBtn->setEnabled(is_correct_type); } else { - mPanelOutfitsInventory->updateVerbs(); + mEditBtn->setEnabled(FALSE); + mWearBtn->setEnabled(FALSE); } } -- cgit v1.2.3 From e6caf96b0a60dbbc75958ea4a74529601c51541f Mon Sep 17 00:00:00 2001 From: "Eric M. Tulla (BigPapi)" Date: Tue, 17 Nov 2009 19:03:30 -0500 Subject: post viewer2 merge compile fix (minor) --HG-- branch : avatar-pipeline --- indra/newview/llsidepanelappearance.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'indra/newview/llsidepanelappearance.cpp') diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index c30997fbdc..aeab3e2876 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -234,16 +234,9 @@ void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible) mNewLookBtn->setVisible(!visible); mOverflowBtn->setVisible(!visible); mCurrLookPanel->setVisible(!visible); - - if (visible) - { - LLRect rect = getRect(); - LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); - mLookInfo->reshape(new_rect.getWidth(),new_rect.getHeight()); - } } -void LLPanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) +void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) { if (!wearable) { -- cgit v1.2.3