diff options
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/automation_controller.cc | 36 | ||||
-rw-r--r-- | gtk2_ardour/automation_controller.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/automation_line.cc | 18 | ||||
-rw-r--r-- | gtk2_ardour/automation_line.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/automation_time_axis.cc | 7 | ||||
-rw-r--r-- | gtk2_ardour/generic_pluginui.cc | 151 | ||||
-rw-r--r-- | gtk2_ardour/lv2_plugin_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/plugin_ui.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 2 |
9 files changed, 135 insertions, 100 deletions
diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index 564387a55e..c4cc93386f 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -36,7 +36,9 @@ using namespace ARDOUR; using namespace Gtk; -AutomationController::AutomationController(boost::shared_ptr<Automatable> printer, boost::shared_ptr<AutomationControl> ac, Adjustment* adj) +AutomationController::AutomationController(boost::shared_ptr<Automatable> printer, + boost::shared_ptr<AutomationControl> ac, + Adjustment* adj) : BarController (*adj, ac) , _ignore_change(false) , _printer (printer) @@ -64,21 +66,27 @@ AutomationController::~AutomationController() } boost::shared_ptr<AutomationController> -AutomationController::create( - boost::shared_ptr<Automatable> printer, - const Evoral::Parameter& param, - boost::shared_ptr<AutomationControl> ac) +AutomationController::create(boost::shared_ptr<Automatable> printer, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + boost::shared_ptr<AutomationControl> ac) { - double const lo = ac->internal_to_interface(param.min()); - double const up = ac->internal_to_interface(param.max()); + const double lo = ac->internal_to_interface(desc.lower); + const double up = ac->internal_to_interface(desc.upper); + const double normal = ac->internal_to_interface(desc.normal); + double smallstep = desc.smallstep; + double largestep = desc.largestep; + if (smallstep == 0.0) { + smallstep = (up - lo) / 100; + } + if (largestep == 0.0) { + largestep = (up - lo) / 10; + } + smallstep = ac->internal_to_interface(smallstep); + largestep = ac->internal_to_interface(largestep); + Gtk::Adjustment* adjustment = manage ( - new Gtk::Adjustment ( - ac->internal_to_interface(param.normal()), - lo, up, - // TODO we should use explicit step-sizes if provided by Plugin::ParameterDescriptor - (up - lo) / 100, (up - lo) / 10 - ) - ); + new Gtk::Adjustment (normal, lo, up, smallstep, largestep)); assert (ac); assert(ac->parameter() == param); diff --git a/gtk2_ardour/automation_controller.h b/gtk2_ardour/automation_controller.h index 29635c8488..e5799cc519 100644 --- a/gtk2_ardour/automation_controller.h +++ b/gtk2_ardour/automation_controller.h @@ -46,9 +46,10 @@ namespace ARDOUR { class AutomationController : public Gtkmm2ext::BarController { public: static boost::shared_ptr<AutomationController> create( - boost::shared_ptr<ARDOUR::Automatable> parent, - const Evoral::Parameter& param, - boost::shared_ptr<ARDOUR::AutomationControl> ac); + boost::shared_ptr<ARDOUR::Automatable> parent, + const Evoral::Parameter& param, + const ARDOUR::ParameterDescriptor& desc, + boost::shared_ptr<ARDOUR::AutomationControl> ac); ~AutomationController(); @@ -62,7 +63,9 @@ public: void stop_updating (); private: - AutomationController (boost::shared_ptr<ARDOUR::Automatable> printer, boost::shared_ptr<ARDOUR::AutomationControl> ac, Gtk::Adjustment* adj); + AutomationController (boost::shared_ptr<ARDOUR::Automatable> printer, + boost::shared_ptr<ARDOUR::AutomationControl> ac, + Gtk::Adjustment* adj); std::string get_label (double&); void start_touch(); diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index b22681f1f8..c1549ecab3 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -69,8 +69,10 @@ using namespace Editing; /** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session frames. * This will not be deleted by AutomationLine. */ -AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Item& parent, - boost::shared_ptr<AutomationList> al, +AutomationLine::AutomationLine (const string& name, + TimeAxisView& tv, + ArdourCanvas::Item& parent, + boost::shared_ptr<AutomationList> al, Evoral::TimeConverter<double, framepos_t>* converter) : trackview (tv) , _name (name) @@ -1160,7 +1162,7 @@ AutomationLine::view_to_model_coord (double& x, double& y) const void AutomationLine::view_to_model_coord_y (double& y) const { - /* TODO: This should be more generic ... */ + /* TODO: This should be more generic (use ParameterDescriptor) */ if (alist->parameter().type() == GainAutomation || alist->parameter().type() == EnvelopeAutomation) { y = slider_position_to_gain_with_max (y, Config->get_max_gain()); @@ -1171,17 +1173,15 @@ AutomationLine::view_to_model_coord_y (double& y) const y = 1.0 - y; } else if (alist->parameter().type() == PanWidthAutomation) { y = 2.0 * y - 1.0; - } else if (alist->parameter().type() == PluginAutomation) { - y = y * (double)(alist->get_max_y()- alist->get_min_y()) + alist->get_min_y(); } else { - y = rint (y * alist->parameter().max()); + y = y * (double)(alist->get_max_y() - alist->get_min_y()) + alist->get_min_y(); } } void AutomationLine::model_to_view_coord (double& x, double& y) const { - /* TODO: This should be more generic ... */ + /* TODO: This should be more generic (use ParameterDescriptor) */ if (alist->parameter().type() == GainAutomation || alist->parameter().type() == EnvelopeAutomation) { y = gain_to_slider_position_with_max (y, Config->get_max_gain()); @@ -1190,10 +1190,8 @@ AutomationLine::model_to_view_coord (double& x, double& y) const y = 1.0 - y; } else if (alist->parameter().type() == PanWidthAutomation) { y = .5 + y * .5; - } else if (alist->parameter().type() == PluginAutomation) { - y = (y - alist->get_min_y()) / (double)(alist->get_max_y()- alist->get_min_y()); } else { - y = y / (double)alist->parameter().max(); /* ... like this */ + y = (y - alist->get_min_y()) / (double)(alist->get_max_y() - alist->get_min_y()); } x = _time_converter->to (x) - _offset; diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 663310dc46..02c67d0dcf 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -60,9 +60,12 @@ public: SelectedControlPoints = 0x4 }; - AutomationLine (const std::string& name, TimeAxisView&, ArdourCanvas::Item&, - boost::shared_ptr<ARDOUR::AutomationList>, + AutomationLine (const std::string& name, + TimeAxisView& tv, + ArdourCanvas::Item& parent, + boost::shared_ptr<ARDOUR::AutomationList> al, Evoral::TimeConverter<double, ARDOUR::framepos_t>* converter = 0); + virtual ~AutomationLine (); void queue_reset (); diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 87f2a2e26a..a49bcf0086 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -28,6 +28,7 @@ #include "ardour/automation_control.h" #include "ardour/event_type_map.h" +#include "ardour/parameter_types.h" #include "ardour/profile.h" #include "ardour/route.h" #include "ardour/session.h" @@ -103,7 +104,7 @@ AutomationTimeAxisView::AutomationTimeAxisView ( } if (_automatable && _control) { - _controller = AutomationController::create (_automatable, _control->parameter(), _control); + _controller = AutomationController::create (_automatable, _control->parameter(), _control->desc(), _control); } automation_menu = 0; @@ -559,7 +560,7 @@ AutomationTimeAxisView::build_display_menu () /* current interpolation state */ AutomationList::InterpolationStyle const s = _view ? _view->interpolation() : _control->list()->interpolation (); - if (EventTypeMap::instance().is_midi_parameter(_parameter)) { + if (ARDOUR::parameter_is_midi((AutomationType)_parameter.type())) { Menu* auto_mode_menu = manage (new Menu); auto_mode_menu->set_name ("ArdourContextMenu"); @@ -838,7 +839,7 @@ AutomationTimeAxisView::what_has_visible_automation (const boost::shared_ptr<Aut boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (i->second); - if (ac) { + if (ac && ac->alist()) { const XMLNode* gui_node = ac->extra_xml ("GUI"); diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 459c8d54d9..fb35882b34 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -239,9 +239,9 @@ GenericPluginUI::build () frame->add (*box); hpacker.pack_start(*frame, true, true); - /* find all ports. build control elements for all appropriate control ports */ - std::vector<ControlUI *> cui_controls_list; + std::vector<ControlUI *> control_uis; + // Build a ControlUI for each control port for (i = 0; i < plugin->parameter_count(); ++i) { if (plugin->parameter_is_control (i)) { @@ -274,77 +274,73 @@ GenericPluginUI::build () ARDOUR_UI::instance()->set_tip(cui, param_docs.c_str()); } - if (cui->controller || cui->clickbox || cui->combo) { - // Get all of the controls into a list, so that - // we can lay them out a bit more nicely later. - cui_controls_list.push_back(cui); - } else if (cui->button) { - - if (!is_scrollable && button_row == button_rows) { - button_row = 0; - if (++button_col == button_cols) { - button_cols += 2; - button_table.resize (button_rows, button_cols); - } - } + control_uis.push_back(cui); + } + } + + // Build a ControlUI for each property + const Plugin::PropertyDescriptors& descs = plugin->get_supported_properties(); + for (Plugin::PropertyDescriptors::const_iterator d = descs.begin(); d != descs.end(); ++d) { + const ParameterDescriptor& desc = d->second; - button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1, - FILL|EXPAND, FILL); - button_row++; + boost::shared_ptr<ARDOUR::AutomationControl> c + = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>( + insert->control(Evoral::Parameter(PluginPropertyAutomation, 0, desc.key))); - } else if (cui->display) { + if (!c) { + error << string_compose(_("Plugin Editor: no control for property %1"), desc.key) << endmsg; + continue; + } - output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1, - FILL|EXPAND, FILL); + ControlUI* cui = build_control_ui(desc, c, true); + if (!cui) { + error << string_compose(_("Plugin Editor: could not build control element for property %1"), + desc.key) << endmsg; + continue; + } - // TODO: The meters should be divided into multiple rows + control_uis.push_back(cui); + } + if (!descs.empty()) { + plugin->announce_property_values(); + } - if (++output_col == output_cols) { - output_cols ++; - output_table.resize (output_rows, output_cols); + // Add special controls to UI, and build list of normal controls to be layed out later + std::vector<ControlUI *> cui_controls_list; + for (i = 0; i < control_uis.size(); ++i) { + ControlUI* cui = control_uis[i]; + + if (cui->controller || cui->clickbox || cui->combo) { + // Get all of the controls into a list, so that + // we can lay them out a bit more nicely later. + cui_controls_list.push_back(cui); + } else if (cui->button || cui->file_button) { + + if (!is_scrollable && button_row == button_rows) { + button_row = 0; + if (++button_col == button_cols) { + button_cols += 2; + button_table.resize (button_rows, button_cols); } } - } - } - - // Add property controls (currently file chooser button for paths only) - typedef std::vector<ParameterDescriptor> Descs; - Descs descs; - plugin->get_supported_properties(descs); - for (Descs::const_iterator d = descs.begin(); d != descs.end(); ++d) { - if (d->datatype == Variant::PATH) { - // Create/add label - Gtk::Label* label = manage(new Label(d->label)); - button_table.attach(*label, - 0, button_cols, button_row, button_row + 1, - FILL|EXPAND, FILL); - ++button_row; - // Create/add controller - Gtk::FileChooserButton* widget = manage( - new Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_OPEN)); - widget->set_title(d->label); - _property_controls.insert(std::make_pair(d->key, widget)); - button_table.attach(*widget, - 0, button_cols, button_row, button_row + 1, - FILL|EXPAND, FILL); - ++button_row; - - // Connect signals - widget->signal_file_set().connect( - sigc::bind(sigc::mem_fun(*this, &GenericPluginUI::set_property), *d, widget)); - plugin->PropertyChanged.connect(*this, invalidator(*this), - boost::bind(&GenericPluginUI::property_changed, this, _1, _2), - gui_context()); - } else { - // TODO: widgets for other datatypes, use ControlUI? - std::cerr << "warning: unsupported property " << d->key - << " type " << d->datatype << std::endl; + 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, + FILL|EXPAND, FILL); + + // TODO: The meters should be divided into multiple rows + + if (++output_col == output_cols) { + output_cols ++; + output_table.resize (output_rows, output_cols); + } } } - if (!descs.empty()) { - plugin->announce_property_values(); - } // Iterate over the list of controls to find which adjacent controls // are similar enough to be grouped together. @@ -455,6 +451,7 @@ GenericPluginUI::build () GenericPluginUI::ControlUI::ControlUI () : automate_button (X_("")) // force creation of a label + , file_button(NULL) { automate_button.set_name ("PluginAutomateButton"); ARDOUR_UI::instance()->set_tip (automate_button, _("Automation control")); @@ -652,10 +649,35 @@ GenericPluginUI::build_control_ui (const ParameterDescriptor& desc, return control_ui; } + if (desc.datatype == Variant::PATH) { + + /* Build a file selector button */ + + // Create/add controller + control_ui->file_button = manage(new Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_OPEN)); + control_ui->file_button->set_title(desc.label); + + control_ui->pack_start (control_ui->label, true, true); + control_ui->pack_start (*control_ui->file_button, true, true); + + // Connect signals (TODO: do this via the Control) + control_ui->file_button->signal_file_set().connect( + sigc::bind(sigc::mem_fun(*this, &GenericPluginUI::set_property), + desc, control_ui->file_button)); + plugin->PropertyChanged.connect(*this, invalidator(*this), + boost::bind(&GenericPluginUI::property_changed, this, _1, _2), + gui_context()); + + _property_controls.insert(std::make_pair(desc.key, control_ui->file_button)); + control_ui->file_button = control_ui->file_button; + + return control_ui; + } + /* create the controller */ if (mcontrol) { - control_ui->controller = AutomationController::create(insert, mcontrol->parameter(), mcontrol); + control_ui->controller = AutomationController::create(insert, mcontrol->parameter(), desc, mcontrol); } /* XXX this code is not right yet, because it doesn't handle @@ -663,7 +685,6 @@ GenericPluginUI::build_control_ui (const ParameterDescriptor& desc, */ Adjustment* adj = control_ui->controller->adjustment(); - boost::shared_ptr<PluginInsert::PluginControl> pc = boost::dynamic_pointer_cast<PluginInsert::PluginControl> (control_ui->control); if (desc.integer_step) { control_ui->clickbox = new ClickBox (adj, "PluginUIClickBox"); diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index 51ab79287e..9f6f650f56 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -56,7 +56,7 @@ LV2PluginUI::write_from_ui(void* controller, if (ac) { ac->set_value(*(const float*)buffer); } - } else if (format == me->_lv2->urids.atom_eventTransfer) { + } else if (format == URIMap::instance().urids.atom_eventTransfer) { const int cnt = me->_pi->get_count(); for (int i=0; i < cnt; i++ ) { diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 9ebd56436e..9f4e2effcf 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -241,6 +241,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox bool update_pending; char ignore_change; Gtk::Button automate_button; + Gtk::FileChooserButton* file_button; /* output */ diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index b68e814fba..31c2eb1712 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -2103,7 +2103,7 @@ RouteTimeAxisView::add_automation_child (Evoral::Parameter param, boost::shared_ request_redraw (); } - if (!EventTypeMap::instance().is_midi_parameter(param)) { + if (!ARDOUR::parameter_is_midi((AutomationType)param.type())) { /* MIDI-related parameters are always in the menu, there's no reason to rebuild the menu just because we added a automation lane for one of them. But if we add a non-MIDI automation |