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:
parent
b2bf4eee3d
commit
822ee79d84
@ -65,6 +65,7 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv
|
|||||||
, alist (al)
|
, alist (al)
|
||||||
, _parent_group (parent)
|
, _parent_group (parent)
|
||||||
, _time_converter (converter ? (*converter) : default_converter)
|
, _time_converter (converter ? (*converter) : default_converter)
|
||||||
|
, _maximum_time (max_frames)
|
||||||
{
|
{
|
||||||
points_visible = false;
|
points_visible = false;
|
||||||
update_pending = false;
|
update_pending = false;
|
||||||
@ -1322,3 +1323,12 @@ AutomationLine::memento_command_binder ()
|
|||||||
{
|
{
|
||||||
return new SimpleMementoCommandBinder<AutomationList> (*alist.get());
|
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;
|
||||||
|
}
|
||||||
|
@ -138,6 +138,11 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
|||||||
return _time_converter;
|
return _time_converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_maximum_time (ARDOUR::framepos_t);
|
||||||
|
ARDOUR::framepos_t maximum_time () const {
|
||||||
|
return _maximum_time;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
@ -218,6 +223,9 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
|||||||
|
|
||||||
PBD::ScopedConnectionList _list_connections;
|
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;
|
friend class AudioRegionGainLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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->set_height ((uint32_t)rint(trackview.current_height() - NAME_HIGHLIGHT_SIZE));
|
||||||
_line->show();
|
_line->show();
|
||||||
_line->show_all_control_points();
|
_line->show_all_control_points();
|
||||||
|
_line->set_maximum_time (_region->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -177,6 +178,10 @@ AutomationRegionView::set_height (double h)
|
|||||||
bool
|
bool
|
||||||
AutomationRegionView::set_position (nframes64_t pos, void* src, double* ignored)
|
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);
|
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);
|
RegionView::reset_width_dependent_items(pixel_width);
|
||||||
|
|
||||||
if (_line)
|
if (_line) {
|
||||||
_line->reset();
|
_line->reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -196,8 +202,10 @@ AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
|
|||||||
{
|
{
|
||||||
RegionView::region_resized(what_changed);
|
RegionView::region_resized(what_changed);
|
||||||
|
|
||||||
if (_line)
|
if (_line) {
|
||||||
_line->reset();
|
_line->reset();
|
||||||
|
_line->set_maximum_time (_region->length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2736,12 +2736,12 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
|
|||||||
|
|
||||||
// start the grab at the center of the control point so
|
// start the grab at the center of the control point so
|
||||||
// the point doesn't 'jump' to the mouse after the first drag
|
// the point doesn't 'jump' to the mouse after the first drag
|
||||||
_time_axis_view_grab_x = _point->get_x();
|
_fixed_grab_x = _point->get_x();
|
||||||
_time_axis_view_grab_y = _point->get_y();
|
_fixed_grab_y = _point->get_y();
|
||||||
|
|
||||||
float const fraction = 1 - (_point->get_y() / _point->line().height());
|
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),
|
_editor->set_verbose_canvas_cursor (_point->line().get_verbose_cursor_string (fraction),
|
||||||
event->button.x + 10, event->button.y + 10);
|
event->button.x + 10, event->button.y + 10);
|
||||||
@ -2760,9 +2760,10 @@ ControlPointDrag::motion (GdkEvent* event, bool)
|
|||||||
dy *= 0.1;
|
dy *= 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* coordinate in TimeAxisView's space */
|
/* coordinate in pixels relative to the start of the region (for region-based automation)
|
||||||
double cx = _time_axis_view_grab_x + _cumulative_x_drag + dx;
|
or track (for track-based automation) */
|
||||||
double cy = _time_axis_view_grab_y + _cumulative_y_drag + dy;
|
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
|
// calculate zero crossing point. back off by .01 to stay on the
|
||||||
// positive side of zero
|
// positive side of zero
|
||||||
@ -2774,25 +2775,27 @@ ControlPointDrag::motion (GdkEvent* event, bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_x_constrained) {
|
if (_x_constrained) {
|
||||||
cx = _time_axis_view_grab_x;
|
cx = _fixed_grab_x;
|
||||||
}
|
}
|
||||||
if (_y_constrained) {
|
if (_y_constrained) {
|
||||||
cy = _time_axis_view_grab_y;
|
cy = _fixed_grab_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cumulative_x_drag = cx - _time_axis_view_grab_x;
|
_cumulative_x_drag = cx - _fixed_grab_x;
|
||||||
_cumulative_y_drag = cy - _time_axis_view_grab_y;
|
_cumulative_y_drag = cy - _fixed_grab_y;
|
||||||
|
|
||||||
cx = max (0.0, cx);
|
cx = max (0.0, cx);
|
||||||
cy = max (0.0, cy);
|
cy = max (0.0, cy);
|
||||||
cy = min ((double) _point->line().height(), 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) {
|
if (!_x_constrained) {
|
||||||
_editor->snap_to_with_modifier (cx_frames, event);
|
_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());
|
float const fraction = 1.0 - (cy / _point->line().height());
|
||||||
|
|
||||||
bool const push = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier);
|
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 */
|
/* store grab start in parent frame */
|
||||||
|
|
||||||
_time_axis_view_grab_x = cx;
|
_fixed_grab_x = cx;
|
||||||
_time_axis_view_grab_y = cy;
|
_fixed_grab_y = cy;
|
||||||
|
|
||||||
double fraction = 1.0 - (cy / _line->height());
|
double fraction = 1.0 - (cy / _line->height());
|
||||||
|
|
||||||
@ -2897,9 +2900,9 @@ LineDrag::motion (GdkEvent* event, bool)
|
|||||||
dy *= 0.1;
|
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 = max (0.0, cy);
|
||||||
cy = min ((double) _line->height(), cy);
|
cy = min ((double) _line->height(), cy);
|
||||||
|
@ -596,8 +596,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
ControlPoint* _point;
|
ControlPoint* _point;
|
||||||
double _time_axis_view_grab_x;
|
double _fixed_grab_x;
|
||||||
double _time_axis_view_grab_y;
|
double _fixed_grab_y;
|
||||||
double _cumulative_x_drag;
|
double _cumulative_x_drag;
|
||||||
double _cumulative_y_drag;
|
double _cumulative_y_drag;
|
||||||
static double const _zero_gain_fraction;
|
static double const _zero_gain_fraction;
|
||||||
@ -621,8 +621,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
AutomationLine* _line;
|
AutomationLine* _line;
|
||||||
double _time_axis_view_grab_x;
|
double _fixed_grab_x;
|
||||||
double _time_axis_view_grab_y;
|
double _fixed_grab_y;
|
||||||
uint32_t _before;
|
uint32_t _before;
|
||||||
uint32_t _after;
|
uint32_t _after;
|
||||||
double _cumulative_y_drag;
|
double _cumulative_y_drag;
|
||||||
|
Loading…
Reference in New Issue
Block a user