From 5d0df7febe3ed134518f894c626026d3ae0feb39 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Wed, 6 Jan 2021 23:58:05 +0100 Subject: [PATCH] Fully implement IContextMenuTarget --- src/common/logging/vst3.cpp | 1 + src/common/serialization/vst3.h | 1 + .../serialization/vst3/context-menu-proxy.h | 2 +- .../vst3/context-menu-target.cpp | 7 +++-- .../serialization/vst3/context-menu-target.h | 29 ++++++++++++++++++- .../vst3-impls/context-menu-target.cpp | 8 +++-- .../bridges/vst3-impls/context-menu-proxy.cpp | 2 +- .../bridges/vst3-impls/context-menu-proxy.h | 7 +++++ src/wine-host/bridges/vst3.cpp | 8 +++++ 9 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index 7ba21859..703b06da 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -170,6 +170,7 @@ bool Vst3Logger::log_request( const YaContextMenuTarget::ExecuteMenuItem& request) { return log_request_base(is_host_vst, [&](auto& message) { message << request.owner_instance_id << ": ::executeMenuItem(tag = " << request.tag << ")"; }); } diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index 53046055..e80b3eaf 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -74,6 +74,7 @@ using ControlRequest = YaConnectionPoint::Connect, YaConnectionPoint::Disconnect, YaConnectionPoint::Notify, + YaContextMenuTarget::ExecuteMenuItem, YaEditController::SetComponentState, YaEditController::GetParameterCount, YaEditController::GetParameterInfo, diff --git a/src/common/serialization/vst3/context-menu-proxy.h b/src/common/serialization/vst3/context-menu-proxy.h index 872e7ab1..589eb970 100644 --- a/src/common/serialization/vst3/context-menu-proxy.h +++ b/src/common/serialization/vst3/context-menu-proxy.h @@ -129,7 +129,7 @@ class Vst3ContextMenuProxy : public YaContextMenu { } /** - * Get the unique ID for this context menu + * Get the unique ID for this context menu. */ inline size_t context_menu_id() const { return arguments.context_menu_id; } diff --git a/src/common/serialization/vst3/context-menu-target.cpp b/src/common/serialization/vst3/context-menu-target.cpp index 44bc83d2..ab62509f 100644 --- a/src/common/serialization/vst3/context-menu-target.cpp +++ b/src/common/serialization/vst3/context-menu-target.cpp @@ -18,8 +18,11 @@ YaContextMenuTarget::ConstructArgs::ConstructArgs( native_size_t owner_instance_id, - native_size_t context_menu_id) - : owner_instance_id(owner_instance_id), context_menu_id(context_menu_id) {} + native_size_t context_menu_id, + int32 tag) + : owner_instance_id(owner_instance_id), + context_menu_id(context_menu_id), + tag(tag) {} YaContextMenuTarget::YaContextMenuTarget(const ConstructArgs&& args) : arguments(std::move(args)){FUNKNOWN_CTOR} diff --git a/src/common/serialization/vst3/context-menu-target.h b/src/common/serialization/vst3/context-menu-target.h index a637f0ba..3c697aa4 100644 --- a/src/common/serialization/vst3/context-menu-target.h +++ b/src/common/serialization/vst3/context-menu-target.h @@ -47,17 +47,21 @@ class YaContextMenuTarget : public Steinberg::Vst::IContextMenuTarget { * context menu belongs to. * @param context_menu_id The unique ID of the context menu requested by * `owwner_instance_id`. + * @param tag The tag of the menu item this target belongs to. */ ConstructArgs(native_size_t owner_instance_id, - native_size_t context_menu_id); + native_size_t context_menu_id, + int32 tag); native_size_t owner_instance_id; native_size_t context_menu_id; + int32 tag; template void serialize(S& s) { s.value8b(owner_instance_id); s.value8b(context_menu_id); + s.value4b(tag); } }; @@ -71,6 +75,23 @@ class YaContextMenuTarget : public Steinberg::Vst::IContextMenuTarget { DECLARE_FUNKNOWN_METHODS + /** + * Get the instance ID of the owner of this object. + */ + inline size_t owner_instance_id() const { + return arguments.owner_instance_id; + } + + /** + * Get the unique ID for the context menu this target belongs to. + */ + inline size_t context_menu_id() const { return arguments.context_menu_id; } + + /** + * Get the tag of the menu item this target was passed to. + */ + inline int32 target_tag() const { return arguments.tag; } + /* * Message to pass through a call to * `IContextMenuTarget::executeMenuItem(tag)` to the proxied object provided @@ -81,6 +102,11 @@ class YaContextMenuTarget : public Steinberg::Vst::IContextMenuTarget { native_size_t owner_instance_id; native_size_t context_menu_id; + /** + * The tag this target was passed for. This should be the same as `tag`, + * but it doesn't have to be. + */ + int32 target_tag; int32 tag; @@ -88,6 +114,7 @@ class YaContextMenuTarget : public Steinberg::Vst::IContextMenuTarget { void serialize(S& s) { s.value8b(owner_instance_id); s.value8b(context_menu_id); + s.value4b(target_tag); s.value4b(tag); } }; diff --git a/src/plugin/bridges/vst3-impls/context-menu-target.cpp b/src/plugin/bridges/vst3-impls/context-menu-target.cpp index 60ed93f9..fe443bdf 100644 --- a/src/plugin/bridges/vst3-impls/context-menu-target.cpp +++ b/src/plugin/bridges/vst3-impls/context-menu-target.cpp @@ -31,7 +31,9 @@ YaContextMenuTargetImpl::queryInterface(const Steinberg::TUID _iid, } tresult PLUGIN_API YaContextMenuTargetImpl::executeMenuItem(int32 tag) { - // TODO: Implement - bridge.logger.log("TODO: IContextMenuTarget::executeMenuItem()"); - return Steinberg::kNotImplemented; + return bridge.send_message(YaContextMenuTarget::ExecuteMenuItem{ + .owner_instance_id = owner_instance_id(), + .context_menu_id = context_menu_id(), + .target_tag = target_tag(), + .tag = tag}); } diff --git a/src/wine-host/bridges/vst3-impls/context-menu-proxy.cpp b/src/wine-host/bridges/vst3-impls/context-menu-proxy.cpp index fc28d22a..636d4678 100644 --- a/src/wine-host/bridges/vst3-impls/context-menu-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/context-menu-proxy.cpp @@ -47,7 +47,7 @@ Vst3ContextMenuProxyImpl::queryInterface(const Steinberg::TUID _iid, int32 PLUGIN_API Vst3ContextMenuProxyImpl::getItemCount() { // TODO: Implement std::cerr << "TODO: IContextMenu::getItemCount()" << std::endl; - return Steinberg::kNotImplemented; + return 0; } tresult PLUGIN_API Vst3ContextMenuProxyImpl::getItem( diff --git a/src/wine-host/bridges/vst3-impls/context-menu-proxy.h b/src/wine-host/bridges/vst3-impls/context-menu-proxy.h index 9acc2cb5..3b705d62 100644 --- a/src/wine-host/bridges/vst3-impls/context-menu-proxy.h +++ b/src/wine-host/bridges/vst3-impls/context-menu-proxy.h @@ -50,6 +50,13 @@ class Vst3ContextMenuProxyImpl : public Vst3ContextMenuProxy { Steinberg::Vst::IContextMenuTarget* target) override; tresult PLUGIN_API popup(Steinberg::UCoord x, Steinberg::UCoord y) override; + /** + * The targets passed when to `addItem` calls made by the plugin. This way + * we can call these same targets later. + */ + std::map> + context_menu_targets; + private: Vst3Bridge& bridge; }; diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 8d9e880c..9a67003d 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -261,6 +261,14 @@ void Vst3Bridge::run() { .connection_point->notify( request.message_ptr.get_original()); }, + [&](YaContextMenuTarget::ExecuteMenuItem& request) + -> YaContextMenuTarget::ExecuteMenuItem::Response { + return object_instances[request.owner_instance_id] + .registered_context_menus.at(request.context_menu_id) + .get() + .context_menu_targets[request.target_tag] + ->executeMenuItem(request.tag); + }, [&](YaEditController::SetComponentState& request) -> YaEditController::SetComponentState::Response { return object_instances[request.instance_id]