summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/automation_controller.cc36
-rw-r--r--gtk2_ardour/automation_controller.h11
-rw-r--r--gtk2_ardour/automation_line.cc18
-rw-r--r--gtk2_ardour/automation_line.h7
-rw-r--r--gtk2_ardour/automation_time_axis.cc7
-rw-r--r--gtk2_ardour/generic_pluginui.cc151
-rw-r--r--gtk2_ardour/lv2_plugin_ui.cc2
-rw-r--r--gtk2_ardour/plugin_ui.h1
-rw-r--r--gtk2_ardour/route_time_axis.cc2
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