diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index a2a38d5593..e263a7be2c 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -89,6 +89,7 @@ #include "gtkmm2ext/application.h" #include "gtkmm2ext/bindings.h" +#include "gtkmm2ext/doi.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/window_title.h" @@ -108,6 +109,7 @@ #include "ardour/filename_extensions.h" #include "ardour/filesystem_paths.h" #include "ardour/ltc_file_reader.h" +#include "ardour/lv2_plugin.h" #include "ardour/monitor_control.h" #include "ardour/midi_track.h" #include "ardour/port.h" @@ -174,6 +176,7 @@ #include "location_ui.h" #include "lua_script_manager.h" #include "luawindow.h" +#include "lv2_plugin_ui.h" #include "main_clock.h" #include "missing_file_dialog.h" #include "missing_plugin_dialog.h" @@ -437,6 +440,11 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dialog, this, _1), gui_context()); +#ifdef HAVE_LV2_1_17_2 + ARDOUR::LV2Plugin::Request.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::lv2_plugin_request, this, _1, _2, _3, _4), gui_context()); + LV2PluginUI::CatchDeletion.connect_same_thread (forever_connections, boost::bind (&delete_when_idle, _1)); +#endif + /* handle pending state with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */ ARDOUR::Session::AskAboutPendingState.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::pending_state_dialog, this)); diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 72ed532344..ebed6a8c01 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -72,6 +72,9 @@ #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/visibility_tracker.h" +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" + #include "ardour/ardour.h" #include "ardour/types.h" #include "ardour/utils.h" @@ -177,6 +180,7 @@ namespace ARDOUR { class Route; class RouteGroup; class Location; + class PluginInsert; class ProcessThread; } @@ -236,6 +240,8 @@ public: bool ask_about_loading_existing_session (const std::string& session_path); int load_session_from_startup_fsm (); + void lv2_plugin_request (boost::weak_ptr, LV2_URID, LV2_URID, LV2_Feature const* const*); + /// @return true if session was successfully unloaded. int unload_session (bool hide_stuff = false); void close_session(); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index f026242f50..993ce2f1b7 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -40,6 +40,8 @@ #include "ardour/audioengine.h" #include "ardour/automation_watch.h" #include "ardour/control_protocol_manager.h" +#include "ardour/lv2_plugin.h" +#include "ardour/plugin_insert.h" #include "ardour/profile.h" #include "ardour/session.h" @@ -63,6 +65,7 @@ #include "location_ui.h" #include "lua_script_manager.h" #include "luawindow.h" +#include "lv2_plugin_ui.h" #include "main_clock.h" #include "meterbridge.h" #include "meter_patterns.h" @@ -1034,6 +1037,25 @@ ARDOUR_UI::show_plugin_manager () tact->set_active(); } +void +ARDOUR_UI::lv2_plugin_request (boost::weak_ptr wi, LV2_URID key, LV2_URID type, LV2_Feature const* const* features) +{ +#ifdef HAVE_LV2_1_17_2 + boost::shared_ptr insert = wi.lock (); + if (!insert) { + return; + } + boost::shared_ptr vp = boost::dynamic_pointer_cast (insert->plugin()); + if (!vp) { + return; + } + LV2PluginUI* lpu = new LV2PluginUI (insert, vp); + if (LV2PluginUI::request_value (lpu, key, type, features) != LV2UI_REQUEST_VALUE_SUCCESS) { + delete lpu; + } +#endif +} + bool ARDOUR_UI::timecode_button_press (GdkEventButton* ev) { diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index b205c8ccbc..dbb3973b52 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -25,17 +25,18 @@ #include +#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" + #include "ardour/lv2_plugin.h" #include "ardour/session.h" #include "pbd/error.h" +#include "gtkmm2ext/utils.h" + #include "gui_thread.h" #include "lv2_plugin_ui.h" #include "timers.h" - -#include "gtkmm2ext/utils.h" - -#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" +#include "ardour_message.h" #include #include @@ -48,6 +49,10 @@ using namespace PBD; #define NS_UI "http://lv2plug.in/ns/extensions/ui#" +#ifdef HAVE_LV2_1_17_2 +PBD::Signal1 LV2PluginUI::CatchDeletion; +#endif + static SuilHost* ui_host = NULL; void @@ -121,24 +126,31 @@ LV2PluginUI::touch(void* controller, } } +#ifdef HAVE_LV2_1_17_2 + void -LV2PluginUI::set_path_property (int response, - const ParameterDescriptor& desc, - Gtk::FileChooserDialog* widget) +LV2PluginUI::request_response (int response, + const ParameterDescriptor& desc, + Gtk::Widget* widget) { - if (response == Gtk::RESPONSE_ACCEPT) { - plugin->set_property (desc.key, Variant (Variant::PATH, widget->get_filename())); + switch (desc.datatype) { + case Variant::PATH: + if (response == Gtk::RESPONSE_ACCEPT) { + set_path_property (desc.key, Variant (Variant::PATH, dynamic_cast (widget)->get_filename ())); + } + break; + case Variant::BOOL: + set_path_property (desc.key, Variant (Variant::BOOL, response == Gtk::RESPONSE_YES)); + break; + default: + break; } -#if 0 - widget->hide (); - delete_when_idle (widget); -#else + delete widget; -#endif - active_parameter_requests.erase (desc.key); + _active_parameter_requests.erase (desc.key); + CatchDeletion (this); /* EMIT SIGNAL */ } -#ifdef HAVE_LV2_1_17_2 LV2UI_Request_Value_Status LV2PluginUI::request_value(void* handle, LV2_URID key, @@ -150,39 +162,62 @@ LV2PluginUI::request_value(void* handle, const ParameterDescriptor& desc (me->_lv2->get_property_descriptor(key)); if (desc.key == (uint32_t)-1) { return LV2UI_REQUEST_VALUE_ERR_UNKNOWN; - } else if (desc.datatype != Variant::PATH) { - return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; - } else if (me->active_parameter_requests.count (key)) { + } else if (me->_active_parameter_requests.count (key)) { return LV2UI_REQUEST_VALUE_BUSY; } - me->active_parameter_requests.insert (key); - Gtk::FileChooserDialog* lv2ui_file_dialog = new Gtk::FileChooserDialog(desc.label, FILE_CHOOSER_ACTION_OPEN); - Gtkmm2ext::add_volume_shortcuts (*lv2ui_file_dialog); - lv2ui_file_dialog->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - lv2ui_file_dialog->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT); - lv2ui_file_dialog->set_default_response(Gtk::RESPONSE_ACCEPT); + me->_active_parameter_requests.insert (key); - /* this assumes announce_property_values() was called, or - * the plugin has previously sent a patch:Set */ - const Variant& value = me->_lv2->get_property_value (desc.key); - if (value.type() == Variant::PATH) { - lv2ui_file_dialog->set_filename (value.get_path()); - } + switch (desc.datatype) { + case Variant::PATH: + { + Gtk::FileChooserDialog* lv2ui_file_dialog = new Gtk::FileChooserDialog(desc.label, FILE_CHOOSER_ACTION_OPEN); + Gtkmm2ext::add_volume_shortcuts (*lv2ui_file_dialog); + lv2ui_file_dialog->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + lv2ui_file_dialog->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT); + lv2ui_file_dialog->set_default_response(Gtk::RESPONSE_ACCEPT); + + /* this assumes announce_property_values() was called, or + * the plugin has previously sent a patch:Set */ + const Variant& value = me->_lv2->get_property_value (desc.key); + if (value.type() == Variant::PATH) { + lv2ui_file_dialog->set_filename (value.get_path()); + } #if 0 // TODO mime-type, file-extension filter, get from LV2 Parameter Property - FileFilter file_ext_filter; - file_ext_filter.add_pattern ("*.foo"); - file_ext_filter.set_name ("Foo File"); - lv2ui_file_dialog.add_filter (file_ext_filter); + FileFilter file_ext_filter; + file_ext_filter.add_pattern ("*.foo"); + file_ext_filter.set_name ("Foo File"); + lv2ui_file_dialog.add_filter (file_ext_filter); #endif + lv2ui_file_dialog->signal_response().connect (sigc::bind (sigc::mem_fun (*me, &LV2PluginUI::request_response), desc, lv2ui_file_dialog)); + lv2ui_file_dialog->present(); + } + break; + + case Variant::BOOL: + { + ArdourMessageDialog* msg = new ArdourMessageDialog (desc.label, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, false); + msg->signal_response().connect (sigc::bind (sigc::mem_fun (*me, &LV2PluginUI::request_response), desc, msg)); + msg->present(); + } + break; + + default: + me->_active_parameter_requests.erase (key); + return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; + } - lv2ui_file_dialog->signal_response().connect (sigc::bind (sigc::mem_fun (*me, &LV2PluginUI::set_path_property), desc, lv2ui_file_dialog)); - lv2ui_file_dialog->present(); return LV2UI_REQUEST_VALUE_SUCCESS; } #endif +void +LV2PluginUI::set_path_property (const uint32_t key, ARDOUR::Variant const& val) +{ + plugin->set_property (key, val); +} + void LV2PluginUI::update_timeout() { diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h index 74d30148b3..45d33a83bc 100644 --- a/gtk2_ardour/lv2_plugin_ui.h +++ b/gtk2_ardour/lv2_plugin_ui.h @@ -66,6 +66,16 @@ public: int package (Gtk::Window&); void grab_focus (); +#ifdef HAVE_LV2_1_17_2 + static LV2UI_Request_Value_Status + request_value(void* handle, + LV2_URID key, + LV2_URID type, + const LV2_Feature* const* features); + + static PBD::Signal1 CatchDeletion; +#endif + private: void control_changed (uint32_t); @@ -88,6 +98,7 @@ private: #ifdef HAVE_LV2_1_17_2 LV2UI_Request_Value _lv2ui_request_value; LV2_Feature _lv2ui_request_feature; + std::set _active_parameter_requests; #endif struct lv2_external_ui* _external_ui_ptr; LV2_Feature _parent_feature; @@ -115,18 +126,14 @@ private: uint32_t port_index, bool grabbed); + void set_path_property (const uint32_t key, ARDOUR::Variant const&); + #ifdef HAVE_LV2_1_17_2 - static LV2UI_Request_Value_Status - request_value(void* handle, - LV2_URID key, - LV2_URID type, - const LV2_Feature* const* features); + void request_response (int, + ARDOUR::ParameterDescriptor const&, + Gtk::Widget*); #endif - void set_path_property (int, - const ARDOUR::ParameterDescriptor&, - Gtk::FileChooserDialog*); - std::set active_parameter_requests; void update_timeout();