From 5f9f6dcdec0de015e3c9a88afad6f4761c3c6527 Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Fri, 6 Aug 2010 17:14:01 +0300 Subject: EXT-8577 WIP Context menu items for multi-attachments. Done: - 1. Dropped the obsolete "MultipleAttachments" setting. - 2. Added an "Add" item to the following attachment-related context menus: * My Appearance (ex-My Outfits) context menu. * Edit Outfit -> Add More context menu. * Object in-world context menu. * Inventory context menu. * Object inspector gear menu. - 3. Modified "Attach To / Attach To HUD" to perform the "add" instead of "replace" action. TODO: - Ability to attach multiple objects at once from the Add More panel (bulk attach). - Make sure there's no memleak when you click Wear/Attach in the in-world object context menu and the callback isn't invoked (because e.g. avatar fails to get close enough to the object). Issues: 0. I'm not sure whether LLAgentWearables::userAttachMultipleAttachments() should replace attachments or add them. Assumed the former. 1. I couldn't verify that adding objects from the object inspector menu works because I either could wear an object or see its inspector, not both. 2. > 1. Right-click on an object in your inventory and select "Wear". > VERIFY: Attaches the object and replaces whatever's there; asks for > confirmation before replacing an existing object. I think this is impossible to implement because we don't know in advance what point the object will be attached to, so we can't display a confirmation dialog. Reviewed by Seraph at https://codereview.productengine.com/secondlife/r/843/ --HG-- branch : product-engine --- indra/newview/llviewermenu.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a83980dc23..92195f0a4d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5852,6 +5852,7 @@ void handle_buy_land() class LLObjectAttachToAvatar : public view_listener_t { public: + LLObjectAttachToAvatar(bool replace) : mReplace(replace) {} static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; } private: @@ -5865,22 +5866,38 @@ private: LLViewerJointAttachment* attachment_point = NULL; if (index > 0) attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); - confirm_replace_attachment(0, attachment_point); + confirmReplaceAttachment(0, attachment_point); } return true; } + static void onNearAttachObject(BOOL success, void *user_data); + void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point); + + struct CallbackData + { + CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {} + + LLViewerJointAttachment* mAttachmentPoint; + bool mReplace; + }; + protected: static LLObjectSelectionHandle sObjectSelection; + bool mReplace; }; LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection; -void near_attach_object(BOOL success, void *user_data) +// static +void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data) { + if (!user_data) return; + CallbackData* cb_data = static_cast(user_data); + if (success) { - const LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint; U8 attachment_id = 0; if (attachment) @@ -5900,12 +5917,15 @@ void near_attach_object(BOOL success, void *user_data) // interpret 0 as "default location" attachment_id = 0; } - LLSelectMgr::getInstance()->sendAttach(attachment_id); + LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace); } LLObjectAttachToAvatar::setObjectSelection(NULL); + + delete cb_data; } -void confirm_replace_attachment(S32 option, void* user_data) +// static +void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point) { if (option == 0/*YES*/) { @@ -5930,7 +5950,8 @@ void confirm_replace_attachment(S32 option, void* user_data) delta = delta * 0.5f; walkToSpot -= delta; - gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance); + CallbackData* user_data = new CallbackData(attachment_point, mReplace); // *TODO: leak if the callback isn't called? + gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance); gAgentCamera.clearFocusObject(); } } @@ -8115,7 +8136,8 @@ void initialize_menus() commit.add("Object.Touch", boost::bind(&handle_object_touch)); commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); commit.add("Object.Delete", boost::bind(&handle_object_delete)); - view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar"); + view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar"); + view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar"); view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); -- cgit v1.2.3