fix clicking when processors become active/inactive; reduce crazy 2.5sec delay for...
[ardour.git] / gtk2_ardour / gain_meter.cc
index 597e2a2fbeac5d8bfd3570d7b6f8b132c25ac1e4..e6f0c7404221f5bdf6fd37372dd29056d453e8ce 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <limits.h>
 
+#include "ardour/amp.h"
 #include "ardour/io.h"
 #include "ardour/route.h"
 #include "ardour/route_group.h"
@@ -80,7 +81,8 @@ GainMeterBase::GainMeterBase (Session& s,
          // 0.781787 is the value needed for gain to be set to 0.
          gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1),
          gain_automation_style_button (""),
-         gain_automation_state_button ("")
+         gain_automation_state_button (""),
+         dpi_changed (false)
        
 {
        using namespace Menu_Helpers;
@@ -159,57 +161,59 @@ GainMeterBase::~GainMeterBase ()
 }
 
 void
-GainMeterBase::set_io (boost::shared_ptr<IO> io)
+GainMeterBase::set_controls (boost::shared_ptr<Route> r,
+                            boost::shared_ptr<PeakMeter> pm, 
+                            boost::shared_ptr<Amp> amp)
 {
        connections.clear ();
-       
-       _io = io;
-       
-       if (!_io) {
+
+       if (!pm && !amp) {
                level_meter->set_meter (0);
                gain_slider->set_controllable (boost::shared_ptr<PBD::Controllable>());
+               _meter.reset ();
+               _amp.reset ();
+               _route.reset ();
                return;
        } 
 
-       level_meter->set_meter (&_io->peak_meter());
-       gain_slider->set_controllable (_io->gain_control());
+       _meter = pm;
+       _amp = amp;
+       _route = r;
 
-       boost::shared_ptr<Route> r;
-
-       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
-
-               if (!r->is_hidden()) {
+       level_meter->set_meter (pm.get());
+       gain_slider->set_controllable (amp->gain_control());
+       
+       if (!_route || !_route->is_hidden()) {
+               
+               using namespace Menu_Helpers;
+               
+               gain_astate_menu.items().clear ();
+               
+               gain_astate_menu.items().push_back (MenuElem (_("Manual"), 
+                                                             bind (mem_fun (*(amp.get()), &Automatable::set_parameter_automation_state),
+                                                                   Evoral::Parameter(GainAutomation), (AutoState) Off)));
+               gain_astate_menu.items().push_back (MenuElem (_("Play"),
+                                                             bind (mem_fun (*(amp.get()), &Automatable::set_parameter_automation_state),
+                                                                   Evoral::Parameter(GainAutomation), (AutoState) Play)));
+               gain_astate_menu.items().push_back (MenuElem (_("Write"),
+                                                             bind (mem_fun (*(amp.get()), &Automatable::set_parameter_automation_state),
+                                                                   Evoral::Parameter(GainAutomation), (AutoState) Write)));
+               gain_astate_menu.items().push_back (MenuElem (_("Touch"),
+                                                             bind (mem_fun (*(amp.get()), &Automatable::set_parameter_automation_state),
+                                                                   Evoral::Parameter(GainAutomation), (AutoState) Touch)));
+               
+               connections.push_back (gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_style_button_event), false));
+               connections.push_back (gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_state_button_event), false));
 
-                       using namespace Menu_Helpers;
-       
-                       gain_astate_menu.items().clear ();
-
-                       gain_astate_menu.items().push_back (MenuElem (_("Manual"), 
-                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                           Evoral::Parameter(GainAutomation), (AutoState) Off)));
-                       gain_astate_menu.items().push_back (MenuElem (_("Play"),
-                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                           Evoral::Parameter(GainAutomation), (AutoState) Play)));
-                       gain_astate_menu.items().push_back (MenuElem (_("Write"),
-                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                           Evoral::Parameter(GainAutomation), (AutoState) Write)));
-                       gain_astate_menu.items().push_back (MenuElem (_("Touch"),
-                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                           Evoral::Parameter(GainAutomation), (AutoState) Touch)));
-                       
-                       connections.push_back (gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_style_button_event), false));
-                       connections.push_back (gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_state_button_event), false));
-                       
-                       connections.push_back (r->gain_control()->alist()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed)));
-                       connections.push_back (r->gain_control()->alist()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed)));
+               boost::shared_ptr<AutomationControl> gc = amp->gain_control();
 
-                       gain_automation_state_changed ();
-               }
+               connections.push_back (gc->alist()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed)));
+               connections.push_back (gc->alist()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed)));
+               
+               gain_automation_state_changed ();
        }
 
-       //cerr << "Connect " << this << " to gain change for " << _io->name() << endl;
-
-       connections.push_back (_io->gain_control()->Changed.connect (mem_fun(*this, &GainMeterBase::gain_changed)));
+       connections.push_back (amp->gain_control()->Changed.connect (mem_fun (*this, &GainMeterBase::gain_changed)));
 
        gain_changed ();
        show_gain ();
@@ -271,10 +275,8 @@ GainMeterBase::peak_button_release (GdkEventButton* ev)
        if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) {
                ResetAllPeakDisplays ();
        } else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-               boost::shared_ptr<Route> r;
-
-               if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
-                       ResetGroupPeakDisplays (r->mix_group());
+               if (_route) {
+                       ResetGroupPeakDisplays (_route->route_group());
                }
        } else {
                reset_peak_display ();
@@ -286,12 +288,7 @@ GainMeterBase::peak_button_release (GdkEventButton* ev)
 void
 GainMeterBase::reset_peak_display ()
 {
-       boost::shared_ptr<Route> r;
-
-       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
-               r->peak_meter().reset_max();
-       }
-
+       _meter->reset_max();
        level_meter->clear_meters();
        max_peak = -INFINITY;
        peak_display.set_label (_("-Inf"));
@@ -301,13 +298,9 @@ GainMeterBase::reset_peak_display ()
 void
 GainMeterBase::reset_group_peak_display (RouteGroup* group)
 {
-       boost::shared_ptr<Route> r;
-       
-       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
-               if (group == r->mix_group()) {
-                       reset_peak_display ();
+       if (_route && group == _route->route_group()) {
+               reset_peak_display ();
                }
-       }
 }
 
 void
@@ -353,7 +346,7 @@ GainMeterBase::gain_activated ()
 
                f = min (f, 6.0f);
 
-               _io->gain_control()->set_value (dB_to_coefficient(f));
+               _amp->set_gain (dB_to_coefficient(f), this);
 
                if (gain_display.has_focus()) {
                        PublicEditor::instance().reset_focus();
@@ -380,19 +373,23 @@ GainMeterBase::show_gain ()
 void
 GainMeterBase::gain_adjusted ()
 {
-       //cerr << this << " for " << _io->name() << " GAIN ADJUSTED\n";
        if (!ignore_toggle) {
-               //cerr << "Set GC\n";
-               _io->gain_control()->set_value (slider_position_to_gain (gain_adjustment.get_value()));
-               //cerr << "Set GC OUT\n";
+               if (_route) {
+                       if (_route->amp() == _amp) {
+                               _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
+                       } else {
+                               _amp->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
+                       }
+               }
        }
+
        show_gain ();
 }
 
 void
 GainMeterBase::effective_gain_display ()
 {
-       gfloat value = gain_to_slider_position (_io->effective_gain());
+       gfloat value = gain_to_slider_position (_amp->gain());
        
        //cerr << this << " for " << _io->name() << " EGAIN = " << value
        //              << " AGAIN = " << gain_adjustment.get_value () << endl;
@@ -426,11 +423,10 @@ GainMeterBase::set_fader_name (const char * name)
 void
 GainMeterBase::update_gain_sensitive ()
 {
-       static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (
-                       !(_io->gain_control()->alist()->automation_state() & Play));
+       bool x = !(_amp->gain_control()->alist()->automation_state() & Play);
+       static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (x);
 }
 
-
 static MeterPoint
 next_meter_point (MeterPoint mp)
 {
@@ -454,11 +450,9 @@ next_meter_point (MeterPoint mp)
 gint
 GainMeterBase::meter_press(GdkEventButton* ev)
 {
-       boost::shared_ptr<Route> _route;
-
        wait_for_release = false;
        
-       if ((_route = boost::dynamic_pointer_cast<Route>(_io)) == 0) {
+       if (!_route) {
                return FALSE;
        }
 
@@ -481,10 +475,10 @@ GainMeterBase::meter_press(GdkEventButton* ev)
                                }
                        }
 
-                       if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
+                       if (_route && (ev->button == 1 || Keyboard::is_button2_event (ev))) {
 
                                if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
-
+                                       
                                        /* Primary+Tertiary-click applies change to all routes */
 
                                        _session.begin_reversible_command (_("meter point change"));
@@ -533,10 +527,8 @@ GainMeterBase::meter_release(GdkEventButton* ev)
                if (wait_for_release){
                        wait_for_release = false;
                        
-                       boost::shared_ptr<Route> r;
-                       
-                       if ((r = boost::dynamic_pointer_cast<Route>(_io)) != 0) {
-                               set_meter_point (*r, old_meter_point);
+                       if (_route) {
+                               set_meter_point (*_route, old_meter_point);
                        }
                }
        }
@@ -555,7 +547,7 @@ GainMeterBase::set_mix_group_meter_point (Route& route, MeterPoint mp)
 {
        RouteGroup* mix_group;
 
-       if((mix_group = route.mix_group()) != 0){
+       if((mix_group = route.route_group()) != 0){
                mix_group->apply (&Route::set_meter_point, mp, this);
        } else {
                route.set_meter_point (mp, this);
@@ -565,9 +557,7 @@ GainMeterBase::set_mix_group_meter_point (Route& route, MeterPoint mp)
 void
 GainMeterBase::meter_point_clicked ()
 {
-       boost::shared_ptr<Route> r;
-
-       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
+       if (_route) {
                /* WHAT? */
        }
 }
@@ -575,14 +565,14 @@ GainMeterBase::meter_point_clicked ()
 gint
 GainMeterBase::start_gain_touch (GdkEventButton* ev)
 {
-       _io->gain_control()->start_touch ();
+       _amp->gain_control()->start_touch ();
        return FALSE;
 }
 
 gint
 GainMeterBase::end_gain_touch (GdkEventButton* ev)
 {
-       _io->gain_control()->stop_touch ();
+       _amp->gain_control()->stop_touch ();
        return FALSE;
 }
 
@@ -685,10 +675,10 @@ GainMeterBase::gain_automation_style_changed ()
 {
        switch (_width) {
        case Wide:
-               gain_automation_style_button.set_label (astyle_string(_io->gain_control()->alist()->automation_style()));
+               gain_automation_style_button.set_label (astyle_string(_amp->gain_control()->alist()->automation_style()));
                break;
        case Narrow:
-               gain_automation_style_button.set_label  (short_astyle_string(_io->gain_control()->alist()->automation_style()));
+               gain_automation_style_button.set_label  (short_astyle_string(_amp->gain_control()->alist()->automation_style()));
                break;
        }
 }
@@ -702,14 +692,14 @@ GainMeterBase::gain_automation_state_changed ()
 
        switch (_width) {
        case Wide:
-               gain_automation_state_button.set_label (astate_string(_io->gain_control()->alist()->automation_state()));
+               gain_automation_state_button.set_label (astate_string(_amp->gain_control()->alist()->automation_state()));
                break;
        case Narrow:
-               gain_automation_state_button.set_label (short_astate_string(_io->gain_control()->alist()->automation_state()));
+               gain_automation_state_button.set_label (short_astate_string(_amp->gain_control()->alist()->automation_state()));
                break;
        }
 
-       x = (_io->gain_control()->alist()->automation_state() != Off);
+       x = (_amp->gain_control()->alist()->automation_state() != Off);
        
        if (gain_automation_state_button.get_active() != x) {
                ignore_toggle = true;
@@ -810,8 +800,10 @@ GainMeter::GainMeter (Session& s)
        meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
 }
 
-void
-GainMeter::set_io (boost::shared_ptr<IO> io)
+void 
+GainMeter::set_controls (boost::shared_ptr<Route> r,
+                        boost::shared_ptr<PeakMeter> meter,
+                        boost::shared_ptr<Amp> amp)
 {
        if (level_meter->get_parent()) {
                hbox.remove (*level_meter);
@@ -825,32 +817,22 @@ GainMeter::set_io (boost::shared_ptr<IO> io)
                fader_vbox->remove (gain_automation_state_button);
        }
 
-       GainMeterBase::set_io (io);
-
-       boost::shared_ptr<Route> r;
-
-       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
-               
-               /* 
-                  if we have a non-hidden route (ie. we're not the click or the auditioner), 
-                  pack some route-dependent stuff.
-               */
+       GainMeterBase::set_controls (r, meter, amp);
 
-               gain_display_box.pack_end (peak_display, true, true);
-               hbox.pack_end (*level_meter, true, true);
-
-               if (!r->is_hidden()) {
-                       fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
-               }
-
-       } else {
-
-               /* we're managing a non-Route IO (e.g. Send) */
-
-               gain_display_box.pack_end (peak_display, true, true);
-               hbox.pack_end (*level_meter, true, true);
+       /* 
+          if we have a non-hidden route (ie. we're not the click or the auditioner), 
+          pack some route-dependent stuff.
+       */
+       
+       gain_display_box.pack_end (peak_display, true, true);
+       hbox.pack_end (*level_meter, true, true);
+       
+       if (!r->is_hidden()) {
                fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
        }
+
+       setup_meters ();
+       hbox.show_all ();
 }
 
 int
@@ -940,7 +922,11 @@ GainMeter::meter_metrics_expose (GdkEventExpose *ev)
 boost::shared_ptr<PBD::Controllable>
 GainMeterBase::get_controllable()
 {
-       return _io->gain_control();
+       if (_amp) {
+               return _amp->gain_control();
+       } else {
+               return boost::shared_ptr<PBD::Controllable>();
+       }
 }