Separate Ardour UI widgets into dedicated library
[ardour.git] / gtk2_ardour / processor_box.cc
index 84767535a7bee1bdd5fe64a0478c56db0d8bfebc..a3d1833e3461bbd10d26e25f3fc6ed79bef04c7b 100644 (file)
 
 #include <gtkmm/messagedialog.h>
 
-#include <gtkmm2ext/gtk_ui.h>
+#include "gtkmm2ext/gtk_ui.h"
 #include "gtkmm2ext/menu_elems.h"
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/doi.h>
-#include <gtkmm2ext/rgb_macros.h>
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/choice.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/doi.h"
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "widgets/tooltips.h"
 
 #include "ardour/amp.h"
 #include "ardour/audio_track.h"
@@ -84,7 +86,6 @@
 #include "script_selector.h"
 #include "send_ui.h"
 #include "timers.h"
-#include "tooltips.h"
 #include "new_plugin_preset_dialog.h"
 
 #include "pbd/i18n.h"
@@ -103,6 +104,7 @@ using namespace PBD;
 using namespace Gtk;
 using namespace Glib;
 using namespace Gtkmm2ext;
+using namespace ArdourWidgets;
 
 ProcessorBox*  ProcessorBox::_current_processor_box = 0;
 RefPtr<Action> ProcessorBox::paste_action;
@@ -516,10 +518,10 @@ ProcessorEntry::setup_tooltip ()
                        }
 
                        if (pi->plugin()->has_editor()) {
-                               ARDOUR_UI_UTILS::set_tooltip (_button,
+                               set_tooltip (_button,
                                                string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI.%3"), name (Wide), Keyboard::secondary_modifier_name (), postfix));
                        } else {
-                               ARDOUR_UI_UTILS::set_tooltip (_button,
+                               set_tooltip (_button,
                                                string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), name (Wide), postfix));
                        }
                        return;
@@ -533,14 +535,14 @@ ProcessorEntry::setup_tooltip ()
                if ((send = boost::dynamic_pointer_cast<Send> (_processor)) != 0 &&
                                !boost::dynamic_pointer_cast<InternalSend>(_processor)) {
                        if (send->remove_on_disconnect ()) {
-                               ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>&gt; %1</b>\nThis (sidechain) send will be removed when disconnected.", _processor->name()));
+                               set_tooltip (_button, string_compose ("<b>&gt; %1</b>\nThis (sidechain) send will be removed when disconnected.", _processor->name()));
                        } else {
-                               ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>&gt; %1</b>", _processor->name()));
+                               set_tooltip (_button, string_compose ("<b>&gt; %1</b>", _processor->name()));
                        }
                        return;
                }
        }
-       ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>%1</b>", name (Wide)));
+       set_tooltip (_button, string_compose ("<b>%1</b>", name (Wide)));
 }
 
 string
@@ -823,8 +825,11 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
 
                _button.signal_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked));
                _button.signal_led_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked_event));
-               // dup. currently timers are used :(
-               //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+               c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+               if (c->alist ()) {
+                       c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+                       control_automation_state_changed ();
+               }
 
        } else {
 
@@ -835,23 +840,11 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
                _slider.show ();
 
                const ARDOUR::ParameterDescriptor& desc = c->desc();
-               double const lo = c->internal_to_interface(desc.lower);
-               double const up = c->internal_to_interface(desc.upper);
-               double const normal = c->internal_to_interface(desc.normal);
-               double smallstep = desc.smallstep;
-               double largestep = desc.largestep;
-
-               if (smallstep == 0.0) {
-                       smallstep = up / 1000.;
-               } else {
-                       smallstep = c->internal_to_interface(desc.lower + smallstep);
-               }
-
-               if (largestep == 0.0) {
-                       largestep = up / 40.;
-               } else {
-                       largestep = c->internal_to_interface(desc.lower + largestep);
-               }
+               double const lo        = c->internal_to_interface (desc.lower);
+               double const up        = c->internal_to_interface (desc.upper);
+               double const normal    = c->internal_to_interface (desc.normal);
+               double const smallstep = c->internal_to_interface (desc.lower + desc.smallstep);
+               double const largestep = c->internal_to_interface (desc.lower + desc.largestep);
 
                _adjustment.set_lower (lo);
                _adjustment.set_upper (up);
@@ -860,14 +853,13 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
                _slider.set_default_value (normal);
 
                _adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Control::slider_adjusted));
-               // dup. currently timers are used :(
-               //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+               c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+               if (c->alist ()) {
+                       c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+                       control_automation_state_changed ();
+               }
        }
 
-       // yuck, do we really need to do this?
-       // according to c404374 this is only needed for send automation
-       timer_connection = Timers::rapid_connect (sigc::mem_fun (*this, &Control::control_changed));
-
        control_changed ();
        set_tooltip ();
 
@@ -877,7 +869,6 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
 
 ProcessorEntry::Control::~Control ()
 {
-       timer_connection.disconnect ();
 }
 
 void
@@ -891,7 +882,7 @@ ProcessorEntry::Control::set_tooltip ()
        std::string tt = _name + ": " + ARDOUR::value_as_string (c->desc(), c->get_value ());
        string sm = Gtkmm2ext::markup_escape_text (tt);
        _slider_persistant_tooltip.set_tip (sm);
-       ARDOUR_UI_UTILS::set_tooltip (_button, sm);
+       ArdourWidgets::set_tooltip (_button, sm);
 }
 
 void
@@ -935,6 +926,21 @@ ProcessorEntry::Control::button_clicked_event (GdkEventButton *ev)
        button_clicked ();
 }
 
+void
+ProcessorEntry::Control::control_automation_state_changed ()
+{
+       boost::shared_ptr<AutomationControl> c = _control.lock ();
+       if (!c) {
+               return;
+       }
+       bool x = c->alist()->automation_state() & Play;
+       if (c->toggled ()) {
+               _button.set_sensitive (!x);
+       } else {
+               _slider.set_sensitive (!x);
+       }
+}
+
 void
 ProcessorEntry::Control::control_changed ()
 {
@@ -946,12 +952,9 @@ ProcessorEntry::Control::control_changed ()
        _ignore_ui_adjustment = true;
 
        if (c->toggled ()) {
-
                _button.set_active (c->get_value() > 0.5);
-
        } else {
-               // as long as rapid timers are used, only update the tooltip
-               // if the value has changed.
+               // Note: the _slider watches the controllable by itself
                const double nval = c->internal_to_interface (c->get_value ());
                if (_adjustment.get_value() != nval) {
                        _adjustment.set_value (nval);
@@ -1555,10 +1558,10 @@ ProcessorEntry::PluginDisplay::PluginDisplay (ProcessorEntry& e, boost::shared_p
        std::string postfix = string_compose(_("\n%1+double-click to toggle inline-display"), Keyboard::tertiary_modifier_name ());
 
        if (_plug->has_editor()) {
-               ARDOUR_UI_UTILS::set_tooltip (*this,
+               set_tooltip (*this,
                                string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI.%3"), e.name (Wide), Keyboard::primary_modifier_name (), postfix));
        } else {
-               ARDOUR_UI_UTILS::set_tooltip (*this,
+               set_tooltip (*this,
                                string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), e.name (Wide), postfix));
        }
 }
@@ -1855,7 +1858,7 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
                        );
        }
 
-       ARDOUR_UI_UTILS::set_tooltip (processor_display, _("Right-click to add/remove/edit\nplugins,inserts,sends and more"));
+       set_tooltip (processor_display, _("Right-click to add/remove/edit\nplugins,inserts,sends and more"));
 }
 
 ProcessorBox::~ProcessorBox ()