forward port automation handling changes from 2.x, upto and including about rev 6981...
[ardour.git] / gtk2_ardour / panner_ui.cc
index 5977f9903aa84a377fdc05161d4157fce7e287fd..263a8ec51836d3f9c3f59c85ebcfbffd4bf43ced 100644 (file)
@@ -21,7 +21,6 @@
 #include "ardour/io.h"
 #include "ardour/dB.h"
 #include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/stop_signal.h>
 #include <gtkmm2ext/barcontroller.h>
 #include "midi++/manager.h"
 #include "pbd/fastlog.h"
@@ -125,7 +124,7 @@ PannerUI::PannerUI (Session* s)
 
        pack_start (pan_vbox, true, true);
 
-       panner = 0;
+       twod_panner = 0;
        big_window = 0;
 
        set_width(Narrow);
@@ -144,16 +143,16 @@ PannerUI::set_panner (boost::shared_ptr<Panner> p)
 
        _panner = p;
 
-       delete panner;
-       panner = 0;
+       delete twod_panner;
+       twod_panner = 0;
 
        if (!_panner) {
                return;
        }
 
-       _panner->Changed.connect (connections, boost::bind (&PannerUI::panner_changed, this), gui_context());
-       _panner->LinkStateChanged.connect (connections, boost::bind (&PannerUI::update_pan_linkage, this), gui_context());
-       _panner->StateChanged.connect (connections, boost::bind (&PannerUI::update_pan_state, this), gui_context());
+       _panner->Changed.connect (connections, invalidator (*this), boost::bind (&PannerUI::panner_changed, this), gui_context());
+       _panner->LinkStateChanged.connect (connections, invalidator (*this), boost::bind (&PannerUI::update_pan_linkage, this), gui_context());
+       _panner->StateChanged.connect (connections, invalidator (*this), boost::bind (&PannerUI::update_pan_state, this), gui_context());
 
        setup_pan ();
 
@@ -161,22 +160,6 @@ PannerUI::set_panner (boost::shared_ptr<Panner> p)
        update_pan_sensitive ();
        update_pan_linkage ();
        pan_automation_state_changed ();
-
-#if WHERE_DOES_THIS_LIVE
-       pan_bar_packer.show();
-       panning_viewport.show();
-       panning_up.show();
-       panning_up_arrow.show();
-       panning_down.show();
-       panning_down_arrow.show();
-       pan_vbox.show();
-       panning_link_button.show();
-       panning_link_direction_button.show();
-       panning_link_box.show();
-       pan_automation_style_button.show();
-       pan_automation_state_button.show();
-       show();
-#endif
 }
 
 void
@@ -261,8 +244,8 @@ PannerUI::update_pan_linkage ()
 {
        ENSURE_GUI_THREAD (*this, &PannerUI::update_pan_linkage)
 
-       bool x = _panner->linked();
-       bool bx = panning_link_button.get_active();
+       bool const x = _panner->linked();
+       bool const bx = panning_link_button.get_active();
 
        if (x != bx) {
 
@@ -309,7 +292,7 @@ PannerUI::~PannerUI ()
                delete (*i);
        }
 
-       delete panner;
+       delete twod_panner;
        delete big_window;
        delete pan_menu;
        delete pan_astyle_menu;
@@ -346,6 +329,11 @@ PannerUI::setup_pan ()
                return;
        }
 
+       _pan_control_connections.drop_connections ();
+       for (uint32_t i = 0; i < _panner->npanners(); ++i) {
+               connect_to_pan_control (i);
+       }
+
        _current_nouts = nouts;
        _current_npans = npans;
 
@@ -358,8 +346,8 @@ PannerUI::setup_pan ()
                        pan_adjustments.pop_back ();
                }
 
-               delete panner;
-               panner = 0;
+               delete twod_panner;
+               twod_panner = 0;
 
                /* stick something into the panning viewport so that it redraws */
 
@@ -379,8 +367,8 @@ PannerUI::setup_pan ()
                        pan_adjustments.pop_back ();
                }
 
-               delete panner;
-               panner = 0;
+               delete twod_panner;
+               twod_panner = 0;
 
                while ((asz = pan_adjustments.size()) < npans) {
 
@@ -409,8 +397,7 @@ PannerUI::setup_pan ()
                        /* now set adjustment with current value of panner, then connect the signals */
                        pan_adjustments.back()->set_value(rx);
                        pan_adjustments.back()->signal_value_changed().connect (sigc::bind (sigc::mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
-
-                       _panner->pan_control( asz )->Changed.connect (connections, boost::bind (&PannerUI::pan_value_changed, this, (uint32_t) asz), gui_context());
+                       connect_to_pan_control (asz);
 
                        bc->set_name ("PanSlider");
                        bc->set_shadow_type (Gtk::SHADOW_NONE);
@@ -418,8 +405,10 @@ PannerUI::setup_pan ()
                        boost::shared_ptr<AutomationControl> ac = _panner->pan_control (asz);
 
                        if (asz) {
-                               bc->StartGesture.connect (sigc::mem_fun (*ac, &AutomationControl::start_touch));
-                               bc->StopGesture.connect (sigc::mem_fun (*ac, &AutomationControl::stop_touch));
+                               bc->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), 
+                                                                      boost::weak_ptr<AutomationControl> (ac)));
+                               bc->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), 
+                                                                     boost::weak_ptr<AutomationControl>(ac)));
                        }
 
                        char buf[64];
@@ -448,36 +437,56 @@ PannerUI::setup_pan ()
 
        } else {
 
-               if (!panner) {
-                       panner = new Panner2d (_panner, 61);
-                       panner->set_name ("MixerPanZone");
-                       panner->show ();
+               if (!twod_panner) {
+                       twod_panner = new Panner2d (_panner, 61);
+                       twod_panner->set_name ("MixerPanZone");
+                       twod_panner->show ();
 
-                       panner->signal_button_press_event().connect
+                       twod_panner->signal_button_press_event().connect
                                (sigc::bind (sigc::mem_fun(*this, &PannerUI::pan_button_event), (uint32_t) 0), false);
                }
 
                update_pan_sensitive ();
-               panner->reset (npans);
+               twod_panner->reset (npans);
                if (big_window) {
                        big_window->reset (npans);
                }
-               panner->set_size_request (-1, 61);
+               twod_panner->set_size_request (-1, 61);
 
                /* and finally, add it to the panner frame */
 
                panning_viewport.remove ();
-               panning_viewport.add (*panner);
+               panning_viewport.add (*twod_panner);
                panning_viewport.show_all ();
        }
 }
 
+void
+PannerUI::start_touch (boost::weak_ptr<AutomationControl> wac)
+{
+        boost::shared_ptr<AutomationControl> ac = wac.lock();
+        if (!ac) {
+                return;
+        }
+        ac->start_touch (ac->session().transport_frame());
+}
+
+void
+PannerUI::stop_touch (boost::weak_ptr<AutomationControl> wac)
+{
+        boost::shared_ptr<AutomationControl> ac = wac.lock();
+        if (!ac) {
+                return;
+        }
+        ac->stop_touch (false, ac->session().transport_frame());
+}
+
 bool
 PannerUI::pan_button_event (GdkEventButton* ev, uint32_t which)
 {
        switch (ev->button) {
        case 1:
-               if (panner && ev->type == GDK_2BUTTON_PRESS) {
+               if (twod_panner && ev->type == GDK_2BUTTON_PRESS) {
                        if (!big_window) {
                                big_window = new Panner2dWindow (_panner, 400, _panner->npanners());
                        }
@@ -598,11 +607,11 @@ PannerUI::pan_changed (void *src)
                panning_link_button.set_sensitive (false);
                break;
        default:
-               panning_link_direction_button.set_sensitive (true);
+               panning_link_direction_button.set_sensitive (_panner->linked ());
                panning_link_button.set_sensitive (true);
        }
 
-       uint32_t nouts = _panner->nouts();
+       uint32_t const nouts = _panner->nouts();
 
        switch (nouts) {
        case 0:
@@ -659,7 +668,17 @@ PannerUI::pan_value_changed (uint32_t which)
 {
        ENSURE_GUI_THREAD (*this, &PannerUI::pan_value_changed, which)
 
-       if (_panner->npanners() > 1 && which < _panner->npanners()) {
+       if (twod_panner) {
+
+               float x;
+               float y;
+               _panner->streampanner(which).get_position (x, y);
+
+               in_pan_update = true;
+               twod_panner->move_puck (which, x, y);
+               in_pan_update = false;
+
+       } else if (_panner->npanners() > 0 && which < _panner->npanners()) {
                float xpos;
                float val = pan_adjustments[which]->get_value ();
 
@@ -722,8 +741,8 @@ PannerUI::update_pan_sensitive ()
                }
                break;
        default:
-               if (panner) {
-                       panner->set_sensitive (sensitive);
+               if (twod_panner) {
+                       twod_panner->set_sensitive (sensitive);
                }
                if (big_window) {
                        big_window->set_sensitive (sensitive);
@@ -900,4 +919,11 @@ PannerUI::set_mono (bool yn)
        update_pan_sensitive ();
 }
 
-       
+
+void
+PannerUI::connect_to_pan_control (uint32_t i)
+{
+       _panner->pan_control(i)->Changed.connect (
+               _pan_control_connections, invalidator (*this), boost::bind (&PannerUI::pan_value_changed, this, i), gui_context ()
+               );
+}