Skip to content

Commit

Permalink
Adding support for context menus.
Browse files Browse the repository at this point in the history
* adding host side context menu functions
* extending the calling structure of plugview
  • Loading branch information
defiantnerd committed Apr 19, 2024
1 parent 5526acb commit 389a9df
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 17 deletions.
71 changes: 65 additions & 6 deletions src/clap_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,23 @@ const clap_host_posix_fd_support hostposixfd = {
const clap_host_latency latency = {[](const clap_host_t* host) -> void
{ self(host)->latency_changed(); }};

const clap_host_state_t state = {[](const clap_host_t* host) -> void { self(host)->mark_dirty(); }};

const clap_host_context_menu_t context_menu = {
/* populate */
[](const clap_host_t* host, const clap_context_menu_target_t* target,
const clap_context_menu_builder_t* builder) -> bool
{ return self(host)->context_menu_populate(target, builder); },
/* perform */
[](const clap_host_t* host, const clap_context_menu_target_t* target, clap_id action_id) -> bool
{ return self(host)->context_menu_perform(target, action_id); },
/* can_popup */
[](const clap_host_t* host) -> bool { return self(host)->context_menu_can_popup(); },
/* popup */
[](const clap_host_t* host, const clap_context_menu_target_t* target, int32_t screen_index,
int32_t x, int32_t y) -> bool
{ return self(host)->context_menu_popup(target, screen_index, x, y); }};

static void tail_changed(const clap_host_t* host)
{
self(host)->tail_changed();
Expand All @@ -119,23 +136,23 @@ const clap_host_tail tail = {tail_changed};

} // namespace HostExt

std::shared_ptr<Plugin> Plugin::createInstance(const clap_plugin_factory* fac, const std::string& id,
std::shared_ptr<Plugin> Plugin::createInstance(const clap_plugin_factory* factory, const std::string& id,
Clap::IHost* host)
{
auto plug = std::shared_ptr<Plugin>(new Plugin(host));
auto instance = fac->create_plugin(fac, plug->getClapHostInterface(), id.c_str());
auto instance = factory->create_plugin(factory, plug->getClapHostInterface(), id.c_str());
plug->connectClap(instance);

return plug;
}

std::shared_ptr<Plugin> Plugin::createInstance(const clap_plugin_factory* fac, size_t idx,
std::shared_ptr<Plugin> Plugin::createInstance(const clap_plugin_factory* factory, size_t idx,
Clap::IHost* host)
{
auto pc = fac->get_plugin_count(fac);
auto pc = factory->get_plugin_count(factory);
if (idx >= pc) return nullptr;
auto desc = fac->get_plugin_descriptor(fac, (uint32_t)idx);
return createInstance(fac, desc->id, host);
auto desc = factory->get_plugin_descriptor(factory, (uint32_t)idx);
return createInstance(factory, desc->id, host);
}

std::shared_ptr<Plugin> Plugin::createInstance(Clap::Library& library, size_t index, IHost* host)
Expand Down Expand Up @@ -195,6 +212,13 @@ void Plugin::connectClap(const clap_plugin_t* clap)
getExtension(_plugin, _ext._tail, CLAP_EXT_TAIL);
getExtension(_plugin, _ext._gui, CLAP_EXT_GUI);
getExtension(_plugin, _ext._timer, CLAP_EXT_TIMER_SUPPORT);

getExtension(_plugin, _ext._contextmenu, CLAP_EXT_CONTEXT_MENU);
if (_ext._contextmenu == nullptr)
{
getExtension(_plugin, _ext._contextmenu, CLAP_EXT_CONTEXT_MENU_COMPAT);
}

#if LIN
getExtension(_plugin, _ext._posixfd, CLAP_EXT_POSIX_FD_SUPPORT);
#endif
Expand Down Expand Up @@ -331,6 +355,11 @@ const clap_plugin_gui_t* Plugin::getUI() const
return nullptr;
}

void Plugin::mark_dirty()
{
_parentHost->mark_dirty();
}

void Plugin::latency_changed()
{
_parentHost->latency_changed();
Expand All @@ -341,6 +370,34 @@ void Plugin::tail_changed()
_parentHost->tail_changed();
}

bool Plugin::context_menu_populate(const clap_context_menu_target_t* target,
const clap_context_menu_builder_t* builder)
{
if (_parentHost->supportsContextMenu())
{
return this->_parentHost->context_menu_populate(target, builder);
}

// don't interfere with the context menu building
return true;
}

bool Plugin::context_menu_perform(const clap_context_menu_target_t* target, clap_id action_id)
{
return this->_parentHost->context_menu_perform(target, action_id);
}

bool Plugin::context_menu_can_popup()
{
return this->_parentHost->supportsContextMenu();
}

bool Plugin::context_menu_popup(const clap_context_menu_target_t* target, int32_t screen_index,
int32_t x, int32_t y)
{
return this->_parentHost->context_menu_popup(target, screen_index, x, y);
}

void Plugin::log(clap_log_severity severity, const char* msg)
{
std::string n;
Expand Down Expand Up @@ -448,6 +505,8 @@ const void* Plugin::clapExtension(const clap_host* /*host*/, const char* extensi
{
// TODO: implement CLAP_EXT_RENDER
}
if (!strcmp(extension, CLAP_EXT_STATE)) return &HostExt::state;
if (!strcmp(extension, CLAP_EXT_CONTEXT_MENU)) return &HostExt::context_menu;

return nullptr;
}
Expand Down
45 changes: 45 additions & 0 deletions src/clap_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,39 @@ class IHost

virtual const char* host_get_name() = 0;

// context menu

// actually, everything here should be virtual only, but until all wrappers are updated,
// IHost provides default implementations.

virtual bool supportsContextMenu() const
{
return false;
}

virtual bool context_menu_populate(const clap_context_menu_target_t* target,
const clap_context_menu_builder_t* builder)
{
return false;
}

virtual bool context_menu_perform(const clap_context_menu_target_t* target, clap_id action_id)
{
return false;
}

virtual bool context_menu_can_popup()
{
return false;
}

virtual bool context_menu_popup(const clap_context_menu_target_t* target, int32_t screen_index,
int32_t x, int32_t y)
{
return false;
}


#if LIN
virtual bool register_fd(int fd, clap_posix_fd_flags_t flags) = 0;
virtual bool modify_fd(int fd, clap_posix_fd_flags_t flags) = 0;
Expand Down Expand Up @@ -98,6 +131,7 @@ struct ClapPluginExtensions
const clap_plugin_render_t* _render = nullptr;
const clap_plugin_tail_t* _tail = nullptr;
const clap_plugin_timer_support_t* _timer = nullptr;
const clap_plugin_context_menu_t* _contextmenu = nullptr;
#if LIN
const clap_plugin_posix_fd_support* _posixfd = nullptr;
#endif
Expand Down Expand Up @@ -179,12 +213,23 @@ class Plugin
void param_clear(clap_id param, clap_param_clear_flags flags);
void param_request_flush();

// state
void mark_dirty();

// latency
void latency_changed();

// tail
void tail_changed();

// context_menu
bool context_menu_populate(const clap_context_menu_target_t* target,
const clap_context_menu_builder_t* builder);
bool context_menu_perform(const clap_context_menu_target_t* target, clap_id action_id);
bool context_menu_can_popup();
bool context_menu_popup(const clap_context_menu_target_t* target, int32_t screen_index,
int32_t x, int32_t y);

// hostgui
void resize_hints_changed()
{
Expand Down
20 changes: 13 additions & 7 deletions src/detail/vst3/plugview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@
#include <cassert>

WrappedView::WrappedView(const clap_plugin_t* plugin, const clap_plugin_gui_t* gui,
std::function<void()> onDestroy, std::function<void()> onRunLoopAvailable)
std::function<void()> onRemoved, std::function<void()> onDestroy,
std::function<void()> onRunLoopAvailable)
: IPlugView()
, FObject()
, _plugin(plugin)
, _extgui(gui)
, _onRemoved(onRemoved)
, _onDestroy(onDestroy)
, _onRunLoopAvailable(onRunLoopAvailable)
{
}

WrappedView::~WrappedView()
{
if (_onDestroy)
{
_onDestroy();
}
drop_ui();
}

Expand Down Expand Up @@ -47,9 +45,13 @@ void WrappedView::drop_ui()
{
if (_created)
{
_created = false;
_attached = false;
if (_onDestroy)
{
_onDestroy();
}
_extgui->destroy(_plugin);
_created = false;
}
}

Expand Down Expand Up @@ -113,7 +115,11 @@ tresult PLUGIN_API WrappedView::attached(void* parent, FIDString /*type*/)

tresult PLUGIN_API WrappedView::removed()
{
drop_ui();
if (_onRemoved)
{
_onRemoved();
}
_attached = false;
_window.ptr = nullptr;
return kResultOk;
}
Expand Down
4 changes: 2 additions & 2 deletions src/detail/vst3/plugview.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace Steinberg;
class WrappedView : public Steinberg::IPlugView, public Steinberg::FObject
{
public:
WrappedView(const clap_plugin_t* plugin, const clap_plugin_gui_t* gui, std::function<void()> onDestroy,
WrappedView(const clap_plugin_t* plugin, const clap_plugin_gui_t* gui, std::function<void()> onRemoved, std::function<void()> onDestroy,
std::function<void()> onRunLoopAvailable);
~WrappedView();

Expand Down Expand Up @@ -92,7 +92,7 @@ class WrappedView : public Steinberg::IPlugView, public Steinberg::FObject
void drop_ui();
const clap_plugin_t* _plugin = nullptr;
const clap_plugin_gui_t* _extgui = nullptr;
std::function<void()> _onDestroy = nullptr, _onRunLoopAvailable = nullptr;
std::function<void()> _onRemoved = nullptr, _onDestroy = nullptr, _onRunLoopAvailable = nullptr;
clap_window_t _window = {nullptr, {nullptr}};
IPlugFrame* _plugFrame = nullptr;
ViewRect _rect = {0, 0, 0, 0};
Expand Down
Loading

0 comments on commit 389a9df

Please sign in to comment.