diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index e6e4d1328f..5fad03a1c1 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -537,6 +537,7 @@ + diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 3ed9352755..e7ba8d70bd 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -74,7 +74,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol set_border_width (10); //set_homogeneous (false); - pack_start (main_contents, false, false); + pack_start (main_contents, true, true); settings_box.set_homogeneous (false); HBox* constraint_hbox = manage (new HBox); @@ -99,7 +99,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol VBox* v1_box = manage (new VBox); VBox* v2_box = manage (new VBox); - pack_end (plugin_analysis_expander, true, true); + pack_end (plugin_analysis_expander, false, false); v1_box->pack_start (*smaller_hbox, false, true); v2_box->pack_start (focus_button, false, true); @@ -111,7 +111,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol main_contents.pack_start (*constraint_hbox, false, false); - if ( is_scrollable ) { + if (is_scrollable ) { scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); scroller.set_name ("PluginEditor"); scroller_view.set_name("PluginEditor"); @@ -120,8 +120,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol main_contents.pack_start (scroller, true, true); - } - else { + } else { main_contents.pack_start (hpacker, false, false); } @@ -216,7 +215,7 @@ GenericPluginUI::build () box->set_spacing (1); frame->add (*box); - hpacker.pack_start(*frame,true,true); + hpacker.pack_start(*frame, true, true); x = 1; } @@ -650,7 +649,7 @@ GenericPluginUI::update_control_display (ControlUI* cui) cui->ignore_change++; - if (cui->combo) { + if (cui->combo && cui->combo_map) { std::map::iterator it; for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) { if (it->second == val) { @@ -694,7 +693,7 @@ GenericPluginUI::control_port_toggled (ControlUI* cui) void GenericPluginUI::control_combo_changed (ControlUI* cui) { - if (!cui->ignore_change) { + if (!cui->ignore_change && cui->combo_map) { string value = cui->combo->get_active_text(); std::map mapping = *cui->combo_map; insert->automation_control(cui->parameter())->set_value(mapping[value]); diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 76764f8a5c..1e54344a83 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -77,17 +77,23 @@ using namespace PBD; using namespace Gtkmm2ext; using namespace Gtk; -PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr insert, bool scrollable) +PluginUIWindow::PluginUIWindow ( + Gtk::Window* win, + boost::shared_ptr insert, + bool scrollable, + bool editor) : parent (win) - , was_visible (false) - , _keyboard_focused (false) + , was_visible (false) + , _keyboard_focused (false) { bool have_gui = false; Label* label = manage (new Label()); label->set_markup ("THIS IS THE PLUGIN UI"); - if (insert->plugin()->has_editor()) { + std::cout << "SHOW UI " << insert->plugin()->unique_id() + << " editor: " << editor << std::endl; + if (editor && insert->plugin()->has_editor()) { switch (insert->type()) { case ARDOUR::VST: have_gui = create_vst_editor (insert); @@ -119,8 +125,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptrKeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); @@ -281,7 +286,7 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr) #else VBox* box; _pluginui = create_au_gui (insert, &box); - _pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); + _pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); add (*box); Application::instance()->ActivationChanged.connect (mem_fun (*this, &PluginUIWindow::app_activated)); @@ -347,32 +352,32 @@ PluginUIWindow::on_key_press_event (GdkEventKey* event) { if (_keyboard_focused) { if (_pluginui) { - if (_pluginui->non_gtk_gui()) { - _pluginui->forward_key_event (event); - } else { - return relay_key_press (event, this); - } + if (_pluginui->non_gtk_gui()) { + _pluginui->forward_key_event (event); + } else { + return relay_key_press (event, this); + } } return true; } else { - /* for us to be getting key press events, there really - MUST be a _pluginui, but just to be safe, check ... - */ + /* for us to be getting key press events, there really + MUST be a _pluginui, but just to be safe, check ... + */ - if (_pluginui) { - if (_pluginui->non_gtk_gui()) { - /* pass editor window as the window for the event - to be handled in, not this one, because there are - no widgets in this window that we want to have - key focus. - */ - return relay_key_press (event, &PublicEditor::instance()); - } else { - return relay_key_press (event, this); - } - } else { - return false; - } + if (_pluginui) { + if (_pluginui->non_gtk_gui()) { + /* pass editor window as the window for the event + to be handled in, not this one, because there are + no widgets in this window that we want to have + key focus. + */ + return relay_key_press (event, &PublicEditor::instance()); + } else { + return relay_key_press (event, this); + } + } else { + return false; + } } } @@ -381,10 +386,10 @@ PluginUIWindow::on_key_release_event (GdkEventKey *event) { if (_keyboard_focused) { if (_pluginui) { - if (_pluginui->non_gtk_gui()) { - _pluginui->forward_key_event (event); - } - return true; + if (_pluginui->non_gtk_gui()) { + _pluginui->forward_key_event (event); + } + return true; } return false; } else { diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 3176e4a14d..743234f16a 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -211,7 +211,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox /* input */ - Gtk::ComboBoxText* combo; + Gtk::ComboBoxText* combo; std::map* combo_map; Gtk::ToggleButton* button; boost::shared_ptr controller; @@ -261,7 +261,10 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox class PluginUIWindow : public Gtk::Window { public: - PluginUIWindow (Gtk::Window*, boost::shared_ptr insert, bool scrollable=false); + PluginUIWindow (Gtk::Window*, + boost::shared_ptr insert, + bool scrollable=false, + bool editor=true); ~PluginUIWindow (); PlugUIBase& pluginui() { return *_pluginui; } diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index ff1c05e18a..7ae9ddf16f 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -92,6 +92,7 @@ RefPtr ProcessorBox::paste_action; RefPtr ProcessorBox::cut_action; RefPtr ProcessorBox::rename_action; RefPtr ProcessorBox::edit_action; +RefPtr ProcessorBox::controls_action; Glib::RefPtr SendProcessorEntry::_slider; ProcessorEntry::ProcessorEntry (boost::shared_ptr p, Width w) @@ -883,14 +884,24 @@ ProcessorBox::build_processor_menu () void ProcessorBox::selection_changed () { - bool const sensitive = (processor_display.selection().empty()) ? false : true; - ActionManager::set_sensitive (ActionManager::plugin_selection_sensitive_actions, sensitive); - edit_action->set_sensitive (one_processor_can_be_edited ()); + const bool sensitive = !processor_display.selection().empty(); + ActionManager::set_sensitive(ActionManager::plugin_selection_sensitive_actions, + sensitive); + edit_action->set_sensitive(one_processor_can_be_edited()); + + const bool single_selection = (processor_display.selection().size() == 1); + + boost::shared_ptr pi; + if (single_selection) { + pi = boost::dynamic_pointer_cast( + processor_display.selection().front()->processor()); + } + + /* enable gui for plugin inserts with editors */ + controls_action->set_sensitive(pi && pi->plugin()->has_editor()); /* disallow rename for multiple selections and for plugin inserts */ - rename_action->set_sensitive ( - processor_display.selection().size() == 1 && boost::dynamic_pointer_cast (processor_display.selection().front()->processor()) == 0 - ); + rename_action->set_sensitive(single_selection && pi); } void @@ -1838,10 +1849,10 @@ ProcessorBox::toggle_edit_processor (boost::shared_ptr processor) } else if ((retrn = boost::dynamic_pointer_cast (processor)) != 0) { - if (boost::dynamic_pointer_cast (retrn)) { - /* no GUI for these */ - return; - } + if (boost::dynamic_pointer_cast (retrn)) { + /* no GUI for these */ + return; + } if (!_session->engine().connected()) { return; @@ -1921,6 +1932,28 @@ ProcessorBox::toggle_edit_processor (boost::shared_ptr processor) } } +void +ProcessorBox::toggle_processor_controls (boost::shared_ptr processor) +{ + boost::shared_ptr plugin_insert + = boost::dynamic_pointer_cast(processor); + if (!plugin_insert) { + return; + } + + Container* toplevel = get_toplevel(); + Window* win = dynamic_cast(toplevel); + PluginUIWindow* plugin_ui = new PluginUIWindow(win, plugin_insert, true, false); + plugin_ui->set_title(generate_processor_title (plugin_insert)); + + if (plugin_ui->is_visible()) { + plugin_ui->hide(); + } else { + plugin_ui->show_all(); + plugin_ui->present(); + } +} + void ProcessorBox::register_actions () { @@ -1971,15 +2004,21 @@ ProcessorBox::register_actions () /* activation etc. */ ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"), - sigc::ptr_fun (ProcessorBox::rb_activate_all)); + sigc::ptr_fun (ProcessorBox::rb_activate_all)); ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"), - sigc::ptr_fun (ProcessorBox::rb_deactivate_all)); + sigc::ptr_fun (ProcessorBox::rb_deactivate_all)); ActionManager::register_action (popup_act_grp, X_("ab_plugins"), _("A/B Plugins"), - sigc::ptr_fun (ProcessorBox::rb_ab_plugins)); + sigc::ptr_fun (ProcessorBox::rb_ab_plugins)); /* show editors */ - edit_action = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit..."), - sigc::ptr_fun (ProcessorBox::rb_edit)); + edit_action = ActionManager::register_action ( + popup_act_grp, X_("edit"), _("Edit..."), + sigc::ptr_fun (ProcessorBox::rb_edit)); + + /* show plugin GUI */ + controls_action = ActionManager::register_action ( + popup_act_grp, X_("controls"), _("Controls..."), + sigc::ptr_fun (ProcessorBox::rb_controls)); ActionManager::add_action_group (popup_act_grp); } @@ -2160,6 +2199,16 @@ ProcessorBox::rb_edit () _current_processor_box->for_selected_processors (&ProcessorBox::toggle_edit_processor); } +void +ProcessorBox::rb_controls () +{ + if (_current_processor_box == 0) { + return; + } + + _current_processor_box->for_selected_processors (&ProcessorBox::toggle_processor_controls); +} + void ProcessorBox::route_property_changed (const PropertyChange& what_changed) { @@ -2255,9 +2304,9 @@ void ProcessorBox::set_processor_ui (boost::shared_ptr p, Gtk::Window* w) { list::iterator i = _processor_window_proxies.begin (); - - p->set_ui (w); - + + p->set_ui (w); + while (i != _processor_window_proxies.end()) { boost::shared_ptr t = (*i)->processor().lock (); if (t && t == p) { diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index bd5f18b947..559945e0fe 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -215,6 +215,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD Gtk::Window* get_processor_ui (boost::shared_ptr) const; void toggle_edit_processor (boost::shared_ptr); + void toggle_processor_controls (boost::shared_ptr); sigc::signal > ProcessorSelected; sigc::signal > ProcessorUnselected; @@ -313,12 +314,13 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr)); void get_selected_processors (ProcSelection&) const; - bool can_cut() const; + bool can_cut() const; static Glib::RefPtr cut_action; static Glib::RefPtr paste_action; static Glib::RefPtr rename_action; static Glib::RefPtr edit_action; + static Glib::RefPtr controls_action; void paste_processor_state (const XMLNodeList&, boost::shared_ptr); void activate_processor (boost::shared_ptr); @@ -353,6 +355,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD static void rb_deactivate_all (); static void rb_ab_plugins (); static void rb_edit (); + static void rb_controls (); void route_property_changed (const PBD::PropertyChange&); std::string generate_processor_title (boost::shared_ptr pi); diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index a0e2e19a13..feab43bac7 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -57,7 +57,7 @@ class PluginInsert : public Processor void activate (); void deactivate (); - void flush (); + void flush (); int set_block_size (pframes_t nframes); @@ -83,13 +83,13 @@ class PluginInsert : public Processor void set_value (double val); double get_value (void) const; - XMLNode& get_state(); + XMLNode& get_state(); double user_to_ui (double) const; double ui_to_user (double) const; double plugin_to_ui (double) const; double plugin_to_user (double) const; - + private: double user_to_plugin (double) const; @@ -158,7 +158,7 @@ class PluginInsert : public Processor void set_automatable (); void control_list_automation_state_changed (Evoral::Parameter, AutoState); void set_parameter_state_2X (const XMLNode& node, int version); - void set_control_ids (const XMLNode&, int version); + void set_control_ids (const XMLNode&, int version); int32_t count_for_configuration (ChanCount in, ChanCount out) const;