From 53a5b74af12ec772a2a69cff49b2e52da51c5c8f Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Sat, 15 May 2010 14:40:15 +0300 Subject: EXT-7241 FIXED Changed all "Edit Appearance" links to "Change Outfit" and pointed them to the My Outfits tab. Renamed the following menu items to "Change Outfit" and made them open My Outfits tab: - Avatar in-world context menu -> My Appearance. - Avatar inspector menu -> My Appearance. - Me -> My Appearance. To enable the Appearance SP switch to My outfits I cleaned up the logic of switching between my outfits <-> edit outfit <-> edit wearable panels. Also done the following cleanups and minor improvements: - Removed unused LLSidepanelAppearance::mEditBtn and mLookInfoType members. - Removed empty LLSidepanelAppearance::updateVerbs() method. - Made the "params" argument of LLSideTray::showPanel() and togglePanel() optional. Reviewed by Nyx at https://codereview.productengine.com/secondlife/r/389/ --HG-- branch : product-engine --- indra/newview/llviewermenu.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 42428bab03..c245650d51 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5597,10 +5597,7 @@ void handle_viewer_disable_message_log(void*) void handle_customize_avatar() { - if (gAgentWearables.areWearablesLoaded()) - { - gAgentCamera.changeCameraToCustomizeAvatar(); - } + LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "my_outfits")); } void handle_report_abuse() -- cgit v1.3 From 9aacdbc155b894532a85b18912288691ecb3832c Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Wed, 19 May 2010 14:03:29 +0300 Subject: EXT-7242 FIXED Added a new "Edit my Shape" link to avatar self-click context menu and made it open the shape editing panel. Again, as in EXT-7241, I tried to improve the way the appearance panels (outfits / edit outfit / edit wearables) are switched, this time aiming to eliminate redundant time-consuming operations (fetches/updated/etc). I'm not particularly satisfied with the resulting code but it seems to work. A better solution might be to wrap the panels with LLSideTrayPanelContainer. Additional minor changes: - Fixed unsafe pointer cast in LLSidepanelAppearance::editWearable(). - Removed redundant onEditOutfitButtonClicked() and onEditWearBackClicked() methods from LLSidepanelAppearance. Reviewed by Nyx at https://codereview.productengine.com/secondlife/r/395/ --HG-- branch : product-engine --- indra/newview/llpaneloutfitedit.cpp | 13 +- indra/newview/llpaneloutfitedit.h | 3 + indra/newview/llpaneloutfitsinventory.cpp | 26 +++- indra/newview/llpaneloutfitsinventory.h | 4 + indra/newview/llsidepanelappearance.cpp | 139 ++++++++++++--------- indra/newview/llsidepanelappearance.h | 13 +- indra/newview/llviewermenu.cpp | 15 +++ .../skins/default/xui/en/menu_avatar_self.xml | 9 ++ .../skins/default/xui/en/sidepanel_appearance.xml | 1 + 9 files changed, 155 insertions(+), 68 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 44832ac496..c1623a4fa7 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -210,7 +210,8 @@ LLPanelOutfitEdit::LLPanelOutfitEdit() mCOFWearables(NULL), mInventoryItemsPanel(NULL), mCOFObserver(NULL), - mCOFDragAndDropObserver(NULL) + mCOFDragAndDropObserver(NULL), + mInitialized(false) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -307,6 +308,16 @@ BOOL LLPanelOutfitEdit::postBuild() return TRUE; } +// virtual +void LLPanelOutfitEdit::onOpen(const LLSD& key) +{ + if (!mInitialized) + { + displayCurrentOutfit(); + mInitialized = true; + } +} + void LLPanelOutfitEdit::moveWearable(bool closer_to_body) { LLUUID item_id = mCOFWearables->getSelectedUUID(); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 953a70785c..a08dc653ef 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -61,6 +61,7 @@ class LLFilteredWearableListManager; class LLPanelOutfitEdit : public LLPanel { + LOG_CLASS(LLPanelOutfitEdit); public: // NOTE: initialize mLookItemTypes at the index of any new enum you add in the LLPanelOutfitEdit() constructor @@ -83,6 +84,7 @@ public: /*virtual*/ ~LLPanelOutfitEdit(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); void moveWearable(bool closer_to_body); @@ -146,6 +148,7 @@ private: std::vector mLookItemTypes; LLCOFWearables* mCOFWearables; + bool mInitialized; }; #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index ea75c16c56..0760c57f8e 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -73,7 +73,8 @@ static LLRegisterPanelClassWrapper t_inventory("panel_o LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), - mParent(NULL) + mParent(NULL), + mInitialized(false) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -106,6 +107,18 @@ BOOL LLPanelOutfitsInventory::postBuild() // virtual void LLPanelOutfitsInventory::onOpen(const LLSD& key) { + if (!mInitialized) + { + LLSidepanelAppearance* panel_appearance = getAppearanceSP(); + if (panel_appearance) + { + // *TODO: move these methods to LLPanelOutfitsInventory? + panel_appearance->fetchInventory(); + panel_appearance->refreshCurrentOutfitName(); + } + mInitialized = true; + } + // Make sure we know which tab is selected, update the filter, // and update verbs. onTabChange(); @@ -249,8 +262,7 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& { LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name); - LLSidepanelAppearance* panel_appearance = - dynamic_cast(LLSideTray::getInstance()->getPanel("sidepanel_appearance")); + LLSidepanelAppearance* panel_appearance = getAppearanceSP(); if (panel_appearance) { panel_appearance->showOutfitsInventoryPanel(); @@ -661,3 +673,11 @@ void LLPanelOutfitsInventory::onWearablesLoaded() { setWearablesLoading(false); } + +LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP() +{ + static LLSidepanelAppearance* panel_appearance = + dynamic_cast + (LLSideTray::getInstance()->getPanel("sidepanel_appearance")); + return panel_appearance; +} diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 6b4d1dbd84..a0fe91cd80 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -49,6 +49,7 @@ class LLTabContainer; class LLPanelOutfitsInventory : public LLPanel { + LOG_CLASS(LLPanelOutfitsInventory); public: LLPanelOutfitsInventory(); virtual ~LLPanelOutfitsInventory(); @@ -72,6 +73,7 @@ public: void setParent(LLSidepanelAppearance *parent); LLFolderView* getRootFolder(); + LLSidepanelAppearance* getAppearanceSP(); static LLPanelOutfitsInventory* findInstance(); @@ -132,6 +134,8 @@ private: // List Commands // //////////////////////////////////////////////////////////////////////////////// /// + + bool mInitialized; }; #endif //LL_LLPANELOUTFITSINVENTORY_H diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 658a7b52e3..3f05e05fd4 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -97,7 +97,8 @@ LLSidepanelAppearance::LLSidepanelAppearance() : mFilterSubString(LLStringUtil::null), mFilterEditor(NULL), mOutfitEdit(NULL), - mCurrOutfitPanel(NULL) + mCurrOutfitPanel(NULL), + mOpened(false) { } @@ -116,7 +117,7 @@ BOOL LLSidepanelAppearance::postBuild() mEditAppearanceBtn = getChild("editappearance_btn"); mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this)); - childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::onEditOutfitButtonClicked, this)); + childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this)); mNewOutfitBtn = getChild("newlook_btn"); mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this)); @@ -148,7 +149,7 @@ BOOL LLSidepanelAppearance::postBuild() LLButton* edit_wearable_back_btn = mEditWearable->getChild("back_btn"); if (edit_wearable_back_btn) { - edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this)); + edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this)); } } @@ -167,27 +168,36 @@ BOOL LLSidepanelAppearance::postBuild() // virtual void LLSidepanelAppearance::onOpen(const LLSD& key) { - fetchInventory(); - refreshCurrentOutfitName(); - - if (mPanelOutfitsInventory) - { - mPanelOutfitsInventory->onOpen(key); - } - if (!key.has("type")) - return; - - // Switch to the requested panel. - std::string type = key["type"].asString(); - if (type == "my_outfits") { - showOutfitsInventoryPanel(); + // No specific panel requested. + // If we're opened for the first time then show My Outfits. + // Else do nothing. + if (!mOpened) + { + showOutfitsInventoryPanel(); + } } - else if (type == "edit_outfit") + else { - showOutfitEditPanel(/*update = */ true); + // Switch to the requested panel. + // *TODO: replace this crap with LLSideTrayPanelContainer + std::string type = key["type"].asString(); + if (type == "my_outfits") + { + showOutfitsInventoryPanel(); + } + else if (type == "edit_outfit") + { + showOutfitEditPanel(); + } + else if (type == "edit_shape") + { + showWearableEditPanel(); + } } + + mOpened = true; } void LLSidepanelAppearance::onFilterEdit(const std::string& search_string) @@ -239,13 +249,6 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked() } } -void LLSidepanelAppearance::onEditOutfitButtonClicked() -{ - LLSD key; - key["type"] = "edit_outfit"; - LLSideTray::getInstance()->showPanel("sidepanel_appearance", key); -} - void LLSidepanelAppearance::onNewOutfitButtonClicked() { if (!mOutfitEdit->getVisible()) @@ -254,52 +257,68 @@ void LLSidepanelAppearance::onNewOutfitButtonClicked() } } -void LLSidepanelAppearance::onEditWearBackClicked() +void LLSidepanelAppearance::showOutfitsInventoryPanel() { - showOutfitEditPanel(/* update = */ false); + toggleWearableEditPanel(FALSE); + toggleOutfitEditPanel(FALSE); + togglMyOutfitsPanel(TRUE); } -void LLSidepanelAppearance::showOutfitsInventoryPanel() +void LLSidepanelAppearance::showOutfitEditPanel() { + togglMyOutfitsPanel(FALSE); toggleWearableEditPanel(FALSE); + toggleOutfitEditPanel(TRUE); +} + +void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/) +{ + togglMyOutfitsPanel(FALSE); toggleOutfitEditPanel(FALSE); + toggleWearableEditPanel(TRUE, wearable); } -void LLSidepanelAppearance::showOutfitEditPanel(bool update) +void LLSidepanelAppearance::togglMyOutfitsPanel(BOOL visible) { - if (!mOutfitEdit) + if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible) + { + // visibility isn't changing, hence nothing to do return; + } - toggleWearableEditPanel(FALSE); - toggleOutfitEditPanel(TRUE); + mPanelOutfitsInventory->setVisible(visible); + + // *TODO: Move these controls to panel_outfits_inventory.xml + // so that we don't need to toggle them explicitly. + mFilterEditor->setVisible(visible); + mNewOutfitBtn->setVisible(visible); + mCurrOutfitPanel->setVisible(visible); - if (update) + if (visible) { - mOutfitEdit->displayCurrentOutfit(); + mPanelOutfitsInventory->onOpen(LLSD()); } } void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible) { - if (!mOutfitEdit) - return; - - if (mOutfitEdit->getVisible() == visible) + if (!mOutfitEdit || mOutfitEdit->getVisible() == visible) { // visibility isn't changing, hence nothing to do return; } mOutfitEdit->setVisible(visible); - if (mPanelOutfitsInventory) mPanelOutfitsInventory->setVisible(!visible); - mFilterEditor->setVisible(!visible); - mNewOutfitBtn->setVisible(!visible); - mCurrOutfitPanel->setVisible(!visible); + + if (visible) + { + mOutfitEdit->onOpen(LLSD()); + } } void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) { - if (mEditWearable->getVisible() == visible) + if (!mEditWearable || mEditWearable->getVisible() == visible) { // visibility isn't changing, hence nothing to do return; @@ -309,24 +328,24 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we { wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0); } - if (!mEditWearable || !wearable) + if (!wearable) { return; } - // Save changes if closing. - if (!visible) - { - mEditWearable->saveChanges(); - } - // Toggle panel visibility. - mCurrOutfitPanel->setVisible(!visible); - mEditWearable->setVisible(visible); mEditWearable->setWearable(wearable); - mFilterEditor->setVisible(!visible); - mPanelOutfitsInventory->setVisible(!visible); + + if (visible) + { + mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency + } + else + { + // Save changes if closing. + mEditWearable->saveChanges(); + } } void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name) @@ -356,11 +375,13 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name) } //static -void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data) +void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data) { - LLSidepanelAppearance *panel = (LLSidepanelAppearance*) data; - panel->toggleOutfitEditPanel(FALSE); - panel->toggleWearableEditPanel(TRUE, wearable); + LLSidepanelAppearance *panel = dynamic_cast(data); + if (panel) + { + panel->showWearableEditPanel(wearable); + } } // Fetch currently worn items and only enable the New Look button after everything's been diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index a919b07ed6..f243bbd471 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -47,6 +47,7 @@ class LLPanelOutfitsInventory; class LLSidepanelAppearance : public LLPanel { + LOG_CLASS(LLSidepanelAppearance); public: LLSidepanelAppearance(); virtual ~LLSidepanelAppearance(); @@ -56,14 +57,15 @@ public: void refreshCurrentOutfitName(const std::string& name = ""); - static void editWearable(LLWearable *wearable, void *data); + static void editWearable(LLWearable *wearable, LLView *data); void fetchInventory(); void inventoryFetched(); void onNewOutfitButtonClicked(); void showOutfitsInventoryPanel(); - void showOutfitEditPanel(bool update); + void showOutfitEditPanel(); + void showWearableEditPanel(LLWearable *wearable = NULL); void setWearablesLoading(bool val); private: @@ -71,10 +73,8 @@ private: void onOpenOutfitButtonClicked(); void onEditAppearanceButtonClicked(); - void onEditOutfitButtonClicked(); - void onEditWearBackClicked(); - //@deprecated use showXXX() methods instead + void togglMyOutfitsPanel(BOOL visible); void toggleOutfitEditPanel(BOOL visible); void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL); @@ -100,6 +100,9 @@ private: // Search string for filtering landmarks and teleport // history locations std::string mFilterSubString; + + // Gets set to true when we're opened for the first time. + bool mOpened; }; #endif //LL_LLSIDEPANELAPPEARANCE_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c245650d51..a14fbdca82 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3629,6 +3629,14 @@ class LLEditEnableCustomizeAvatar : public view_listener_t } }; +class LLEnableEditShape : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0); + } +}; + bool enable_sit_object() { LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -5600,6 +5608,11 @@ void handle_customize_avatar() LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "my_outfits")); } +void handle_edit_shape() +{ + LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_shape")); +} + void handle_report_abuse() { // Prevent menu from appearing in screen shot. @@ -7716,7 +7729,9 @@ void initialize_menus() view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate"); view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff"); view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); + view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape"); commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); + commit.add("EditShape", boost::bind(&handle_edit_shape)); // View menu view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook"); diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 0efe598243..b0cfb261cb 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -191,6 +191,15 @@ + + + + height="493" min_height="410" width="320" + visible="false" left="0" tab_group="1" top_pad="6" -- cgit v1.3 From 8487341b0f255e65044c3f7e3dc09461b4e2351e Mon Sep 17 00:00:00 2001 From: Nyx Linden Date: Wed, 19 May 2010 19:48:23 -0400 Subject: AVP-44 WIP Back-end support for multiwearables Changed a lot of areas of code that were not dealing with multiwearables properly. Little functionality changed, as the support mechanisms that were out of date were subtle, but getting closer to no further areas of code that don't properly support multi-wearables. Code reviewed by Vir. --- indra/newview/llagent.cpp | 15 +-- indra/newview/llagentwearables.cpp | 190 ++++-------------------------------- indra/newview/llagentwearables.h | 22 +---- indra/newview/llappearancemgr.cpp | 13 ++- indra/newview/llinventorybridge.cpp | 26 ++--- indra/newview/llviewermenu.cpp | 56 +++++------ indra/newview/llvoavatarself.cpp | 28 +++--- indra/newview/llvoavatarself.h | 6 +- 8 files changed, 100 insertions(+), 256 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 529ce950e4..f96a59e97a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3583,12 +3583,15 @@ void LLAgent::sendAgentSetAppearance() { // LLWearableType::EType wearable_type = gBakedWearableMap[baked_index][wearable_num]; const LLWearableType::EType wearable_type = baked_dict->mWearables[i]; - // MULTI-WEARABLE: fixed to 0th - extend to everything once messaging works. - const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0); - if (wearable) - { - hash ^= wearable->getAssetID(); - } + for (U8 wearable_index =0; wearable_index < gAgentWearables.getWearableCount(wearable_type); ++wearable_index) + { + const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,wearable_index); + if (wearable) + { + // MULTI-WEARABLE: make order-dependent (use MD5 hash) + hash ^= wearable->getAssetID(); + } + } } if (hash.notNull()) { diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 3e73bbef15..545c5b845b 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -125,7 +125,6 @@ void LLAgentWearables::dump() } } -// MULTI-WEARABLE: debugging struct LLAgentDumper { LLAgentDumper(std::string name): @@ -191,7 +190,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal * @param todo Bitmask of actions to take on completion. */ LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( - LLPointer cb, S32 type, U32 index, LLWearable* wearable, U32 todo) : + LLPointer cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) : mType(type), mIndex(index), mWearable(wearable), @@ -240,7 +239,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i } } -void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, +void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type, const U32 index, const LLUUID& item_id, LLWearable* wearable) @@ -250,7 +249,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, if (item_id.isNull()) return; - LLUUID old_item_id = getWearableItemID((LLWearableType::EType)type,index); + LLUUID old_item_id = getWearableItemID(type,index); if (wearable) { @@ -259,11 +258,11 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, if (old_item_id.notNull()) { gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - setWearable((LLWearableType::EType)type,index,wearable); + setWearable(type,index,wearable); } else { - pushWearable((LLWearableType::EType)type,wearable); + pushWearable(type,wearable); } } @@ -285,13 +284,12 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, void LLAgentWearables::sendAgentWearablesUpdate() { - // MULTI-WEARABLE: call i "type" or something. // First make sure that we have inventory items for each wearable for (S32 type=0; type < LLWearableType::WT_COUNT; ++type) { - for (U32 j=0; j < getWearableCount((LLWearableType::EType)type); ++j) + for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index) { - LLWearable* wearable = getWearable((LLWearableType::EType)type,j); + LLWearable* wearable = getWearable((LLWearableType::EType)type,index); if (wearable) { if (wearable->getItemID().isNull()) @@ -299,8 +297,8 @@ void LLAgentWearables::sendAgentWearablesUpdate() LLPointer cb = new addWearableToAgentInventoryCallback( LLPointer(NULL), - type, - j, + (LLWearableType::EType)type, + index, wearable, addWearableToAgentInventoryCallback::CALL_NONE); addWearableToAgentInventory(cb, wearable); @@ -325,7 +323,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); lldebugs << "sendAgentWearablesUpdate()" << llendl; - // MULTI-WEARABLE: update for multi-wearables after server-side support is in. + // MULTI-WEARABLE: DEPRECATED: HACK: index to 0- server database tables don't support concept of multiwearables. for (S32 type=0; type < LLWearableType::WT_COUNT; ++type) { gMessageSystem->nextBlockFast(_PREHASH_WearableData); @@ -333,7 +331,6 @@ void LLAgentWearables::sendAgentWearablesUpdate() U8 type_u8 = (U8)type; gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8); - // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this. LLWearable* wearable = getWearable((LLWearableType::EType)type, 0); if (wearable) { @@ -405,7 +402,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 LLPointer cb = new addWearableToAgentInventoryCallback( LLPointer(NULL), - (S32)type, + type, index, new_wearable, todo); @@ -871,7 +868,7 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const return FALSE; } -// MULTI-WEARABLE: update for multiple +// MULTI-WEARABLE: DEPRECATED (see backwards compatibility) // static // ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume // that viewers have a Current Outfit Folder and won't need this message, and thus @@ -909,7 +906,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; // Add wearables - // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. + // MULTI-WEARABLE: DEPRECATED: Message only supports one wearable per type, will be ignored in future. gAgentWearables.mItemsAwaitingWearableUpdate.clear(); for (S32 i=0; i < num_wearables; i++) { @@ -939,10 +936,10 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs continue; } - // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. + // MULTI-WEARABLE: DEPRECATED: this message only supports one wearable per type. Should be ignored in future versions // Store initial wearables data until we know whether we have the current outfit folder or need to use the data. - LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update + LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); outfit->add(wearable_data); } @@ -977,7 +974,6 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type); - S32 type_s32 = (S32) type; setWearable(type,index,new_wearable); //new_wearable->writeToAvatar(TRUE); @@ -988,7 +984,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, LLPointer cb = new addWearableToAgentInventoryCallback( LLPointer(NULL), - type_s32, + type, index, new_wearable, addWearableToAgentInventoryCallback::CALL_RECOVERDONE); @@ -1172,158 +1168,6 @@ void LLAgentWearables::createStandardWearablesAllDone() gAgentAvatarp->onFirstTEMessageReceived(); } -// MULTI-WEARABLE: Properly handle multiwearables later. -void LLAgentWearables::getAllWearablesArray(LLDynamicArray& wearables) -{ - for( S32 i = 0; i < LLWearableType::WT_COUNT; ++i ) - { - if (getWearableCount((LLWearableType::EType) i) != 0) - { - wearables.push_back(i); - } - } -} - -// Note: wearables_to_include should be a list of LLWearableType::EType types -// attachments_to_include should be a list of attachment points -void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, - const LLDynamicArray& wearables_to_include, - const LLDynamicArray& attachments_to_include, - BOOL rename_clothing) -{ - if (!isAgentAvatarValid()) return; - - // First, make a folder in the Clothes directory. - LLUUID folder_id = gInventory.createNewCategory( - gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING), - LLFolderType::FT_NONE, - new_folder_name); - - bool found_first_item = false; - - /////////////////// - // Wearables - - if (wearables_to_include.count()) - { - // Then, iterate though each of the wearables and save copies of them in the folder. - S32 i; - S32 count = wearables_to_include.count(); - LLDynamicArray delete_items; - LLPointer cbdone = NULL; - for (i = 0; i < count; ++i) - { - const S32 type = wearables_to_include[i]; - for (U32 j=0; jgetTypeLabel()); - LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); - new_wearable->setName(new_name); - } - - LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((LLWearableType::EType)type,j)); - S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; - if (!found_first_item) - { - found_first_item = true; - /* set the focus to the first item */ - todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE; - /* send the agent wearables update when done */ - cbdone = new sendAgentWearablesUpdateCallback; - } - LLPointer cb = - new addWearableToAgentInventoryCallback( - cbdone, - type, - j, - new_wearable, - todo); - llassert(item); - if (item) - { - if (isWearableCopyable((LLWearableType::EType)type, j)) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - folder_id, - new_name, - cb); - } - else - { - move_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - item->getUUID(), - folder_id, - new_name, - cb); - } - } - } - } - } - gInventory.notifyObservers(); - } - - - /////////////////// - // Attachments - - if (attachments_to_include.count()) - { - BOOL msg_started = FALSE; - LLMessageSystem* msg = gMessageSystem; - for (S32 i = 0; i < attachments_to_include.count(); i++) - { - S32 attachment_pt = attachments_to_include[i]; - LLViewerJointAttachment* attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL); - 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 = (*attachment_iter)->getItemID(); - if(item_id.isNull()) continue; - LLInventoryItem* item = gInventory.getItem(item_id); - if(!item) continue; - if(!msg_started) - { - msg_started = TRUE; - msg->newMessage("CreateNewOutfitAttachments"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("HeaderData"); - msg->addUUID("NewFolderID", folder_id); - } - msg->nextBlock("ObjectData"); - msg->addUUID("OldItemID", item_id); - msg->addUUID("OldFolderID", item->getParentUUID()); - } - } - - if (msg_started) - { - gAgent.sendReliableMessage(); - } - - } -} class LLShowCreatedOutfit: public LLInventoryCallback { @@ -2010,7 +1854,7 @@ BOOL LLAgentWearables::areWearablesLoaded() const return mWearablesLoaded; } -// MULTI-WEARABLE: update for multiple indices. +// MULTI-WEARABLE: DEPRECATED: item pending count relies on old messages that don't support multi-wearables. do not trust to be accurate void LLAgentWearables::updateWearablesLoaded() { mWearablesLoaded = (itemUpdatePendingCount()==0); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index def16e4e85..27453b5b25 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -62,7 +62,6 @@ public: void cleanup(); void dump(); protected: - // MULTI-WEARABLE: assuming one per type. Type is called index - rename. void createStandardWearablesDone(S32 type, U32 index/* = 0*/); void createStandardWearablesAllDone(); @@ -93,7 +92,6 @@ public: const LLWearable* getWearableFromItemID(const LLUUID& item_id) const; LLWearable* getWearableFromAssetID(const LLUUID& asset_id); LLInventoryItem* getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/); - // MULTI-WEARABLE: assuming one per type. static BOOL selfHasWearable(LLWearableType::EType type); LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/); const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; @@ -128,7 +126,7 @@ protected: LLWearable* wearable, const LLUUID& category_id = LLUUID::null, BOOL notify = TRUE); - void addWearabletoAgentInventoryDone(const S32 type, + void addWearabletoAgentInventoryDone(const LLWearableType::EType type, const U32 index, const LLUUID& item_id, LLWearable* wearable); @@ -163,15 +161,6 @@ protected: // Outfits //-------------------------------------------------------------------- public: - void getAllWearablesArray(LLDynamicArray& wearables); - - // Note: wearables_to_include should be a list of LLWearableType::EType types - // attachments_to_include should be a list of attachment points - void makeNewOutfit(const std::string& new_folder_name, - const LLDynamicArray& wearables_to_include, - const LLDynamicArray& attachments_to_include, - BOOL rename_clothing); - // Should only be called if we *know* we've never done so before, since users may // not want the Library outfits to stay in their quick outfit selector and can delete them. @@ -184,7 +173,6 @@ private: // Save Wearables //-------------------------------------------------------------------- public: - // MULTI-WEARABLE: assumes one per type. void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found); void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE); void saveAllWearables(); @@ -249,7 +237,7 @@ private: class addWearableToAgentInventoryCallback : public LLInventoryCallback { public: - enum EType + enum ETodo { CALL_NONE = 0, CALL_UPDATE = 1, @@ -259,16 +247,14 @@ private: CALL_WEARITEM = 16 }; - // MULTI-WEARABLE: index is an LLWearableType::EType - more confusing usage. - // MULTI-WEARABLE: need to have type and index args both? addWearableToAgentInventoryCallback(LLPointer cb, - S32 type, + LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo = CALL_NONE); virtual void fire(const LLUUID& inv_item); private: - S32 mType; + LLWearableType::EType mType; U32 mIndex; LLWearable* mWearable; U32 mTodo; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4aef72ab0b..7d39ba30f0 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1469,14 +1469,21 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update { // Are these links to the same object? const LLViewerInventoryItem* inv_item = item_array.get(i).get(); + const LLWearableType::EType wearable_type = inv_item->getWearableType(); + + const bool is_body_part = (wearable_type == LLWearableType::WT_SHAPE) + || (wearable_type == LLWearableType::WT_HAIR) + || (wearable_type == LLWearableType::WT_EYES) + || (wearable_type == LLWearableType::WT_SKIN); + if (inv_item->getLinkedUUID() == vitem->getLinkedUUID()) { linked_already = true; } - // Are these links to different items of the same wearable + // Are these links to different items of the same body part // type? If so, new item will replace old. - // MULTI-WEARABLES: revisit if more than one per type is allowed. - else if (FALSE/*areMatchingWearables(vitem,inv_item)*/) + // TODO: MULTI-WEARABLE: check for wearable limit for clothing types + else if (is_body_part) { if (inv_item->getIsLinkType()) { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b9b4fa8b03..ab7eeae3e8 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4980,18 +4980,20 @@ void LLWearableBridge::removeAllClothesFromAvatar() if (itype == LLWearableType::WT_SHAPE || itype == LLWearableType::WT_SKIN || itype == LLWearableType::WT_HAIR || itype == LLWearableType::WT_EYES) continue; - // MULTI-WEARABLES: fixed to index 0 - LLViewerInventoryItem *item = dynamic_cast( - gAgentWearables.getWearableInventoryItem((LLWearableType::EType)itype, 0)); - if (!item) - continue; - const LLUUID &item_id = gInventory.getLinkedItemID(item->getUUID()); - const LLWearable *wearable = gAgentWearables.getWearableFromItemID(item_id); - if (!wearable) - continue; - - // Find and remove this item from the COF. - LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); + for (S32 index = gAgentWearables.getWearableCount(itype)-1; index >= 0 ; --index) + { + LLViewerInventoryItem *item = dynamic_cast( + gAgentWearables.getWearableInventoryItem((LLWearableType::EType)itype, index)); + if (!item) + continue; + const LLUUID &item_id = gInventory.getLinkedItemID(item->getUUID()); + const LLWearable *wearable = gAgentWearables.getWearableFromItemID(item_id); + if (!wearable) + continue; + + // Find and remove this item from the COF. + LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); + } } gInventory.notifyObservers(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c245650d51..729424353f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -292,8 +292,8 @@ void handle_toggle_pg(void*); void handle_dump_attachments(void *); void handle_dump_avatar_local_textures(void*); void handle_debug_avatar_textures(void*); -void handle_grab_texture(void*); -BOOL enable_grab_texture(void*); +void handle_grab_baked_texture(void*); +BOOL enable_grab_baked_texture(void*); void handle_dump_region_object_cache(void*); BOOL enable_save_into_inventory(void*); @@ -1460,28 +1460,28 @@ class LLAdvancedGrabBakedTexture : public view_listener_t std::string texture_type = userdata.asString(); if ("iris" == texture_type) { - handle_grab_texture( (void*)TEX_EYES_BAKED ); + handle_grab_baked_texture( (void*)BAKED_EYES ); } else if ("head" == texture_type) { - handle_grab_texture( (void*)TEX_HEAD_BAKED ); + handle_grab_baked_texture( (void*)BAKED_HEAD ); } else if ("upper" == texture_type) { - handle_grab_texture( (void*)TEX_UPPER_BAKED ); + handle_grab_baked_texture( (void*)BAKED_UPPER ); } else if ("lower" == texture_type) { - handle_grab_texture( (void*)TEX_SKIRT_BAKED ); + handle_grab_baked_texture( (void*)BAKED_LOWER ); } else if ("skirt" == texture_type) { - handle_grab_texture( (void*)TEX_SKIRT_BAKED ); + handle_grab_baked_texture( (void*)BAKED_SKIRT ); } else if ("hair" == texture_type) { - handle_grab_texture( (void*)TEX_HAIR_BAKED ); -} + handle_grab_baked_texture( (void*)BAKED_HAIR ); + } return true; } @@ -1496,23 +1496,27 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t if ("iris" == texture_type) { - new_value = enable_grab_texture( (void*)TEX_EYES_BAKED ); + new_value = enable_grab_baked_texture( (void*)BAKED_EYES ); } else if ("head" == texture_type) { - new_value = enable_grab_texture( (void*)TEX_HEAD_BAKED ); + new_value = enable_grab_baked_texture( (void*)BAKED_HEAD ); } else if ("upper" == texture_type) { - new_value = enable_grab_texture( (void*)TEX_UPPER_BAKED ); + new_value = enable_grab_baked_texture( (void*)BAKED_UPPER ); } else if ("lower" == texture_type) { - new_value = enable_grab_texture( (void*)TEX_LOWER_BAKED ); + new_value = enable_grab_baked_texture( (void*)BAKED_LOWER ); } else if ("skirt" == texture_type) { - new_value = enable_grab_texture( (void*)TEX_SKIRT_BAKED ); + new_value = enable_grab_baked_texture( (void*)BAKED_SKIRT ); + } + else if ("hair" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_HAIR ); } return new_value; @@ -6933,27 +6937,20 @@ void handle_debug_avatar_textures(void*) } } -void handle_grab_texture(void* data) +void handle_grab_baked_texture(void* data) { - ETextureIndex tex_index = (ETextureIndex)((intptr_t)data); + EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data); if (!isAgentAvatarValid()) return; - // MULTI-WEARABLE: change to support an index - const LLUUID& asset_id = gAgentAvatarp->grabLocalTexture(tex_index, 0); + const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index); LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl; LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type)); if(folder_id.notNull()) { - std::string name = "Unknown"; - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(tex_index); - if (texture_dict->mIsBakedTexture) - { - EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mNameCapitalized; - } - name += " Texture"; + std::string name; + name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture"; LLUUID item_id; item_id.generate(); @@ -7006,13 +7003,12 @@ void handle_grab_texture(void* data) } } -BOOL enable_grab_texture(void* data) +BOOL enable_grab_baked_texture(void* data) { - ETextureIndex index = (ETextureIndex)((intptr_t)data); + EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data); if (isAgentAvatarValid()) { - // MULTI-WEARABLE: - return gAgentAvatarp->canGrabLocalTexture(index,0); + return gAgentAvatarp->canGrabBakedTexture(index); } return FALSE; } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 8bf082ad45..ac7adebb3a 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1798,21 +1798,31 @@ void LLVOAvatarSelf::bakedTextureUpload(EBakedTextureIndex index, BOOL finished) mBakedTextureTimes[index][done] = mSelfLoadTimer.getElapsedTimeF32(); } -const LLUUID& LLVOAvatarSelf::grabLocalTexture(ETextureIndex type, U32 index) const +const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const { - if (canGrabLocalTexture(type, index)) + if (canGrabBakedTexture(baked_index)) { - return getTEImage( type )->getID(); + ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return LLUUID::null; + } + return getTEImage( tex_index )->getID(); } return LLUUID::null; } -BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const +BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const { + ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return FALSE; + } // Check if the texture hasn't been baked yet. - if (!isTextureDefined(type, index)) + if (!isTextureDefined(tex_index, 0)) { - lldebugs << "getTEImage( " << (U32) type << ", " << index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; + lldebugs << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; return FALSE; } @@ -1822,13 +1832,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const // Check permissions of textures that show up in the // baked texture. We don't want people copying people's // work via baked textures. - /* switch(type) - case TEX_EYES_BAKED: - textures.push_back(TEX_EYES_IRIS); */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(type); - if (!texture_dict->mIsUsedByBakedTexture) return FALSE; - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); iter != baked_dict->mLocalTextures.end(); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 03856b3a3b..587c2363f6 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -201,8 +201,6 @@ public: LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const; const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const; void setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index); - const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const; - BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const; /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index); protected: /*virtual*/ void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index); @@ -252,6 +250,10 @@ public: void setupComposites(); void updateComposites(); + const LLUUID& grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + BOOL canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + + //-------------------------------------------------------------------- // Scratch textures (used for compositing) //-------------------------------------------------------------------- -- cgit v1.3 From f91481c82faf1f9527cf54f7dbf4cbc28555003b Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Fri, 21 May 2010 17:02:53 -0400 Subject: EXT-7209 EXT-7366 FIX avatar needs to enter "appearance editing" mode Avatar now enters "appearance editing" mode when opening the outfit or wearable editors in the sidepanel. Changed code to ensure we don't accidentally switch out of it and back in when switching from one to the other. Note that this cuts out LLFLoaterCustomize from being built and shown to the user from any UI. The code for this (and related classes) will be removed once we have pulled any code out of it that we still need. The current outfit and wearable editors should be working sufficiently for most purposes. Bugs should be reported to Nyx Linden or the avatar team. Code reviewed by Vir --- indra/newview/llmorphview.cpp | 17 ++------------- indra/newview/llsidepanelappearance.cpp | 25 ++++++++++++++++++---- indra/newview/llsidepanelappearance.h | 4 ++-- indra/newview/llviewermenu.cpp | 6 ++++++ .../skins/default/xui/en/menu_avatar_self.xml | 11 ++++++++-- 5 files changed, 40 insertions(+), 23 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index d670eb6ffd..27a27fb65a 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -131,14 +131,7 @@ void LLMorphView::setVisible(BOOL visible) if (visible) { - llassert( !gFloaterCustomize ); - gFloaterCustomize = new LLFloaterCustomize(); - gFloaterCustomize->fetchInventory(); - gFloaterCustomize->openFloater(); - - // Must do this _after_ gFloaterView is initialized. - gFloaterCustomize->switchToDefaultSubpart(); - + // TODO: verify some user action has already opened outfit editor? - Nyx initialize(); // First run dialog @@ -146,13 +139,7 @@ void LLMorphView::setVisible(BOOL visible) } else { - if( gFloaterCustomize ) - { - gFloaterView->removeChild( gFloaterCustomize ); - delete gFloaterCustomize; - gFloaterCustomize = NULL; - } - + // TODO: verify some user action has already closed outfit editor ? - Nyx shutdown(); } } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 3f05e05fd4..010d593b27 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -47,6 +47,7 @@ #include "llsidetray.h" #include "lltextbox.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewerregion.h" #include "llvoavatarself.h" #include "llwearable.h" @@ -267,14 +268,14 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel() void LLSidepanelAppearance::showOutfitEditPanel() { togglMyOutfitsPanel(FALSE); - toggleWearableEditPanel(FALSE); + toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode toggleOutfitEditPanel(TRUE); } void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/) { togglMyOutfitsPanel(FALSE); - toggleOutfitEditPanel(FALSE); + toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode toggleWearableEditPanel(TRUE, wearable); } @@ -300,7 +301,7 @@ void LLSidepanelAppearance::togglMyOutfitsPanel(BOOL visible) } } -void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible) +void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch) { if (!mOutfitEdit || mOutfitEdit->getVisible() == visible) { @@ -313,10 +314,18 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible) if (visible) { mOutfitEdit->onOpen(LLSD()); + if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + { + gAgentCamera.changeCameraToCustomizeAvatar(); + } + } + else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + { + gAgentCamera.changeCameraToDefault(); } } -void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable) +void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch) { if (!mEditWearable || mEditWearable->getVisible() == visible) { @@ -340,11 +349,19 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we if (visible) { mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency + if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + { + gAgentCamera.changeCameraToCustomizeAvatar(); + } } else { // Save changes if closing. mEditWearable->saveChanges(); + if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + { + gAgentCamera.changeCameraToDefault(); + } } } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index f243bbd471..12303b6e96 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -75,8 +75,8 @@ private: void onEditAppearanceButtonClicked(); void togglMyOutfitsPanel(BOOL visible); - void toggleOutfitEditPanel(BOOL visible); - void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL); + void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE); + void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE); LLFilterEditor* mFilterEditor; LLPanelOutfitsInventory* mPanelOutfitsInventory; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f905892982..4bfb87343c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5612,6 +5612,11 @@ void handle_customize_avatar() LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "my_outfits")); } +void handle_edit_outfit() +{ + LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit")); +} + void handle_edit_shape() { LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_shape")); @@ -7727,6 +7732,7 @@ void initialize_menus() view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape"); commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); + commit.add("EditOutfit", boost::bind(&handle_edit_outfit)); commit.add("EditShape", boost::bind(&handle_edit_shape)); // View menu diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index b0cfb261cb..d5b993152a 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -191,8 +191,15 @@ - + + + + Date: Fri, 21 May 2010 15:22:32 -0700 Subject: VI-65 - Addition of Quick/Eazy Buy Web based floater. Switched off by default for now until Web content ready - turn on with Debug Settings - 'QuickBuyCurrency' Reviewed by Sam/Richard --- indra/newview/CMakeLists.txt | 4 + indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llassetuploadresponders.cpp | 4 +- indra/newview/llbuycurrencyhtml.cpp | 165 +++++++++++++++++++++ indra/newview/llbuycurrencyhtml.h | 57 +++++++ indra/newview/llfloaterbuycurrencyhtml.cpp | 119 +++++++++++++++ indra/newview/llfloaterbuycurrencyhtml.h | 65 ++++++++ indra/newview/llpanelobjectinventory.cpp | 4 +- indra/newview/llpanelplaceprofile.cpp | 4 +- indra/newview/llstatusbar.cpp | 5 +- indra/newview/llviewerfloaterreg.cpp | 2 + indra/newview/llviewermenu.cpp | 9 +- indra/newview/llviewermenufile.cpp | 4 +- indra/newview/llviewermessage.cpp | 5 +- .../default/xui/en/floater_buy_currency_html.xml | 27 ++++ 15 files changed, 468 insertions(+), 17 deletions(-) create mode 100644 indra/newview/llbuycurrencyhtml.cpp create mode 100644 indra/newview/llbuycurrencyhtml.h create mode 100644 indra/newview/llfloaterbuycurrencyhtml.cpp create mode 100644 indra/newview/llfloaterbuycurrencyhtml.h create mode 100644 indra/newview/skins/default/xui/en/floater_buy_currency_html.xml (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d77d53f6af..28a5555ca2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -91,6 +91,7 @@ set(viewer_SOURCE_FILES llbottomtray.cpp llbox.cpp llbreadcrumbview.cpp + llbuycurrencyhtml.cpp llcallbacklist.cpp llcallfloater.cpp llcallingcard.cpp @@ -159,6 +160,7 @@ set(viewer_SOURCE_FILES llfloaterbuy.cpp llfloaterbuycontents.cpp llfloaterbuycurrency.cpp + llfloaterbuycurrencyhtml.cpp llfloaterbuyland.cpp llfloatercamera.cpp llfloatercolorpicker.cpp @@ -604,6 +606,7 @@ set(viewer_HEADER_FILES llbottomtray.h llbox.h llbreadcrumbview.h + llbuycurrencyhtml.h llcallbacklist.h llcallfloater.h llcallingcard.h @@ -674,6 +677,7 @@ set(viewer_HEADER_FILES llfloaterbuy.h llfloaterbuycontents.h llfloaterbuycurrency.h + llfloaterbuycurrencyhtml.h llfloaterbuyland.h llfloatercamera.h llfloatercolorpicker.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 418032c554..1d27d00451 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6028,6 +6028,17 @@ Value 0 + QuickBuyCurrency + + Comment + Toggle between HTML based currency purchase floater and legacy XUI version + Persist + 1 + Type + Boolean + Value + 0 + RegionTextureSize Comment diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 2f90d652e4..27dcb9f1c7 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -37,7 +37,7 @@ // viewer includes #include "llagent.h" #include "llcompilequeue.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfilepicker.h" #include "llinventorydefines.h" #include "llinventoryobserver.h" @@ -186,7 +186,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content) S32 price = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", price); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("uploading_costs", args), price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("uploading_costs", args), price ); } else { diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp new file mode 100644 index 0000000000..cb06f487e6 --- /dev/null +++ b/indra/newview/llbuycurrencyhtml.cpp @@ -0,0 +1,165 @@ +/** + * @file llbuycurrencyhtml.cpp + * @brief Manages Buy Currency HTML floater + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2006-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 "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" +#include "llfloaterbuycurrencyhtml.h" + +#include "llfloaterreg.h" +#include "llcommandhandler.h" +#include "llviewercontrol.h" + +// support for secondlife:///app/buycurrencyhtml/{ACTION}/{NEXT_ACTION}/{RETURN_CODE} SLapps +class LLBuyCurrencyHTMLHandler : + public LLCommandHandler +{ +public: + // requests will be throttled from a non-trusted browser + LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {} + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + std::string action( "" ); + if ( params.size() >= 1 ) + { + action = params[ 0 ].asString(); + }; + + std::string next_action( "" ); + if ( params.size() >= 2 ) + { + next_action = params[ 1 ].asString(); + }; + + int result_code = 0; + if ( params.size() >= 3 ) + { + result_code = params[ 2 ].asInteger(); + }; + + // open the legacy XUI based currency floater + if ( "open_legacy" == next_action ) + { + LLFloaterBuyCurrency::buyCurrency(); + }; + + // ask the Buy Currency floater to close + // note: this is the last thing we can do so make + // sure any other actions are processed before this. + if ( "close" == action ) + { + LLBuyCurrencyHTML::closeDialog(); + }; + + return true; + }; +}; +LLBuyCurrencyHTMLHandler gBuyCurrencyHTMLHandler; + +//////////////////////////////////////////////////////////////////////////////// +// static +// Opens the legacy XUI based floater or new HTML based one based on +// the QuickBuyCurrency value in settings.xml - this overload is for +// the case where the amount is not requested. +void LLBuyCurrencyHTML::openCurrencyFloater() +{ + if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) ) + { + // HTML version + LLBuyCurrencyHTML::showDialog( false, "", 0 ); + } + else + { + // legacy version + LLFloaterBuyCurrency::buyCurrency(); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +// Opens the legacy XUI based floater or new HTML based one based on +// the QuickBuyCurrency value in settings.xml - this overload is for +// the case where the amount and a string to display are requested. +void LLBuyCurrencyHTML::openCurrencyFloater( const std::string& message, S32 sum ) +{ + if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) ) + { + // HTML version + LLBuyCurrencyHTML::showDialog( true, message, sum ); + } + else + { + // legacy version + LLFloaterBuyCurrency::buyCurrency( message, sum ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLBuyCurrencyHTML::showDialog( bool specific_sum_requested, const std::string& message, S32 sum ) +{ + LLFloaterBuyCurrencyHTML* buy_currency_floater = dynamic_cast< LLFloaterBuyCurrencyHTML* >( LLFloaterReg::getInstance( "buy_currency_html" ) ); + if ( buy_currency_floater ) + { + // pass on flag indicating if we want to buy specific amount and if so, how much + buy_currency_floater->setParams( specific_sum_requested, message, sum ); + + // force navigate to new URL + buy_currency_floater->navigateToFinalURL(); + + // make it visible and raise to front + BOOL visible = TRUE; + buy_currency_floater->setVisible( visible ); + BOOL take_focus = TRUE; + buy_currency_floater->setFrontmost( take_focus ); + + // spec calls for floater to be centered on client window + buy_currency_floater->center(); + } + else + { + llwarns << "Buy Currency (HTML) Floater not found" << llendl; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLBuyCurrencyHTML::closeDialog() +{ + LLFloaterBuyCurrencyHTML* buy_currency_floater = dynamic_cast< LLFloaterBuyCurrencyHTML* >(LLFloaterReg::getInstance( "buy_currency_html" ) ); + if ( buy_currency_floater ) + { + buy_currency_floater->closeFloater(); + }; +} diff --git a/indra/newview/llbuycurrencyhtml.h b/indra/newview/llbuycurrencyhtml.h new file mode 100644 index 0000000000..dbb2281343 --- /dev/null +++ b/indra/newview/llbuycurrencyhtml.h @@ -0,0 +1,57 @@ +/** + * @file llbuycurrencyhtml.h + * @brief Manages Buy Currency HTML floater + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2006-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_LLBUYCURRENCYHTML_H +#define LL_LLBUYCURRENCYHTML_H + +#include "llsingleton.h" + +class LLFloaterBuyCurrencyHTML; + +class LLBuyCurrencyHTML +{ + public: + // choke point for opening a legacy or new currency floater - this overload is when the L$ sum is not required + static void openCurrencyFloater(); + + // choke point for opening a legacy or new currency floater - this overload is when the L$ sum is required + static void openCurrencyFloater( const std::string& message, S32 sum ); + + // show and give focus to actual currency floater - this is used for both cases + // where the sum is required and where it is not + static void showDialog( bool specific_sum_requested, const std::string& message, S32 sum ); + + // close (and destroy) the currency floater + static void closeDialog(); +}; + +#endif // LL_LLBUYCURRENCYHTML_H diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp new file mode 100644 index 0000000000..e4be706ac4 --- /dev/null +++ b/indra/newview/llfloaterbuycurrencyhtml.cpp @@ -0,0 +1,119 @@ +/** + * @file llfloaterbuycurrencyhtml.cpp + * @brief buy currency implemented in HTML floater - uses embedded media browser control + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2006-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 "llfloaterbuycurrencyhtml.h" +#include "llstatusbar.h" + +//////////////////////////////////////////////////////////////////////////////// +// +LLFloaterBuyCurrencyHTML::LLFloaterBuyCurrencyHTML( const LLSD& key ): + LLFloater( key ), + mSpecificSumRequested( false ), + mMessage( "" ), + mSum( 0 ) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLFloaterBuyCurrencyHTML::postBuild() +{ + // observer media events + mBrowser = getChild( "browser" ); + mBrowser->addObserver( this ); + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterBuyCurrencyHTML::navigateToFinalURL() +{ + // URL for actual currency buy contents is in XUI file + std::string buy_currency_url = getString( "buy_currency_url" ); + + // replace [LANGUAGE] meta-tag with view language + LLStringUtil::format_map_t replace; + + // viewer language + replace[ "[LANGUAGE]" ] = LLUI::getLanguage(); + + // flag that specific amount requested + replace[ "[SPECIFIC_AMOUNT]" ] = ( mSpecificSumRequested ? "y":"n" ); + + // amount requested + std::ostringstream codec( "" ); + codec << mSum; + replace[ "[SUM]" ] = codec.str(); + + // users' current balance + codec.clear(); + codec.str( "" ); + codec << gStatusBar->getBalance(); + replace[ "[BAL]" ] = codec.str(); + + // message - "This cost L$x,xxx for example + replace[ "[MSG]" ] = LLURI::escape( mMessage ); + LLStringUtil::format( buy_currency_url, replace ); + + // kick off the navigation + mBrowser->navigateTo( buy_currency_url ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event ) +{ + // placeholder for now - just in case we want to catch media events + if ( LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event ) + { + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting ) +{ + destroy(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterBuyCurrencyHTML::setParams( bool specific_sum_requested, const std::string& message, S32 sum ) +{ + // save these away - used to construct URL later + mSpecificSumRequested = specific_sum_requested; + mMessage = message; + mSum = sum; +} diff --git a/indra/newview/llfloaterbuycurrencyhtml.h b/indra/newview/llfloaterbuycurrencyhtml.h new file mode 100644 index 0000000000..daee5d6f75 --- /dev/null +++ b/indra/newview/llfloaterbuycurrencyhtml.h @@ -0,0 +1,65 @@ +/** + * @file llfloaterbuycurrencyhtml.h + * @brief buy currency implemented in HTML floater - uses embedded media browser control + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2006-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_LLFLOATERBUYCURRENCYHTML_H +#define LL_LLFLOATERBUYCURRENCYHTML_H + +#include "llfloater.h" +#include "llmediactrl.h" + +class LLFloaterBuyCurrencyHTML : + public LLFloater, + public LLViewerMediaObserver +{ + public: + LLFloaterBuyCurrencyHTML( const LLSD& key ); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose( bool app_quitting ); + + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event ); + + // allow our controlling parent to tell us paramters + void setParams( bool specific_sum_requested, const std::string& message, S32 sum ); + + // parse and construct URL and set browser to navigate there. + void navigateToFinalURL(); + + private: + LLMediaCtrl* mBrowser; + bool mSpecificSumRequested; + std::string mMessage; + S32 mSum; +}; + +#endif // LL_LLFLOATERBUYCURRENCYHTML_H diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index de16f9d343..39ade40967 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -48,7 +48,7 @@ #include "llagent.h" #include "llavataractions.h" #include "llcallbacklist.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfloaterreg.h" #include "llinventorybridge.h" #include "llinventorydefines.h" @@ -616,7 +616,7 @@ void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string actio { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", price); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("this_costs", args), price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price ); } else { diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 1a1650c38b..c8abcc83c4 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -50,7 +50,7 @@ #include "llagentui.h" #include "llappviewer.h" #include "llcallbacklist.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llstatusbar.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" @@ -573,7 +573,7 @@ void LLPanelPlaceProfile::onForSaleBannerClick() { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", price); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("buying_selected_land", args), price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("buying_selected_land", args), price ); } else { diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index b660a2b8ea..5628205dd4 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -41,6 +41,7 @@ #include "llcommandhandler.h" #include "llviewercontrol.h" #include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfloaterlagmeter.h" #include "llpanelnearbymedia.h" #include "llpanelvolumepulldown.h" @@ -509,7 +510,9 @@ S32 LLStatusBar::getSquareMetersLeft() const void LLStatusBar::onClickBuyCurrency() { - LLFloaterBuyCurrency::buyCurrency(); + // open a currency floater - actual one open depends on + // value specified in settings.xml + LLBuyCurrencyHTML::openCurrencyFloater(); } static void onClickHealth(void* ) diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 506cebfe73..49ea0348f9 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -49,6 +49,7 @@ #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" +#include "llfloaterbuycurrencyhtml.h" #include "llfloaterbuyland.h" #include "llfloaterbulkpermission.h" #include "llfloaterbump.h" @@ -141,6 +142,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("bulk_perms", "floater_bulk_perms.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("buy_currency", "floater_buy_currency.xml", &LLFloaterBuyCurrency::buildFloater); + LLFloaterReg::add("buy_currency_html", "floater_buy_currency_html.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("buy_land", "floater_buy_land.xml", &LLFloaterBuyLand::buildFloater); LLFloaterReg::add("buy_object", "floater_buy_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("buy_object_contents", "floater_buy_contents.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 4bfb87343c..10ceab2656 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -53,7 +53,7 @@ //#include "llfirstuse.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfloatercustomize.h" #include "llfloatergodtools.h" #include "llfloaterinventory.h" @@ -3288,7 +3288,7 @@ void handle_buy_object(LLSaleInfo sale_info) { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", price); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("this_object_costs", args), price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price ); return; } @@ -4430,8 +4430,7 @@ void handle_buy_or_take() { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", total_price); - LLFloaterBuyCurrency::buyCurrency( - LLTrans::getString("BuyingCosts", args), total_price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "BuyingCosts", args ), total_price ); } } else @@ -5631,7 +5630,7 @@ void handle_report_abuse() void handle_buy_currency() { - LLFloaterBuyCurrency::buyCurrency(); + LLBuyCurrencyHTML::openCurrencyFloater(); } class LLFloaterVisible : public view_listener_t diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index c415d89e9c..5570fe5fec 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -39,7 +39,7 @@ #include "llagentcamera.h" #include "llfilepicker.h" #include "llfloaterreg.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfloatersnapshot.h" #include "llimage.h" #include "llimagebmp.h" @@ -811,7 +811,7 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt LLStringUtil::format_map_t args; args["NAME"] = data->mAssetInfo.getName(); args["AMOUNT"] = llformat("%d", expected_upload_cost); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("UploadingCosts", args), expected_upload_cost); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); is_balance_sufficient = FALSE; } else if(region) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5b0b603d63..5836aff4e7 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -55,8 +55,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "llcallingcard.h" -//#include "llfirstuse.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llfloaterbuyland.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" @@ -283,7 +282,7 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_ { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", amount); - LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("giving", args), amount); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("giving", args), amount ); } } diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml new file mode 100644 index 0000000000..ab44082070 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml @@ -0,0 +1,27 @@ + + + + http://user.lindenlab.com/~callum/ez/index.php?lang=[LANGUAGE]&sa=[SPECIFIC_AMOUNT]&sum=[SUM]&msg=[MSG]&bal=[BAL] + + + -- cgit v1.3 From ecd93410ff819bb301f115e40c8f2d6fef8b2396 Mon Sep 17 00:00:00 2001 From: Andrew Polunin Date: Tue, 25 May 2010 15:31:07 +0300 Subject: EXT-7142 FIXED Upload functionality duplicated in the Build menu and Select Linked Parts menu moved up - LLPanelMainInventory::setUploadCostIfNeeded() - uncommented the line which enables retrieving of the upload cost price using LLGlobalEconomy class. - Implemented LLUploadCostCalculator event handler in the llviewermenu.cpp (the fact that it should be implemented in this file was discussed with Mike Antipov). - LLUploadCostCalculator::calculateCost() is implemented only for code readability: it's name is more descriptive than a code snippet placed directly in the constructor (LLPanelMainInventory::setUploadCostIfNeeded() works in similar way: it calculates cost_str only once). - 'Select Linked Parts' menu was moved below 'Edit Linked Parts'. - 'Upload' menu was added at the bottom, below 'Options' menu Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/425/ --HG-- branch : product-engine --- indra/newview/llpanelmaininventory.cpp | 2 +- indra/newview/llviewermenu.cpp | 39 +++++++ indra/newview/skins/default/xui/en/menu_viewer.xml | 113 ++++++++++++++++----- 3 files changed, 125 insertions(+), 29 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 5ff51b8165..54d1b46016 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1187,7 +1187,7 @@ void LLPanelMainInventory::setUploadCostIfNeeded() LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild("upload"); if(upload_menu) { - S32 upload_cost = -1;//LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); std::string cost_str; // getPriceUpload() returns -1 if no data available yet. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 10ceab2656..d0ac103f56 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -108,6 +108,7 @@ #include "lluilistener.h" #include "llappearancemgr.h" #include "lltrans.h" +#include "lleconomy.h" using namespace LLVOAvatarDefines; @@ -7658,6 +7659,42 @@ class LLWorldToggleCameraControls : public view_listener_t } }; +class LLUploadCostCalculator : public view_listener_t +{ + std::string mCostStr; + + bool handleEvent(const LLSD& userdata) + { + std::string menu_name = userdata.asString(); + gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr); + + return true; + } + + void calculateCost(); + +public: + LLUploadCostCalculator() + { + calculateCost(); + } +}; + +void LLUploadCostCalculator::calculateCost() +{ + S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + + // getPriceUpload() returns -1 if no data available yet. + if(upload_cost >= 0) + { + mCostStr = llformat("%d", upload_cost); + } + else + { + mCostStr = llformat("%d", gSavedSettings.getU32("DefaultUploadCost")); + } +} + void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) { static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_hide_navbar.xml", @@ -7699,6 +7736,8 @@ void initialize_menus() enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); + view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); + // Agent commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 16c2581d63..aff8f7ddf4 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -521,6 +521,52 @@ + + + + + + + + + + + + + + + + + + + label="Image (L$[COST])..." + layout="topleft" + name="Upload Image" + shortcut="control|U"> + function="File.UploadImage" + parameter="" /> + function="File.EnableUpload" /> + + label="Sound (L$[COST])..." + layout="topleft" + name="Upload Sound"> + function="File.UploadSound" + parameter="" /> + function="File.EnableUpload" /> + + label="Animation (L$[COST])..." + layout="topleft" + name="Upload Animation"> + function="File.UploadAnim" + parameter="" /> + function="File.EnableUpload" /> + + label="Bulk (L$[COST] per file)..." + layout="topleft" + name="Bulk Upload"> - + function="File.UploadBulk" + parameter="" /> + - + \ No newline at end of file -- cgit v1.3