From 822ee79d840f20036b5729277f90e641cb0bb06f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 20 Aug 2010 22:43:10 +0000 Subject: [PATCH] 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 --- gtk2_ardour/automation_line.cc | 10 ++++++++ gtk2_ardour/automation_line.h | 8 ++++++ gtk2_ardour/automation_region_view.cc | 12 +++++++-- gtk2_ardour/editor_drag.cc | 35 +++++++++++++++------------ gtk2_ardour/editor_drag.h | 8 +++--- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index bf8b5c51b1..052691cb60 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -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 (*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; +} diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 6578e12ea4..3e23729e67 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -137,6 +137,11 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible const Evoral::TimeConverter& 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; }; diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc index a576101048..2cc3059350 100644 --- a/gtk2_ardour/automation_region_view.cc +++ b/gtk2_ardour/automation_region_view.cc @@ -86,6 +86,7 @@ AutomationRegionView::create_line (boost::shared_ptr 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()); + } } diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d4b918adf2..1e3823961e 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -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); diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index d710e3a639..9e503201b8 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -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;