OSC: Add preset loading to OSC GUI
[ardour.git] / gtk2_ardour / mixer_strip.cc
index f8386e7706ee0b4f2fdea75a14b04300dca42264..935542e74ef7e4f4081ac36d81d830bdcf0b9da8 100644 (file)
@@ -71,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;
@@ -353,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);
 
@@ -457,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<Controllable> none;
+               trim_control.set_controllable (none);
+       }
+}
+
 void
 MixerStrip::set_route (boost::shared_ptr<Route> rt)
 {
@@ -563,14 +576,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> 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<Controllable> none;
-               trim_control.set_controllable (none);
-       }
+       update_trim_control();
 
        if (is_midi_track()) {
                if (midi_input_enable_button == 0) {
@@ -911,7 +917,9 @@ MixerStrip::output_press (GdkEventButton *ev)
                citems.push_back (SeparatorElem());
                citems.push_back (MenuElem (_("Routing Grid"), sigc::mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::edit_output_configuration)));
 
-               output_menu.popup (1, ev->time);
+               Gtkmm2ext::anchored_menu_popup(&output_menu, &output_button, "",
+                                              1, ev->time);
+
                break;
        }
 
@@ -1013,7 +1021,8 @@ MixerStrip::input_press (GdkEventButton *ev)
                citems.push_back (SeparatorElem());
                citems.push_back (MenuElem (_("Routing Grid"), sigc::mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::edit_input_configuration)));
 
-               input_menu.popup (1, ev->time);
+               Gtkmm2ext::anchored_menu_popup(&input_menu, &input_button, "",
+                                              1, ev->time);
 
                break;
        }
@@ -1235,24 +1244,67 @@ MixerStrip::update_io_button (boost::shared_ptr<ARDOUR::Route> 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<MidiTrack>(route) != 0 ) {
-               dt = DataType::MIDI;
-               // avoid further confusion with Midi-tracks that have a synth.
-               // Audio-ports may be connected, but button says "Disconnected"
-               tooltip << _("MIDI ");
-       }
+       bool match = false;
 
        if (for_input) {
                io = route->input();
-               tooltip << string_compose (_("<b>INPUT</b> to %1"), Gtkmm2ext::markup_escape_text (route->name()));
        } else {
                io = route->output();
-               tooltip << string_compose (_("<b>OUTPUT</b> from %1"), Gtkmm2ext::markup_escape_text (route->name()));
        }
 
        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) {
+               tooltip << string_compose (_("<b>INPUT</b> to %1"), Gtkmm2ext::markup_escape_text (route->name()));
+       } else {
+               tooltip << string_compose (_("<b>OUTPUT</b> from %1"), Gtkmm2ext::markup_escape_text (route->name()));
+       }
 
        for (io_index = 0; io_index < io_count; ++io_index) {
                port = io->nth (io_index);
@@ -1466,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
@@ -1532,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;
@@ -1667,12 +1725,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;
        }
@@ -1680,20 +1743,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)
 {