Update mixer strip colours when route active state changes
[ardour.git] / gtk2_ardour / mixer_strip.cc
index 3b59b247dc591bd03d996441ff74447f0fd01f08..f767396308265762650428719fbdc7ae953d2856 100644 (file)
@@ -73,8 +73,6 @@ using namespace Gtk;
 using namespace Gtkmm2ext;
 using namespace std;
 
-sigc::signal<void,boost::shared_ptr<Route> > MixerStrip::SwitchIO;
-
 int MixerStrip::scrollbar_height = 0;
 PBD::Signal1<void,MixerStrip*> MixerStrip::CatchDeletion;
 
@@ -86,6 +84,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer)
        , processor_box (sess, boost::bind (&MixerStrip::plugin_selector, this), mx.selection(), this, in_mixer)
        , gpm (sess, 250)
        , panners (sess)
+       , button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
        , button_table (3, 1)
        , rec_solo_table (2, 2)
        , top_button_table (1, 2)
@@ -115,6 +114,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
        , processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer)
        , gpm (sess, 250)
        , panners (sess)
+       , button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
        , button_table (3, 1)
        , middle_button_table (1, 2)
        , bottom_button_table (1, 2)
@@ -227,12 +227,34 @@ MixerStrip::init ()
        button_table.set_homogeneous (false);
        button_table.set_spacings (0);
 
+       if (solo_button) {
+               button_size_group->add_widget (*solo_button);
+       }
+       if (mute_button) {
+               button_size_group->add_widget (*mute_button);
+       }
+       if (solo_isolated_led) {
+               button_size_group->add_widget (*solo_isolated_led);
+       }
+       if (solo_safe_led) {
+               button_size_group->add_widget (*solo_safe_led);
+       }
+       if (rec_enable_button) {
+               button_size_group->add_widget (*rec_enable_button);
+       }
+       if (monitor_disk_button) {
+               button_size_group->add_widget (*monitor_disk_button);
+       }
+       if (monitor_input_button) {
+               button_size_group->add_widget (*monitor_input_button);
+       }
+
        button_table.attach (name_button, 0, 1, 0, 1);
        button_table.attach (input_button_box, 0, 1, 1, 2);
        button_table.attach (_invert_button_box, 0, 1, 2, 3);
 
        middle_button_table.set_homogeneous (true);
-       middle_button_table.set_spacings (0);
+       middle_button_table.set_spacings (2);
        middle_button_table.attach (*mute_button, 0, 1, 0, 1);
         middle_button_table.attach (*solo_button, 1, 2, 0, 1);
 
@@ -302,12 +324,6 @@ MixerStrip::init ()
        input_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::input_press), false);
        output_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::output_press), false);
 
-       /* we don't need this if its not an audio track, but we don't know that yet and it doesn't
-          hurt (much).
-       */
-
-       rec_enable_button->set_name ("MixerRecordEnableButton");
-
        /* ditto for this button and busses */
 
        name_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::name_button_button_press), false);
@@ -337,8 +353,6 @@ MixerStrip::init ()
 
        set_flags (get_flags() | Gtk::CAN_FOCUS);
 
-       SwitchIO.connect (sigc::mem_fun (*this, &MixerStrip::switch_io));
-
        AudioEngine::instance()->PortConnectedOrDisconnected.connect (
                *this, invalidator (*this), boost::bind (&MixerStrip::port_connected_or_disconnected, this, _1, _3), gui_context ()
                );
@@ -348,8 +362,8 @@ MixerStrip::init ()
           are recognised when they occur.
        */
        _visibility.add (&_invert_button_box, X_("PhaseInvert"), _("Phase Invert"));
-       _visibility.add (solo_safe_led, X_("SoloSafe"), _("Solo Safe"));
-       _visibility.add (solo_isolated_led, X_("SoloIsolated"), _("Solo Isolated"));
+       _visibility.add (solo_safe_led, X_("SoloSafe"), _("Solo Safe"), true, boost::bind (&MixerStrip::override_solo_visibility, this));
+       _visibility.add (solo_isolated_led, X_("SoloIsolated"), _("Solo Isolated"), true, boost::bind (&MixerStrip::override_solo_visibility, this));
        _visibility.add (&_comment_button, X_("Comments"), _("Comments"));
        _visibility.add (&group_button, X_("Group"), _("Group"));
        _visibility.add (&meter_point_button, X_("MeterPoint"), _("Meter Point"));
@@ -684,6 +698,16 @@ MixerStrip::output_press (GdkEventButton *ev)
                output_menu_bundles.clear ();
 
                citems.push_back (MenuElem (_("Disconnect"), sigc::mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_output)));
+
+               for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) {
+                       citems.push_back (
+                               MenuElem (
+                                       string_compose ("Add %1 port", (*i).to_i18n_string()),
+                                       sigc::bind (sigc::mem_fun (*this, &MixerStrip::add_output_port), *i)
+                                       )
+                               );
+               }
+               
                citems.push_back (SeparatorElem());
 
                ARDOUR::BundleList current = _route->output()->bundles_connected ();
@@ -795,6 +819,16 @@ MixerStrip::input_press (GdkEventButton *ev)
        case 3:
        {
                citems.push_back (MenuElem (_("Disconnect"), sigc::mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_input)));
+
+               for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) {
+                       citems.push_back (
+                               MenuElem (
+                                       string_compose ("Add %1 port", (*i).to_i18n_string()),
+                                       sigc::bind (sigc::mem_fun (*this, &MixerStrip::add_input_port), *i)
+                                       )
+                               );
+               }
+
                citems.push_back (SeparatorElem());
                input_menu_bundles.clear ();
 
@@ -874,7 +908,7 @@ MixerStrip::maybe_add_bundle_to_input_menu (boost::shared_ptr<Bundle> b, ARDOUR:
 {
        using namespace Menu_Helpers;
 
-       if (b->ports_are_outputs() == false || b->nchannels() != _route->n_inputs()) {
+       if (b->ports_are_outputs() == false || b->nchannels() != _route->n_inputs() || *b == *_route->output()->bundle()) {
                return;
        }
 
@@ -908,7 +942,7 @@ MixerStrip::maybe_add_bundle_to_output_menu (boost::shared_ptr<Bundle> b, ARDOUR
 {
        using namespace Menu_Helpers;
 
-       if (b->ports_are_inputs() == false || b->nchannels() != _route->n_outputs()) {
+       if (b->ports_are_inputs() == false || b->nchannels() != _route->n_outputs() || *b == *_route->input()->bundle()) {
                return;
        }
 
@@ -1653,36 +1687,21 @@ MixerStrip::meter_changed ()
        gpm.reset_peak_display();
 }
 
+/** The bus that we are displaying sends to has changed, or been turned off.
+ *  @param send_to New bus that we are displaying sends to, or 0.
+ */
 void
-MixerStrip::switch_io (boost::shared_ptr<Route> target)
+MixerStrip::bus_send_display_changed (boost::shared_ptr<Route> send_to)
 {
-       /* don't respond to switch IO signal outside of the mixer window */
-
-       if (!_mixer_owned) {
-               return;
-       }
-
-       if (_route == target || _route->is_master()) {
-               /* don't change the display for the target or the master bus */
-               return;
-       } else if (!is_track() && show_sends_button) {
-               /* make sure our show sends button is inactive, and we no longer blink,
-                  since we're not the target.
-               */
-               send_blink_connection.disconnect ();
-               show_sends_button->unset_active_state ();
-       }
+       RouteUI::bus_send_display_changed (send_to);
 
-       if (!target) {
-               /* switch back to default */
-               revert_to_default_display ();
-               return;
-       }
-
-       boost::shared_ptr<Send> send = _route->internal_send_for (target);
-
-       if (send) {
-               show_send (send);
+       if (send_to) {
+               boost::shared_ptr<Send> send = _route->internal_send_for (send_to);
+               if (send) {
+                       show_send (send);
+               } else {
+                       revert_to_default_display ();
+               }
        } else {
                revert_to_default_display ();
        }
@@ -1761,10 +1780,6 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
 void
 MixerStrip::revert_to_default_display ()
 {
-       if (show_sends_button) {
-               show_sends_button->unset_active_state ();
-       }
-
        drop_send ();
 
        set_current_delivery (_route->main_outs ());
@@ -1783,7 +1798,7 @@ MixerStrip::set_button_names ()
 {
        switch (_width) {
        case Wide:
-               rec_enable_button_label.set_text (_("Rec"));
+               rec_enable_button->set_text (_("Rec"));
                mute_button->set_text (_("Mute"));
                monitor_input_button->set_text (_("In"));
                monitor_disk_button->set_text (_("Disk"));
@@ -1812,7 +1827,7 @@ MixerStrip::set_button_names ()
                break;
 
        default:
-               rec_enable_button_label.set_text (_("R"));
+               rec_enable_button->set_text (_("R"));
                mute_button->set_text (_("M"));
                monitor_input_button->set_text (_("I"));
                monitor_disk_button->set_text (_("D"));
@@ -2029,3 +2044,36 @@ MixerStrip::parameter_changed (string p)
                _visibility.set_state (Config->get_mixer_strip_visibility ());
        }
 }
+
+/** Called to decide whether the solo isolate / solo lock button visibility should
+ *  be overridden from that configured by the user.  We do this for the master bus.
+ *
+ *  @return optional value that is present if visibility state should be overridden.
+ */
+boost::optional<bool>
+MixerStrip::override_solo_visibility () const
+{
+       if (_route && _route->is_master ()) {
+               return boost::optional<bool> (false);
+       }
+       
+       return boost::optional<bool> ();
+}
+
+void
+MixerStrip::add_input_port (DataType t)
+{
+       _route->input()->add_port ("", this, t);
+}
+
+void
+MixerStrip::add_output_port (DataType t)
+{
+       _route->output()->add_port ("", this, t);
+}
+
+void
+MixerStrip::route_active_changed ()
+{
+       reset_strip_style ();
+}