Limit region-based automation to the edges of regions. Fixes #3201.

git-svn-id: svn://localhost/ardour2/branches/3.0@7662 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-08-20 22:43:10 +00:00
parent b2bf4eee3d
commit 822ee79d84
5 changed files with 51 additions and 22 deletions

View File

@ -65,6 +65,7 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv
, alist (al)
, _parent_group (parent)
, _time_converter (converter ? (*converter) : default_converter)
, _maximum_time (max_frames)
{
points_visible = false;
update_pending = false;
@ -1322,3 +1323,12 @@ AutomationLine::memento_command_binder ()
{
return new SimpleMementoCommandBinder<AutomationList> (*alist.get());
}
/** Set the maximum time that points on this line can be at, relative
* to the start of the track or region that it is on.
*/
void
AutomationLine::set_maximum_time (framepos_t t)
{
_maximum_time = t;
}

View File

@ -137,6 +137,11 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
const Evoral::TimeConverter<double, ARDOUR::sframes_t>& time_converter () const {
return _time_converter;
}
void set_maximum_time (ARDOUR::framepos_t);
ARDOUR::framepos_t maximum_time () const {
return _maximum_time;
}
protected:
@ -217,6 +222,9 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
void model_representation (ControlPoint&, ModelRepresentation&);
PBD::ScopedConnectionList _list_connections;
/** maximum time that a point on this line can be at, relative to the start of its region or track */
ARDOUR::framecnt_t _maximum_time;
friend class AudioRegionGainLine;
};

View File

@ -86,6 +86,7 @@ AutomationRegionView::create_line (boost::shared_ptr<ARDOUR::AutomationList> lis
_line->set_height ((uint32_t)rint(trackview.current_height() - NAME_HIGHLIGHT_SIZE));
_line->show();
_line->show_all_control_points();
_line->set_maximum_time (_region->length());
}
bool
@ -177,6 +178,10 @@ AutomationRegionView::set_height (double h)
bool
AutomationRegionView::set_position (nframes64_t pos, void* src, double* ignored)
{
if (_line) {
_line->set_maximum_time (_region->length ());
}
return RegionView::set_position(pos, src, ignored);
}
@ -186,8 +191,9 @@ AutomationRegionView::reset_width_dependent_items (double pixel_width)
{
RegionView::reset_width_dependent_items(pixel_width);
if (_line)
if (_line) {
_line->reset();
}
}
@ -196,8 +202,10 @@ AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
{
RegionView::region_resized(what_changed);
if (_line)
if (_line) {
_line->reset();
_line->set_maximum_time (_region->length());
}
}

View File

@ -2736,12 +2736,12 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
// start the grab at the center of the control point so
// the point doesn't 'jump' to the mouse after the first drag
_time_axis_view_grab_x = _point->get_x();
_time_axis_view_grab_y = _point->get_y();
_fixed_grab_x = _point->get_x();
_fixed_grab_y = _point->get_y();
float const fraction = 1 - (_point->get_y() / _point->line().height());
_point->line().start_drag_single (_point, _time_axis_view_grab_x, fraction);
_point->line().start_drag_single (_point, _fixed_grab_x, fraction);
_editor->set_verbose_canvas_cursor (_point->line().get_verbose_cursor_string (fraction),
event->button.x + 10, event->button.y + 10);
@ -2760,9 +2760,10 @@ ControlPointDrag::motion (GdkEvent* event, bool)
dy *= 0.1;
}
/* coordinate in TimeAxisView's space */
double cx = _time_axis_view_grab_x + _cumulative_x_drag + dx;
double cy = _time_axis_view_grab_y + _cumulative_y_drag + dy;
/* coordinate in pixels relative to the start of the region (for region-based automation)
or track (for track-based automation) */
double cx = _fixed_grab_x + _cumulative_x_drag + dx;
double cy = _fixed_grab_y + _cumulative_y_drag + dy;
// calculate zero crossing point. back off by .01 to stay on the
// positive side of zero
@ -2774,25 +2775,27 @@ ControlPointDrag::motion (GdkEvent* event, bool)
}
if (_x_constrained) {
cx = _time_axis_view_grab_x;
cx = _fixed_grab_x;
}
if (_y_constrained) {
cy = _time_axis_view_grab_y;
cy = _fixed_grab_y;
}
_cumulative_x_drag = cx - _time_axis_view_grab_x;
_cumulative_y_drag = cy - _time_axis_view_grab_y;
_cumulative_x_drag = cx - _fixed_grab_x;
_cumulative_y_drag = cy - _fixed_grab_y;
cx = max (0.0, cx);
cy = max (0.0, cy);
cy = min ((double) _point->line().height(), cy);
nframes64_t cx_frames = _editor->unit_to_frame (cx);
framepos_t cx_frames = _editor->unit_to_frame (cx);
if (!_x_constrained) {
_editor->snap_to_with_modifier (cx_frames, event);
}
cx_frames = min (cx_frames, _point->line().maximum_time());
float const fraction = 1.0 - (cy / _point->line().height());
bool const push = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier);
@ -2875,8 +2878,8 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
/* store grab start in parent frame */
_time_axis_view_grab_x = cx;
_time_axis_view_grab_y = cy;
_fixed_grab_x = cx;
_fixed_grab_y = cy;
double fraction = 1.0 - (cy / _line->height());
@ -2897,9 +2900,9 @@ LineDrag::motion (GdkEvent* event, bool)
dy *= 0.1;
}
double cy = _time_axis_view_grab_y + _cumulative_y_drag + dy;
double cy = _fixed_grab_y + _cumulative_y_drag + dy;
_cumulative_y_drag = cy - _time_axis_view_grab_y;
_cumulative_y_drag = cy - _fixed_grab_y;
cy = max (0.0, cy);
cy = min ((double) _line->height(), cy);

View File

@ -596,8 +596,8 @@ public:
private:
ControlPoint* _point;
double _time_axis_view_grab_x;
double _time_axis_view_grab_y;
double _fixed_grab_x;
double _fixed_grab_y;
double _cumulative_x_drag;
double _cumulative_y_drag;
static double const _zero_gain_fraction;
@ -621,8 +621,8 @@ public:
private:
AutomationLine* _line;
double _time_axis_view_grab_x;
double _time_axis_view_grab_y;
double _fixed_grab_x;
double _fixed_grab_y;
uint32_t _before;
uint32_t _after;
double _cumulative_y_drag;