Put some up/down buttons to the right of the summary. Might help with #3786.
[ardour.git] / gtk2_ardour / generic_pluginui.cc
index b843120f8c7ea02a738eb6c4d77c3bbfd79d5174..fdf0d62482d86cd7a85a806afbf31935e6fb3d77 100644 (file)
@@ -45,6 +45,7 @@
 #ifdef HAVE_SLV2
 #include "ardour/lv2_plugin.h"
 #endif
+#include "ardour/session.h"
 
 #include <lrdf.h>
 
@@ -62,7 +63,6 @@ using namespace ARDOUR;
 using namespace PBD;
 using namespace Gtkmm2ext;
 using namespace Gtk;
-using namespace sigc;
 
 GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrollable)
        : PlugUIBase (pi),
@@ -78,21 +78,24 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
        set_border_width (10);
        //set_homogeneous (false);
 
-       pack_start(main_contents);
+       pack_start (main_contents, false, false);
        settings_box.set_homogeneous (false);
 
        HBox* constraint_hbox = manage (new HBox);
        HBox* smaller_hbox = manage (new HBox);
+       smaller_hbox->set_spacing (4);
        Label* combo_label = manage (new Label (_("<span size=\"large\">Presets</span>")));
        combo_label->set_use_markup (true);
 
        latency_button.add (latency_label);
-       latency_button.signal_clicked().connect (mem_fun (*this, &PlugUIBase::latency_button_clicked));
+       latency_button.signal_clicked().connect (sigc::mem_fun (*this, &PlugUIBase::latency_button_clicked));
        set_latency_label ();
 
        smaller_hbox->pack_start (latency_button, false, false, 10);
-       smaller_hbox->pack_start (preset_combo, false, false);
+       smaller_hbox->pack_start (_preset_box, false, false);
+       smaller_hbox->pack_start (add_button, false, false);
        smaller_hbox->pack_start (save_button, false, false);
+       smaller_hbox->pack_start (delete_button, false, false);
        smaller_hbox->pack_start (bypass_button, false, true);
 
        constraint_hbox->set_spacing (5);
@@ -100,7 +103,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
 
        VBox* v1_box = manage (new VBox);
        VBox* v2_box = manage (new VBox);
-       pack_end(plugin_analysis_expander);
+       pack_end (plugin_analysis_expander, true, true);
 
        v1_box->pack_start (*smaller_hbox, false, true);
        v2_box->pack_start (focus_button, false, true);
@@ -126,8 +129,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
                main_contents.pack_start (hpacker, false, false);
        }
 
-       pi->ActiveChanged.connect (bind(mem_fun(*this, &GenericPluginUI::processor_active_changed),
-                                       boost::weak_ptr<Processor>(pi)));
+       pi->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&GenericPluginUI::processor_active_changed, this, boost::weak_ptr<Processor>(pi)), gui_context());
 
        bypass_button.set_active (!pi->active());
 
@@ -227,7 +229,7 @@ GenericPluginUI::build ()
 
                        boost::shared_ptr<ARDOUR::AutomationControl> c
                                = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
-                                       insert->data().control(Evoral::Parameter(PluginAutomation, 0, i)));
+                                       insert->control(Evoral::Parameter(PluginAutomation, 0, i)));
 
                        if ((cui = build_control_ui (i, c)) == 0) {
                                error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
@@ -317,14 +319,14 @@ GenericPluginUI::ControlUI::ControlUI ()
        : automate_button (X_("")) // force creation of a label
 {
        automate_button.set_name ("PluginAutomateButton");
-       ARDOUR_UI::instance()->tooltips().set_tip (automate_button, _("Automation control"));
+       ARDOUR_UI::instance()->set_tip (automate_button, _("Automation control"));
 
        /* XXX translators: use a string here that will be at least as long
           as the longest automation label (see ::automation_state_changed()
           below). be sure to include a descender.
        */
 
-       set_size_request_to_display_given_text (*automate_button.get_child(), _("Mgnual"), 5, 5);
+        set_size_request_to_display_given_text (automate_button, _("Mgnual"), 15, 10);
 
        ignore_change = 0;
        display = 0;
@@ -348,7 +350,7 @@ GenericPluginUI::automation_state_changed (ControlUI* cui)
 
        // don't lock to avoid deadlock because we're triggered by
        // AutomationControl::Changed() while the automation lock is taken
-       switch (insert->get_parameter_automation_state (cui->parameter(), false)
+       switch (insert->get_parameter_automation_state (cui->parameter())
                        & (Off|Play|Touch|Write)) {
        case Off:
                cui->automate_button.set_label (_("Manual"));
@@ -383,9 +385,10 @@ GenericPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
 GenericPluginUI::ControlUI*
 GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<AutomationControl> mcontrol)
 {
-       ControlUI* control_ui = NULL;
-       if (!mcontrol)
+       ControlUI* control_ui = 0;
+       if (!mcontrol) {
                return control_ui;
+       }
 
        Plugin::ParameterDescriptor desc;
 
@@ -421,8 +424,8 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
                                control_ui->combo = new Gtk::ComboBoxText;
                                //control_ui->combo->set_value_in_list(true, false);
                                set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
-                               control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
-                               mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui));
+                               control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
+                               mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
                                control_ui->pack_start(control_ui->label, true, true);
                                control_ui->pack_start(*control_ui->combo, false, true);
 
@@ -442,8 +445,8 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
                                control_ui->combo = new Gtk::ComboBoxText;
                                //control_ui->combo->set_value_in_list(true, false);
                                set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
-                               control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
-                               mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui));
+                               control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
+                               mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
                                control_ui->pack_start(control_ui->label, true, true);
                                control_ui->pack_start(*control_ui->combo, false, true);
 
@@ -465,67 +468,59 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
 
                        control_ui->pack_start (control_ui->label, true, true);
                        control_ui->pack_start (*control_ui->button, false, true);
-                       // control_ui->pack_start (control_ui->automate_button, false, false);
+                       control_ui->pack_start (control_ui->automate_button, false, false);
 
-                       control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui));
-                       mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::toggle_parameter_changed), control_ui));
+                       control_ui->button->signal_clicked().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui));
+                       control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
 
+                       mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::toggle_parameter_changed, this, control_ui), gui_context());
+                        mcontrol->alist()->automation_state_changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::automation_state_changed, this, control_ui), gui_context());
+       
                        if (plugin->get_parameter (port_index) > 0.5){
                                control_ui->button->set_active(true);
                        }
 
+                        automation_state_changed (control_ui);
+
                        return control_ui;
                }
 
                /* create the controller */
 
                control_ui->controller = AutomationController::create(insert, mcontrol->parameter(), mcontrol);
+
                /* XXX this code is not right yet, because it doesn't handle
                   the absence of bounds in any sensible fashion.
                */
 
-//#if 0
-               control_ui->controller->adjustment()->set_lower (desc.lower);
-               control_ui->controller->adjustment()->set_upper (desc.upper);
-
-               control_ui->logarithmic = false; // just disable it for now
-               /*
-               control_ui->logarithmic = desc.logarithmic;
-               if (control_ui->logarithmic) {
-                       if (control_ui->controller->adjustment()->get_lower() == 0.0) {
-                               control_ui->controller->adjustment()->set_lower (control_ui->controller->adjustment()->get_upper()/10000);
-                       }
-                       control_ui->controller->adjustment()->set_upper (log(control_ui->controller->adjustment()->get_upper()));
-                       control_ui->controller->adjustment()->set_lower (log(control_ui->controller->adjustment()->get_lower()));
-               }*/
+                Adjustment* adj = control_ui->controller->adjustment();
+               boost::shared_ptr<PluginInsert::PluginControl> pc = boost::dynamic_pointer_cast<PluginInsert::PluginControl> (control_ui->control);
 
+               adj->set_lower (pc->user_to_ui (desc.lower));
+               adj->set_upper (pc->user_to_ui (desc.upper));
 
-               control_ui->controller->adjustment()->set_step_increment (desc.step);
-               control_ui->controller->adjustment()->set_page_increment (desc.largestep);
-//#endif
+               adj->set_step_increment (desc.step);
+               adj->set_page_increment (desc.largestep);
 
                if (desc.integer_step) {
-                       control_ui->clickbox = new ClickBox (control_ui->controller->adjustment(), "PluginUIClickBox");
+                       control_ui->clickbox = new ClickBox (adj, "PluginUIClickBox");
                        Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2);
                        control_ui->clickbox->set_print_func (integer_printer, 0);
                } else {
-                       //sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &GenericPluginUI::print_parameter), (uint32_t) port_index);
+                       //sigc::slot<void,char*,uint32_t> pslot = sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::print_parameter), (uint32_t) port_index);
 
                        control_ui->controller->set_size_request (200, req.height);
                        control_ui->controller->set_name (X_("PluginSlider"));
                        control_ui->controller->set_style (BarController::LeftToRight);
                        control_ui->controller->set_use_parent (true);
+                        control_ui->controller->set_logarithmic (desc.logarithmic);
 
-                       control_ui->controller->StartGesture.connect (bind (mem_fun(*this, &GenericPluginUI::start_touch), control_ui));
-                       control_ui->controller->StopGesture.connect (bind (mem_fun(*this, &GenericPluginUI::stop_touch), control_ui));
+                       control_ui->controller->StartGesture.connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::start_touch), control_ui));
+                       control_ui->controller->StopGesture.connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::stop_touch), control_ui));
 
                }
 
-               if (control_ui->logarithmic) {
-                       control_ui->controller->adjustment()->set_value(log(plugin->get_parameter(port_index)));
-               } else{
-                       control_ui->controller->adjustment()->set_value(plugin->get_parameter(port_index));
-               }
+               adj->set_value (pc->plugin_to_ui (plugin->get_parameter (port_index)));
 
                /* XXX memory leak: SliderController not destroyed by ControlUI
                   destructor, and manage() reports object hierarchy
@@ -540,13 +535,14 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
                }
 
                control_ui->pack_start (control_ui->automate_button, false, false);
-               control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
+               control_ui->automate_button.signal_clicked().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
 
                automation_state_changed (control_ui);
 
-               mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui));
-               mcontrol->alist()->automation_state_changed.connect
-                       (bind (mem_fun(*this, &GenericPluginUI::automation_state_changed), control_ui));
+               mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
+               mcontrol->alist()->automation_state_changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::automation_state_changed, this, control_ui), gui_context());
+
+               input_controls.push_back (control_ui);
 
        } else if (plugin->parameter_is_output (port_index)) {
 
@@ -595,7 +591,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
                output_controls.push_back (control_ui);
        }
 
-       mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui));
+       mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
 
        return control_ui;
 }
@@ -603,13 +599,13 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
 void
 GenericPluginUI::start_touch (GenericPluginUI::ControlUI* cui)
 {
-       cui->control->start_touch ();
+       cui->control->start_touch (cui->control->session().transport_frame());
 }
 
 void
 GenericPluginUI::stop_touch (GenericPluginUI::ControlUI* cui)
 {
-       cui->control->stop_touch ();
+       cui->control->stop_touch (false, cui->control->session().transport_frame());
 }
 
 void
@@ -626,13 +622,13 @@ GenericPluginUI::astate_clicked (ControlUI* cui, uint32_t /*port*/)
 
        items.clear ();
        items.push_back (MenuElem (_("Manual"),
-                                  bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Off, cui)));
+                                  sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Off, cui)));
        items.push_back (MenuElem (_("Play"),
-                                  bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Play, cui)));
+                                  sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Play, cui)));
        items.push_back (MenuElem (_("Write"),
-                                  bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Write, cui)));
+                                  sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Write, cui)));
        items.push_back (MenuElem (_("Touch"),
-                                  bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Touch, cui)));
+                                  sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Touch, cui)));
 
        automation_menu->popup (1, gtk_get_current_event_time());
 }
@@ -658,11 +654,11 @@ GenericPluginUI::toggle_parameter_changed (ControlUI* cui)
 }
 
 void
-GenericPluginUI::parameter_changed (ControlUI* cui)
+GenericPluginUI::ui_parameter_changed (ControlUI* cui)
 {
        if (!cui->update_pending) {
                cui->update_pending = true;
-               Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &GenericPluginUI::update_control_display), cui));
+               Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, boost::bind (&GenericPluginUI::update_control_display, this, cui));
        }
 }
 
@@ -731,7 +727,7 @@ GenericPluginUI::control_combo_changed (ControlUI* cui)
 void
 GenericPluginUI::processor_active_changed (boost::weak_ptr<Processor> weak_processor)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &GenericPluginUI::processor_active_changed), weak_processor));
+       ENSURE_GUI_THREAD (*this, &GenericPluginUI::processor_active_changed, weak_processor)
 
        boost::shared_ptr<Processor> processor = weak_processor.lock();
 
@@ -744,7 +740,7 @@ GenericPluginUI::start_updating (GdkEventAny*)
        if (output_controls.size() > 0 ) {
                screen_update_connection.disconnect();
                screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect
-                       (mem_fun(*this, &GenericPluginUI::output_update));
+                       (sigc::mem_fun(*this, &GenericPluginUI::output_update));
        }
        return false;
 }
@@ -752,9 +748,14 @@ GenericPluginUI::start_updating (GdkEventAny*)
 bool
 GenericPluginUI::stop_updating (GdkEventAny*)
 {
+       for (vector<ControlUI*>::iterator i = input_controls.begin(); i != input_controls.end(); ++i) {
+               (*i)->controller->stop_updating ();
+       }
+       
        if (output_controls.size() > 0 ) {
                screen_update_connection.disconnect();
        }
+       
        return false;
 }