diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index fc73b9b748..187b87b44f 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -403,6 +403,7 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) HBox* smaller_hbox = manage (new HBox); smaller_hbox->set_spacing (6); + smaller_hbox->pack_start (modulate_script_button, false, false, 4); smaller_hbox->pack_start (pin_management_button, false, false, 4); smaller_hbox->pack_start (preset_label, false, false, 4); smaller_hbox->pack_start (_preset_modified, false, false); diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 066aa95fa8..e90eec04cf 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -87,6 +87,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol set_latency_label (); smaller_hbox->pack_start (latency_button, false, false, 4); + smaller_hbox->pack_start (modulate_script_button, false, false, 4); smaller_hbox->pack_start (pin_management_button, false, false, 4); smaller_hbox->pack_start (_preset_combo, false, false); smaller_hbox->pack_start (_preset_modified, false, false); diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index 7f735dfcc5..0d15dfd806 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -242,6 +242,7 @@ LV2PluginUI::LV2PluginUI(boost::shared_ptr pi, _ardour_buttons_box.pack_end (_preset_combo, false, false); _ardour_buttons_box.pack_end (_preset_modified, false, false); _ardour_buttons_box.pack_end (pin_management_button, false, false); + _ardour_buttons_box.pack_end (modulate_script_button, false, false); plugin->PresetLoaded.connect (*this, invalidator (*this), boost::bind (&LV2PluginUI::queue_port_update, this), gui_context ()); } diff --git a/gtk2_ardour/plugin_modulate_script_dialog.cc b/gtk2_ardour/plugin_modulate_script_dialog.cc new file mode 100644 index 0000000000..381028f26e --- /dev/null +++ b/gtk2_ardour/plugin_modulate_script_dialog.cc @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2016 Robin Gareus + * Copyright (C) 2011 Paul Davis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pbd/compose.h" + +#include "gtkmm2ext/gui_thread.h" + +#include "plugin_modulate_script_dialog.h" + +#include "pbd/i18n.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace Gtk; + +PluginModulateScriptDialog::PluginModulateScriptDialog (boost::shared_ptr pi) + : ArdourWindow (string_compose (_("Modulate %1"), pi->name())) + , _pi (pi) + , _set_button (_("Set Script")) + , _read_button (_("Read Active Script")) + , _clear_button (_("Remove Script")) +{ + Gtk::ScrolledWindow *scrollin = manage (new Gtk::ScrolledWindow); + scrollin->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scrollin->add (entry); + + Gtk::HBox *hbox = manage (new HBox()); + hbox->pack_start (_set_button, false, false, 2); + hbox->pack_start (_read_button, false, false, 2); + hbox->pack_start (_clear_button, false, false, 2); + hbox->pack_end (_status, false, false, 2); + + vbox.pack_start (*scrollin, true, true, 0); + vbox.pack_start (*hbox, false, false, 2); + add (vbox); + + set_size_request (640, 480); // XXX + + _set_button.signal_clicked.connect (sigc::mem_fun(*this, &PluginModulateScriptDialog::set_script)); + _read_button.signal_clicked.connect (sigc::mem_fun(*this, &PluginModulateScriptDialog::read_script)); + _clear_button.signal_clicked.connect (sigc::mem_fun(*this, &PluginModulateScriptDialog::unload_script)); + + + _pi->ModulationScriptChanged.connect ( + _plugin_connection, invalidator (*this), boost::bind (&PluginModulateScriptDialog::script_changed, this), gui_context () + ); + + read_script (); + script_changed (); +} + +PluginModulateScriptDialog::~PluginModulateScriptDialog () +{ +} + +void +PluginModulateScriptDialog::script_changed () +{ + if (_pi->modulation_script_loaded ()) { + _read_button.set_sensitive (true); + _clear_button.set_sensitive (true); + _status.set_text (_("Status: running")); + } else { + _read_button.set_sensitive (false); + _clear_button.set_sensitive (false); + _status.set_text (_("Status: inactive")); + } +} + +void +PluginModulateScriptDialog::read_script () +{ + Glib::RefPtr tb (entry.get_buffer()); + tb->set_text (_pi->modulation_script ()); +} + +void +PluginModulateScriptDialog::set_script () +{ + Glib::RefPtr tb (entry.get_buffer()); + std::string script = tb->get_text(); + if (!_pi->load_modulation_script (script)) { + Gtk::MessageDialog msg (*this, _("Loading the Script failed. Check syntax")); + msg.run(); + } +} + +void +PluginModulateScriptDialog::unload_script () +{ + _pi->unload_modulation_script (); +} + +/* ***************************************************************************/ + + +PluginModulateScriptProxy::PluginModulateScriptProxy(std::string const &name, boost::weak_ptr pi) + : WM::ProxyBase (name, std::string()) + , _pi (pi) +{ + boost::shared_ptr p = _pi.lock (); + if (!p) { + return; + } + p->DropReferences.connect (going_away_connection, MISSING_INVALIDATOR, boost::bind (&PluginModulateScriptProxy::processor_going_away, this), gui_context()); +} + +PluginModulateScriptProxy::~PluginModulateScriptProxy() +{ + _window = 0; +} + +ARDOUR::SessionHandlePtr* +PluginModulateScriptProxy::session_handle () +{ + ArdourWindow* aw = dynamic_cast (_window); + if (aw) { return aw; } + return 0; +} + +Gtk::Window* +PluginModulateScriptProxy::get (bool create) +{ + boost::shared_ptr pi = _pi.lock (); + if (!pi) { + return 0; + } + + if (!_window) { + if (!create) { + return 0; + } + _window = new PluginModulateScriptDialog (pi); + ArdourWindow* aw = dynamic_cast (_window); + if (aw) { + aw->set_session (_session); + } + _window->show_all (); + } + return _window; +} + +void +PluginModulateScriptProxy::processor_going_away () +{ + delete _window; + _window = 0; + WM::Manager::instance().remove (this); + going_away_connection.disconnect(); + delete this; +} diff --git a/gtk2_ardour/plugin_modulate_script_dialog.h b/gtk2_ardour/plugin_modulate_script_dialog.h new file mode 100644 index 0000000000..9ec8f3eb24 --- /dev/null +++ b/gtk2_ardour/plugin_modulate_script_dialog.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016 Robin Gareus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __gtkardour_modulate_script_dialog_h__ +#define __gtkardour_modulate_script_dialog_h__ + +#include "ardour/plugin_insert.h" + +#include +#include + +#include "ardour_button.h" +#include "ardour_window.h" +#include "window_manager.h" + +class PluginModulateScriptDialog : public ArdourWindow +{ +public: + PluginModulateScriptDialog (boost::shared_ptr); + ~PluginModulateScriptDialog (); + +private: + boost::shared_ptr _pi; + + ArdourButton _set_button; + ArdourButton _read_button; + ArdourButton _clear_button; + + Gtk::TextView entry; + Gtk::VBox vbox; + Gtk::Label _status; + + PBD::ScopedConnection _plugin_connection; + + void script_changed (); + void read_script (); + void set_script (); + void unload_script (); +}; + +class PluginModulateScriptProxy : public WM::ProxyBase +{ + public: + PluginModulateScriptProxy (std::string const&, boost::weak_ptr); + ~PluginModulateScriptProxy(); + + Gtk::Window* get (bool create = false); + ARDOUR::SessionHandlePtr* session_handle(); + + private: + boost::weak_ptr _pi; + + void processor_going_away (); + PBD::ScopedConnection going_away_connection; +}; + +#endif diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 15600772e2..1071c38a4c 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -72,6 +72,7 @@ #include "keyboard.h" #include "latency_gui.h" #include "plugin_eq_gui.h" +#include "plugin_modulate_script_dialog.h" #include "new_plugin_preset_dialog.h" #include "tooltips.h" @@ -459,6 +460,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr pi) , reset_button (_("Reset")) , bypass_button (ArdourButton::led_default_elements) , pin_management_button (_("Pinout")) + , modulate_script_button (_("Modulate")) , description_expander (_("Description")) , plugin_analysis_expander (_("Plugin analysis")) , latency_gui (0) @@ -473,6 +475,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr pi) set_tooltip (delete_button, _("Delete the current preset")); set_tooltip (reset_button, _("Reset parameters to default (if no parameters are in automation play mode)")); set_tooltip (pin_management_button, _("Show Plugin Pin Management Dialog")); + set_tooltip (modulate_script_button, _("Set a Lua script to modulate controls")); set_tooltip (bypass_button, _("Disable signal processing by the plugin")); _no_load_preset = 0; @@ -493,6 +496,8 @@ PlugUIBase::PlugUIBase (boost::shared_ptr pi) pin_management_button.set_name ("generic button"); pin_management_button.signal_clicked.connect (sigc::mem_fun (*this, &PlugUIBase::manage_pins)); + modulate_script_button.set_name ("generic button"); + modulate_script_button.signal_clicked.connect (sigc::mem_fun (*this, &PlugUIBase::modulate_it)); insert->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&PlugUIBase::processor_active_changed, this, boost::weak_ptr(insert)), gui_context()); @@ -711,6 +716,27 @@ PlugUIBase::manage_pins () } } +void +PlugUIBase::modulate_it () +{ + PluginModulateScriptProxy* proxy = insert->modscript_proxy (); + + if (!proxy) { + proxy = new PluginModulateScriptProxy (string_compose ("MM-%2-%3", insert->id()), insert); + proxy->set_session (&insert->session()); + const XMLNode* ui_xml = insert->session().extra_xml (X_("UI")); + if (ui_xml) { + proxy->set_state (*ui_xml, 0); + } + insert->set_modscript_proxy (proxy); + WM::Manager::instance().register_window (proxy); + } + + proxy->get (true); + proxy->present (); + proxy->get ()->raise(); +} + bool PlugUIBase::bypass_button_release (GdkEventButton*) { diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index ad800e284d..5cd7020651 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -132,6 +132,8 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL ArdourButton bypass_button; /** and self-explaining button :) */ ArdourButton pin_management_button; + /** re/set modulation script */ + ArdourButton modulate_script_button; /** a button to acquire keyboard focus */ Gtk::EventBox focus_button; /** an expander containing the plugin description */ @@ -166,6 +168,7 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL void delete_plugin_setting (); void reset_plugin_parameters (); void manage_pins (); + void modulate_it (); bool focus_toggled(GdkEventButton*); bool bypass_button_release(GdkEventButton*); void toggle_description (); diff --git a/gtk2_ardour/vst_plugin_ui.cc b/gtk2_ardour/vst_plugin_ui.cc index 532fcf6722..259b4d3ed7 100644 --- a/gtk2_ardour/vst_plugin_ui.cc +++ b/gtk2_ardour/vst_plugin_ui.cc @@ -47,6 +47,7 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr insert, boost: box->pack_end (_preset_combo, false, false); box->pack_end (_preset_modified, false, false); box->pack_end (pin_management_button, false, false); + box->pack_end (modulate_script_button, false, false); bypass_button.set_active (!insert->active ()); diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 2e3ff2e6be..94089c7d52 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -186,6 +186,7 @@ gtk2_ardour_sources = [ 'pingback.cc', 'playlist_selector.cc', 'plugin_eq_gui.cc', + 'plugin_modulate_script_dialog.cc', 'plugin_pin_dialog.cc', 'plugin_setup_dialog.cc', 'plugin_selector.cc',