mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-13 10:06:33 +01:00
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:
parent
e8e4e677aa
commit
2b5a04d3f4
2 changed files with 264 additions and 93 deletions
|
|
@ -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, &_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)++;
|
||||||
|
|
|
||||||
|
|
@ -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__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue