summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-04-07 18:36:04 +0200
committerRobin Gareus <robin@gareus.org>2016-04-07 18:36:04 +0200
commit3868c5b4a4a4a41e7568da039345472ed4da71f0 (patch)
tree75b87e09186fa2348ed49d0b2425a4cf4ac491c3 /gtk2_ardour
parent18713b7d1fc4a1fcec0a60f2c80a327b50b9c529 (diff)
GUI support for plugin port bypass connections
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/plugin_pin_dialog.cc124
-rw-r--r--gtk2_ardour/plugin_pin_dialog.h3
-rw-r--r--gtk2_ardour/processor_box.cc72
-rw-r--r--gtk2_ardour/processor_box.h27
4 files changed, 181 insertions, 45 deletions
diff --git a/gtk2_ardour/plugin_pin_dialog.cc b/gtk2_ardour/plugin_pin_dialog.cc
index 18c6852b0c..0096f8d913 100644
--- a/gtk2_ardour/plugin_pin_dialog.cc
+++ b/gtk2_ardour/plugin_pin_dialog.cc
@@ -712,6 +712,16 @@ PluginPinDialog::darea_expose_event (GdkEventExpose* ev)
draw_connection (cr, cw0, cw1, true);
}
+ /* thru connections */
+ const ChanMapping::Mappings thru_map = _pi->thru_map ().mappings ();
+ for (ChanMapping::Mappings::const_iterator t = thru_map.begin (); t != thru_map.end (); ++t) {
+ for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
+ const CtrlWidget& cw0 = get_io_ctrl (Output, t->first, c->first);
+ const CtrlWidget& cw1 = get_io_ctrl (Input, t->first, c->second);
+ draw_connection (cr, cw1, cw0, true);
+ }
+ }
+
/* labels */
Glib::RefPtr<Pango::Layout> layout;
layout = Pango::Layout::create (get_pango_context ());
@@ -842,10 +852,12 @@ PluginPinDialog::drag_type_matches (CtrlType ct) {
if (!_dragging || !_selection) {
return true;
}
- if (_selection->ct == Input && ct == Sink) { return true; }
- if (_selection->ct == Sink && ct == Input) { return true; }
+ if (_selection->ct == Input && ct == Sink) { return true; }
+ if (_selection->ct == Sink && ct == Input) { return true; }
if (_selection->ct == Output && ct == Source) { return true; }
if (_selection->ct == Source && ct == Output) { return true; }
+ if (_selection->ct == Input && ct == Output) { return true; }
+ if (_selection->ct == Output && ct == Input) { return true; }
return false;
}
@@ -896,10 +908,12 @@ PluginPinDialog::darea_button_press_event (GdkEventButton* ev)
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 == 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; }
+ else if (_selection->ct == Input && _hover->ct == Output) { _actor = _hover; }
+ else if (_selection->ct == Output && _hover->ct == Input) { _actor = _hover; }
if (!_actor) {
_selection = _hover;
_dragging = true;
@@ -950,6 +964,12 @@ PluginPinDialog::darea_button_release_event (GdkEventButton* ev)
else if (_selection->ct == Source && _actor->ct == Output) {
handle_output_action (_selection, _actor);
}
+ else if (_selection->ct == Input && _actor->ct == Output) {
+ handle_thru_action (_actor, _selection);
+ }
+ else if (_selection->ct == Output && _actor->ct == Input) {
+ handle_thru_action (_selection, _actor);
+ }
_selection.reset ();
} else if (_hover == _selection && _selection && ev->button == 3) {
handle_disconnect (_selection);
@@ -989,6 +1009,39 @@ PluginPinDialog::handle_input_action (const CtrlElem &s, const CtrlElem &i)
}
void
+PluginPinDialog::disconnect_other_outputs (uint32_t skip_pc, DataType dt, uint32_t id)
+{
+ _ignore_updates = true;
+ for (uint32_t n = 0; n < _n_plugins; ++n) {
+ if (n == skip_pc) {
+ continue;
+ }
+ bool valid;
+ ChanMapping n_out_map (_pi->output_map (n));
+ uint32_t idx = n_out_map.get_src (dt, id, &valid);
+ if (valid) {
+ n_out_map.unset (dt, idx);
+ _pi->set_output_map (n, n_out_map);
+ }
+ }
+ _ignore_updates = false;
+}
+
+void
+PluginPinDialog::disconnect_other_thru (DataType dt, uint32_t id)
+{
+ _ignore_updates = true;
+ bool valid;
+ ChanMapping n_thru_map (_pi->thru_map ());
+ n_thru_map.get (dt, id, &valid);
+ if (valid) {
+ n_thru_map.unset (dt, id);
+ _pi->set_thru_map (n_thru_map);
+ }
+ _ignore_updates = false;
+}
+
+void
PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
{
const uint32_t pc = s->ip;
@@ -1006,20 +1059,9 @@ PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
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;
+ disconnect_other_outputs (pc, s->dt, o->id);
+ disconnect_other_thru (s->dt, o->id);
+
idx = out_map.get_src (s->dt, o->id, &valid);
if (valid) {
out_map.unset (s->dt, idx);
@@ -1031,6 +1073,26 @@ PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
}
void
+PluginPinDialog::handle_thru_action (const CtrlElem &o, const CtrlElem &i)
+{
+ bool valid;
+ ChanMapping thru_map (_pi->thru_map ());
+ uint32_t idx = thru_map.get (o->dt, o->id, &valid);
+
+ if (valid && idx == i->id) {
+ // disconnect
+ thru_map.unset (o->dt, o->id);
+ } else {
+ // disconnect other outputs first
+ disconnect_other_outputs (UINT32_MAX, o->dt, o->id);
+ disconnect_other_thru (o->dt, o->id);
+
+ thru_map.set (o->dt, o->id, i->id);
+ }
+ _pi->set_thru_map (thru_map);
+}
+
+void
PluginPinDialog::handle_disconnect (const CtrlElem &e)
{
_ignore_updates = true;
@@ -1039,6 +1101,19 @@ PluginPinDialog::handle_disconnect (const CtrlElem &e)
switch (e->ct) {
case Input:
+ {
+ ChanMapping n_thru_map (_pi->thru_map ());
+ for (uint32_t i = 0; i < _sources.n_total (); ++i) {
+ uint32_t idx = n_thru_map.get (e->dt, i, &valid);
+ if (valid && idx == e->id) {
+ n_thru_map.unset (e->dt, i);
+ changed = true;
+ }
+ }
+ if (changed) {
+ _pi->set_thru_map (n_thru_map);
+ }
+ }
for (uint32_t n = 0; n < _n_plugins; ++n) {
ChanMapping map (_pi->input_map (n));
for (uint32_t i = 0; i < _sinks.n_total (); ++i) {
@@ -1083,7 +1158,18 @@ PluginPinDialog::handle_disconnect (const CtrlElem &e)
changed = true;
}
}
- _pi->set_output_map (n, map);
+ if (changed) {
+ _pi->set_output_map (n, map);
+ }
+ }
+ {
+ ChanMapping n_thru_map (_pi->thru_map ());
+ n_thru_map.get (e->dt, e->id, &valid);
+ if (valid) {
+ n_thru_map.unset (e->dt, e->id);
+ changed = true;
+ _pi->set_thru_map (n_thru_map);
+ }
}
break;
}
diff --git a/gtk2_ardour/plugin_pin_dialog.h b/gtk2_ardour/plugin_pin_dialog.h
index 70e4fca3f7..ac7912f908 100644
--- a/gtk2_ardour/plugin_pin_dialog.h
+++ b/gtk2_ardour/plugin_pin_dialog.h
@@ -125,7 +125,10 @@ private:
void add_sidechain_port (ARDOUR::DataType);
void handle_input_action (const CtrlElem &, const CtrlElem &);
void handle_output_action (const CtrlElem &, const CtrlElem &);
+ void handle_thru_action (const CtrlElem &, const CtrlElem &);
void handle_disconnect (const CtrlElem &);
+ void disconnect_other_outputs (uint32_t skip_pc, ARDOUR::DataType dt, uint32_t id);
+ void disconnect_other_thru (ARDOUR::DataType dt, uint32_t id);
void add_port_to_table (boost::shared_ptr<ARDOUR::Port>, uint32_t, bool);
void remove_port (boost::weak_ptr<ARDOUR::Port>);
void disconnect_port (boost::weak_ptr<ARDOUR::Port>);
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc
index a058788e7f..ff6731e6e7 100644
--- a/gtk2_ardour/processor_box.cc
+++ b/gtk2_ardour/processor_box.cc
@@ -1025,12 +1025,16 @@ ProcessorEntry::RoutingIcon::set (
const ARDOUR::ChanCount& sinks,
const ARDOUR::ChanCount& sources,
const ARDOUR::ChanMapping& in_map,
- const ARDOUR::ChanMapping& out_map)
+ const ARDOUR::ChanMapping& out_map,
+ const ARDOUR::ChanMapping& thru_map)
{
- _in = in; _out = out;
- _sources = sources; _sinks = sinks;
- _in_map = in_map; _out_map = out_map;
-
+ _in = in;
+ _out = out;
+ _sources = sources;
+ _sinks = sinks;
+ _in_map = in_map;
+ _out_map = out_map;
+ _thru_map = thru_map;
}
bool
@@ -1060,6 +1064,9 @@ ProcessorEntry::RoutingIcon::out_identity () const {
if (_out_map.count () != _sources.n_total () || _out.n_total () != _sources.n_total ()) {
return false;
}
+ if (_thru_map.count () > 0) {
+ return false;
+ }
return true;
}
@@ -1067,12 +1074,14 @@ void
ProcessorEntry::RoutingIcon::set_feed (
const ARDOUR::ChanCount& out,
const ARDOUR::ChanCount& sources,
- const ARDOUR::ChanMapping& out_map)
+ const ARDOUR::ChanMapping& out_map,
+ const ARDOUR::ChanMapping& thru_map)
{
- _f_out = out;
- _f_sources = sources;
- _f_out_map = out_map;
- _feed = true;
+ _f_out = out;
+ _f_sources = sources;
+ _f_out_map = out_map;
+ _f_thru_map = thru_map;
+ _feed = true;
}
double
@@ -1139,6 +1148,22 @@ ProcessorEntry::RoutingIcon::draw_sidechain (cairo_t* cr, double x0, double heig
}
void
+ProcessorEntry::RoutingIcon::draw_thru (cairo_t* cr, double x0, double height, bool midi)
+{
+ const double dx = 1 + rint (max(2., 2. * UIConfiguration::instance().get_ui_scale()));
+ const double y0 = rint (height * .5) - .5;
+
+ cairo_move_to (cr, x0 - dx, y0);
+ cairo_line_to (cr, x0, height);
+ cairo_line_to (cr, x0 + dx, y0);
+ cairo_close_path (cr);
+
+ set_routing_color (cr, midi);
+ cairo_set_line_width (cr, 1.0);
+ cairo_fill (cr);
+}
+
+void
ProcessorEntry::RoutingIcon::draw_connection (cairo_t* cr, double x0, double x1, double y0, double y1, bool midi, bool dashed)
{
double bz = abs (y1 - y0);
@@ -1224,7 +1249,13 @@ ProcessorEntry::RoutingIcon::expose_input_map (cairo_t* cr, const double width,
uint32_t src = _f_out_map.get_src (dt, idx, &valid_src);
if (!valid_src) {
double x = pin_x_pos (i, width, pc_in, 0, false);
- draw_gnd (cr, x, height, is_midi);
+ bool valid_thru;
+ _f_thru_map.get (dt, idx, &valid_thru);
+ if (valid_thru) {
+ draw_thru (cr, x, height, is_midi);
+ } else {
+ draw_gnd (cr, x, height, is_midi);
+ }
continue;
}
c_x0 = pin_x_pos (src, width, _f_sources.n_total(), _f_sources.n_midi(), is_midi);
@@ -1266,10 +1297,17 @@ ProcessorEntry::RoutingIcon::expose_output_map (cairo_t* cr, const double width,
double x = pin_x_pos (i, width, n_out, 0, is_midi);
uint32_t pn = is_midi ? i : i - n_out_midi;
DataType dt = is_midi ? DataType::MIDI : DataType::AUDIO;
+ // TODO check thru
bool valid_src;
_out_map.get_src (dt, pn, &valid_src);
if (!valid_src) {
- draw_gnd (cr, x, height, is_midi);
+ bool valid_thru;
+ _thru_map.get (dt, pn, &valid_thru);
+ if (valid_thru) {
+ draw_thru (cr, x, height, is_midi);
+ } else {
+ draw_gnd (cr, x, height, is_midi);
+ }
}
set_routing_color (cr, is_midi);
cairo_move_to (cr, x , height);
@@ -2619,10 +2657,11 @@ ProcessorBox::setup_routing_feeds ()
sinks * count + midi_thru,
sources * count + midi_bypass,
input_map,
- pi->output_map ());
+ pi->output_map (),
+ pi->thru_map ());
if (next != children.end()) {
- (*next)->routing_icon.set_feed (out, sources * count + midi_bypass, pi->output_map ());
+ (*next)->routing_icon.set_feed (out, sources * count + midi_bypass, pi->output_map (), pi->thru_map ());
}
} else {
@@ -2630,15 +2669,16 @@ ProcessorBox::setup_routing_feeds ()
(*i)->output_icon.set_ports (p->output_streams());
ChanMapping inmap (p->input_streams ());
ChanMapping outmap (p->input_streams ());
+ ChanMapping thrumap;
(*i)->routing_icon.set (
p->input_streams(),
p->output_streams(),
p->input_streams(),
p->output_streams(),
- inmap, outmap);
+ inmap, outmap, thrumap);
if (next != children.end()) {
- (*next)->routing_icon.set_feed (p->output_streams(), p->output_streams(), outmap);
+ (*next)->routing_icon.set_feed (p->output_streams(), p->output_streams(), outmap, thrumap);
}
}
diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h
index 8336864a6c..de3eaf03ab 100644
--- a/gtk2_ardour/processor_box.h
+++ b/gtk2_ardour/processor_box.h
@@ -290,23 +290,27 @@ private:
const ARDOUR::ChanCount&,
const ARDOUR::ChanCount&,
const ARDOUR::ChanMapping&,
+ const ARDOUR::ChanMapping&,
const ARDOUR::ChanMapping&);
void set_feed (
const ARDOUR::ChanCount&,
const ARDOUR::ChanCount&,
+ const ARDOUR::ChanMapping&,
const ARDOUR::ChanMapping&);
void copy_state (const RoutingIcon& other) {
- _in = other._in;
- _out = other._out;
- _sources = other._sources;
- _sinks = other._sinks;
- _in_map = other._in_map;
- _out_map = other._out_map;
- _f_out = other._f_out;
- _f_out_map = other._f_out_map;
- _f_sources = other._f_sources;
- _feed = other._feed;
+ _in = other._in;
+ _out = other._out;
+ _sources = other._sources;
+ _sinks = other._sinks;
+ _in_map = other._in_map;
+ _out_map = other._out_map;
+ _thru_map = other._thru_map;
+ _f_out = other._f_out;
+ _f_out_map = other._f_out_map;
+ _f_thru_map = other._f_thru_map;
+ _f_sources = other._f_sources;
+ _feed = other._feed;
}
void unset_feed () { _feed = false ; }
@@ -318,6 +322,7 @@ private:
static void draw_gnd (cairo_t*, double, double, bool);
static void draw_X (cairo_t*, double, double, bool);
static void draw_sidechain (cairo_t*, double, double, bool);
+ static void draw_thru (cairo_t*, double, double, bool);
private:
bool on_expose_event (GdkEventExpose *);
@@ -330,8 +335,10 @@ private:
ARDOUR::ChanCount _sinks;
ARDOUR::ChanMapping _in_map;
ARDOUR::ChanMapping _out_map;
+ ARDOUR::ChanMapping _thru_map;
ARDOUR::ChanCount _f_out;
ARDOUR::ChanMapping _f_out_map;
+ ARDOUR::ChanMapping _f_thru_map;
ARDOUR::ChanCount _f_sources;
bool _feed;
bool _input;