continued work on processor-routing visualization

major re-design.
 * change splitting-icon into routing-icon
 * add it to all processors (not only plugin-inserts)
 * subscribe to ChanCount configuration changes
 * add 'wiring' to BlankProcessorEntry pre-fader placeholder
 * visualize routing for non-matching port-counts

currently still wire+color design with #if'ed debug messages
and optional #ifdef wires for matching connections.
This commit is contained in:
Robin Gareus 2014-01-04 05:54:20 +01:00
parent e8e4e677aa
commit 2b5a04d3f4
2 changed files with 264 additions and 93 deletions

View file

@ -17,6 +17,8 @@
*/ */
//#define ALWAYS_DISPLAY_WIRES
#ifdef WAF_BUILD #ifdef WAF_BUILD
#include "gtk2ardour-config.h" #include "gtk2ardour-config.h"
#endif #endif
@ -98,6 +100,8 @@ ProcessorEntry::ProcessorEntry (ProcessorBox* parent, boost::shared_ptr<Processo
, _processor (p) , _processor (p)
, _width (w) , _width (w)
, _visual_state (Gtk::STATE_NORMAL) , _visual_state (Gtk::STATE_NORMAL)
, _input_icon(true)
, _output_icon(false)
{ {
_vbox.show (); _vbox.show ();
@ -109,13 +113,23 @@ ProcessorEntry::ProcessorEntry (ProcessorBox* parent, boost::shared_ptr<Processo
if (_processor) { if (_processor) {
_vbox.pack_start (_routing_icon);
_vbox.pack_start (_input_icon);
_vbox.pack_start (_button, true, true); _vbox.pack_start (_button, true, true);
_vbox.pack_end (_output_icon);
_button.set_active (_processor->active()); _button.set_active (_processor->active());
_button.show (); _button.show ();
#ifdef ALWAYS_DISPLAY_WIRES
_routing_icon.show();
#endif
_input_icon.show();
_output_icon.show();
_processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context()); _processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
_processor->PropertyChanged.connect (name_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context()); _processor->PropertyChanged.connect (name_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
_processor->ConfigurationChanged.connect (config_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_configuration_changed, this, _1, _2), gui_context());
set<Evoral::Parameter> p = _processor->what_can_be_automated (); set<Evoral::Parameter> p = _processor->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) { for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) {
@ -135,6 +149,12 @@ ProcessorEntry::ProcessorEntry (ProcessorBox* parent, boost::shared_ptr<Processo
} }
} }
_input_icon.set_ports(_processor->input_streams());
_output_icon.set_ports(_processor->output_streams());
_routing_icon.set_sources(_processor->input_streams());
_routing_icon.set_sinks(_processor->output_streams());
setup_tooltip (); setup_tooltip ();
setup_visuals (); setup_visuals ();
} else { } else {
@ -190,14 +210,17 @@ ProcessorEntry::setup_visuals ()
switch (_position) { switch (_position) {
case PreFader: case PreFader:
_button.set_name ("processor prefader"); _button.set_name ("processor prefader");
_routing_icon.set_name ("ProcessorPreFader");
break; break;
case Fader: case Fader:
_button.set_name ("processor fader"); _button.set_name ("processor fader");
_routing_icon.set_name ("ProcessorFader");
break; break;
case PostFader: case PostFader:
_button.set_name ("processor postfader"); _button.set_name ("processor postfader");
_routing_icon.set_name ("ProcessorPostFader");
break; break;
} }
} }
@ -245,6 +268,24 @@ ProcessorEntry::processor_property_changed (const PropertyChange& what_changed)
} }
} }
void
ProcessorEntry::processor_configuration_changed (const ChanCount in, const ChanCount out)
{
#if 0 // debug, devel information
printf("ProcessorEntry::processor_config_changed %s %d %d\n",
name(Wide).c_str(),
in.n_audio(), out.n_audio());
#endif
_input_icon.set_ports(in);
_output_icon.set_ports(out);
_routing_icon.set_sources(in);
_routing_icon.set_sinks(out);
_input_icon.queue_draw();
_output_icon.queue_draw();
_routing_icon.queue_draw();
}
void void
ProcessorEntry::setup_tooltip () ProcessorEntry::setup_tooltip ()
{ {
@ -593,9 +634,20 @@ ProcessorEntry::Control::state_id () const
return string_compose (X_("control %1"), c->id().to_s ()); return string_compose (X_("control %1"), c->id().to_s ());
} }
BlankProcessorEntry::BlankProcessorEntry (ProcessorBox* b, Width w) BlankProcessorEntry::BlankProcessorEntry (ProcessorBox* b, Width w, ChanCount cc)
: ProcessorEntry (b, boost::shared_ptr<Processor>(), w) : ProcessorEntry (b, boost::shared_ptr<Processor>(), w)
{ {
#ifdef ALWAYS_DISPLAY_WIRES
_vbox.pack_start (_routing_icon);
_routing_icon.set_sources(cc);
_routing_icon.set_sinks(cc);
_routing_icon.show();
setup_visuals ();
_routing_icon.set_size_request (-1, 8);
_vbox.set_size_request (-1, 8);
#else
_vbox.set_size_request (-1, 0);
#endif
} }
PluginInsertProcessorEntry::PluginInsertProcessorEntry (ProcessorBox* b, boost::shared_ptr<ARDOUR::PluginInsert> p, Width w) PluginInsertProcessorEntry::PluginInsertProcessorEntry (ProcessorBox* b, boost::shared_ptr<ARDOUR::PluginInsert> p, Width w)
@ -606,31 +658,74 @@ PluginInsertProcessorEntry::PluginInsertProcessorEntry (ProcessorBox* b, boost::
_splitting_connection, invalidator (*this), boost::bind (&PluginInsertProcessorEntry::plugin_insert_splitting_changed, this), gui_context() _splitting_connection, invalidator (*this), boost::bind (&PluginInsertProcessorEntry::plugin_insert_splitting_changed, this), gui_context()
); );
_splitting_icon.set_size_request (-1, 12);
_vbox.pack_start (_splitting_icon);
_vbox.reorder_child (_splitting_icon, 0);
plugin_insert_splitting_changed (); plugin_insert_splitting_changed ();
} }
void void
PluginInsertProcessorEntry::plugin_insert_splitting_changed () PluginInsertProcessorEntry::plugin_insert_splitting_changed ()
{ {
_splitting_icon.set_inputs(_plugin_insert->input_streams()); #if 0 // debug, devel information
_splitting_icon.set_outputs(_plugin_insert->output_streams()); printf("--%s--\n", _plugin_insert->name().c_str());
printf("AUDIO src: %d -> in:%d | * cnt %d * | out: %d -> snk: %d\n",
_plugin_insert->input_streams().n_audio(),
_plugin_insert->natural_input_streams().n_audio(),
_plugin_insert->get_count(),
_plugin_insert->natural_output_streams().n_audio(),
_plugin_insert->output_streams().n_audio());
printf("MIDI src: %d -> in:%d | * cnt %d * | out: %d -> snk: %d\n",
_plugin_insert->input_streams().n_midi(),
_plugin_insert->natural_input_streams().n_midi(),
_plugin_insert->get_count(),
_plugin_insert->natural_output_streams().n_midi(),
_plugin_insert->output_streams().n_midi());
printf("TOTAL src: %d -> in:%d | * cnt %d * | out: %d -> snk: %d\n",
_plugin_insert->input_streams().n_total(),
_plugin_insert->natural_input_streams().n_total(),
_plugin_insert->get_count(),
_plugin_insert->natural_output_streams().n_total(),
_plugin_insert->output_streams().n_total());
#endif
if (_plugin_insert->splitting () || ( _output_icon.set_ports(_plugin_insert->output_streams());
_plugin_insert->input_streams().n_midi() == 0 _routing_icon.set_splitting(_plugin_insert->splitting ());
&& _plugin_insert->input_streams().n_audio() < _plugin_insert->output_streams().n_audio()
) ChanCount sources = _plugin_insert->input_streams();
ChanCount sinks = _plugin_insert->natural_input_streams();
/* replicated instances */
if (!_plugin_insert->splitting () && _plugin_insert->get_count() > 1) {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
sinks.set(*t, sinks.get(*t) * _plugin_insert->get_count());
}
}
/* MIDI bypass */
if (_plugin_insert->natural_output_streams().n_midi() == 0 &&
_plugin_insert->output_streams().n_midi() == 1) {
sinks.set(DataType::MIDI, 1);
sources.set(DataType::MIDI, 1);
}
_input_icon.set_ports(sinks);
_routing_icon.set_sinks(sinks);
_routing_icon.set_sources(sources);
if (_plugin_insert->splitting () ||
_plugin_insert->input_streams().n_audio() < _plugin_insert->natural_input_streams().n_audio()
) )
{ {
_splitting_icon.show (); _routing_icon.set_size_request (-1, 8);
_splitting_icon.queue_draw(); _routing_icon.show();
} else { } else {
_splitting_icon.hide (); #ifdef ALWAYS_DISPLAY_WIRES
_routing_icon.set_size_request (-1, 4);
#else
_routing_icon.hide();
#endif
} }
_input_icon.queue_draw();
_output_icon.queue_draw();
_routing_icon.queue_draw();
} }
void void
@ -640,28 +735,59 @@ PluginInsertProcessorEntry::hide_things ()
plugin_insert_splitting_changed (); plugin_insert_splitting_changed ();
} }
void
PluginInsertProcessorEntry::setup_visuals () bool
ProcessorEntry::PortIcon::on_expose_event (GdkEventExpose* ev)
{ {
switch (_position) { cairo_t* cr = gdk_cairo_create (get_window()->gobj());
case PreFader:
_splitting_icon.set_name ("ProcessorPreFader");
break;
case Fader: cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
_splitting_icon.set_name ("ProcessorFader"); cairo_clip (cr);
break;
case PostFader: cairo_set_line_width (cr, 5.0);
_splitting_icon.set_name ("ProcessorPostFader"); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
break;
Gtk::Allocation a = get_allocation();
double const width = a.get_width();
double const height = a.get_height();
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 y0 = _input ? height-.5 : .5;
if (_ports.n_total() > 1) {
for (uint32_t i = 0; i < _ports.n_total(); ++i) {
if (i < _ports.n_midi()) {
cairo_set_source_rgb (cr, .8, .3, .3);
} else {
cairo_set_source_rgb (cr, .4, .4, .8);
}
const float x = rintf(width * (.2f + .6f * i / (_ports.n_total() - 1.f))) + .5f;
cairo_move_to (cr, x, y0);
cairo_close_path(cr);
cairo_stroke(cr);
}
} else if (_ports.n_total() == 1) {
if (_ports.n_midi() == 1) {
cairo_set_source_rgb (cr, .8, .3, .3);
} else {
cairo_set_source_rgb (cr, .4, .4, .8);
}
cairo_move_to (cr, rintf(width * .5) + .5f, y0);
cairo_close_path(cr);
cairo_stroke(cr);
} }
ProcessorEntry::setup_visuals (); cairo_destroy(cr);
return true;
} }
bool bool
PluginInsertProcessorEntry::SplittingIcon::on_expose_event (GdkEventExpose* ev) ProcessorEntry::RoutingIcon::on_expose_event (GdkEventExpose* ev)
{ {
cairo_t* cr = gdk_cairo_create (get_window()->gobj()); cairo_t* cr = gdk_cairo_create (get_window()->gobj());
@ -684,54 +810,58 @@ PluginInsertProcessorEntry::SplittingIcon::on_expose_event (GdkEventExpose* ev)
Gdk::Color const fg = get_style()->get_fg (STATE_NORMAL); Gdk::Color const fg = get_style()->get_fg (STATE_NORMAL);
cairo_set_source_rgb (cr, fg.get_red_p (), fg.get_green_p (), fg.get_blue_p ()); cairo_set_source_rgb (cr, fg.get_red_p (), fg.get_green_p (), fg.get_blue_p ());
const uint32_t inputs = _inputs.n_audio(); const uint32_t sources = _sources.n_total();
const uint32_t outputs = _outputs.n_audio(); const uint32_t sinks = _sinks.n_total();
const float si_m = rintf(height * 0.5) + .5f; /* MIDI */
cairo_set_source_rgb (cr, .6, .2, .2);
const uint32_t midi_sources = _sources.n_midi();
const uint32_t midi_sinks = _sinks.n_midi();
if (inputs == 1) { if (midi_sources > 0 && midi_sinks > 0 && sinks > 1 && sources > 1) {
const float si_l = rintf(width * 0.2) + .5f; for (uint32_t i = 0 ; i < midi_sources; ++i) {
const float si_c = rintf(width * 0.5) + .5f; const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f;
const float si_r = rintf(width * 0.8) + .5f; const float si_x0 = rintf(width * (.2f + .6f * i / (sources - 1.f))) + .5f;
cairo_move_to (cr, si_x, height);
cairo_move_to (cr, si_l, height); cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
cairo_line_to (cr, si_l, si_m);
cairo_line_to (cr, si_r, si_m);
cairo_line_to (cr, si_r, height);
cairo_stroke (cr);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
const uint32_t outputs = _outputs.n_audio();
for (uint32_t i = 2; i < outputs; ++i) {
const float si_b = rintf(width * (.2f + .6f * (i - 1.f) / (outputs - 1.f))) + .5f;
cairo_move_to (cr, si_b, height);
cairo_line_to (cr, si_b, si_m);
cairo_stroke (cr); cairo_stroke (cr);
} }
} else if (midi_sources == 1 && midi_sinks == 1 && sinks == 1 && sources == 1) {
cairo_move_to (cr, si_c, si_m); const float si_x = rintf(width * .5f) + .5f;
cairo_line_to (cr, si_c, 0); cairo_move_to (cr, si_x, height);
cairo_line_to (cr, si_x, 0);
cairo_stroke (cr); cairo_stroke (cr);
} else {
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
for (uint32_t i = 0 ; i < outputs; ++i) {
const float si_x = rintf(width * (.2f + .6f * i / (outputs - 1.f))) + .5f;
if (i < inputs) {
cairo_move_to (cr, si_x, height);
cairo_line_to (cr, si_x, 0);
cairo_stroke (cr);
} else {
cairo_move_to (cr, si_x, si_m);
cairo_line_to (cr, si_x, height);
cairo_stroke (cr);
cairo_move_to (cr, si_x+4, si_m);
cairo_line_to (cr, si_x-4, si_m);
cairo_stroke (cr);
}
}
} }
/* AUDIO */
cairo_set_source_rgb (cr, .6, .6, .8);
const uint32_t audio_sources = _sources.n_audio();
const uint32_t audio_sinks = _sinks.n_audio();
if (_splitting) {
assert(audio_sinks > 1);
const float si_x0 = rintf(width * .5f) + .5f;
for (uint32_t i = midi_sinks; i < sinks; ++i) {
const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f;
cairo_move_to (cr, si_x, height);
cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
cairo_stroke (cr);
}
} else if (audio_sources > 1) {
for (uint32_t i = 0 ; i < audio_sources; ++i) {
const float si_x = rintf(width * (.2f + .6f * (i + midi_sinks) / (sinks - 1.f))) + .5f;
const float si_x0 = rintf(width * (.2f + .6f * (i + midi_sources) / (sources - 1.f))) + .5f;
cairo_move_to (cr, si_x, height);
cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
cairo_stroke (cr);
}
} else if (audio_sources == 1 && audio_sinks == 1) {
const float si_x = rintf(width * .5f) + .5f;
cairo_move_to (cr, si_x, height);
cairo_line_to (cr, si_x, 0);
cairo_stroke (cr);
}
cairo_destroy(cr);
return true; return true;
} }
@ -761,7 +891,7 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
processor_display.set_name ("ProcessorList"); processor_display.set_name ("ProcessorList");
processor_display.set_data ("processorbox", this); processor_display.set_data ("processorbox", this);
processor_display.set_size_request (48, -1); processor_display.set_size_request (48, -1);
processor_display.set_spacing (2); processor_display.set_spacing (0);
processor_display.signal_enter_notify_event().connect (sigc::mem_fun(*this, &ProcessorBox::enter_notify), false); processor_display.signal_enter_notify_event().connect (sigc::mem_fun(*this, &ProcessorBox::enter_notify), false);
processor_display.signal_leave_notify_event().connect (sigc::mem_fun(*this, &ProcessorBox::leave_notify), false); processor_display.signal_leave_notify_event().connect (sigc::mem_fun(*this, &ProcessorBox::leave_notify), false);
@ -821,6 +951,12 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
_route->PropertyChanged.connect ( _route->PropertyChanged.connect (
_route_connections, invalidator (*this), boost::bind (&ProcessorBox::route_property_changed, this, _1), gui_context() _route_connections, invalidator (*this), boost::bind (&ProcessorBox::route_property_changed, this, _1), gui_context()
); );
#ifdef ALWAYS_DISPLAY_WIRES
/* update BlankProcessorEntry wire-count */
_route->io_changed.connect (
_route_connections, invalidator (*this), boost::bind (&ProcessorBox::io_changed_proxy, this), gui_context ()
);
#endif
redisplay_processors (); redisplay_processors ();
} }
@ -1414,6 +1550,7 @@ ProcessorBox::redisplay_processors ()
{ {
ENSURE_GUI_THREAD (*this, &ProcessorBox::redisplay_processors); ENSURE_GUI_THREAD (*this, &ProcessorBox::redisplay_processors);
bool fader_seen; bool fader_seen;
ChanCount amp_chan_count;
if (no_processor_redisplay) { if (no_processor_redisplay) {
return; return;
@ -1425,10 +1562,10 @@ ProcessorBox::redisplay_processors ()
fader_seen = false; fader_seen = false;
_route->foreach_processor (sigc::bind (sigc::mem_fun (*this, &ProcessorBox::help_count_visible_prefader_processors), _route->foreach_processor (sigc::bind (sigc::mem_fun (*this, &ProcessorBox::help_count_visible_prefader_processors),
&_visible_prefader_processors, &fader_seen)); &_visible_prefader_processors, &fader_seen, &amp_chan_count));
if (_visible_prefader_processors == 0) { // fader only if (_visible_prefader_processors == 0) { // fader only
BlankProcessorEntry* bpe = new BlankProcessorEntry (this, _width); BlankProcessorEntry* bpe = new BlankProcessorEntry (this, _width, amp_chan_count);
processor_display.add_child (bpe); processor_display.add_child (bpe);
} }
@ -1486,6 +1623,12 @@ ProcessorBox::redisplay_processors ()
setup_entry_positions (); setup_entry_positions ();
} }
void
ProcessorBox::io_changed_proxy ()
{
Glib::signal_idle().connect_once (sigc::mem_fun (*this, &ProcessorBox::redisplay_processors));
}
/** Add a ProcessorWindowProxy for a processor to our list, if that processor does /** Add a ProcessorWindowProxy for a processor to our list, if that processor does
* not already have one. * not already have one.
*/ */
@ -1552,7 +1695,7 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w)
} }
void void
ProcessorBox::help_count_visible_prefader_processors (boost::weak_ptr<Processor> p, uint32_t* cnt, bool* amp_seen) ProcessorBox::help_count_visible_prefader_processors (boost::weak_ptr<Processor> p, uint32_t* cnt, bool* amp_seen, ChanCount *cc)
{ {
boost::shared_ptr<Processor> processor (p.lock ()); boost::shared_ptr<Processor> processor (p.lock ());
@ -1560,6 +1703,9 @@ ProcessorBox::help_count_visible_prefader_processors (boost::weak_ptr<Processor>
if (boost::dynamic_pointer_cast<Amp>(processor)) { if (boost::dynamic_pointer_cast<Amp>(processor)) {
*amp_seen = true; *amp_seen = true;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
cc->set(*t, processor->input_streams().get(*t));
}
} else { } else {
if (!*amp_seen) { if (!*amp_seen) {
(*cnt)++; (*cnt)++;

View file

@ -150,6 +150,7 @@ private:
void led_clicked(); void led_clicked();
void processor_active_changed (); void processor_active_changed ();
void processor_property_changed (const PBD::PropertyChange&); void processor_property_changed (const PBD::PropertyChange&);
void processor_configuration_changed (const ARDOUR::ChanCount in, const ARDOUR::ChanCount out);
std::string name (Width) const; std::string name (Width) const;
void setup_tooltip (); void setup_tooltip ();
@ -159,6 +160,7 @@ private:
Gtk::StateType _visual_state; Gtk::StateType _visual_state;
PBD::ScopedConnection active_connection; PBD::ScopedConnection active_connection;
PBD::ScopedConnection name_connection; PBD::ScopedConnection name_connection;
PBD::ScopedConnection config_connection;
class Control : public sigc::trackable { class Control : public sigc::trackable {
public: public:
@ -204,12 +206,49 @@ private:
std::list<Control*> _controls; std::list<Control*> _controls;
void toggle_control_visibility (Control *); void toggle_control_visibility (Control *);
class PortIcon : public Gtk::DrawingArea {
public:
PortIcon(bool input) {
_input = input;
_ports = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 1);
set_size_request (-1, 3);
}
void set_ports(ARDOUR::ChanCount const ports) { _ports = ports; }
private:
bool on_expose_event (GdkEventExpose *);
bool _input;
ARDOUR::ChanCount _ports;
};
class RoutingIcon : public Gtk::DrawingArea {
public:
RoutingIcon() {
_sources = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 1);
_sinks = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 1);
_splitting = false;
set_size_request (-1, 4);
}
void set_sources(ARDOUR::ChanCount const sources) { _sources = sources; }
void set_sinks(ARDOUR::ChanCount const sinks) { _sinks = sinks; }
void set_splitting(const bool splitting) { _splitting = splitting; }
private:
bool on_expose_event (GdkEventExpose *);
ARDOUR::ChanCount _sources; // signals available to feed into the processor(s)
ARDOUR::ChanCount _sinks; // combined number of outputs of the processor
bool _splitting;
};
protected:
RoutingIcon _routing_icon;
PortIcon _input_icon;
PortIcon _output_icon;
}; };
class BlankProcessorEntry : public ProcessorEntry class BlankProcessorEntry : public ProcessorEntry
{ {
public: public:
BlankProcessorEntry (ProcessorBox *, Width w); BlankProcessorEntry (ProcessorBox *, Width w, ARDOUR::ChanCount cc);
}; };
class PluginInsertProcessorEntry : public ProcessorEntry class PluginInsertProcessorEntry : public ProcessorEntry
@ -220,25 +259,9 @@ public:
void hide_things (); void hide_things ();
private: private:
void setup_visuals ();
void plugin_insert_splitting_changed (); void plugin_insert_splitting_changed ();
class SplittingIcon : public Gtk::DrawingArea {
public:
SplittingIcon() {
_inputs = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 1);
_outputs = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 2);
}
void set_inputs(ARDOUR::ChanCount const inputs) { _inputs = inputs; }
void set_outputs(ARDOUR::ChanCount const outputs) { _outputs = outputs; }
private:
bool on_expose_event (GdkEventExpose *);
ARDOUR::ChanCount _inputs;
ARDOUR::ChanCount _outputs;
};
boost::shared_ptr<ARDOUR::PluginInsert> _plugin_insert; boost::shared_ptr<ARDOUR::PluginInsert> _plugin_insert;
SplittingIcon _splitting_icon;
PBD::ScopedConnection _splitting_connection; PBD::ScopedConnection _splitting_connection;
}; };
@ -349,11 +372,12 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
bool processor_button_release_event (GdkEventButton *, ProcessorEntry *); bool processor_button_release_event (GdkEventButton *, ProcessorEntry *);
void redisplay_processors (); void redisplay_processors ();
void add_processor_to_display (boost::weak_ptr<ARDOUR::Processor>); void add_processor_to_display (boost::weak_ptr<ARDOUR::Processor>);
void help_count_visible_prefader_processors (boost::weak_ptr<ARDOUR::Processor>, uint32_t*, bool*); void help_count_visible_prefader_processors (boost::weak_ptr<ARDOUR::Processor>, uint32_t*, bool*, ARDOUR::ChanCount*);
void reordered (); void reordered ();
void report_failed_reorder (); void report_failed_reorder ();
void route_processors_changed (ARDOUR::RouteProcessorChange); void route_processors_changed (ARDOUR::RouteProcessorChange);
void processor_menu_unmapped (); void processor_menu_unmapped ();
void io_changed_proxy ();
void processors_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*); void processors_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_processor_sort_keys (); void compute_processor_sort_keys ();
@ -434,6 +458,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
void mixer_strip_delivery_changed (boost::weak_ptr<ARDOUR::Delivery>); void mixer_strip_delivery_changed (boost::weak_ptr<ARDOUR::Delivery>);
XMLNode* entry_gui_object_state (ProcessorEntry *); XMLNode* entry_gui_object_state (ProcessorEntry *);
PBD::ScopedConnection amp_config_connection;
}; };
#endif /* __ardour_gtk_processor_box__ */ #endif /* __ardour_gtk_processor_box__ */