PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> pi)
: ArdourWindow (string_compose (_("Pin Configuration: %1"), pi->name ()))
- , _strict_io (_("Strict I/O"))
- , _automatic (_("Automatic"))
+ , _ind_strict_io (_("Strict I/O"))
+ , _ind_customized (_("Customized"))
+ , _rst_config (_("Configuration"))
+ , _rst_mapping (_("Connections"))
, _add_plugin (_("+"))
, _del_plugin (_("-"))
, _add_output_audio (_("+"))
, _add_output_midi (_("+"))
, _del_output_midi (_("-"))
, _pi (pi)
- , _pin_box_size (4)
+ , _pin_box_size (8)
+ , _min_width (300)
, _position_valid (false)
, _ignore_updates (false)
{
_plugin_connections, invalidator (*this), boost::bind (&PluginPinDialog::plugin_reconfigured, this), gui_context()
);
- // TODO min. width depending on # of pins.
- darea.set_size_request(600, 200);
- _strict_io.set_sensitive (false);
+ // needs a better way: insensitive indicators
+ _ind_strict_io.set_sensitive (false); // track status
+ _ind_strict_io.set_name ("rude solo");
+ _ind_customized.set_sensitive (false); // plugin status
+ _ind_customized.set_name ("rude solo");
Label* l;
int r = 0;
l = manage (new Label (_("Track/Bus:"), ALIGN_END));
t->attach (*l, 0, 1, r, r + 1);
l = manage (new Label ());
+ l->set_alignment (ALIGN_START);
+ l->set_padding (2, 1);
l->set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
l->set_width_chars (24);
l->set_max_width_chars (24);
l = manage (new Label (_("Plugin:"), ALIGN_END));
t->attach (*l, 0, 1, r, r + 1);
l = manage (new Label ());
+ l->set_alignment(ALIGN_START);
+ l->set_padding (2, 1);
l->set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
l->set_width_chars (24);
l->set_max_width_chars (24);
t->attach (*l, 1, 3, r, r + 1);
++r;
- l = manage (new Label (_("Settings:"), ALIGN_END));
+ l = manage (new Label (_("Status:"), ALIGN_END));
t->attach (*l, 0, 1, r, r + 1);
- t->attach (_strict_io, 1, 2, r, r + 1, FILL, SHRINK);
- t->attach (_automatic, 2, 3, r, r + 1, FILL, SHRINK);
+ t->attach (_ind_strict_io, 1, 2, r, r + 1, FILL, SHRINK);
+ t->attach (_ind_customized, 2, 3, r, r + 1, FILL, SHRINK);
+ ++r;
+
+ l = manage (new Label (_("Reset:"), ALIGN_END));
+ t->attach (*l, 0, 1, r, r + 1);
+ t->attach (_rst_mapping, 1, 2, r, r + 1, FILL, SHRINK);
+ t->attach (_rst_config, 2, 3, r, r + 1, FILL, SHRINK);
++r;
l = manage (new Label (_("Instances:"), ALIGN_END));
VBox* vbox = manage (new VBox);
vbox->pack_start (*hbox, true, true);
add (*vbox);
- vbox->show_all();
+ vbox->show_all ();
plugin_reconfigured ();
darea.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
- darea.signal_size_allocate().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_size_allocate));
- darea.signal_expose_event().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_expose_event));
- darea.signal_button_press_event().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_button_press_event));
- darea.signal_button_release_event().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_button_release_event));
- darea.signal_motion_notify_event().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_motion_notify_event));
-
- _automatic.signal_clicked.connect (sigc::mem_fun(*this, &PluginPinDialog::automatic_clicked));
- _add_plugin.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_plugin_clicked), true));
- _del_plugin.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_plugin_clicked), false));
-
- _add_output_audio.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_port_clicked), true, DataType::AUDIO));
- _del_output_audio.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_port_clicked), false, DataType::AUDIO));
- _add_output_midi.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_port_clicked), true, DataType::MIDI));
- _del_output_midi.signal_clicked.connect (sigc::bind (sigc::mem_fun(*this, &PluginPinDialog::add_remove_port_clicked), false, DataType::MIDI));
+ darea.signal_size_request ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_size_request));
+ darea.signal_size_allocate ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_size_allocate));
+ darea.signal_expose_event ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_expose_event));
+ darea.signal_button_press_event ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_button_press_event));
+ darea.signal_button_release_event ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_button_release_event));
+ darea.signal_motion_notify_event ().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_motion_notify_event));
+
+ _rst_mapping.signal_clicked.connect (sigc::mem_fun (*this, &PluginPinDialog::reset_mapping));
+ _rst_config.signal_clicked.connect (sigc::mem_fun (*this, &PluginPinDialog::reset_configuration));
+ _add_plugin.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_plugin_clicked), true));
+ _del_plugin.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_plugin_clicked), false));
+
+ _add_output_audio.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_port_clicked), true, DataType::AUDIO));
+ _del_output_audio.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_port_clicked), false, DataType::AUDIO));
+ _add_output_midi.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_port_clicked), true, DataType::MIDI));
+ _del_output_midi.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &PluginPinDialog::add_remove_port_clicked), false, DataType::MIDI));
}
-PluginPinDialog::~PluginPinDialog()
+PluginPinDialog::~PluginPinDialog ()
{
}
_del_plugin.set_sensitive (_n_plugins > 1);
_del_output_audio.set_sensitive (_out.n_audio () > 0 && _out.n_total () > 1);
_del_output_midi.set_sensitive (_out.n_midi () > 0 && _out.n_total () > 1);
- _strict_io.set_active (_pi->strict_io());
+ _ind_strict_io.set_active (_pi->strict_io ());
+ _ind_customized.set_active (_pi->custom_cfg ());
+
+ // calc minimum width
+ const uint32_t max_ports = std::max (_in.n_total (), _out.n_total ());
+ const uint32_t max_pins = std::max ((_sinks * _n_plugins).n_total (), (_sources * _n_plugins).n_total ());
+ uint32_t min_width = std::max (25 * max_ports, (uint32_t)(20 + _pin_box_size) * max_pins);
+ min_width = std::max (min_width, 64 * _n_plugins); // bxh2 = 18 ; aspect 16:9 (incl. 10% space)
+ min_width = std::max ((uint32_t)300, min_width);
+ min_width = 10 * ceilf (min_width / 10.f);
+ if (min_width != _min_width) {
+ _min_width = min_width;
+ darea.queue_resize ();
+ }
update_elements ();
}
PluginPinDialog::update_elements ()
{
_elements.clear ();
- _hover.reset();
- _actor.reset();
- _selection.reset();
+ _hover.reset ();
+ _actor.reset ();
+ _selection.reset ();
for (uint32_t i = 0; i < _in.n_total (); ++i) {
- _elements.push_back (CtrlWidget (Input, (i < _in.n_midi () ? DataType::MIDI : DataType::AUDIO), i));
+ int id = (i < _in.n_midi ()) ? i : i - _in.n_midi ();
+ _elements.push_back (CtrlWidget (Input, (i < _in.n_midi () ? DataType::MIDI : DataType::AUDIO), id));
}
for (uint32_t i = 0; i < _out.n_total (); ++i) {
- _elements.push_back (CtrlWidget (Output, (i < _out.n_midi () ? DataType::MIDI : DataType::AUDIO), i));
+ int id = (i < _out.n_midi ()) ? i : i - _out.n_midi ();
+ _elements.push_back (CtrlWidget (Output, (i < _out.n_midi () ? DataType::MIDI : DataType::AUDIO), id));
}
for (uint32_t n = 0; n < _n_plugins; ++n) {
- for (uint32_t i = 0; i < _sinks.n_total(); ++i) {
+ for (uint32_t i = 0; i < _sinks.n_total (); ++i) {
_elements.push_back (CtrlWidget (Sink, (i < _sinks.n_midi () ? DataType::MIDI : DataType::AUDIO), i, n));
}
- for (uint32_t i = 0; i < _sources.n_total(); ++i) {
+ for (uint32_t i = 0; i < _sources.n_total (); ++i) {
_elements.push_back (CtrlWidget (Source, (i < _sources.n_midi () ? DataType::MIDI : DataType::AUDIO), i, n));
}
}
const double y_in = 40;
const double y_out = _height - 40;
- _pin_box_size = rint (max (6., 8. * UIConfiguration::instance().get_ui_scale()));
+ _pin_box_size = rint (max (6., 8. * UIConfiguration::instance ().get_ui_scale ()));
- for (CtrlElemList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ for (CtrlElemList::iterator i = _elements.begin (); i != _elements.end (); ++i) {
switch (i->e->ct) {
case Input:
- i->x = rint ((i->e->id + 1) * _width / (1. + _in.n_total ())) - 5.5;
- i->y = y_in - 25;
- i->w = 10;
- i->h = 25;
+ {
+ uint32_t idx = i->e->id;
+ if (i->e->dt == DataType::AUDIO) { idx += _in.n_midi (); }
+ i->x = rint ((idx + 1) * _width / (1. + _in.n_total ())) - 5.5;
+ i->y = y_in - 25;
+ i->w = 10;
+ i->h = 25;
+ }
break;
case Output:
- i->x = rint ((i->e->id + 1) * _width / (1. + _out.n_total ())) - 5.5;
- i->y = y_out;
- i->w = 10;
- i->h = 25;
+ {
+ uint32_t idx = i->e->id;
+ if (i->e->dt == DataType::AUDIO) { idx += _out.n_midi (); }
+ i->x = rint ((idx + 1) * _width / (1. + _out.n_total ())) - 5.5;
+ i->y = y_out;
+ i->w = 10;
+ i->h = 25;
+ }
break;
case Sink:
{
if (midi) {
cairo_set_source_rgb (cr,
- UINT_RGBA_R_FLT(midi_port_color),
- UINT_RGBA_G_FLT(midi_port_color),
- UINT_RGBA_B_FLT(midi_port_color));
+ UINT_RGBA_R_FLT (midi_port_color),
+ UINT_RGBA_G_FLT (midi_port_color),
+ UINT_RGBA_B_FLT (midi_port_color));
} else {
cairo_set_source_rgb (cr,
- UINT_RGBA_R_FLT(audio_port_color),
- UINT_RGBA_G_FLT(audio_port_color),
- UINT_RGBA_B_FLT(audio_port_color));
+ UINT_RGBA_R_FLT (audio_port_color),
+ UINT_RGBA_G_FLT (audio_port_color),
+ UINT_RGBA_B_FLT (audio_port_color));
}
}
cairo_fill (cr);
}
-bool
-PluginPinDialog::is_valid_port (uint32_t i, uint32_t n_total, uint32_t n_midi, bool midi)
-{
- if (!midi) { i += n_midi; }
- if (i >= n_total) {
- return false;
- }
- return true;
-}
-
double
PluginPinDialog::pin_x_pos (uint32_t i, double x0, double width, uint32_t n_total, uint32_t n_midi, bool midi)
{
PluginPinDialog::draw_connection (cairo_t* cr, double x0, double x1, double y0, double y1, bool midi, bool dashed)
{
const double bz = 2 * _pin_box_size;
+ const double bc = dashed ? 1.25 * _pin_box_size : 0;
cairo_move_to (cr, x0, y0);
- cairo_curve_to (cr, x0, y0 + bz, x1, y1 - bz, x1, y1);
+ cairo_curve_to (cr, x0 - bc, y0 + bz, x1 - bc, y1 - bz, x1, y1);
cairo_set_line_width (cr, 3.0);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_set_source_rgb (cr, 1, 0, 0);
bool
PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
{
- Gtk::Allocation a = darea.get_allocation();
- double const width = a.get_width();
- double const height = a.get_height();
+ Gtk::Allocation a = darea.get_allocation ();
+ double const width = a.get_width ();
+ double const height = a.get_height ();
if (!_position_valid) {
_width = width;
_position_valid = true;
}
- cairo_t* cr = gdk_cairo_create (darea.get_window()->gobj());
+ cairo_t* cr = gdk_cairo_create (darea.get_window ()->gobj ());
cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
cairo_clip (cr);
- Gdk::Color const bg = get_style()->get_bg (STATE_NORMAL);
+ Gdk::Color const bg = get_style ()->get_bg (STATE_NORMAL);
cairo_set_source_rgb (cr, bg.get_red_p (), bg.get_green_p (), bg.get_blue_p ());
cairo_rectangle (cr, 0, 0, width, height);
cairo_fill (cr);
const double bxw = rint ((width * .9) / ((_n_plugins) + .2 * (_n_plugins - 1)));
const double bxw2 = rint (bxw * .5);
- const uint32_t pc_in = _in.n_total();
- const uint32_t pc_in_midi = _in.n_midi();
- const uint32_t pc_out = _out.n_total();
- const uint32_t pc_out_midi = _out.n_midi();
+ const uint32_t pc_in = _in.n_total ();
+ const uint32_t pc_in_midi = _in.n_midi ();
+ const uint32_t pc_out = _out.n_total ();
+ const uint32_t pc_out_midi = _out.n_midi ();
/* draw midi-bypass (behind) */
if (_pi->has_midi_bypass ()) {
rounded_rectangle (cr, x0 - bxw2, yc - bxh2, bxw, 2 * bxh2, 7);
cairo_fill (cr);
- const ChanMapping::Mappings in_map = _pi->input_map (i).mappings();
- const ChanMapping::Mappings out_map = _pi->output_map (i).mappings();
+ const ChanMapping::Mappings in_map = _pi->input_map (i).mappings ();
+ const ChanMapping::Mappings out_map = _pi->output_map (i).mappings ();
for (ChanMapping::Mappings::const_iterator t = in_map.begin (); t != in_map.end (); ++t) {
bool is_midi = t->first == DataType::MIDI;
for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
uint32_t pn = (*c).first; // pin
uint32_t pb = (*c).second;
- if (!is_valid_port (pb, pc_in, pc_in_midi, is_midi)) {
- continue;
- }
double c_x0 = pin_x_pos (pb, 0, width, pc_in, pc_in_midi, is_midi);
double c_x1 = pin_x_pos (pn, x0 - bxw2, bxw, _sinks.n_total (), _sinks.n_midi (), is_midi);
draw_connection (cr, c_x0, c_x1, y_in, yc - bxh2 - _pin_box_size, is_midi);
for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
uint32_t pn = (*c).first; // pin
uint32_t pb = (*c).second;
- if (!is_valid_port (pb, pc_out, pc_out_midi, is_midi)) {
- continue;
- }
double c_x0 = pin_x_pos (pn, x0 - bxw2, bxw, _sources.n_total (), _sources.n_midi (), is_midi);
double c_x1 = pin_x_pos (pb, 0, width, pc_out, pc_out_midi, is_midi);
draw_connection (cr, c_x0, c_x1, yc + bxh2 + _pin_box_size, y_out, is_midi);
}
/* pins and ports */
- for (CtrlElemList::const_iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ for (CtrlElemList::const_iterator i = _elements.begin (); i != _elements.end (); ++i) {
switch (i->e->ct) {
case Input:
case Output:
return true;
}
+void
+PluginPinDialog::darea_size_request (Gtk::Requisition* req)
+{
+ req->width = _min_width;
+ req->height = 200;
+}
+
void
PluginPinDialog::darea_size_allocate (Gtk::Allocation&)
{
{
bool changed = false;
_hover.reset ();
- for (CtrlElemList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ for (CtrlElemList::iterator i = _elements.begin (); i != _elements.end (); ++i) {
if (ev->x >= i->x && ev->x <= i->x + i->w
&& ev->y >= i->y && ev->y <= i->y + i->h)
{
void
PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
{
- const int pc = s->ip;
+ const uint32_t pc = s->ip;
bool valid;
ChanMapping out_map (_pi->output_map (pc));
uint32_t idx = out_map.get (s->dt, s->id, &valid);
}
void
-PluginPinDialog::automatic_clicked ()
+PluginPinDialog::reset_configuration ()
+{
+ _route ()->reset_plugin_insert (_pi);
+}
+
+void
+PluginPinDialog::reset_mapping ()
{
- _route()->reset_plugin_insert (_pi);
+ _pi->reset_map ();
}
void
{
ChanCount out = _out;
assert (add || _n_plugins > 0);
- _route()->customize_plugin_insert (_pi, _n_plugins + (add ? 1 : -1), out);
+ _route ()->customize_plugin_insert (_pi, _n_plugins + (add ? 1 : -1), out);
}
void
ChanCount out = _out;
assert (add || out.get (dt) > 0);
out.set (dt, out.get (dt) + (add ? 1 : -1));
- _route()->customize_plugin_insert (_pi, _n_plugins, out);
+ _route ()->customize_plugin_insert (_pi, _n_plugins, out);
}