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
This commit is contained in:
@@ -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 (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;
|
||||
if (dragging_left) {
|
||||
position_control->set_value (pv - delta);
|
||||
} else {
|
||||
position_control->set_value (pv + delta);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
_panner->thaw ();
|
||||
|
||||
} else {
|
||||
/* width needs to change by 2 * delta because both L & R move */
|
||||
width_control->set_value (current_width + delta * 2);
|
||||
|
||||
/* 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 if (dragging_position) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -118,3 +118,17 @@ Panner::set_state (XMLNode const &, int)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Panner::freeze ()
|
||||
{
|
||||
_frozen++;
|
||||
}
|
||||
|
||||
void
|
||||
Panner::thaw ()
|
||||
{
|
||||
if (_frozen > 0.0) {
|
||||
_frozen--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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().
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ class Panner2in2out : public Panner
|
||||
void update ();
|
||||
|
||||
void reset ();
|
||||
void thaw ();
|
||||
|
||||
protected:
|
||||
float left[2];
|
||||
|
||||
Reference in New Issue
Block a user