diff options
author | Vadim Savchuk <vsavchuk@productengine.com> | 2010-08-06 17:14:01 +0300 |
---|---|---|
committer | Vadim Savchuk <vsavchuk@productengine.com> | 2010-08-06 17:14:01 +0300 |
commit | 5f9f6dcdec0de015e3c9a88afad6f4761c3c6527 (patch) | |
tree | b85dd598af4740146853076e19cc326ac391def8 /indra/newview/llviewermenu.cpp | |
parent | 593a6f0bbf25877f7e3b7482d8644cf34840f923 (diff) |
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
Diffstat (limited to 'indra/newview/llviewermenu.cpp')
-rw-r--r-- | indra/newview/llviewermenu.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
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<CallbackData*>(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"); |