diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-05-31 13:58:59 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-05-31 13:58:59 +0000 |
commit | 0b958b7f15decdce3ebb8234504014768ac12bba (patch) | |
tree | 8ac90c0fdf336b657cc574d17fceb3e6e371cd23 | |
parent | 78c0811ed7319a87be66c1207d1b01360576977b (diff) |
allow alt-drag on stereo panner to move just one side of the stereo field. this wiggles a bit, possibly because of rounding, and that probably needs to be addressed
git-svn-id: svn://localhost/ardour2/branches/3.0@12500 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/stereo_panner.cc | 70 | ||||
-rw-r--r-- | libs/ardour/ardour/panner.h | 5 | ||||
-rw-r--r-- | libs/ardour/panner.cc | 14 | ||||
-rw-r--r-- | libs/panners/2in2out/panner_2in2out.cc | 13 | ||||
-rw-r--r-- | libs/panners/2in2out/panner_2in2out.h | 1 |
5 files changed, 84 insertions, 19 deletions
diff --git a/gtk2_ardour/stereo_panner.cc b/gtk2_ardour/stereo_panner.cc index 730ef58910..96e1821ee6 100644 --- a/gtk2_ardour/stereo_panner.cc +++ b/gtk2_ardour/stereo_panner.cc @@ -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) { diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 51d75ebf03..4c585f8b31 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -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 diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index 6f3aec4646..2f52cb26d8 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -118,3 +118,17 @@ Panner::set_state (XMLNode const &, int) { return 0; } + +void +Panner::freeze () +{ + _frozen++; +} + +void +Panner::thaw () +{ + if (_frozen > 0.0) { + _frozen--; + } +} diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index 8e798315d0..57b8836787 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -124,8 +124,21 @@ 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(). diff --git a/libs/panners/2in2out/panner_2in2out.h b/libs/panners/2in2out/panner_2in2out.h index 232d63ec62..001d3064e8 100644 --- a/libs/panners/2in2out/panner_2in2out.h +++ b/libs/panners/2in2out/panner_2in2out.h @@ -67,6 +67,7 @@ class Panner2in2out : public Panner void update (); void reset (); + void thaw (); protected: float left[2]; |