Proxy host context menu items for VST3 plugins

This wasn't implemented yet because no plugin tried using the interface
in this way before this, but Surge XT incorporates the host's context
menu items into their own (much more elaborate) context menu. To
accommodate this, we now copy over all of the host's prepopulated
context menu items to the Wine plugin host, and calling the targets
associated with any of those items will cause the target on the
associated context menu item on the host to be called.

This is slightly more complicated than what would otherwise be necessary
because Bitwig does not assign tags to their context menu items and
instead always uses 0.
This commit is contained in:
Robbert van der Helm
2022-01-03 17:04:00 +01:00
parent 89cd1e9ee3
commit c625deadef
16 changed files with 219 additions and 107 deletions
@@ -20,9 +20,8 @@
class Vst3ContextMenuProxyImpl : public Vst3ContextMenuProxy {
public:
Vst3ContextMenuProxyImpl(
Vst3Bridge& bridge,
Vst3ContextMenuProxy::ConstructArgs&& args) noexcept;
Vst3ContextMenuProxyImpl(Vst3Bridge& bridge,
Vst3ContextMenuProxy::ConstructArgs&& args);
/**
* When the reference count reaches zero and this destructor is called,
@@ -52,19 +51,35 @@ class Vst3ContextMenuProxyImpl : public Vst3ContextMenuProxy {
tresult PLUGIN_API popup(Steinberg::UCoord x, Steinberg::UCoord y) override;
/**
* The targets passed when to `addItem` calls made by the plugin. This way
* The targets passed when to `addItem()` calls made by the plugin. This way
* we can call these same targets later. The key here is the item's tag.
*
* If `getItem()` returns a context menu item with a tag that is not in this
* map then it's from an item belonging to the host, and we'll return a
* proxy target that would call the host's target instead.
*/
std::unordered_map<int32,
Steinberg::IPtr<Steinberg::Vst::IContextMenuTarget>>
context_menu_targets_;
plugin_targets_;
private:
Vst3Bridge& bridge_;
/**
* As mentioned above, these are the targets belonging to context items
* prepopulated by the host. Because Bitwig doesn't assign a tag to its own
* context menu items all of these this map is indexed by the **item id**.
* Calling one of these sends a message to the host to call the
* corresponding menu item.
*/
std::unordered_map<int32, Steinberg::IPtr<YaContextMenuTarget>>
host_targets_;
/**
* The items passed when to `addItem` calls made by the plugin. This way we
* can call these same targets later.
*
* This will be initialized with targets created by the host.
*/
std::vector<Steinberg::Vst::IContextMenuItem> items_;
};