MIDI/Controllables for monitor section, and related fixes
[ardour.git] / gtk2_ardour / monitor_section.cc
index e85bbf13ff09cefcab51d66e0f255aef26adc5c4..b9e4c1b8a592f136d854b5784ab47c4e21b2ad4d 100644 (file)
@@ -31,39 +31,18 @@ Glib::RefPtr<ActionGroup> MonitorSection::monitor_actions;
 Glib::RefPtr<Gdk::Pixbuf> MonitorSection::big_knob_pixbuf;
 Glib::RefPtr<Gdk::Pixbuf> MonitorSection::little_knob_pixbuf;
 
-static bool
-fixup_prelight (GdkEventCrossing* /* ignored */, GtkWidget* widget)
-{
-        GtkRcStyle* style = gtk_rc_style_copy (gtk_widget_get_modifier_style (widget));
-        int current = gtk_widget_get_state (widget);
-
-        style->fg[GTK_STATE_PRELIGHT] = style->fg[current];
-        style->bg[GTK_STATE_PRELIGHT] = style->bg[current];
-
-        gtk_widget_modify_style(widget, style);
-        g_object_unref(style);
-
-       return false;
-}
-
-static void
-block_prelight (Gtk::Widget& w)
-{
-       w.signal_enter_notify_event().connect (sigc::bind (sigc::ptr_fun (fixup_prelight), w.gobj()), false);
-}
-
 MonitorSection::MonitorSection (Session* s)
         : AxisView (s)
         , RouteUI (s)
         , main_table (2, 3)
         , _tearoff (0)
-        , gain_adjustment (1.0, 0.0, 1.0, 0.01, 0.1)
+        , gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1) // initial value is unity gain
         , gain_control (0)
-        , dim_adjustment (0.2, 0.0, 1.0, 0.01, 0.1) 
+        , dim_adjustment (0.2, 0.0, 1.0, 0.01, 0.1) // upper+lower will be reset to match model
         , dim_control (0)
-        , solo_boost_adjustment (1.0, 1.0, 2.0, 0.01, 0.1) 
+        , solo_boost_adjustment (1.0, 1.0, 3.0, 0.01, 0.1)  // upper and lower will be reset to match model
         , solo_boost_control (0)
-        , solo_cut_adjustment (0.0, 0.0, 1.0, 0.01, 0.1)
+        , solo_cut_adjustment (0.0, 0.0, 1.0, 0.01, 0.1) // upper and lower will be reset to match model
         , solo_cut_control (0)
         , solo_in_place_button (solo_model_group, _("SiP"))
         , afl_button (solo_model_group, _("AFL"))
@@ -85,14 +64,13 @@ MonitorSection::MonitorSection (Session* s)
         }
         
         set_session (s);
-        
+
         VBox* spin_packer;
         Label* spin_label;
 
         /* Dim */
 
         dim_control = new VolumeController (little_knob_pixbuf, &dim_adjustment, false, 30, 30);
-        dim_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::dim_level_changed));
 
         HBox* dim_packer = manage (new HBox);
         dim_packer->show ();
@@ -111,7 +89,6 @@ MonitorSection::MonitorSection (Session* s)
 
        rude_solo_button.set_name ("TransportSoloAlert");
         rude_solo_button.show ();
-        block_prelight (rude_solo_button);
 
         ARDOUR_UI::Blink.connect (sigc::mem_fun (*this, &MonitorSection::solo_blink));
        rude_solo_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo), false);
@@ -147,7 +124,6 @@ MonitorSection::MonitorSection (Session* s)
         /* Solo Boost */
 
         solo_boost_control = new VolumeController (little_knob_pixbuf, &solo_boost_adjustment, false, 30, 30);
-        solo_boost_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::solo_boost_changed));
 
         HBox* solo_packer = manage (new HBox);
         solo_packer->set_spacing (12);
@@ -165,7 +141,6 @@ MonitorSection::MonitorSection (Session* s)
         /* Solo (SiP) cut */
 
         solo_cut_control = new VolumeController (little_knob_pixbuf, &solo_cut_adjustment, false, 30, 30);
-        solo_cut_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::solo_cut_changed));
 
         spin_label = manage (new Label (_("SiP Cut")));
         spin_packer = manage (new VBox);
@@ -196,6 +171,8 @@ MonitorSection::MonitorSection (Session* s)
                 act->connect_proxy (mono_button);
         } 
 
+        cut_all_button.set_name (X_("MonitorMuteButton"));
+        cut_all_button.unset_flags (Gtk::CAN_FOCUS);
         cut_all_button.set_size_request (50,50);
         cut_all_button.show ();
 
@@ -205,6 +182,11 @@ MonitorSection::MonitorSection (Session* s)
         bbox->pack_start (mono_button, true, true);
         bbox->pack_start (dim_all_button, true, true);
 
+        dim_all_button.set_name (X_("MonitorDimButton"));
+        dim_all_button.unset_flags (Gtk::CAN_FOCUS);
+        mono_button.set_name (X_("MonitorMonoButton"));
+        mono_button.unset_flags (Gtk::CAN_FOCUS);
+
         lower_packer.set_spacing (12);
         lower_packer.pack_start (*bbox, false, false);
         lower_packer.pack_start (cut_all_button, false, false);
@@ -212,7 +194,6 @@ MonitorSection::MonitorSection (Session* s)
         /* Gain */
 
         gain_control = new VolumeController (big_knob_pixbuf, &gain_adjustment, false, 80, 80);
-        gain_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::gain_value_changed));
 
         spin_label = manage (new Label (_("Gain")));
         spin_packer = manage (new VBox);
@@ -246,6 +227,7 @@ MonitorSection::MonitorSection (Session* s)
 
         populate_buttons ();
         map_state ();
+        assign_controllables ();
 
         _tearoff = new TearOff (hpacker);
 
@@ -256,7 +238,7 @@ MonitorSection::MonitorSection (Session* s)
 
         /* catch changes that affect us */
 
-        Config->ParameterChanged.connect (config_connection, ui_bind (&MonitorSection::parameter_changed, this, _1), gui_context());
+        Config->ParameterChanged.connect (config_connection, invalidator (*this), ui_bind (&MonitorSection::parameter_changed, this, _1), gui_context());
 }
 
 MonitorSection::~MonitorSection ()
@@ -285,16 +267,19 @@ MonitorSection::set_session (Session* s)
                 if (_route) {
                         /* session with control outs */
                         _monitor = _route->monitor_control ();
+                        assign_controllables ();
                 } else { 
                         /* session with no control outs */
                         _monitor.reset ();
                         _route.reset ();
                 }
+                
                         
         } else {
                 /* no session */
                 _monitor.reset ();
                 _route.reset ();
+                control_connections.drop_connections ();
         }
 
         /* both might be null */
@@ -306,19 +291,20 @@ MonitorSection::ChannelButtonSet::ChannelButtonSet ()
         , solo (X_(""))
         , invert (X_(""))
 {
-        cut.set_name (X_("MixerMuteButton"));
-        dim.set_name (X_("MixerMuteButton"));
+        cut.set_name (X_("MonitorMuteButton"));
+        dim.set_name (X_("MonitorDimButton"));
         solo.set_name (X_("MixerSoloButton"));
+        invert.set_name (X_("MonitorInvertButton"));
 
         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (cut.gobj()), false);
         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dim.gobj()), false);
         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (invert.gobj()), false);
         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (solo.gobj()), false);
 
-        block_prelight (cut);
-        block_prelight (dim);
-        block_prelight (solo);
-        block_prelight (invert);
+        cut.unset_flags (Gtk::CAN_FOCUS);
+        dim.unset_flags (Gtk::CAN_FOCUS);
+        solo.unset_flags (Gtk::CAN_FOCUS);
+        invert.unset_flags (Gtk::CAN_FOCUS);
 }
 
 void
@@ -683,30 +669,6 @@ MonitorSection::setup_knob_images ()
         }
 }
 
-void
-MonitorSection::gain_value_changed ()
-{
-        if (_route) {
-                _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
-        }
-}
-
-void
-MonitorSection::dim_level_changed ()
-{
-        if (_monitor) {
-                _monitor->set_dim_level (dim_adjustment.get_value());
-        }
-}
-
-void
-MonitorSection::solo_boost_changed ()
-{
-        if (_monitor) {
-                _monitor->set_solo_boost_level (solo_boost_adjustment.get_value());
-        }
-}
-
 bool
 MonitorSection::nonlinear_gain_printer (SpinButton* button)
 {
@@ -894,3 +856,53 @@ MonitorSection::parameter_changed (std::string name)
                 solo_cut_adjustment.set_value (gain_to_slider_position (Config->get_solo_mute_gain()));
         }
 }
+
+void
+MonitorSection::assign_controllables ()
+{
+        boost::shared_ptr<Controllable> none;
+
+        if (!gain_control) {
+                /* too early - GUI controls not set up yet */
+                return;
+        }
+
+        if (_route) {
+                gain_control->set_controllable (_route->gain_control());
+                control_link (control_connections, _route->gain_control(), gain_adjustment);
+        } else {
+                gain_control->set_controllable (none);
+        }
+
+        if (_monitor) {
+
+                cut_all_button.set_controllable (_monitor->cut_control());
+                cut_all_button.watch ();
+                dim_all_button.set_controllable (_monitor->dim_control());
+                dim_all_button.watch ();
+                mono_button.set_controllable (_monitor->mono_control());
+                mono_button.watch ();
+
+                boost::shared_ptr<Controllable> c (_monitor->dim_level_control ());
+
+                dim_control->set_controllable (c);
+                dim_adjustment.set_lower (c->lower());
+                dim_adjustment.set_upper (c->upper());
+                control_link (control_connections, c, dim_adjustment);
+                
+                c = _monitor->solo_boost_control ();
+                solo_boost_control->set_controllable (c);
+                solo_boost_adjustment.set_lower (c->lower());
+                solo_boost_adjustment.set_upper (c->upper());
+                control_link (control_connections, c, solo_boost_adjustment);
+
+        } else {
+
+                cut_all_button.set_controllable (none);
+                dim_all_button.set_controllable (none);
+                mono_button.set_controllable (none);
+
+                dim_control->set_controllable (none);
+                solo_boost_control->set_controllable (none);
+        }
+}