X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fplugin_pin_dialog.cc;h=9cf42c6a75c88b623c8b43c16d99ad823a05fb19;hb=565730525d3406d280e86863a62e48b3607403db;hp=ad11f68a6ad5e0c12f939f392ab12f69a572b024;hpb=9a8a5f4f20d6e6f8495e264880f123ca4b9a1a1b;p=ardour.git diff --git a/gtk2_ardour/plugin_pin_dialog.cc b/gtk2_ardour/plugin_pin_dialog.cc index ad11f68a6a..9cf42c6a75 100644 --- a/gtk2_ardour/plugin_pin_dialog.cc +++ b/gtk2_ardour/plugin_pin_dialog.cc @@ -38,8 +38,10 @@ using namespace Gtkmm2ext; PluginPinDialog::PluginPinDialog (boost::shared_ptr 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 (_("+")) @@ -47,7 +49,10 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr pi) , _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) { assert (pi->owner ()); // Route @@ -63,21 +68,23 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr pi) _plugin_connections, invalidator (*this), boost::bind (&PluginPinDialog::plugin_reconfigured, this), gui_context() ); - darea.signal_expose_event().connect (sigc::mem_fun (*this, &PluginPinDialog::darea_expose_event)); + // 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"); - // TODO min. width depending on # of pins. - darea.set_size_request(600, 200); - _strict_io.set_sensitive (false); - - Label *l; + Label* l; int r = 0; - Table *t = manage (new Table (4, 3)); + Table* t = manage (new Table (4, 3)); t->set_border_width (0); t->set_spacings (4); 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); @@ -88,6 +95,8 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr pi) 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); @@ -95,10 +104,16 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr pi) 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 (_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 (_strict_io, 1, 2, r, r + 1, FILL, SHRINK); - t->attach (_automatic, 2, 3, r, r + 1, FILL, SHRINK); + 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)); @@ -126,39 +141,153 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr pi) VBox* vbox = manage (new VBox); vbox->pack_start (*hbox, true, true); add (*vbox); - vbox->show_all(); + vbox->show_all (); plugin_reconfigured (); - _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.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK); + 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 () { } void PluginPinDialog::plugin_reconfigured () { - uint32_t plugins = _pi->get_count (); - ChanCount in, out; - _pi->configured_io (in, out); + if (_ignore_updates) { + return; + } + _n_plugins = _pi->get_count (); + _pi->configured_io (_in, _out); + _sinks = _pi->natural_input_streams (); + _sources = _pi->natural_output_streams (); + + _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); + _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 (); +} + +void +PluginPinDialog::update_elements () +{ + _elements.clear (); + _hover.reset (); + _actor.reset (); + _selection.reset (); + + for (uint32_t i = 0; i < _in.n_total (); ++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)); + } - _del_plugin.set_sensitive (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()); + for (uint32_t i = 0; i < _out.n_total (); ++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) { + _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) { + _elements.push_back (CtrlWidget (Source, (i < _sources.n_midi () ? DataType::MIDI : DataType::AUDIO), i, n)); + } + } + _position_valid = false; darea.queue_draw (); } +void +PluginPinDialog::update_element_pos () +{ + /* layout sizes */ + const double yc = rint (_height * .5); + const double bxh2 = 18; + const double bxw = rint ((_width * .9) / ((_n_plugins) + .2 * (_n_plugins - 1))); + const double bxw2 = rint (bxw * .5); + const double y_in = 40; + const double y_out = _height - 40; + + _pin_box_size = rint (max (6., 8. * UIConfiguration::instance ().get_ui_scale ())); + + for (CtrlElemList::iterator i = _elements.begin (); i != _elements.end (); ++i) { + switch (i->e->ct) { + case Input: + { + 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: + { + 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: + { + const double x0 = rint ((i->e->ip + .5) * _width / (double)(_n_plugins)) - .5 - bxw2; + i->x = rint (x0 + (i->e->id + 1) * bxw / (1. + _sinks.n_total ())) - .5 - _pin_box_size * .5; + i->y = yc - bxh2 - _pin_box_size; + i->w = _pin_box_size + 1; + i->h = _pin_box_size; + } + break; + case Source: + { + const double x0 = rint ((i->e->ip + .5) * _width / (double)(_n_plugins)) - .5 - bxw2; + i->x = rint (x0 + (i->e->id + 1) * bxw / (1. + _sources.n_total ())) - .5 - _pin_box_size * .5; + i->y = yc + bxh2; + i->w = _pin_box_size + 1; + i->h = _pin_box_size; + } + break; + } + } + +} + void PluginPinDialog::set_color (cairo_t* cr, bool midi) { @@ -168,47 +297,55 @@ PluginPinDialog::set_color (cairo_t* cr, bool midi) 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)); } } void -PluginPinDialog::draw_io_pins (cairo_t* cr, double y0, double width, uint32_t n_total, uint32_t n_midi, bool input) +PluginPinDialog::draw_io_pin (cairo_t* cr, const CtrlWidget& w) { - double dir = input ? 1. : -1.; - - for (uint32_t i = 0; i < n_total; ++i) { - double x0 = rint ((i + 1) * width / (1. + n_total)) - .5; - cairo_move_to (cr, x0, y0); - cairo_rel_line_to (cr, -5., -5. * dir); - cairo_rel_line_to (cr, 0., -25. * dir); - cairo_rel_line_to (cr, 10., 0.); - cairo_rel_line_to (cr, 0., 25. * dir); - cairo_close_path (cr); - - cairo_set_source_rgb (cr, 0, 0, 0); - cairo_stroke_preserve (cr); - - set_color (cr, i < n_midi); - cairo_fill (cr); + const double dir = (w.e->ct == Input) ? 1 : -1; + + cairo_move_to (cr, w.x + 5.0, w.y + ((w.e->ct == Input) ? 25 : 0)); + cairo_rel_line_to (cr, -5., -5. * dir); + cairo_rel_line_to (cr, 0., -25. * dir); + cairo_rel_line_to (cr, 10., 0.); + cairo_rel_line_to (cr, 0., 25. * dir); + cairo_close_path (cr); + + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_stroke_preserve (cr); + + set_color (cr, w.e->dt == DataType::MIDI); + if (w.e == _selection || w.e == _actor) { + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); + } else if (w.prelight) { + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5); } + cairo_fill (cr); } -bool -PluginPinDialog::is_valid_port (uint32_t i, uint32_t n_total, uint32_t n_midi, bool midi) +void +PluginPinDialog::draw_plugin_pin (cairo_t* cr, const CtrlWidget& w) { - if (!midi) { i += n_midi; } - if (i >= n_total) { - return false; + cairo_rectangle (cr, w.x, w.y, w.w, w.h); + set_color (cr, w.e->dt == DataType::MIDI); + if (w.e == _selection || w.e == _actor) { + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); + } else if (w.prelight) { + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5); } - return true; + cairo_fill (cr); } double @@ -218,30 +355,16 @@ PluginPinDialog::pin_x_pos (uint32_t i, double x0, double width, uint32_t n_tota return rint (x0 + (i + 1) * width / (1. + n_total)) - .5; } -void -PluginPinDialog::draw_plugin_pins (cairo_t* cr, double x0, double y0, double width, uint32_t n_total, uint32_t n_midi, bool input) -{ - // see also ProcessorEntry::PortIcon::on_expose_event - const double dxy = _pin_box_size; - - for (uint32_t i = 0; i < n_total; ++i) { - double x = rint (x0 + (i + 1) * width / (1. + n_total)) - .5; - cairo_rectangle (cr, x - dxy * .5, input ? y0 - dxy : y0, 1 + dxy, dxy); - - set_color (cr, i < n_midi); - cairo_fill(cr); - } -} - void PluginPinDialog::draw_connection (cairo_t* cr, double x0, double x1, double y0, double y1, bool midi, bool dashed) { - double bz = 2 * _pin_box_size; + 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_set_line_width (cr, 3.0); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + 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); if (dashed) { const double dashes[] = { 5, 7 }; @@ -257,80 +380,68 @@ PluginPinDialog::draw_connection (cairo_t* cr, double x0, double x1, double y0, 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(); - - _pin_box_size = rint (max (6., 8. * UIConfiguration::instance().get_ui_scale())); - - cairo_t* cr = gdk_cairo_create (darea.get_window()->gobj()); + Gtk::Allocation a = darea.get_allocation (); + double const width = a.get_width (); + double const height = a.get_height (); + + if (!_position_valid) { + _width = width; + _height = height; + update_element_pos (); + _position_valid = true; + } + 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); - ChanCount in, out; // actual configured i/o - _pi->configured_io (in, out); - - ChanCount sinks = _pi->natural_input_streams (); - ChanCount sources = _pi->natural_output_streams (); - uint32_t plugins = _pi->get_count (); - - /* layout sizes */ + /* layout sizes -- TODO consolidate w/ update_element_pos() */ // i/o pins - double y_in = 40; - double y_out = height - 40; + const double y_in = 40; + const double y_out = height - 40; // plugin box(es) - double yc = rint (height * .5); - double bxh2 = 18; - double bxw = rint ((width * .9) / ((plugins) + .2 * (plugins - 1))); - double bxw2 = rint (bxw * .5); - - // i/o pins - 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 double yc = rint (height * .5); + const double bxh2 = 18; + const double bxw = rint ((width * .9) / ((_n_plugins) + .2 * (_n_plugins - 1))); + const double bxw2 = rint (bxw * .5); - cairo_set_line_width (cr, 1.0); - draw_io_pins (cr, y_in, width, pc_in, pc_in_midi, true); - draw_io_pins (cr, y_out, width, pc_out, pc_out_midi, false); + 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) + /* draw midi-bypass (behind) */ if (_pi->has_midi_bypass ()) { double x0 = rint (width / (1. + pc_in)) - .5; double x1 = rint (width / (1. + pc_out)) - .5; draw_connection (cr, x0, x1, y_in, y_out, true, true); } - for (uint32_t i = 0; i < plugins; ++i) { - double x0 = rint ((i + .5) * width / (double)(plugins)) - .5; - - draw_plugin_pins (cr, x0 - bxw2, yc - bxh2, bxw, sinks.n_total (), sinks.n_midi (), true); - draw_plugin_pins (cr, x0 - bxw2, yc + bxh2, bxw, sources.n_total (), sources.n_midi (), false); + /* plugins & connection wires */ + for (uint32_t i = 0; i < _n_plugins; ++i) { + double x0 = rint ((i + .5) * width / (double)(_n_plugins)) - .5; + /* plugin box */ cairo_set_source_rgb (cr, .3, .3, .3); 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); + 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); } } @@ -338,45 +449,222 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev) for (ChanMapping::Mappings::const_iterator t = out_map.begin (); t != out_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 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_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) { + switch (i->e->ct) { + case Input: + case Output: + draw_io_pin (cr, *i); + break; + case Sink: + case Source: + draw_plugin_pin (cr, *i); + break; + } + } + cairo_destroy (cr); return true; } void -PluginPinDialog::automatic_clicked () +PluginPinDialog::darea_size_request (Gtk::Requisition* req) +{ + req->width = _min_width; + req->height = 200; +} + +void +PluginPinDialog::darea_size_allocate (Gtk::Allocation&) +{ + _position_valid = false; +} + +bool +PluginPinDialog::darea_motion_notify_event (GdkEventMotion* ev) +{ + bool changed = false; + _hover.reset (); + 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) + { + if (!i->prelight) changed = true; + i->prelight = true; + _hover = i->e; + } else { + if (i->prelight) changed = true; + i->prelight = false; + } + } + if (changed) { + darea.queue_draw (); + } + return true; +} + +bool +PluginPinDialog::darea_button_press_event (GdkEventButton* ev) +{ + if (ev->type != GDK_BUTTON_PRESS) { + return false; + } + + switch (ev->button) { + case 1: + if (!_selection || (_selection && !_hover)) { + _selection = _hover; + _actor.reset (); + darea.queue_draw (); + } else if (_selection && _hover && _selection != _hover) { + if (_selection->dt != _hover->dt) { _actor.reset (); } + else if (_selection->ct == Input && _hover->ct == Sink) { _actor = _hover; } + else if (_selection->ct == Sink && _hover->ct == Input) { _actor = _hover; } + else if (_selection->ct == Output && _hover->ct == Source) { _actor = _hover; } + else if (_selection->ct == Source && _hover->ct == Output) { _actor = _hover; } + if (!_actor) { + _selection = _hover; + } + darea.queue_draw (); + } + case 3: + if (_hover) { + } + break; + default: + break; + } + + return true; +} + +bool +PluginPinDialog::darea_button_release_event (GdkEventButton* ev) +{ + if (_hover == _actor && _actor) { + assert (_selection); + assert (_selection->dt == _actor->dt); + if (_selection->ct == Input && _actor->ct == Sink) { + handle_input_action (_actor, _selection); + } + else if (_selection->ct == Sink && _actor->ct == Input) { + handle_input_action (_selection, _actor); + } + else if (_selection->ct == Output && _actor->ct == Source) { + handle_output_action (_actor, _selection); + } + else if (_selection->ct == Source && _actor->ct == Output) { + handle_output_action (_selection, _actor); + } + _selection.reset (); + } + _actor.reset (); + darea.queue_draw (); + return true; +} + +void +PluginPinDialog::handle_input_action (const CtrlElem &s, const CtrlElem &i) +{ + const int pc = s->ip; + bool valid; + ChanMapping in_map (_pi->input_map (pc)); + uint32_t idx = in_map.get (s->dt, s->id, &valid); + + if (valid && idx == i->id) { + // disconnect + in_map.unset (s->dt, s->id); + _pi->set_input_map (pc, in_map); + } + else if (!valid) { + // connect + in_map.set (s->dt, s->id, i->id); + _pi->set_input_map (pc, in_map); + } + else { + // reconnect + in_map.unset (s->dt, s->id); + in_map.set (s->dt, s->id, i->id); + _pi->set_input_map (pc, in_map); + } +} + +void +PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o) +{ + 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); + + if (valid && idx == o->id) { + // disconnect + out_map.unset (s->dt, s->id); + _pi->set_output_map (pc, out_map); + } + else { + // disconnect source + if (valid) { + out_map.unset (s->dt, s->id); + } + // disconnect other outputs + _ignore_updates = true; + for (uint32_t n = 0; n < _n_plugins; ++n) { + if (n == pc) { + continue; + } + ChanMapping n_out_map (_pi->output_map (n)); + idx = n_out_map.get_src (s->dt, o->id, &valid); + if (valid) { + n_out_map.unset (s->dt, idx); + _pi->set_output_map (n, n_out_map); + } + } + _ignore_updates = false; + idx = out_map.get_src (s->dt, o->id, &valid); + if (valid) { + out_map.unset (s->dt, idx); + } + // connect + out_map.set (s->dt, s->id, o->id); + _pi->set_output_map (pc, out_map); + } +} + +void +PluginPinDialog::reset_configuration () +{ + _route ()->reset_plugin_insert (_pi); +} + +void +PluginPinDialog::reset_mapping () { - _route()->reset_plugin_insert (_pi); + _pi->reset_map (); } void PluginPinDialog::add_remove_plugin_clicked (bool add) { - uint32_t plugins = _pi->get_count (); - ChanCount in, out; - _pi->configured_io (in, out); - assert (add || plugins > 0); - _route()->customize_plugin_insert (_pi, plugins + (add ? 1 : -1), out); + ChanCount out = _out; + assert (add || _n_plugins > 0); + _route ()->customize_plugin_insert (_pi, _n_plugins + (add ? 1 : -1), out); } void PluginPinDialog::add_remove_port_clicked (bool add, ARDOUR::DataType dt) { - uint32_t plugins = _pi->get_count (); - ChanCount in, out; - _pi->configured_io (in, out); + ChanCount out = _out; assert (add || out.get (dt) > 0); out.set (dt, out.get (dt) + (add ? 1 : -1)); - _route()->customize_plugin_insert (_pi, plugins, out); + _route ()->customize_plugin_insert (_pi, _n_plugins, out); }