summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-05-31 13:58:59 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-05-31 13:58:59 +0000
commit0b958b7f15decdce3ebb8234504014768ac12bba (patch)
tree8ac90c0fdf336b657cc574d17fceb3e6e371cd23
parent78c0811ed7319a87be66c1207d1b01360576977b (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.cc70
-rw-r--r--libs/ardour/ardour/panner.h5
-rw-r--r--libs/ardour/panner.cc14
-rw-r--r--libs/panners/2in2out/panner_2in2out.cc13
-rw-r--r--libs/panners/2in2out/panner_2in2out.h1
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];