allow alt-drag on stereo panner to move just one side of the stereo field. this wiggl...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 31 May 2012 13:58:59 +0000 (13:58 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 31 May 2012 13:58:59 +0000 (13:58 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@12500 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/stereo_panner.cc
libs/ardour/ardour/panner.h
libs/ardour/panner.cc
libs/panners/2in2out/panner_2in2out.cc
libs/panners/2in2out/panner_2in2out.h

index 730ef58910b0ef4088aaa056b331eca210e4e273..96e1821ee6434cced8f7cef8408296775198718c 100644 (file)
@@ -476,35 +476,67 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev)
        if (dragging_left) {
                delta = -delta;
        }
-
+       
        if (dragging_left || dragging_right) {
 
-               /* maintain position as invariant as we change the width */
+               if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
 
+                       /* change width and position in a way that keeps the
+                        * other side in the same place
+                        */
 
-               /* create a detent close to the center */
+                       _panner->freeze ();
+                       
+                       double pv = position_control->get_value();
 
-               if (!detented && fabs (current_width) < 0.02) {
-                       detented = true;
-                       /* snap to zero */
-                       width_control->set_value (0);
-               }
+                       if (dragging_left) {
+                               position_control->set_value (pv - delta);
+                       } else {
+                               position_control->set_value (pv + delta);
+                       }
 
-               if (detented) {
+                       if (delta > 0.0) {
+                               /* delta is positive, so we're about to
+                                  increase the width. But we need to increase it
+                                  by twice the required value so that the
+                                  other side remains in place when we set
+                                  the position as well.
+                               */
+                               width_control->set_value (current_width + (delta * 2.0));
+                       } else {
+                               width_control->set_value (current_width + delta);
+                       }
 
-                       accumulated_delta += delta;
+                       _panner->thaw ();
 
-                       /* have we pulled far enough to escape ? */
+               } else {
 
-                       if (fabs (accumulated_delta) >= 0.025) {
-                               width_control->set_value (current_width + accumulated_delta);
-                               detented = false;
-                               accumulated_delta = false;
+                       /* maintain position as invariant as we change the width */
+                       
+                       /* create a detent close to the center */
+                       
+                       if (!detented && fabs (current_width) < 0.02) {
+                               detented = true;
+                               /* snap to zero */
+                               width_control->set_value (0);
+                       }
+                       
+                       if (detented) {
+                               
+                               accumulated_delta += delta;
+                               
+                               /* have we pulled far enough to escape ? */
+                               
+                               if (fabs (accumulated_delta) >= 0.025) {
+                                       width_control->set_value (current_width + accumulated_delta);
+                                       detented = false;
+                                       accumulated_delta = false;
+                               }
+                               
+                       } else {
+                               /* width needs to change by 2 * delta because both L & R move */
+                               width_control->set_value (current_width + (delta * 2.0));
                        }
-
-               } else {
-                       /* width needs to change by 2 * delta because both L & R move */
-                       width_control->set_value (current_width + delta * 2);
                }
 
        } else if (dragging_position) {
index 51d75ebf03286c0d0ed10bd2b82e949fb157bebd..4c585f8b31917dfb3fa16a4faa0379c0d9c64dbf 100644 (file)
@@ -151,6 +151,9 @@ public:
                return fabs (a.azi - b.azi) < 1.0;
        }
 
+        virtual void freeze ();
+        virtual void thaw ();
+
 protected:
        boost::shared_ptr<Pannable> _pannable;
 
@@ -158,6 +161,8 @@ protected:
        virtual void distribute_one_automated (AudioBuffer&, BufferSet& obufs,
                                               framepos_t start, framepos_t end, pframes_t nframes,
                                               pan_t** buffers, uint32_t which) = 0;
+
+        int32_t _frozen;
 };
 
 } // namespace
index 6f3aec4646931007ebdbf4bf462b161de67f7460..2f52cb26d897700bc1e2419db8ae6209ea04ac38 100644 (file)
@@ -118,3 +118,17 @@ Panner::set_state (XMLNode const &, int)
 {
        return 0;
 }
+
+void
+Panner::freeze ()
+{
+       _frozen++;
+}
+
+void
+Panner::thaw ()
+{
+       if (_frozen > 0.0) {
+               _frozen--;
+       }
+}
index 8e798315d04fd6b4936b1de88e18aaee219d8365..57b8836787e7701d99af6f796d5ae9c01c657355 100644 (file)
@@ -123,9 +123,22 @@ Panner2in2out::set_width (double p)
         }
 }
 
+void
+Panner2in2out::thaw ()
+{
+       Panner::thaw ();
+       if (_frozen == 0) {
+               update ();
+       }
+}
+
 void
 Panner2in2out::update ()
 {
+       if (_frozen) {
+               return;
+       }
+
         /* it would be very nice to split this out into a virtual function
            that can be accessed from BaseStereoPanner and used in do_distribute_automated().
            
index 232d63ec62257ba988a81f11ee316efc77239563..001d3064e8872ff72e1a321a44f6790020fb9703 100644 (file)
@@ -67,6 +67,7 @@ class Panner2in2out : public Panner
         void update ();
 
        void reset ();
+        void thaw ();
 
   protected:
        float left[2];