summaryrefslogtreecommitdiff
path: root/gtk2_ardour/automation_line.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour/automation_line.cc')
-rw-r--r--gtk2_ardour/automation_line.cc188
1 files changed, 115 insertions, 73 deletions
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index 128cfb5148..0c568ee55a 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -239,7 +239,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
void
-AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool with_push)
+AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool keep_x, bool with_push)
{
double delta = 0.0;
uint32_t last_movable = UINT_MAX;
@@ -257,7 +257,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi
y = min (1.0, y);
y = _height - (y * _height);
- if (cp.can_slide()) {
+ if (cp.can_slide() && !keep_x) {
/* x-coord cannot move beyond adjacent points or the start/end, and is
already in frames. it needs to be converted to canvas units.
@@ -362,15 +362,12 @@ AutomationLine::reset_line_coords (ControlPoint& cp)
}
void
-AutomationLine::sync_model_with_view_line (uint32_t start, uint32_t end)
+AutomationLine::sync_model_with_view_points (list<ControlPoint*> cp, bool did_push, int64_t distance)
{
- ControlPoint *p;
-
update_pending = true;
- for (uint32_t i = start; i <= end; ++i) {
- p = nth(i);
- sync_model_with_view_point (*p, false, 0);
+ for (list<ControlPoint*>::iterator i = cp.begin(); i != cp.end(); ++i) {
+ sync_model_with_view_point (**i, did_push, distance);
}
}
@@ -488,6 +485,14 @@ AutomationLine::determine_visible_control_points (ALPoints& points)
double tx = points[pi].x;
double ty = points[pi].y;
+ if (find (_always_in_view.begin(), _always_in_view.end(), (*model)->when) != _always_in_view.end()) {
+ add_visible_control_point (view_index, pi, tx, ty, model, npoints);
+ prev_rx = this_rx;
+ prev_ry = this_ry;
+ ++view_index;
+ continue;
+ }
+
if (isnan (tx) || isnan (ty)) {
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
_name) << endmsg;
@@ -667,66 +672,36 @@ AutomationLine::invalidate_point (ALPoints& p, uint32_t index)
p[index].y = DBL_MAX;
}
+/** Start dragging a single point.
+ * @param cp Point to drag.
+ * @param x Initial x position (frames).
+ * @param fraction Initial y position (as a fraction of the track height, where 0 is the bottom and 1 the top)
+ */
void
-AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction)
+AutomationLine::start_drag_single (ControlPoint* cp, nframes_t x, float fraction)
{
- if (trackview.editor().session() == 0) { /* how? */
- return;
- }
-
- string str;
-
- if (cp) {
- str = _("automation event move");
- } else {
- str = _("automation range drag");
- }
-
- trackview.editor().session()->begin_reversible_command (str);
+ trackview.editor().session()->begin_reversible_command (_("automation event move"));
trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &get_state(), 0));
- drag_x = x;
- drag_distance = 0;
- first_drag_fraction = fraction;
- last_drag_fraction = fraction;
- drags = 0;
- did_push = false;
-}
-
-void
-AutomationLine::point_drag (ControlPoint& cp, nframes_t x, float fraction, bool with_push)
-{
- if (x > drag_x) {
- drag_distance += (x - drag_x);
- } else {
- drag_distance -= (drag_x - x);
- }
-
- drag_x = x;
-
- modify_view_point (cp, x, fraction, with_push);
-
- if (line_points.size() > 1) {
- line->property_points() = line_points;
- }
-
- drags++;
- did_push = with_push;
+ _drag_points.clear ();
+ _drag_points.push_back (cp);
+ start_drag_common (x, fraction);
}
+/** Start dragging a line vertically (with no change in x)
+ * @param i1 Control point index of the `left' point on the line.
+ * @param i2 Control point index of the `right' point on the line.
+ * @param fraction Initial y position (as a fraction of the track height, where 0 is the bottom and 1 the top)
+ */
void
-AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_push)
+AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
- double ydelta = fraction - last_drag_fraction;
-
- did_push = with_push;
-
- last_drag_fraction = fraction;
+ trackview.editor().session()->begin_reversible_command (_("automation range move"));
+ trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &get_state(), 0));
- line_drag_cp1 = i1;
- line_drag_cp2 = i2;
+ _drag_points.clear ();
- //check if one of the control points on the line is in a selected range
+ // check if one of the control points on the line is in a selected range
bool range_found = false;
ControlPoint *cp;
@@ -740,38 +715,92 @@ AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_p
if (range_found) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
if ((*i)->selected()) {
- modify_view_point (*(*i), trackview.editor().unit_to_frame ((*i)->get_x()), ((_height - (*i)->get_y()) /_height) + ydelta, with_push);
+ _drag_points.push_back (*i);
}
}
} else {
- ControlPoint *cp;
for (uint32_t i = i1 ; i <= i2; i++) {
- cp = nth (i);
- modify_view_point (*cp, trackview.editor().unit_to_frame (cp->get_x()), ((_height - cp->get_y()) /_height) + ydelta, with_push);
+ _drag_points.push_back (nth (i));
}
}
+ start_drag_common (0, fraction);
+}
+
+/** Start dragging multiple points (with no change in x)
+ * @param cp Points to drag.
+ * @param fraction Initial y position (as a fraction of the track height, where 0 is the bottom and 1 the top)
+ */
+void
+AutomationLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
+{
+ trackview.editor().session()->begin_reversible_command (_("automation range move"));
+ trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), state, 0));
+
+ _drag_points = cp;
+ start_drag_common (0, fraction);
+}
+
+/** Common parts of starting a drag.
+ * @param d Description of the drag.
+ * @param x Starting x position in frames, or 0 if x is being ignored.
+ * @param fraction Starting y position (as a fraction of the track height, where 0 is the bottom and 1 the top)
+ */
+void
+AutomationLine::start_drag_common (nframes_t x, float fraction)
+{
+ drag_x = x;
+ drag_distance = 0;
+ _last_drag_fraction = fraction;
+ _drag_had_movement = false;
+ did_push = false;
+}
+
+/** Should be called to indicate motion during a drag.
+ * @param x New x position of the drag in frames, or 0 if x is being ignored.
+ * @param fraction New y fraction.
+ */
+void
+AutomationLine::drag_motion (nframes_t x, float fraction, bool with_push)
+{
+ int64_t const dx = x - drag_x;
+ drag_distance += dx;
+ drag_x = x;
+
+ double const dy = fraction - _last_drag_fraction;
+
+ _last_drag_fraction = fraction;
+
+ for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
+
+ modify_view_point (
+ **i,
+ trackview.editor().unit_to_frame ((*i)->get_x()) + dx,
+ ((_height - (*i)->get_y()) / _height) + dy,
+ (x == 0),
+ with_push
+ );
+ }
+
if (line_points.size() > 1) {
line->property_points() = line_points;
}
- drags++;
+ _drag_had_movement = true;
+ did_push = with_push;
}
+/** Should be called to indicate the end of a drag */
void
-AutomationLine::end_drag (ControlPoint* cp)
+AutomationLine::end_drag ()
{
- if (!drags) {
+ if (!_drag_had_movement) {
return;
}
alist->freeze ();
- if (cp) {
- sync_model_with_view_point (*cp, did_push, drag_distance);
- } else {
- sync_model_with_view_line (line_drag_cp1, line_drag_cp2);
- }
+ sync_model_with_view_points (_drag_points, did_push, drag_distance);
alist->thaw ();
@@ -782,7 +811,6 @@ AutomationLine::end_drag (ControlPoint* cp)
trackview.editor().session()->set_dirty ();
}
-
void
AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int64_t distance)
{
@@ -849,7 +877,6 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int
alist->slide (mr.end, drag_distance);
}
-
}
bool
@@ -1302,7 +1329,7 @@ AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, dou
control_points[view_index]->set_can_slide(true);
shape = ControlPoint::Full;
}
-
+
control_points[view_index]->reset (tx, ty, model, view_index, shape);
/* finally, control visibility */
@@ -1316,3 +1343,18 @@ AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, dou
}
}
}
+
+void
+AutomationLine::add_always_in_view (double x)
+{
+ _always_in_view.push_back (x);
+ alist->apply_to_points (*this, &AutomationLine::reset_callback);
+}
+
+void
+AutomationLine::clear_always_in_view ()
+{
+ _always_in_view.clear ();
+ alist->apply_to_points (*this, &AutomationLine::reset_callback);
+}
+