Query backend’s setup_required() every time. fixes #6041
[ardour.git] / gtk2_ardour / automation_controller.cc
index ff8b1932a213890a9af65ea4f84a7b953e6d6346..e1e16a7848eb8bb34d57ab1e3157dfb731e9123c 100644 (file)
 #include "automation_controller.h"
 #include "gui_thread.h"
 #include "note_select_dialog.h"
+#include "timers.h"
 
 #include "i18n.h"
 
 using namespace ARDOUR;
 using namespace Gtk;
 
+AutomationBarController::AutomationBarController (
+               boost::shared_ptr<Automatable>       printer,
+               boost::shared_ptr<AutomationControl> ac,
+               Adjustment*                          adj)
+       : Gtkmm2ext::BarController(*adj, ac)
+       , _printer(printer)
+       , _controllable(ac)
+{
+}
+
+std::string
+AutomationBarController::get_label (double& xpos)
+{
+        xpos = 0.5;
+        return _printer->value_as_string (_controllable);
+}
+
+AutomationBarController::~AutomationBarController()
+{
+}
+
 AutomationController::AutomationController(boost::shared_ptr<Automatable>       printer,
                                            boost::shared_ptr<AutomationControl> ac,
                                            Adjustment*                          adj)
@@ -67,7 +89,7 @@ AutomationController::AutomationController(boost::shared_ptr<Automatable>
 
                _widget = but;
        } else {
-               Gtkmm2ext::BarController* bar = manage(new Gtkmm2ext::BarController(*adj, ac));
+               AutomationBarController* bar = manage(new AutomationBarController(_printer, ac, adj));
 
                bar->set_name(X_("ProcessorControlSlider"));
                bar->StartGesture.connect(
@@ -83,7 +105,7 @@ AutomationController::AutomationController(boost::shared_ptr<Automatable>
        _adjustment->signal_value_changed().connect(
                sigc::mem_fun(*this, &AutomationController::value_adjusted));
 
-       _screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
+       _screen_update_connection = Timers::rapid_connect (
                        sigc::mem_fun (*this, &AutomationController::display_effective_value));
 
        ac->Changed.connect (_changed_connection, invalidator (*this), boost::bind (&AutomationController::value_changed, this), gui_context());
@@ -105,16 +127,8 @@ AutomationController::create(boost::shared_ptr<Automatable>       printer,
        const double lo        = ac->internal_to_interface(desc.lower);
        const double up        = ac->internal_to_interface(desc.upper);
        const double normal    = ac->internal_to_interface(desc.normal);
-       double       smallstep = desc.smallstep;
-       double       largestep = desc.largestep;
-       if (smallstep == 0.0) {
-               smallstep = (up - lo) / 100;
-       }
-       if (largestep == 0.0) {
-               largestep = (up - lo) / 10;
-       }
-       smallstep = ac->internal_to_interface(smallstep);
-       largestep = ac->internal_to_interface(largestep);
+       const double smallstep = ac->internal_to_interface(desc.lower + desc.smallstep);
+       const double largestep = ac->internal_to_interface(desc.lower + desc.largestep);
 
        Gtk::Adjustment* adjustment = manage (
                new Gtk::Adjustment (normal, lo, up, smallstep, largestep));
@@ -124,13 +138,6 @@ AutomationController::create(boost::shared_ptr<Automatable>       printer,
        return boost::shared_ptr<AutomationController>(new AutomationController(printer, ac, adjustment));
 }
 
-std::string
-AutomationController::get_label (double& xpos)
-{
-        xpos = 0.5;
-        return _printer->value_as_string (_controllable);
-}
-
 void
 AutomationController::display_effective_value()
 {
@@ -148,12 +155,15 @@ AutomationController::value_adjusted ()
 {
        if (!_ignore_change) {
                _controllable->set_value (_controllable->interface_to_internal(_adjustment->get_value()));
-       } else {
-               /* A bar controller will automatically follow the adjustment, but for a
-                  button we have to do it manually. */
-               ArdourButton* but = dynamic_cast<ArdourButton*>(_widget);
-               if (but) {
-                       but->set_active(_adjustment->get_value() >= 0.5);
+       }
+
+       /* A bar controller will automatically follow the adjustment, but for a
+          button we have to do it manually. */
+       ArdourButton* but = dynamic_cast<ArdourButton*>(_widget);
+       if (but) {
+               const bool active = _adjustment->get_value() >= 0.5;
+               if (but->get_active() != active) {
+                       but->set_active(active);
                }
        }
 }
@@ -188,11 +198,19 @@ AutomationController::toggled ()
 {
        ArdourButton* but = dynamic_cast<ArdourButton*>(_widget);
        if (but) {
+               if (_controllable->session().transport_rolling()) {
+                       if (_controllable->automation_state() == Touch) {
+                               _controllable->set_automation_state(Write);
+                       }
+                       if (_controllable->list()) {
+                               _controllable->list()->set_in_write_pass(true, false, _controllable->session().audible_frame());
+                       }
+               }
                const bool was_active = _controllable->get_value() >= 0.5;
-               if (was_active) {
+               if (was_active && but->get_active()) {
                        _adjustment->set_value(0.0);
                        but->set_active(false);
-               } else {
+               } else if (!was_active && !but->get_active()) {
                        _adjustment->set_value(1.0);
                        but->set_active(true);
                }
@@ -285,10 +303,10 @@ AutomationController::on_button_release(GdkEventButton* ev)
                                                 sigc::mem_fun(*this, &AutomationController::run_note_select_dialog)));
                }
                if (is_low) {
-                       for (double beats = 1.0; beats <= 16; ++beats) {
-                               items.push_back(MenuElem(string_compose(_("Set to %1 beat(s)"), (int)beats),
+                       for (int beats = 1; beats <= 16; ++beats) {
+                               items.push_back(MenuElem (string_compose(P_("Set to %1 beat", "Set to %1 beats", beats), beats),
                                                         sigc::bind(sigc::mem_fun(*this, &AutomationController::set_freq_beats),
-                                                                   beats)));
+                                                                   (double)beats)));
                        }
                }
                menu->popup(1, ev->time);
@@ -314,7 +332,7 @@ AutomationController::stop_updating ()
 void
 AutomationController::disable_vertical_scroll ()
 {
-       Gtkmm2ext::BarController* bar = dynamic_cast<Gtkmm2ext::BarController*>(_widget);
+       AutomationBarController* bar = dynamic_cast<AutomationBarController*>(_widget);
        if (bar) {
                bar->set_tweaks (
                        Gtkmm2ext::PixFader::Tweaks(bar->tweaks() |