NO-OP, whitespace
[ardour.git] / gtk2_ardour / plugin_pin_dialog.cc
index eb4d0482b1bde0175678d08fceb54a5cc598e45e..9cf42c6a75c88b623c8b43c16d99ad823a05fb19 100644 (file)
@@ -38,8 +38,10 @@ using namespace Gtkmm2ext;
 
 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 (_("+"))
@@ -47,8 +49,10 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> 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
 
@@ -64,9 +68,11 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> pi)
                        _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;
@@ -77,6 +83,8 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> pi)
        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);
@@ -87,6 +95,8 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> 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);
@@ -94,10 +104,16 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> 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 (_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));
@@ -125,34 +141,39 @@ PluginPinDialog::PluginPinDialog (boost::shared_ptr<ARDOUR::PluginInsert> pi)
        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 ()
 {
 }
 
 void
 PluginPinDialog::plugin_reconfigured ()
 {
+       if (_ignore_updates) {
+               return;
+       }
        _n_plugins = _pi->get_count ();
        _pi->configured_io (_in, _out);
        _sinks = _pi->natural_input_streams ();
@@ -161,7 +182,20 @@ PluginPinDialog::plugin_reconfigured ()
        _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 ();
 }
@@ -170,23 +204,25 @@ void
 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));
                }
        }
@@ -205,21 +241,29 @@ PluginPinDialog::update_element_pos ()
        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:
                                {
@@ -253,14 +297,14 @@ 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));
        }
 }
 
@@ -304,16 +348,6 @@ PluginPinDialog::draw_plugin_pin (cairo_t* cr, const CtrlWidget& w)
        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)
 {
@@ -325,9 +359,10 @@ void
 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);
@@ -345,9 +380,9 @@ 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();
+       Gtk::Allocation a = darea.get_allocation ();
+       double const width = a.get_width ();
+       double const height = a.get_height ();
 
        if (!_position_valid) {
                _width = width;
@@ -356,11 +391,11 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
                _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);
@@ -376,10 +411,10 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
        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 ()) {
@@ -397,17 +432,14 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
                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);
@@ -419,9 +451,6 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
                        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);
@@ -430,7 +459,7 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
        }
 
        /* 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:
@@ -447,6 +476,13 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
        return true;
 }
 
+void
+PluginPinDialog::darea_size_request (Gtk::Requisition* req)
+{
+       req->width = _min_width;
+       req->height = 200;
+}
+
 void
 PluginPinDialog::darea_size_allocate (Gtk::Allocation&)
 {
@@ -458,7 +494,7 @@ PluginPinDialog::darea_motion_notify_event (GdkEventMotion* ev)
 {
        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)
                {
@@ -565,7 +601,7 @@ PluginPinDialog::handle_input_action (const CtrlElem &s, const CtrlElem &i)
 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);
@@ -581,7 +617,20 @@ PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
                        out_map.unset (s->dt, s->id);
                }
                // disconnect other outputs
-               uint32_t idx = out_map.get_src (s->dt, o->id, &valid);
+               _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);
                }
@@ -592,9 +641,15 @@ PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
 }
 
 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
@@ -602,7 +657,7 @@ PluginPinDialog::add_remove_plugin_clicked (bool add)
 {
        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
@@ -611,5 +666,5 @@ PluginPinDialog::add_remove_port_clicked (bool add, ARDOUR::DataType dt)
        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);
 }