mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Fully implement IContextMenu
Although all of this stuff is completely untested, and since no host on Linux uses it we'll likely never know whether this implementation is correct.
This commit is contained in:
@@ -193,6 +193,7 @@ if with_vst3
|
|||||||
'src/common/serialization/vst3/component-handler-proxy.cpp',
|
'src/common/serialization/vst3/component-handler-proxy.cpp',
|
||||||
'src/common/serialization/vst3/connection-point-proxy.cpp',
|
'src/common/serialization/vst3/connection-point-proxy.cpp',
|
||||||
'src/common/serialization/vst3/context-menu-proxy.cpp',
|
'src/common/serialization/vst3/context-menu-proxy.cpp',
|
||||||
|
'src/common/serialization/vst3/context-menu-target.cpp',
|
||||||
'src/common/serialization/vst3/event-list.cpp',
|
'src/common/serialization/vst3/event-list.cpp',
|
||||||
'src/common/serialization/vst3/host-context-proxy.cpp',
|
'src/common/serialization/vst3/host-context-proxy.cpp',
|
||||||
'src/common/serialization/vst3/message.cpp',
|
'src/common/serialization/vst3/message.cpp',
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ for more information on how the serialization works.
|
|||||||
|
|
||||||
The following interfaces are not yet implemented:
|
The following interfaces are not yet implemented:
|
||||||
|
|
||||||
- Every interface introduced after VST 3.1.0 with the exception of
|
- Every interface introduced after VST 3.1.0, although most of the VST 3.5.0
|
||||||
`INoteExpressionController` which has already been implemented
|
interfaces have already been implemented
|
||||||
- The [Presonus extensions](https://presonussoftware.com/en_US/developer),
|
- The [Presonus extensions](https://presonussoftware.com/en_US/developer),
|
||||||
although most of these things seem to overlap with newer VST3 interfaces
|
although most of these things seem to overlap with newer VST3 interfaces
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class YaContextMenu : public Steinberg::Vst::IContextMenu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual tresult PLUGIN_API
|
virtual tresult PLUGIN_API
|
||||||
removeItem(const Item& item,
|
removeItem(const Steinberg::Vst::IContextMenuItem& item,
|
||||||
Steinberg::Vst::IContextMenuTarget* target) override = 0;
|
Steinberg::Vst::IContextMenuTarget* target) override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,39 +45,76 @@ Vst3ContextMenuProxyImpl::queryInterface(const Steinberg::TUID _iid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 PLUGIN_API Vst3ContextMenuProxyImpl::getItemCount() {
|
int32 PLUGIN_API Vst3ContextMenuProxyImpl::getItemCount() {
|
||||||
// TODO: Implement
|
return bridge.send_message(
|
||||||
std::cerr << "TODO: IContextMenu::getItemCount()" << std::endl;
|
YaContextMenu::GetItemCount{.owner_instance_id = owner_instance_id(),
|
||||||
return 0;
|
.context_menu_id = context_menu_id()});
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API Vst3ContextMenuProxyImpl::getItem(
|
tresult PLUGIN_API Vst3ContextMenuProxyImpl::getItem(
|
||||||
int32 index,
|
int32 index,
|
||||||
Steinberg::Vst::IContextMenuItem& item /*out*/,
|
Steinberg::Vst::IContextMenuItem& item /*out*/,
|
||||||
Steinberg::Vst::IContextMenuTarget** target /*out*/) {
|
Steinberg::Vst::IContextMenuTarget** target /*out*/) {
|
||||||
// TODO: Implement
|
// XXX: Should the plugin be able to get targets created by the host this
|
||||||
std::cerr << "TODO: IContextMenu::getItem()" << std::endl;
|
// way? We'll just assume that this function won't ever be called by
|
||||||
return Steinberg::kNotImplemented;
|
// the plugin (but we'll implement a basic version anyways).
|
||||||
|
if (index < 0 || index >= static_cast<int32>(items.size())) {
|
||||||
|
return Steinberg::kInvalidArgument;
|
||||||
|
} else {
|
||||||
|
item = items[index];
|
||||||
|
*target = context_menu_targets[item.tag];
|
||||||
|
|
||||||
|
return Steinberg::kResultOk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API
|
tresult PLUGIN_API
|
||||||
Vst3ContextMenuProxyImpl::addItem(const Steinberg::Vst::IContextMenuItem& item,
|
Vst3ContextMenuProxyImpl::addItem(const Steinberg::Vst::IContextMenuItem& item,
|
||||||
Steinberg::Vst::IContextMenuTarget* target) {
|
Steinberg::Vst::IContextMenuTarget* target) {
|
||||||
// TODO: Implement
|
const tresult result = bridge.send_message(YaContextMenu::AddItem{
|
||||||
std::cerr << "TODO: IContextMenu::addItem()" << std::endl;
|
.owner_instance_id = owner_instance_id(),
|
||||||
return Steinberg::kNotImplemented;
|
.context_menu_id = context_menu_id(),
|
||||||
|
.item = item,
|
||||||
|
.target =
|
||||||
|
(target ? std::make_optional<YaContextMenuTarget::ConstructArgs>(
|
||||||
|
owner_instance_id(), context_menu_id(), item.tag)
|
||||||
|
: std::nullopt)});
|
||||||
|
|
||||||
|
if (result == Steinberg::kResultOk) {
|
||||||
|
items.push_back(item);
|
||||||
|
context_menu_targets[item.tag] = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API Vst3ContextMenuProxyImpl::removeItem(
|
tresult PLUGIN_API Vst3ContextMenuProxyImpl::removeItem(
|
||||||
const Item& item,
|
const Steinberg::Vst::IContextMenuItem& item,
|
||||||
Steinberg::Vst::IContextMenuTarget* target) {
|
Steinberg::Vst::IContextMenuTarget* /*target*/) {
|
||||||
// TODO: Implement
|
const tresult result = bridge.send_message(
|
||||||
std::cerr << "TODO: IContextMenu::removeItem()" << std::endl;
|
YaContextMenu::RemoveItem{.owner_instance_id = owner_instance_id(),
|
||||||
return Steinberg::kNotImplemented;
|
.context_menu_id = context_menu_id(),
|
||||||
|
.item = item});
|
||||||
|
|
||||||
|
if (result == Steinberg::kResultOk) {
|
||||||
|
items.erase(
|
||||||
|
std::remove_if(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
[&](const Steinberg::Vst::IContextMenuItem& candidate_item) {
|
||||||
|
// They didn't implement `operator==` on the struct
|
||||||
|
return candidate_item.tag == item.tag;
|
||||||
|
}),
|
||||||
|
items.end());
|
||||||
|
context_menu_targets.erase(item.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API Vst3ContextMenuProxyImpl::popup(Steinberg::UCoord x,
|
tresult PLUGIN_API Vst3ContextMenuProxyImpl::popup(Steinberg::UCoord x,
|
||||||
Steinberg::UCoord y) {
|
Steinberg::UCoord y) {
|
||||||
// TODO: Implement
|
return bridge.send_message(
|
||||||
std::cerr << "TODO: IContextMenu::popup()" << std::endl;
|
YaContextMenu::Popup{.owner_instance_id = owner_instance_id(),
|
||||||
return Steinberg::kNotImplemented;
|
.context_menu_id = context_menu_id(),
|
||||||
|
.x = x,
|
||||||
|
.y = y});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,17 +46,23 @@ class Vst3ContextMenuProxyImpl : public Vst3ContextMenuProxy {
|
|||||||
addItem(const Steinberg::Vst::IContextMenuItem& item,
|
addItem(const Steinberg::Vst::IContextMenuItem& item,
|
||||||
Steinberg::Vst::IContextMenuTarget* target) override;
|
Steinberg::Vst::IContextMenuTarget* target) override;
|
||||||
tresult PLUGIN_API
|
tresult PLUGIN_API
|
||||||
removeItem(const Item& item,
|
removeItem(const Steinberg::Vst::IContextMenuItem& item,
|
||||||
Steinberg::Vst::IContextMenuTarget* target) override;
|
Steinberg::Vst::IContextMenuTarget* target) override;
|
||||||
tresult PLUGIN_API popup(Steinberg::UCoord x, Steinberg::UCoord y) 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
|
* The targets passed when to `addItem` calls made by the plugin. This way
|
||||||
* we can call these same targets later.
|
* we can call these same targets later. The key here is the item's tag.
|
||||||
*/
|
*/
|
||||||
std::map<int32, Steinberg::IPtr<Steinberg::Vst::IContextMenuTarget>>
|
std::map<int32, Steinberg::IPtr<Steinberg::Vst::IContextMenuTarget>>
|
||||||
context_menu_targets;
|
context_menu_targets;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vst3Bridge& bridge;
|
Vst3Bridge& bridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The items passed when to `addItem` calls made by the plugin. This way we
|
||||||
|
* can call these same targets later.
|
||||||
|
*/
|
||||||
|
std::vector<Steinberg::Vst::IContextMenuItem> items;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user