X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fgeneric_pluginui.cc;h=fdf0d62482d86cd7a85a806afbf31935e6fb3d77;hb=d08e3b94c5ef75ce5d4d28f3636faa8af4661e17;hp=7ae3f45dfb2ff9a1859fba109a610d9e4a8d8aa2;hpb=bb457bb960c5bd7ed538f9d31477293415739f68;p=ardour.git diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 7ae3f45dfb..fdf0d62482 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000 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 @@ -17,14 +17,18 @@ */ +#ifdef WAF_BUILD +#include "gtk2ardour-config.h" +#endif + #include #include #include #include -#include -#include -#include +#include "pbd/stl_delete.h" +#include "pbd/xml++.h" +#include "pbd/failed_constructor.h" #include #include @@ -33,11 +37,15 @@ #include #include -#include +#include "midi++/manager.h" -#include -#include -#include +#include "ardour/plugin.h" +#include "ardour/plugin_insert.h" +#include "ardour/ladspa_plugin.h" +#ifdef HAVE_SLV2 +#include "ardour/lv2_plugin.h" +#endif +#include "ardour/session.h" #include @@ -55,7 +63,6 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtkmm2ext; using namespace Gtk; -using namespace sigc; GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrollable) : PlugUIBase (pi), @@ -69,30 +76,44 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol { set_name ("PluginEditor"); set_border_width (10); - set_homogeneous (false); + //set_homogeneous (false); + 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 (_("Presets"))); combo_label->set_use_markup (true); - Label* latency_label = manage (new Label (_("Latency"))); - latency_label->set_use_markup (true); + latency_button.add (latency_label); + latency_button.signal_clicked().connect (sigc::mem_fun (*this, &PlugUIBase::latency_button_clicked)); + set_latency_label (); - smaller_hbox->pack_start (*latency_label, false, false, 10); - smaller_hbox->pack_start (latency_gui, false, false, 10); - smaller_hbox->pack_start (combo, false, false); + smaller_hbox->pack_start (latency_button, false, false, 10); + 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); - constraint_hbox->pack_start (*smaller_hbox, true, false); - constraint_hbox->pack_end (bypass_button, false, false); + constraint_hbox->set_homogeneous (false); + + VBox* v1_box = manage (new VBox); + VBox* v2_box = manage (new VBox); + pack_end (plugin_analysis_expander, true, true); - settings_box.pack_end (*constraint_hbox, false, false); + v1_box->pack_start (*smaller_hbox, false, true); + v2_box->pack_start (focus_button, false, true); - pack_start (settings_box, false, false); + main_contents.pack_start (settings_box, false, false); + + constraint_hbox->pack_end (*v2_box, false, false); + constraint_hbox->pack_end (*v1_box, false, false); + + main_contents.pack_start (*constraint_hbox, false, false); if ( is_scrollable ) { scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); @@ -100,18 +121,18 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr pi, bool scrol scroller_view.set_name("PluginEditor"); scroller_view.add (hpacker); scroller.add (scroller_view); - - pack_start (scroller, true, true); + + main_contents.pack_start (scroller, true, true); } else { - pack_start (hpacker, false, false); + main_contents.pack_start (hpacker, false, false); } - pi->ActiveChanged.connect (bind(mem_fun(*this, &GenericPluginUI::processor_active_changed), - boost::weak_ptr(pi))); + pi->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&GenericPluginUI::processor_active_changed, this, boost::weak_ptr(pi)), gui_context()); + bypass_button.set_active (!pi->active()); - + build (); } @@ -179,23 +200,23 @@ GenericPluginUI::build () for (i = 0; i < plugin->parameter_count(); ++i) { if (plugin->parameter_is_control (i)) { - + /* Don't show latency control ports */ - if (plugin->describe_parameter (Parameter(PluginAutomation, i)) == X_("latency")) { + if (plugin->describe_parameter (Evoral::Parameter(PluginAutomation, 0, i)) == X_("latency")) { continue; } ControlUI* cui; - + /* if we are scrollable, just use one long column */ if (!is_scrollable) { - if (x++ > 7){ + if (x++ > 20){ frame = manage (new Frame); frame->set_name ("BaseFrame"); box = manage (new VBox); - + box->set_border_width (5); box->set_spacing (1); @@ -206,12 +227,16 @@ GenericPluginUI::build () } } - if ((cui = build_control_ui (i, insert->control(Parameter(PluginAutomation, i)))) == 0) { + boost::shared_ptr c + = boost::dynamic_pointer_cast( + 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; continue; } - - if (cui->control || cui->clickbox || cui->combo) { + + if (cui->controller || cui->clickbox || cui->combo) { box->pack_start (*cui, false, false); @@ -225,25 +250,25 @@ GenericPluginUI::build () } } - button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1, + button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1, FILL|EXPAND, FILL); button_row++; } else if (cui->display) { - output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1, + output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1, FILL|EXPAND, FILL); - - // TODO: The meters should be divided into multiple rows - + + // TODO: The meters should be divided into multiple rows + if (++output_col == output_cols) { output_cols ++; output_table.resize (output_rows, output_cols); } - + /* old code, which divides meters into * columns first, rows later. New code divides into one row - + if (output_row == output_rows) { output_row = 0; if (++output_col == output_cols) { @@ -251,22 +276,22 @@ GenericPluginUI::build () output_table.resize (output_rows, output_cols); } } - - output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1, + + output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1, FILL|EXPAND, FILL); - + output_row++; */ } - + /* HACK: ideally the preferred height would be queried from the complete hpacker, but I can't seem to get that - information in time, so this is an estimation + information in time, so this is an estimation */ prefheight += 30; - } + } } if (box->children().empty()) { @@ -291,17 +316,17 @@ GenericPluginUI::build () } GenericPluginUI::ControlUI::ControlUI () - : automate_button (X_("")) // force creation of a label + : 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; @@ -310,7 +335,7 @@ GenericPluginUI::ControlUI::ControlUI () meterinfo = 0; } -GenericPluginUI::ControlUI::~ControlUI() +GenericPluginUI::ControlUI::~ControlUI() { if (meterinfo) { delete meterinfo->meter; @@ -325,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")); @@ -346,7 +371,7 @@ GenericPluginUI::automation_state_changed (ControlUI* cui) } -static void integer_printer (char buf[32], Adjustment &adj, void *arg) +static void integer_printer (char buf[32], Adjustment &adj, void */*arg*/) { snprintf (buf, 32, "%.0f", adj.get_value()); } @@ -360,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 mcontrol) { - ControlUI* control_ui = NULL; - if (!mcontrol) + ControlUI* control_ui = 0; + if (!mcontrol) { return control_ui; + } Plugin::ParameterDescriptor desc; @@ -384,34 +410,58 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrparameter_is_input (port_index)) { boost::shared_ptr lp; - +#ifdef HAVE_SLV2 + boost::shared_ptr lv2p; +#endif if ((lp = boost::dynamic_pointer_cast(plugin)) != 0) { - + // FIXME: not all plugins have a numeric unique ID uint32_t id = atol (lp->unique_id().c_str()); lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index); - + if (defaults && defaults->count > 0) { - + 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); - + update_control_display(control_ui); - + lrdf_free_setting_values(defaults); return control_ui; } + +#ifdef HAVE_SLV2 + } else if ((lv2p = boost::dynamic_pointer_cast(plugin)) != 0) { + + SLV2Port port = lv2p->slv2_port(port_index); + SLV2ScalePoints points = slv2_port_get_scale_points(lv2p->slv2_plugin(), port); + + if (points) { + 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 (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); + + update_control_display(control_ui); + + slv2_scale_points_free(points); + return control_ui; + } +#endif } - + if (desc.toggled) { /* Build a button */ - + control_ui->button = manage (new ToggleButton ()); control_ui->button->set_name ("PluginEditorButton"); control_ui->button->set_size_request (20, 20); @@ -420,67 +470,58 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrpack_start (*control_ui->button, false, true); 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)); - - if(plugin->get_parameter (port_index) == 1){ + 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->list(), mcontrol); + + 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); + Adjustment* adj = control_ui->controller->adjustment(); + boost::shared_ptr pc = boost::dynamic_pointer_cast (control_ui->control); - 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())); - } - - - float delta = desc.upper - desc.lower; + adj->set_lower (pc->user_to_ui (desc.lower)); + adj->set_upper (pc->user_to_ui (desc.upper)); - control_ui->controller->adjustment()->set_page_size (delta/100.0); - 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 pslot = sigc::bind (mem_fun(*this, &GenericPluginUI::print_parameter), (uint32_t) port_index); + //sigc::slot 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 ambiguity. @@ -494,13 +535,14 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrpack_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->list()->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)) { @@ -521,7 +563,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrmeterinfo = info; - + info->meter = new FastMeter (5, 5, FastMeter::Vertical); info->min_unbound = desc.min_unbound; @@ -532,61 +574,61 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrvbox = manage (new VBox); control_ui->hbox = manage (new HBox); - + control_ui->label.set_angle(90); control_ui->hbox->pack_start (control_ui->label, false, false); control_ui->hbox->pack_start (*info->meter, false, false); control_ui->vbox->pack_start (*control_ui->hbox, false, false); - + control_ui->vbox->pack_start (*control_ui->display, false, false); control_ui->pack_start (*control_ui->vbox); control_ui->meterinfo->meter->show_all(); control_ui->meterinfo->packed = true; - + 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; } void GenericPluginUI::start_touch (GenericPluginUI::ControlUI* cui) { - cui->control->list()->start_touch (); + cui->control->start_touch (cui->control->session().transport_frame()); } void GenericPluginUI::stop_touch (GenericPluginUI::ControlUI* cui) { - cui->control->list()->stop_touch (); + cui->control->stop_touch (false, cui->control->session().transport_frame()); } void -GenericPluginUI::astate_clicked (ControlUI* cui, uint32_t port) +GenericPluginUI::astate_clicked (ControlUI* cui, uint32_t /*port*/) { using namespace Menu_Helpers; if (automation_menu == 0) { automation_menu = manage (new Menu); automation_menu->set_name ("ArdourContextMenu"); - } + } MenuList& items (automation_menu->items()); items.clear (); - items.push_back (MenuElem (_("Manual"), - bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Off, cui))); + items.push_back (MenuElem (_("Manual"), + 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()); } @@ -598,24 +640,39 @@ GenericPluginUI::set_automation_state (AutoState state, ControlUI* cui) } void -GenericPluginUI::parameter_changed (ControlUI* cui) +GenericPluginUI::toggle_parameter_changed (ControlUI* cui) +{ + float val = cui->control->get_value(); + + if (!cui->ignore_change) { + if (val > 0.5) { + cui->button->set_active (true); + } else { + cui->button->set_active (false); + } + } +} + +void +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)); } } void -GenericPluginUI::update_control_display (ControlUI* cui) +GenericPluginUI::update_control_display (ControlUI* cui) { /* XXX how do we handle logarithmic stuff here ? */ - + cui->update_pending = false; float val = cui->control->get_value(); cui->ignore_change++; + if (cui->combo) { std::map::iterator it; for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) { @@ -633,7 +690,9 @@ GenericPluginUI::update_control_display (ControlUI* cui) } } - cui->controller->display_effective_value(); + if( cui->controller ) { + cui->controller->display_effective_value(); + } /*} else { @@ -650,9 +709,9 @@ GenericPluginUI::update_control_display (ControlUI* cui) void GenericPluginUI::control_port_toggled (ControlUI* cui) { - if (!cui->ignore_change) { - insert->set_parameter (cui->parameter(), cui->button->get_active()); - } + cui->ignore_change++; + insert->automation_control (cui->parameter())->set_value (cui->button->get_active()); + cui->ignore_change--; } void @@ -661,38 +720,42 @@ GenericPluginUI::control_combo_changed (ControlUI* cui) if (!cui->ignore_change) { string value = cui->combo->get_active_text(); std::map mapping = *cui->combo_map; - insert->set_parameter (cui->parameter(), mapping[value]); + insert->automation_control(cui->parameter())->set_value(mapping[value]); } - } void GenericPluginUI::processor_active_changed (boost::weak_ptr 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 = weak_processor.lock(); bypass_button.set_active (!processor || !processor->active()); } bool -GenericPluginUI::start_updating (GdkEventAny* ignored) +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)); + screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect + (sigc::mem_fun(*this, &GenericPluginUI::output_update)); } return false; } bool -GenericPluginUI::stop_updating (GdkEventAny* ignored) +GenericPluginUI::stop_updating (GdkEventAny*) { + for (vector::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; } @@ -707,7 +770,7 @@ GenericPluginUI::output_update () /* autoscaling for the meter */ if ((*i)->meterinfo && (*i)->meterinfo->packed) { - + if (val < (*i)->meterinfo->min) { if ((*i)->meterinfo->min_unbound) (*i)->meterinfo->min = val; @@ -721,7 +784,7 @@ GenericPluginUI::output_update () else val = (*i)->meterinfo->max; } - + if ((*i)->meterinfo->max > (*i)->meterinfo->min ) { float lval = (val - (*i)->meterinfo->min) / ((*i)->meterinfo->max - (*i)->meterinfo->min) ; (*i)->meterinfo->meter->set (lval ); @@ -730,30 +793,60 @@ GenericPluginUI::output_update () } } -vector +vector GenericPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui) { vector enums; - boost::shared_ptr lp = boost::dynamic_pointer_cast (plugin); - - cui->combo_map = new std::map; - - // FIXME: not all plugins have a numeric unique ID - uint32_t id = atol (lp->unique_id().c_str()); - lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index); - - if (defaults) { - for (uint32_t i = 0; i < defaults->count; ++i) { - enums.push_back(defaults->items[i].label); - pair newpair; - newpair.first = defaults->items[i].label; - newpair.second = defaults->items[i].value; - cui->combo_map->insert(newpair); + boost::shared_ptr lp; +#ifdef HAVE_SLV2 + boost::shared_ptr lv2p; +#endif + + if ((lp = boost::dynamic_pointer_cast(plugin)) != 0) { + // all LADPSA plugins have a numeric unique ID + uint32_t id = atol (lp->unique_id().c_str()); + + cui->combo_map = new std::map; + lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index); + if (defaults) { + for (uint32_t i = 0; i < defaults->count; ++i) { + enums.push_back(defaults->items[i].label); + pair newpair; + newpair.first = defaults->items[i].label; + newpair.second = defaults->items[i].value; + cui->combo_map->insert(newpair); + } + + lrdf_free_setting_values(defaults); } - lrdf_free_setting_values(defaults); +#ifdef HAVE_SLV2 + } else if ((lv2p = boost::dynamic_pointer_cast(plugin)) != 0) { + + SLV2Port port = lv2p->slv2_port(port_index); + SLV2ScalePoints points = slv2_port_get_scale_points(lv2p->slv2_plugin(), port); + cui->combo_map = new std::map; + + for (unsigned i=0; i < slv2_scale_points_size(points); ++i) { + SLV2ScalePoint p = slv2_scale_points_get_at(points, i); + SLV2Value label = slv2_scale_point_get_label(p); + SLV2Value value = slv2_scale_point_get_value(p); + if (label && (slv2_value_is_float(value) || slv2_value_is_int(value))) { + enums.push_back(slv2_value_as_string(label)); + pair newpair; + newpair.first = slv2_value_as_string(label); + newpair.second = slv2_value_as_float(value); + cui->combo_map->insert(newpair); + } + } + + slv2_scale_points_free(points); +#endif } + return enums; } + +