X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmixer_strip.cc;h=ca1b104e0fdf3528edb098b2af7881005489061b;hb=d7660957325bdebbb75f21c0d19b9f0aad6e7f37;hp=d7007184a75ced25d34bd30f4dc5b853e085823c;hpb=e4ba62e4c40bf8620768f39827c3df1e82976f49;p=ardour.git diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index d7007184a7..ca1b104e0f 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -38,6 +38,7 @@ #include "ardour/audio_track.h" #include "ardour/audioengine.h" #include "ardour/internal_send.h" +#include "ardour/io.h" #include "ardour/meter.h" #include "ardour/midi_track.h" #include "ardour/pannable.h" @@ -70,7 +71,7 @@ #include "tooltips.h" #include "ui_config.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace ARDOUR; using namespace ARDOUR_UI_UTILS; @@ -352,7 +353,6 @@ MixerStrip::init () number_label.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::number_button_button_press), false); name_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::name_button_button_press), false); - name_button.signal_button_release_event().connect (sigc::mem_fun(*this, &MixerStrip::name_button_button_release), false); group_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::select_route_group), false); @@ -456,6 +456,20 @@ MixerStrip::name() const return string(); } +void +MixerStrip::update_trim_control () +{ + if (route()->trim() && route()->trim()->active() && + route()->n_inputs().n_audio() > 0) { + trim_control.show (); + trim_control.set_controllable (route()->trim()->gain_control()); + } else { + trim_control.hide (); + boost::shared_ptr none; + trim_control.set_controllable (none); + } +} + void MixerStrip::set_route (boost::shared_ptr rt) { @@ -562,14 +576,7 @@ MixerStrip::set_route (boost::shared_ptr rt) monitor_disk_button->hide (); } - if (route()->trim() && route()->trim()->active()) { - trim_control.show (); - trim_control.set_controllable (route()->trim()->gain_control()); - } else { - trim_control.hide (); - boost::shared_ptr none; - trim_control.set_controllable (none); - } + update_trim_control(); if (is_midi_track()) { if (midi_input_enable_button == 0) { @@ -910,7 +917,9 @@ MixerStrip::output_press (GdkEventButton *ev) citems.push_back (SeparatorElem()); citems.push_back (MenuElem (_("Routing Grid"), sigc::mem_fun (*(static_cast(this)), &RouteUI::edit_output_configuration))); - output_menu.popup (1, ev->time); + Gtkmm2ext::anchored_menu_popup(&output_menu, &output_button, "", + 1, ev->time); + break; } @@ -1012,7 +1021,8 @@ MixerStrip::input_press (GdkEventButton *ev) citems.push_back (SeparatorElem()); citems.push_back (MenuElem (_("Routing Grid"), sigc::mem_fun (*(static_cast(this)), &RouteUI::edit_input_configuration))); - input_menu.popup (1, ev->time); + Gtkmm2ext::anchored_menu_popup(&input_menu, &input_button, "", + 1, ev->time); break; } @@ -1209,6 +1219,7 @@ MixerStrip::update_io_button (boost::shared_ptr route, Width widt { uint32_t io_count; uint32_t io_index; + boost::shared_ptr io; boost::shared_ptr port; vector port_connections; @@ -1233,30 +1244,70 @@ MixerStrip::update_io_button (boost::shared_ptr route, Width widt ostringstream tooltip; char * tooltip_cstr; - //to avoid confusion, the button caption should only show connections that match the datatype of the track + /* To avoid confusion, the button caption only shows connections that match the expected datatype + * + * First of all, if the user made only connections to a given type, we should use that one since + * it is very probably what the user expects. If there are several connections types, then show + * audio ones as primary, which matches expectations for both audio tracks with midi control and + * synthesisers. This first heuristic can be expressed with these two rules: + * A) If there are connected audio ports, consider audio as primary type. + * B) Else, if there are connected midi ports, consider midi as primary type. + * + * If there are no connected ports, then we choose the primary type based on the type of existing + * but unconnected ports. Again: + * C) If there are audio ports, consider audio as primary type. + * D) Else, if there are midi ports, consider midi as primary type. */ + DataType dt = DataType::AUDIO; - if ( boost::dynamic_pointer_cast(route) != 0 ) { - dt = DataType::MIDI; - // avoid further confusion with Midi-tracks that have a synth. - // Audio-ports may be connected, but button says "Disconnected" + bool match = false; + + if (for_input) { + io = route->input(); + } else { + io = route->output(); + } + + io_count = io->n_ports().n_total(); + for (io_index = 0; io_index < io_count; ++io_index) { + port = io->nth (io_index); + if (port->connected()) { + match = true; + if (port->type() == DataType::AUDIO) { + /* Rule A) applies no matter the remaining ports */ + dt = DataType::AUDIO; + break; + } + if (port->type() == DataType::MIDI) { + /* Rule B) is a good candidate... */ + dt = DataType::MIDI; + /* ...but continue the loop to check remaining ports for rule A) */ + } + } + } + + if (!match) { + /* Neither rule A) nor rule B) matched */ + if ( io->n_ports().n_audio() > 0 ) { + /* Rule C */ + dt = DataType::AUDIO; + } else if ( io->n_ports().n_midi() > 0 ) { + /* Rule D */ + dt = DataType::MIDI; + } + } + + if ( dt == DataType::MIDI ) { tooltip << _("MIDI "); } if (for_input) { - io_count = route->n_inputs().n_total(); tooltip << string_compose (_("INPUT to %1"), Gtkmm2ext::markup_escape_text (route->name())); } else { - io_count = route->n_outputs().n_total(); tooltip << string_compose (_("OUTPUT from %1"), Gtkmm2ext::markup_escape_text (route->name())); } - for (io_index = 0; io_index < io_count; ++io_index) { - if (for_input) { - port = route->input()->nth (io_index); - } else { - port = route->output()->nth (io_index); - } + port = io->nth (io_index); port_connections.clear (); port->get_connections(port_connections); @@ -1467,6 +1518,7 @@ void MixerStrip::io_changed_proxy () { Glib::signal_idle().connect_once (sigc::mem_fun (*this, &MixerStrip::update_panner_choices)); + Glib::signal_idle().connect_once (sigc::mem_fun (*this, &MixerStrip::update_trim_control)); } void @@ -1533,7 +1585,12 @@ MixerStrip::select_route_group (GdkEventButton *ev) WeakRouteList r; r.push_back (route ()); group_menu->build (r); - group_menu->menu()->popup (1, ev->time); + + RouteGroup *rg = _route->route_group(); + + Gtkmm2ext::anchored_menu_popup(group_menu->menu(), &group_button, + rg ? rg->name() : _("No Group"), + 1, ev->time); } return true; @@ -1582,7 +1639,13 @@ MixerStrip::help_count_plugins (boost::weak_ptr p) if (!processor || !processor->display_to_user()) { return; } - if (boost::dynamic_pointer_cast (processor)) { + boost::shared_ptr pi = boost::dynamic_pointer_cast (processor); +#ifdef MIXBUS + if (pi && pi->is_channelstrip ()) { + return; + } +#endif + if (pi) { ++_plugin_insert_cnt; } } @@ -1633,6 +1696,12 @@ MixerStrip::build_route_ops_menu () items.push_back (MenuElem (_("Pin Connections..."), sigc::mem_fun (*this, &RouteUI::manage_pins))); } + if (_route->the_instrument () && _route->the_instrument ()->output_streams().n_audio() > 2) { + // TODO ..->n_audio() > 1 && separate_output_groups) hard to check here every time. + items.push_back (MenuElem (_("Fan out to Busses"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), true, true))); + items.push_back (MenuElem (_("Fan out to Tracks"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), false, true))); + } + items.push_back (SeparatorElem()); items.push_back (MenuElem (_("Adjust Latency..."), sigc::mem_fun (*this, &RouteUI::adjust_latency))); @@ -1668,12 +1737,17 @@ MixerStrip::build_route_ops_menu () gboolean MixerStrip::name_button_button_press (GdkEventButton* ev) { - if (ev->button == 3) { + if (ev->button == 1 || ev->button == 3) { list_route_operations (); /* do not allow rename if the track is record-enabled */ rename_menu_item->set_sensitive (!is_track() || !track()->rec_enable_control()->get_value()); - route_ops_menu->popup (1, ev->time); + if (ev->button == 1) { + Gtkmm2ext::anchored_menu_popup(route_ops_menu, &name_button, "", + 1, ev->time); + } else { + route_ops_menu->popup (3, ev->time); + } return true; } @@ -1681,20 +1755,6 @@ MixerStrip::name_button_button_press (GdkEventButton* ev) return false; } -gboolean -MixerStrip::name_button_button_release (GdkEventButton* ev) -{ - if (ev->button == 1) { - list_route_operations (); - - /* do not allow rename if the track is record-enabled */ - rename_menu_item->set_sensitive (!is_track() || !track()->rec_enable_control()->get_value()); - route_ops_menu->popup (1, ev->time); - } - - return false; -} - gboolean MixerStrip::number_button_button_press (GdkEventButton* ev) { @@ -1719,8 +1779,10 @@ MixerStrip::list_route_operations () } void -MixerStrip::show_selected () +MixerStrip::set_selected (bool yn) { + AxisView::set_selected (yn); + if (selected()) { global_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT); global_frame.set_name ("MixerStripSelectedFrame");