X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fautomation_line.cc;h=7f9bd6b45551666bd2f68417ea561bd3cacd608b;hb=f6fdd8dcbf41f864e9f0cc32dabe81fe3533ddfe;hp=a7eada37e7290bcae118e16bf31ea6bdc88ceb7d;hpb=1380f4fafbdf7dcc5f6f699c57ebf53621f84078;p=ardour.git diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index a7eada37e7..7f9bd6b455 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2003 Paul Davis + Copyright (C) 2002-2003 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,13 +22,13 @@ #include #include -#include -#include -#include +#include "pbd/stl_delete.h" +#include "pbd/memento_command.h" +#include "pbd/stacktrace.h" -#include -#include -#include +#include "ardour/automation_list.h" +#include "ardour/dB.h" +#include "evoral/Curve.hpp" #include "simplerect.h" #include "automation_line.h" @@ -44,23 +44,27 @@ #include "automation_time_axis.h" #include "public_editor.h" -#include -#include +#include "ardour/event_type_map.h" +#include "ardour/session.h" #include "i18n.h" using namespace std; -using namespace sigc; using namespace ARDOUR; using namespace PBD; using namespace Editing; using namespace Gnome; // for Canvas -AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr al) - : trackview (tv), - _name (name), - alist (al), - _parent_group (parent) +static const Evoral::IdentityConverter default_converter; + +AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent, + boost::shared_ptr al, + const Evoral::TimeConverter* converter) + : trackview (tv) + , _name (name) + , alist (al) + , _parent_group (parent) + , _time_converter (converter ? (*converter) : default_converter) { _interpolation = al->interpolation(); points_visible = false; @@ -79,11 +83,11 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv line->property_width_pixels() = (guint)1; line->set_data ("line", this); - line->signal_event().connect (mem_fun (*this, &AutomationLine::event_handler)); + line->signal_event().connect (sigc::mem_fun (*this, &AutomationLine::event_handler)); - alist->StateChanged.connect (mem_fun(*this, &AutomationLine::list_changed)); + alist->StateChanged.connect (sigc::mem_fun(*this, &AutomationLine::list_changed)); - trackview.session().register_with_memento_command_factory(alist->id(), this); + trackview.session()->register_with_memento_command_factory(alist->id(), this); if (alist->parameter().type() == GainAutomation || alist->parameter().type() == EnvelopeAutomation) { @@ -110,12 +114,12 @@ AutomationLine::queue_reset () { if (!update_pending) { update_pending = true; - Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AutomationLine::reset)); + Gtkmm2ext::UI::instance()->call_slot (boost::bind (&AutomationLine::reset, this)); } } void -AutomationLine::show () +AutomationLine::show () { if (_interpolation != AutomationList::Discrete) { line->show(); @@ -131,7 +135,7 @@ AutomationLine::show () } void -AutomationLine::hide () +AutomationLine::hide () { line->hide(); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -152,7 +156,7 @@ AutomationLine::control_point_box_size () return 8.0; } else if (_height > (guint32) TimeAxisView::hNormal) { return 6.0; - } + } return 4.0; } @@ -209,10 +213,10 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y) y = min (1.0, y); y = _height - (y * _height); - double const x = trackview.editor().frame_to_unit ((*cp.model())->when); + double const x = trackview.editor().frame_to_unit (_time_converter.to((*cp.model())->when)); - trackview.editor().current_session()->begin_reversible_command (_("automation event move")); - trackview.editor().current_session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); + trackview.editor().session()->begin_reversible_command (_("automation event move")); + trackview.editor().session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); cp.move_to (x, y, ControlPoint::Full); reset_line_coords (cp); @@ -227,9 +231,9 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y) update_pending = false; - trackview.editor().current_session()->add_command (new MementoCommand(*alist.get(), 0, &alist->get_state())); - trackview.editor().current_session()->commit_reversible_command (); - trackview.editor().current_session()->set_dirty (); + trackview.editor().session()->add_command (new MementoCommand(*alist.get(), 0, &alist->get_state())); + trackview.editor().session()->commit_reversible_command (); + trackview.editor().session()->set_dirty (); } @@ -257,7 +261,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi /* x-coord cannot move beyond adjacent points or the start/end, and is already in frames. it needs to be converted to canvas units. */ - + x = trackview.editor().frame_to_unit (x); /* clamp x position using view coordinates */ @@ -275,14 +279,14 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi if (!with_push) { if (cp.view_index() < control_points.size() - 1) { - + after = nth (cp.view_index() + 1); - + /*if it is a "spike" leave the x alone */ - + if (after->get_x() - before->get_x() < 2) { x = cp.get_x(); - + } else { x = min (x, after->get_x()-1.0); } @@ -293,7 +297,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi } else { ControlPoint* after; - + /* find the first point that can't move */ for (uint32_t n = cp.view_index() + 1; (after = nth (n)) != 0; ++n) { @@ -303,15 +307,15 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi break; } } - + delta = x - cp.get_x(); } - + } else { /* leave the x-coordinate alone */ - x = trackview.editor().frame_to_unit ((*cp.model())->when); + x = trackview.editor().frame_to_unit (_time_converter.to((*cp.model())->when)); } @@ -323,17 +327,17 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi } else { uint32_t limit = min (control_points.size(), (size_t)last_movable); - + /* move the current point to wherever the user told it to go, subject to x_limit. */ - + cp.move_to (min (x, x_limit), y, ControlPoint::Full); reset_line_coords (cp); - + /* now move all subsequent control points, to reflect the motion. */ - + for (uint32_t i = cp.view_index() + 1; i < limit; ++i) { ControlPoint *p = nth (i); double new_x; @@ -349,7 +353,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi void AutomationLine::reset_line_coords (ControlPoint& cp) -{ +{ if (cp.view_index() < line_points.size()) { line_points[cp.view_index()].set_x (cp.get_x()); line_points[cp.view_index()].set_y (cp.get_y()); @@ -359,7 +363,6 @@ AutomationLine::reset_line_coords (ControlPoint& cp) void AutomationLine::sync_model_with_view_line (uint32_t start, uint32_t end) { - ControlPoint *p; update_pending = true; @@ -377,28 +380,27 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) initial results are in canvas units. ask the line to convert them to something relevant. */ - - mr.xval = (nframes_t) floor (cp.get_x()); + + mr.xval = cp.get_x(); mr.yval = 1.0 - (cp.get_y() / _height); /* if xval has not changed, set it directly from the model to avoid rounding errors */ - if (mr.xval == trackview.editor().frame_to_unit((*cp.model())->when)) { - mr.xval = (nframes_t) (*cp.model())->when; + if (mr.xval == trackview.editor().frame_to_unit(_time_converter.to((*cp.model())->when))) { + mr.xval = (*cp.model())->when; } else { mr.xval = trackview.editor().unit_to_frame (mr.xval); } - /* virtual call: this will do the right thing - for whatever particular type of line we are. + /* convert to model units */ - - view_to_model_y (mr.yval); + + view_to_model_coord (mr.xval, mr.yval); /* part 2: find out where the model point is now */ - mr.xpos = (nframes_t) (*cp.model())->when; + mr.xpos = (*cp.model())->when; mr.ypos = (*cp.model())->value; /* part 3: get the position of the visual control @@ -417,7 +419,7 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) after = nth (cp.view_index() + 1); if (before) { - mr.xmin = (nframes_t) (*before->model())->when; + mr.xmin = (*before->model())->when; mr.ymin = (*before->model())->value; mr.start = before->model(); ++mr.start; @@ -448,7 +450,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) uint32_t this_rx = 0; uint32_t prev_rx = 0; uint32_t this_ry = 0; - uint32_t prev_ry = 0; + uint32_t prev_ry = 0; double* slope; uint32_t box_size; uint32_t cpsize; @@ -456,7 +458,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) /* hide all existing points, and the line */ cpsize = 0; - + for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { (*i)->hide(); ++cpsize; @@ -490,7 +492,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) double tx = points[pi].x; double ty = points[pi].y; - + if (isnan (tx) || isnan (ty)) { warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""), _name) << endmsg; @@ -515,11 +517,11 @@ AutomationLine::determine_visible_control_points (ALPoints& points) if (slope[pi] == slope[pi-1]) { /* no reason to display this point */ - + continue; } } - + /* need to round here. the ultimate coordinates are integer pixels, so tiny deltas in the coords will be eliminated and we end up with "colinear" line segments. since the @@ -529,14 +531,14 @@ AutomationLine::determine_visible_control_points (ALPoints& points) */ this_rx = (uint32_t) rint (tx); - this_ry = (uint32_t) rint (ty); - - if (view_index && pi != npoints && /* not the first, not the last */ + this_ry = (uint32_t) rint (ty); + + if (view_index && pi != npoints && /* not the first, not the last */ (((this_rx == prev_rx) && (this_ry == prev_ry)) || /* same point */ (((this_rx - prev_rx) < (box_size + 2)) && /* not identical, but still too close horizontally */ (abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2))))) { /* too close vertically */ - continue; - } + continue; + } /* ok, we should display this point */ @@ -545,8 +547,8 @@ AutomationLine::determine_visible_control_points (ALPoints& points) /* make sure we have enough control points */ ControlPoint* ncp = new ControlPoint (*this); - - ncp->set_size (box_size); + + ncp->set_size (box_size); control_points.push_back (ncp); ++cpsize; @@ -583,7 +585,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) prev_ry = this_ry; /* finally, control visibility */ - + if (_visible && points_visible) { control_points[view_index]->show (); control_points[view_index]->set_visible (true); @@ -595,7 +597,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) view_index++; } - + /* discard extra CP's to avoid confusing ourselves */ while (control_points.size() > view_index) { @@ -613,7 +615,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) if (view_index > 1) { npoints = view_index; - + /* reset the line coordinates */ while (line_points.size() < npoints) { @@ -628,14 +630,14 @@ AutomationLine::determine_visible_control_points (ALPoints& points) line_points[view_index].set_x (control_points[view_index]->get_x()); line_points[view_index].set_y (control_points[view_index]->get_y()); } - + line->property_points() = line_points; if (_visible && _interpolation != AutomationList::Discrete) { line->show(); } - } + } set_selected_points (trackview.editor().get_selection().points); @@ -656,7 +658,6 @@ AutomationLine::get_verbose_cursor_string (double fraction) const * @param fraction y fraction * @return string representation of this value, using dB if appropriate. */ - string AutomationLine::fraction_to_string (double fraction) const { @@ -666,10 +667,11 @@ AutomationLine::fraction_to_string (double fraction) const if (fraction == 0.0) { snprintf (buf, sizeof (buf), "-inf"); } else { - snprintf (buf, sizeof (buf), "%.1f", coefficient_to_dB (slider_position_to_gain (fraction))); + snprintf (buf, sizeof (buf), "%.1f", accurate_coefficient_to_dB (slider_position_to_gain (fraction))); } } else { - view_to_model_y (fraction); + double dummy = 0.0; + view_to_model_coord (dummy, fraction); if (EventTypeMap::instance().is_integer (alist->parameter())) { snprintf (buf, sizeof (buf), "%d", (int)fraction); } else { @@ -685,7 +687,6 @@ AutomationLine::fraction_to_string (double fraction) const * @param s Value string in the form as returned by fraction_to_string. * @return Corresponding y fraction. */ - double AutomationLine::string_to_fraction (string const & s) const { @@ -695,11 +696,12 @@ AutomationLine::string_to_fraction (string const & s) const double v; sscanf (s.c_str(), "%lf", &v); - + if (_uses_gain_mapping) { v = gain_to_slider_position (dB_to_coefficient (v)); } else { - model_to_view_y (v); + double dummy = 0.0; + model_to_view_coord (dummy, v); } return v; @@ -719,9 +721,9 @@ AutomationLine::invalidate_point (ALPoints& p, uint32_t index) } void -AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) +AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) { - if (trackview.editor().current_session() == 0) { /* how? */ + if (trackview.editor().session() == 0) { /* how? */ return; } @@ -733,9 +735,9 @@ AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) str = _("automation range drag"); } - trackview.editor().current_session()->begin_reversible_command (str); - trackview.editor().current_session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); - + trackview.editor().session()->begin_reversible_command (str); + trackview.editor().session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); + drag_x = x; drag_distance = 0; first_drag_fraction = fraction; @@ -745,7 +747,7 @@ AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) } void -AutomationLine::point_drag (ControlPoint& cp, nframes_t x, float fraction, bool with_push) +AutomationLine::point_drag (ControlPoint& cp, nframes_t x, float fraction, bool with_push) { if (x > drag_x) { drag_distance += (x - drag_x); @@ -766,22 +768,40 @@ AutomationLine::point_drag (ControlPoint& cp, nframes_t x, float fraction, bool } void -AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_push) +AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_push) { double ydelta = fraction - last_drag_fraction; did_push = with_push; - + last_drag_fraction = fraction; line_drag_cp1 = i1; line_drag_cp2 = i2; - + + //check if one of the control points on the line is in a selected range + bool range_found = false; 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); + if (cp->selected()) { + range_found = true; + } + } + + if (range_found) { + for (vector::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); + } + } + } 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); + } } if (line_points.size() > 1) { @@ -792,7 +812,7 @@ AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_p } void -AutomationLine::end_drag (ControlPoint* cp) +AutomationLine::end_drag (ControlPoint* cp) { if (!drags) { return; @@ -805,14 +825,14 @@ AutomationLine::end_drag (ControlPoint* cp) } else { sync_model_with_view_line (line_drag_cp1, line_drag_cp2); } - + alist->thaw (); update_pending = false; - trackview.editor().current_session()->add_command (new MementoCommand(*alist.get(), 0, &alist->get_state())); - trackview.editor().current_session()->commit_reversible_command (); - trackview.editor().current_session()->set_dirty (); + trackview.editor().session()->add_command (new MementoCommand(*alist.get(), 0, &alist->get_state())); + trackview.editor().session()->commit_reversible_command (); + trackview.editor().session()->set_dirty (); } @@ -824,7 +844,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int model_representation (cp, mr); - /* how much are we changing the central point by */ + /* how much are we changing the central point by */ ydelta = mr.yval - mr.ypos; @@ -837,13 +857,13 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int /* change all points before the primary point */ for (AutomationList::iterator i = mr.start; i != cp.model(); ++i) { - + double fract = ((*i)->when - mr.xmin) / (mr.xpos - mr.xmin); double y_delta = ydelta * fract; double x_delta = distance * fract; /* interpolate */ - + if (y_delta || x_delta) { alist->modify (i, (*i)->when + x_delta, mr.ymin + y_delta); } @@ -856,24 +876,24 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int /* change later points */ - + AutomationList::iterator i = cp.model(); - + ++i; - + while (i != mr.end) { - + double delta = ydelta * (mr.xmax - (*i)->when) / (mr.xmax - mr.xpos); /* all later points move by the same distance along the x-axis as the main point */ - + if (delta) { alist->modify (i, (*i)->when + distance, (*i)->value + delta); } - + ++i; } - + if (did_push) { /* move all points after the range represented by the view by the same distance @@ -885,25 +905,23 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int } -bool +bool AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_t& after) { ControlPoint *bcp = 0; ControlPoint *acp = 0; double unit_xval; - /* xval is in frames */ - unit_xval = trackview.editor().frame_to_unit (xval); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - + if ((*i)->get_x() <= unit_xval) { if (!bcp || (*i)->get_x() > bcp->get_x()) { bcp = *i; before = bcp->view_index(); - } + } } else if ((*i)->get_x() > unit_xval) { acp = *i; @@ -927,7 +945,7 @@ AutomationLine::is_last_point (ControlPoint& cp) if (!alist->empty() && mr.end == alist->end()) { return true; } - + return false; } @@ -943,7 +961,7 @@ AutomationLine::is_first_point (ControlPoint& cp) if (!alist->empty() && mr.start == alist->begin()) { return true; } - + return false; } @@ -955,42 +973,41 @@ AutomationLine::remove_point (ControlPoint& cp) model_representation (cp, mr); - trackview.editor().current_session()->begin_reversible_command (_("remove control point")); + trackview.editor().session()->begin_reversible_command (_("remove control point")); XMLNode &before = alist->get_state(); alist->erase (mr.start, mr.end); - trackview.editor().current_session()->add_command(new MementoCommand( + trackview.editor().session()->add_command(new MementoCommand( *alist.get(), &before, &alist->get_state())); - trackview.editor().current_session()->commit_reversible_command (); - trackview.editor().current_session()->set_dirty (); + trackview.editor().session()->commit_reversible_command (); + trackview.editor().session()->set_dirty (); } void AutomationLine::get_selectables (nframes_t& start, nframes_t& end, - double botfrac, double topfrac, list& results) + double botfrac, double topfrac, list& results) { double top; double bot; - nframes_t nstart; - nframes_t nend; + double nstart; + double nend; bool collecting = false; /* Curse X11 and its inverted coordinate system! */ - + bot = (1.0 - topfrac) * _height; top = (1.0 - botfrac) * _height; - + nstart = max_frames; nend = 0; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - - nframes_t when = (nframes_t) (*(*i)->model())->when; + double when = (*(*i)->model())->when; if (when >= start && when <= end) { - + if ((*i)->get_y() >= bot && (*i)->get_y() <= top) { (*i)->show(); @@ -1000,10 +1017,10 @@ AutomationLine::get_selectables (nframes_t& start, nframes_t& end, nend = max (nend, when); } else { - + if (collecting) { - results.push_back (new AutomationSelectable (nstart, nend, botfrac, topfrac, trackview)); + results.push_back (new AutomationSelectable (nstart, nend, botfrac, topfrac, &trackview)); collecting = false; nstart = max_frames; nend = 0; @@ -1013,13 +1030,13 @@ AutomationLine::get_selectables (nframes_t& start, nframes_t& end, } if (collecting) { - results.push_back (new AutomationSelectable (nstart, nend, botfrac, topfrac, trackview)); + results.push_back (new AutomationSelectable (nstart, nend, botfrac, topfrac, &trackview)); } } void -AutomationLine::get_inverted_selectables (Selection&, list& results) +AutomationLine::get_inverted_selectables (Selection&, list& /*results*/) { // hmmm .... } @@ -1036,11 +1053,11 @@ AutomationLine::set_selected_points (PointSelection& points) if (points.empty()) { goto out; - } - + } + for (PointSelection::iterator r = points.begin(); r != points.end(); ++r) { - - if (&(*r).track != &trackview) { + + if ((*r).track != &trackview) { continue; } @@ -1050,16 +1067,16 @@ AutomationLine::set_selected_points (PointSelection& points) top = (1.0 - (*r).low_fract) * _height; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - + double rstart, rend; - + rstart = trackview.editor().frame_to_unit ((*r).start); rend = trackview.editor().frame_to_unit ((*r).end); - + if ((*i)->get_x() >= rstart && (*i)->get_x() <= rend) { - + if ((*i)->get_y() >= bot && (*i)->get_y() <= top) { - + (*i)->set_selected(true); } } @@ -1087,21 +1104,21 @@ AutomationLine::show_selection () TimeSelection& time (trackview.editor().get_selection().time); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - + (*i)->set_selected(false); for (list::iterator r = time.begin(); r != time.end(); ++r) { double rstart, rend; - + rstart = trackview.editor().frame_to_unit ((*r).start); rend = trackview.editor().frame_to_unit ((*r).end); - + if ((*i)->get_x() >= rstart && (*i)->get_x() <= rend) { (*i)->set_selected(true); break; } } - + (*i)->show_color (false, !points_visible); } } @@ -1136,13 +1153,14 @@ AutomationLine::reset_callback (const Evoral::ControlList& events) AutomationList::const_iterator ai; for (ai = events.begin(); ai != events.end(); ++ai) { - + + double translated_x = (*ai)->when; double translated_y = (*ai)->value; - model_to_view_y (translated_y); + model_to_view_coord (translated_x, translated_y); add_model_point (tmp_points, (*ai)->when, translated_y); } - + determine_visible_control_points (tmp_points); } @@ -1150,7 +1168,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events) void AutomationLine::add_model_point (ALPoints& tmp_points, double frame, double yfract) { - tmp_points.push_back (ALPoint (trackview.editor().frame_to_unit (frame), + tmp_points.push_back (ALPoint (trackview.editor().frame_to_unit (_time_converter.to(frame)), _height - (yfract * _height))); } @@ -1172,13 +1190,14 @@ AutomationLine::clear () /* parent must create command */ XMLNode &before = get_state(); alist->clear(); - trackview.editor().current_session()->add_command (new MementoCommand(*this, &before, &get_state())); - trackview.editor().current_session()->commit_reversible_command (); - trackview.editor().current_session()->set_dirty (); + trackview.editor().session()->add_command ( + new MementoCommand(*this, &before, &get_state())); + trackview.editor().session()->commit_reversible_command (); + trackview.editor().session()->set_dirty (); } void -AutomationLine::change_model (AutomationList::iterator i, double x, double y) +AutomationLine::change_model (AutomationList::iterator /*i*/, double /*x*/, double /*y*/) { } @@ -1216,7 +1235,7 @@ AutomationLine::hide_all_but_selected_control_points () } } } - + void AutomationLine::track_entered() { @@ -1240,15 +1259,15 @@ AutomationLine::get_state (void) return alist->get_state(); } -int -AutomationLine::set_state (const XMLNode &node) +int +AutomationLine::set_state (const XMLNode &node, int version) { /* function as a proxy for the model */ - return alist->set_state (node); + return alist->set_state (node, version); } void -AutomationLine::view_to_model_y (double& y) const +AutomationLine::view_to_model_coord (double& x, double& y) const { /* TODO: This should be more generic ... */ if (alist->parameter().type() == GainAutomation || @@ -1264,10 +1283,12 @@ AutomationLine::view_to_model_y (double& y) const } else { y = (int)(y * alist->parameter().max()); } + + x = _time_converter.from(x); } void -AutomationLine::model_to_view_y (double& y) const +AutomationLine::model_to_view_coord (double& x, double& y) const { /* TODO: This should be more generic ... */ if (alist->parameter().type() == GainAutomation || @@ -1281,9 +1302,11 @@ AutomationLine::model_to_view_y (double& y) const } else { y = y / (double)alist->parameter().max(); /* ... like this */ } + + x = _time_converter.to(x); } - + void AutomationLine::set_interpolation(AutomationList::InterpolationStyle style) {