more stereo panner work
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 1 Dec 2010 21:24:57 +0000 (21:24 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 1 Dec 2010 21:24:57 +0000 (21:24 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8149 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/stereo_panner.cc
gtk2_ardour/stereo_panner.h
libs/ardour/panner.cc

index cb7debdcd6fc518b71007d12659df03aa6e5233b..1709a72477eab3dd75931350757814183365ba7b 100644 (file)
@@ -103,7 +103,7 @@ StereoPanner::on_expose_event (GdkEventExpose* ev)
         int left = center - (int) floor (fswidth * usable_width / 2.0); // center of leftmost box
         int right = center + (int) floor (fswidth * usable_width / 2.0); // center of rightmost box
 
-        cerr << "pos " << pos << " width = " << width << " swidth = " << swidth << " center @ " << center << " L = " << left << " R = " << right << endl;
+        // cerr << "pos " << pos << " width = " << width << " swidth = " << swidth << " center @ " << center << " L = " << left << " R = " << right << endl;
 
         /* compute & draw the line through the box */
         
@@ -183,12 +183,8 @@ StereoPanner::on_button_press_event (GdkEventButton* ev)
         drag_start_x = ev->x;
         last_drag_x = ev->x;
 
-        /* center 8 pixels are for position drag */
-
-        int w = get_width();
-        double pos = position_control->get_value ();
-
-        if ((ev->x >= (int) floor ((pos * w)-(pos_box_size/2))) && (ev->x <= (int) floor ((pos * w)+(pos_box_size/2)))) {
+        if (ev->y < 20) {
+                /* top section of widget is for position drags */
                 dragging_position = true;
         } else {
                 dragging_position = false;
@@ -218,6 +214,12 @@ StereoPanner::on_button_release_event (GdkEventButton* ev)
         return true;
 }
 
+bool
+StereoPanner::on_scroll_event (GdkEventScroll* ev)
+{
+        return true;
+}
+
 bool
 StereoPanner::on_motion_notify_event (GdkEventMotion* ev)
 {
@@ -226,18 +228,72 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev)
         }
 
         int w = get_width();
-        float delta = (abs (ev->x - last_drag_x)) / (double) (w/2);
+        double delta = (abs (ev->x - last_drag_x)) / (w/2.0);
+        int drag_dir = 0;
 
         if (!dragging_position) {
                 double wv = width_control->get_value();        
+                int inc;
+                double old_wv;
+                double opx; // compute the operational x-coordinate given the current pos+width
                 
-                if (((drag_start_x < w/2) && ev->x > last_drag_x) || // start left of center, move towards it
-                    ((drag_start_x > w/2) && ev->x < last_drag_x)) { // start right of center, move towards it
-                        wv = wv  * (1.0 - delta);
+                if (wv > 0) {
+                        /* positive value: increasing width means adding */
+                        inc = 1;
+                } else {
+                        /* positive value: increasing width means subtracting */
+                        inc = -1;
+                }
+
+                if (drag_start_x < w/2) {
+                        /* started left of center */
+
+                        opx = position_control->get_value() - (wv/2.0);
+
+                        if (opx < 0.5) {
+                                /* still left */
+                                if (ev->x > last_drag_x) {
+                                        /* motion to left */
+                                        drag_dir = -inc;
+                                } else {
+                                        drag_dir = inc;
+                                }
+                        } else {
+                                /* now right */
+                                if (ev->x > last_drag_x) {
+                                        /* motion to left */
+                                        drag_dir = inc;
+                                } else {
+                                        drag_dir = -inc;
+                                }
+                        }
                 } else {
-                        /* moving out, so increase the width */
-                        wv = wv * (1.0 + delta);
+                        /* started right of center */
+                        
+                        opx = position_control->get_value() + (wv/2.0);
+
+                        if (opx > 0.5) {
+                                /* still right */
+                                if (ev->x < last_drag_x) {
+                                        /* motion to right */
+                                        drag_dir = -inc;
+                                } else {
+                                        drag_dir = inc;
+                                }
+                        } else {
+                                /* now left */
+                                if (ev->x < last_drag_x) {
+                                        /* motion to right */
+                                        drag_dir = inc;
+                                } else {
+                                        drag_dir = -inc;
+                                }
+                        }
+
                 }
+
+                old_wv = wv;
+                wv = wv + (drag_dir * delta);
                 
                 width_control->set_value (wv);
 
index 00de9f3b4987ee16dce554197370867adf37afb7..4b08a7ce76f799de9f87301c9bb1455e34b9db1b 100644 (file)
@@ -40,6 +40,7 @@ class StereoPanner : public Gtk::DrawingArea
        bool on_button_press_event (GdkEventButton*);
        bool on_button_release_event (GdkEventButton*);
        bool on_motion_notify_event (GdkEventMotion*);
+        bool on_scroll_event (GdkEventScroll*);
 
   private:
         boost::shared_ptr<PBD::Controllable> position_control;
index e2efead27f5d7c368c45855c02b007bc757cbef1..6bef67788ab89ccc4dd9f4036f04e5727651d0f0 100644 (file)
@@ -116,6 +116,7 @@ StreamPanner::PanControllable::set_value (double val)
         switch (parameter().id()) {
         case 100:
                 /* position */
+                val = max (min (val, 1.0), 0.0);
                 if (p.set_stereo_pan (val, p.width_control()->get_value())) {
                         AutomationControl::set_value(val);
                 }
@@ -123,6 +124,7 @@ StreamPanner::PanControllable::set_value (double val)
 
         case 200:
                 /* width */
+                val = max (min (val, 1.0), -1.0);
                 if (p.set_stereo_pan (p.direction_control()->get_value(), val)) {
                         AutomationControl::set_value(val);
                 }
@@ -1475,7 +1477,7 @@ Panner::set_stereo_pan (double direction_as_lr_fract, double width)
                 _streampanners[l_index]->set_position (AngularVector (l_pos, 0.0));
                 _streampanners[r_index]->set_position (AngularVector (r_pos, 0.0));
 
-                cerr << "left @ " << BaseStereoPanner::azimuth_to_lr_fract (l_pos) << " right @ " << BaseStereoPanner::azimuth_to_lr_fract (r_pos) << endl;
+                // cerr << "left @ " << BaseStereoPanner::azimuth_to_lr_fract (l_pos) << " right @ " << BaseStereoPanner::azimuth_to_lr_fract (r_pos) << endl;
         }
 
         return move_left && move_right;