X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fautomation_line.cc;h=854eb57a9283e8208eeeea8e104ea7a560106d36;hb=41c892802f75e62e452399f0b1c7319fee61e677;hp=683a76793547f84fd62f3873071453a87d71fc89;hpb=789cbb21810802adc478de3134fa42950c5e8569;p=ardour.git diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 683a767935..854eb57a92 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -26,12 +26,13 @@ #include #include -#include -#include +#include #include +#include #include "simplerect.h" #include "automation_line.h" +#include "control_point.h" #include "rgb_macros.h" #include "ardour_ui.h" #include "public_editor.h" @@ -54,185 +55,19 @@ using namespace PBD; using namespace Editing; using namespace Gnome; // for Canvas -ControlPoint::ControlPoint (AutomationLine& al) - : line (al) -{ - model = al.the_list().end(); - view_index = 0; - can_slide = true; - _x = 0; - _y = 0; - _shape = Full; - _size = 4.0; - selected = false; - - item = new Canvas::SimpleRect (line.canvas_group()); - item->property_draw() = true; - item->property_fill() = false; - item->property_fill_color_rgba() = Config->canvasvar_ControlPointFill.get(); - item->property_outline_color_rgba() = Config->canvasvar_ControlPointOutline.get(); - item->property_outline_pixels() = 1; - item->set_data ("control_point", this); - item->signal_event().connect (mem_fun (this, &ControlPoint::event_handler)); - - hide (); - set_visible (false); -} - -ControlPoint::ControlPoint (const ControlPoint& other, bool dummy_arg_to_force_special_copy_constructor) - : line (other.line) -{ - if (&other == this) { - return; - } - - model = other.model; - view_index = other.view_index; - can_slide = other.can_slide; - _x = other._x; - _y = other._y; - _shape = other._shape; - _size = other._size; - selected = false; - - item = new Canvas::SimpleRect (line.canvas_group()); - item->property_fill() = false; - item->property_outline_color_rgba() = Config->canvasvar_EnteredControlPointOutline.get(); - item->property_outline_pixels() = 1; - - /* NOTE: no event handling in copied ControlPoints */ - - hide (); - set_visible (false); -} - -ControlPoint::~ControlPoint () -{ - delete item; -} - -bool -ControlPoint::event_handler (GdkEvent* event) -{ - return PublicEditor::instance().canvas_control_point_event (event, item, this); -} - -void -ControlPoint::hide () -{ - item->hide(); -} - -void -ControlPoint::show() -{ - item->show(); -} - -void -ControlPoint::set_visible (bool yn) -{ - item->property_draw() = (gboolean) yn; -} - -void -ControlPoint::reset (double x, double y, AutomationList::iterator mi, uint32_t vi, ShapeType shape) -{ - model = mi; - view_index = vi; - move_to (x, y, shape); -} - -void -ControlPoint::show_color (bool entered, bool hide_too) -{ - if (entered) { - if (selected) { - item->property_outline_color_rgba() = Config->canvasvar_EnteredControlPointSelected.get(); - set_visible(true); - } else { - item->property_outline_color_rgba() = Config->canvasvar_EnteredControlPoint.get(); - if (hide_too) { - set_visible(false); - } - } - - } else { - if (selected) { - item->property_outline_color_rgba() = Config->canvasvar_ControlPointSelected.get(); - set_visible(true); - } else { - item->property_outline_color_rgba() = Config->canvasvar_ControlPoint.get(); - if (hide_too) { - set_visible(false); - } - } - } -} - -void -ControlPoint::set_size (double sz) -{ - _size = sz; - -#if 0 - if (_size > 6.0) { - item->property_fill() = (gboolean) TRUE; - } else { - item->property_fill() = (gboolean) FALSE; - } -#endif - - move_to (_x, _y, _shape); -} - -void -ControlPoint::move_to (double x, double y, ShapeType shape) -{ - double x1 = 0; - double x2 = 0; - double half_size = rint(_size/2.0); - - switch (shape) { - case Full: - x1 = x - half_size; - x2 = x + half_size; - break; - case Start: - x1 = x; - x2 = x + half_size; - break; - case End: - x1 = x - half_size; - x2 = x; - break; - } - - item->property_x1() = x1; - item->property_x2() = x2; - item->property_y1() = y - half_size; - item->property_y2() = y + half_size; - - _x = x; - _y = y; - _shape = shape; -} - -/*****/ - -AutomationLine::AutomationLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, AutomationList& al) +AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr al) : trackview (tv), _name (name), alist (al), _parent_group (parent) { + _interpolation = al->interpolation(); points_visible = false; update_pending = false; _vc_uses_gain_mapping = false; no_draw = false; _visible = true; terminal_points_can_slide = true; - _y_position = 0; _height = 0; group = new ArdourCanvas::Group (parent); @@ -245,10 +80,14 @@ AutomationLine::AutomationLine (const string & name, TimeAxisView& tv, ArdourCan line->signal_event().connect (mem_fun (*this, &AutomationLine::event_handler)); - alist.StateChanged.connect (mem_fun(*this, &AutomationLine::list_changed)); + alist->StateChanged.connect (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) + set_verbose_cursor_uses_gain_mapping (true); + set_interpolation(alist->interpolation()); } AutomationLine::~AutomationLine () @@ -275,7 +114,8 @@ AutomationLine::queue_reset () void AutomationLine::show () { - line->show(); + if (_interpolation != AutomationList::Discrete) + line->show(); if (points_visible) { for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -299,6 +139,11 @@ AutomationLine::hide () double AutomationLine::control_point_box_size () { + if (_interpolation == AutomationList::Discrete) { + return max((_height*4.0) / (double)(alist->parameter().max() - alist->parameter().min()), + 4.0); + } + if (_height > TimeAxisView::hLarger) { return 8.0; } else if (_height > (guint32) TimeAxisView::hNormal) { @@ -308,27 +153,17 @@ AutomationLine::control_point_box_size () } void -AutomationLine::set_y_position_and_height (guint32 y, guint32 h) +AutomationLine::set_height (guint32 h) { - bool changed = false; - - if (y != _y_position) { - _y_position = y; - changed = true; - } - if (h != _height) { _height = h; - double const bsz = control_point_box_size(); + double bsz = control_point_box_size(); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { (*i)->set_size (bsz); } - changed = true; - } - if (changed) { reset (); } } @@ -376,9 +211,9 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi y = max (0.0, y); y = min (1.0, y); - y = _y_position + _height - (y * _height); + y = _height - (y * _height); - if (cp.can_slide) { + if (cp.can_slide()) { /* x-coord cannot move beyond adjacent points or the start/end, and is already in frames. it needs to be converted to canvas units. @@ -391,8 +226,8 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi ControlPoint *before; ControlPoint *after; - if (cp.view_index) { - before = nth (cp.view_index - 1); + if (cp.view_index()) { + before = nth (cp.view_index() - 1); x = max (x, before->get_x()+1.0); } else { before = &cp; @@ -400,9 +235,9 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi if (!with_push) { - if (cp.view_index < control_points.size() - 1) { + if (cp.view_index() < control_points.size() - 1) { - after = nth (cp.view_index + 1); + after = nth (cp.view_index() + 1); /*if it is a "spike" leave the x alone */ @@ -422,10 +257,10 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi /* find the first point that can't move */ - for (uint32_t n = cp.view_index + 1; (after = nth (n)) != 0; ++n) { - if (!after->can_slide) { + for (uint32_t n = cp.view_index() + 1; (after = nth (n)) != 0; ++n) { + if (!after->can_slide()) { x_limit = after->get_x() - 1.0; - last_movable = after->view_index; + last_movable = after->view_index(); break; } } @@ -437,7 +272,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi /* leave the x-coordinate alone */ - x = trackview.editor.frame_to_unit ((*cp.model)->when); + x = trackview.editor.frame_to_unit ((*cp.model())->when); } @@ -460,11 +295,11 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi /* now move all subsequent control points, to reflect the motion. */ - for (uint32_t i = cp.view_index + 1; i < limit; ++i) { + for (uint32_t i = cp.view_index() + 1; i < limit; ++i) { ControlPoint *p = nth (i); double new_x; - if (p->can_slide) { + if (p->can_slide()) { new_x = min (p->get_x() + delta, x_limit); p->move_to (new_x, p->get_y(), ControlPoint::Full); reset_line_coords (*p); @@ -476,9 +311,9 @@ 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()); + 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()); } } @@ -505,12 +340,12 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) */ mr.xval = (nframes_t) floor (cp.get_x()); - mr.yval = 1.0 - ( (cp.get_y() - _y_position) / _height); + mr.yval = 1.0 - (cp.get_y() / _height); - /* if xval has not changed, set it directly from the model to avoid rounding errors */ + /* 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((*cp.model())->when)) { + mr.xval = (nframes_t) (*cp.model())->when; } else { mr.xval = trackview.editor.unit_to_frame (mr.xval); } @@ -524,8 +359,8 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) /* part 2: find out where the model point is now */ - mr.xpos = (nframes_t) (*cp.model)->when; - mr.ypos = (*cp.model)->value; + mr.xpos = (nframes_t) (*cp.model())->when; + mr.ypos = (*cp.model())->value; /* part 3: get the position of the visual control points before and after us. @@ -534,31 +369,31 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) ControlPoint* before; ControlPoint* after; - if (cp.view_index) { - before = nth (cp.view_index - 1); + if (cp.view_index()) { + before = nth (cp.view_index() - 1); } else { before = 0; } - after = nth (cp.view_index + 1); + after = nth (cp.view_index() + 1); if (before) { - mr.xmin = (nframes_t) (*before->model)->when; - mr.ymin = (*before->model)->value; - mr.start = before->model; + mr.xmin = (nframes_t) (*before->model())->when; + mr.ymin = (*before->model())->value; + mr.start = before->model(); ++mr.start; } else { mr.xmin = mr.xpos; mr.ymin = mr.ypos; - mr.start = cp.model; + mr.start = cp.model(); } if (after) { - mr.end = after->model; + mr.end = after->model(); } else { mr.xmax = mr.xpos; mr.ymax = mr.ypos; - mr.end = cp.model; + mr.end = cp.model(); ++mr.end; } } @@ -612,10 +447,16 @@ AutomationLine::determine_visible_control_points (ALPoints& points) view_index = 0; - for (model = alist.begin(), pi = 0; pi < npoints; ++model, ++pi) { + for (model = alist->begin(), pi = 0; pi < npoints; ++model, ++pi) { 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; + continue; + } /* now ensure that the control_points vector reflects the current curve state, but don't plot control points too close together. also, don't @@ -676,21 +517,21 @@ AutomationLine::determine_visible_control_points (ALPoints& points) if (!terminal_points_can_slide) { if (pi == 0) { - control_points[view_index]->can_slide = false; + control_points[view_index]->set_can_slide(false); if (tx == 0) { shape = ControlPoint::Start; } else { shape = ControlPoint::Full; } } else if (pi == npoints - 1) { - control_points[view_index]->can_slide = false; + control_points[view_index]->set_can_slide(false); shape = ControlPoint::End; } else { - control_points[view_index]->can_slide = true; + control_points[view_index]->set_can_slide(true); shape = ControlPoint::Full; } } else { - control_points[view_index]->can_slide = true; + control_points[view_index]->set_can_slide(true); shape = ControlPoint::Full; } @@ -725,7 +566,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) } if (!terminal_points_can_slide) { - control_points.back()->can_slide = false; + control_points.back()->set_can_slide(false); } delete [] slope; @@ -751,9 +592,8 @@ AutomationLine::determine_visible_control_points (ALPoints& points) line->property_points() = line_points; - if (_visible) { - line->show (); - } + if (_visible && _interpolation != AutomationList::Discrete) + line->show(); } @@ -762,7 +602,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) } string -AutomationLine::get_verbose_cursor_string (float fraction) +AutomationLine::get_verbose_cursor_string (double fraction) { char buf[32]; @@ -773,7 +613,12 @@ AutomationLine::get_verbose_cursor_string (float fraction) snprintf (buf, sizeof (buf), "%.1fdB", coefficient_to_dB (slider_position_to_gain (fraction))); } } else { - snprintf (buf, sizeof (buf), "%.2f", fraction); + view_to_model_y(fraction); + if (EventTypeMap::instance().is_integer(alist->parameter())) { + snprintf (buf, sizeof (buf), "%d", (int)fraction); + } else { + snprintf (buf, sizeof (buf), "%.2f", fraction); + } } return buf; @@ -808,7 +653,7 @@ AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) } trackview.editor.current_session()->begin_reversible_command (str); - trackview.editor.current_session()->add_command (new MementoCommand(alist, &get_state(), 0)); + trackview.editor.current_session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); drag_x = x; drag_distance = 0; @@ -842,7 +687,7 @@ 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) { - double const ydelta = fraction - last_drag_fraction; + double ydelta = fraction - last_drag_fraction; did_push = with_push; @@ -855,7 +700,7 @@ AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_p 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() + _y_position) /_height) + ydelta, with_push); + 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) { @@ -872,7 +717,7 @@ AutomationLine::end_drag (ControlPoint* cp) return; } - alist.freeze (); + alist->freeze (); if (cp) { sync_model_with_view_point (*cp, did_push, drag_distance); @@ -880,11 +725,11 @@ AutomationLine::end_drag (ControlPoint* cp) sync_model_with_view_line (line_drag_cp1, line_drag_cp2); } - alist.thaw (); + alist->thaw (); update_pending = false; - trackview.editor.current_session()->add_command (new MementoCommand(alist, 0, &alist.get_state())); + 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 (); } @@ -910,7 +755,7 @@ 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) { + 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; @@ -919,19 +764,19 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int /* interpolate */ if (y_delta || x_delta) { - alist.modify (i, (*i)->when + x_delta, mr.ymin + y_delta); + alist->modify (i, (*i)->when + x_delta, mr.ymin + y_delta); } } /* change the primary point */ update_pending = true; - alist.modify (cp.model, mr.xval, mr.yval); + alist->modify (cp.model(), mr.xval, mr.yval); /* change later points */ - AutomationList::iterator i = cp.model; + AutomationList::iterator i = cp.model(); ++i; @@ -942,7 +787,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int /* 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); + alist->modify (i, (*i)->when + distance, (*i)->value + delta); } ++i; @@ -954,7 +799,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int as the main point moved. */ - alist.slide (mr.end, drag_distance); + alist->slide (mr.end, drag_distance); } } @@ -976,12 +821,12 @@ AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_ if (!bcp || (*i)->get_x() > bcp->get_x()) { bcp = *i; - before = bcp->view_index; + before = bcp->view_index(); } } else if ((*i)->get_x() > unit_xval) { acp = *i; - after = acp->view_index; + after = acp->view_index(); break; } } @@ -998,7 +843,7 @@ AutomationLine::is_last_point (ControlPoint& cp) // If the list is not empty, and the point is the last point in the list - if (!alist.empty() && mr.end == alist.end()) { + if (!alist->empty() && mr.end == alist->end()) { return true; } @@ -1014,7 +859,7 @@ AutomationLine::is_first_point (ControlPoint& cp) // If the list is not empty, and the point is the first point in the list - if (!alist.empty() && mr.start == alist.begin()) { + if (!alist->empty() && mr.start == alist->begin()) { return true; } @@ -1030,11 +875,12 @@ AutomationLine::remove_point (ControlPoint& cp) model_representation (cp, mr); trackview.editor.current_session()->begin_reversible_command (_("remove control point")); - XMLNode &before = alist.get_state(); + XMLNode &before = alist->get_state(); - alist.erase (mr.start, mr.end); + alist->erase (mr.start, mr.end); - trackview.editor.current_session()->add_command(new MementoCommand(alist, &before, &alist.get_state())); + trackview.editor.current_session()->add_command(new MementoCommand( + *alist.get(), &before, &alist->get_state())); trackview.editor.current_session()->commit_reversible_command (); trackview.editor.current_session()->set_dirty (); } @@ -1052,15 +898,15 @@ AutomationLine::get_selectables (nframes_t& start, nframes_t& end, /* Curse X11 and its inverted coordinate system! */ - bot = _y_position + (1.0 - topfrac) * _height; - top = _y_position + (1.0 - botfrac) * _height; + 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; + nframes_t when = (nframes_t) (*(*i)->model())->when; if (when >= start && when <= end) { @@ -1104,7 +950,7 @@ AutomationLine::set_selected_points (PointSelection& points) double bot; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - (*i)->selected = false; + (*i)->set_selected(false); } if (points.empty()) { @@ -1119,8 +965,8 @@ AutomationLine::set_selected_points (PointSelection& points) /* Curse X11 and its inverted coordinate system! */ - bot = _y_position + (1.0 - (*r).high_fract) * _height; - top = _y_position + (1.0 - (*r).low_fract) * _height; + bot = (1.0 - (*r).high_fract) * _height; + top = (1.0 - (*r).low_fract) * _height; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -1133,7 +979,7 @@ AutomationLine::set_selected_points (PointSelection& points) if ((*i)->get_y() >= bot && (*i)->get_y() <= top) { - (*i)->selected = true; + (*i)->set_selected(true); } } @@ -1148,7 +994,7 @@ AutomationLine::set_selected_points (PointSelection& points) } void AutomationLine::set_colors() { - set_line_color( Config->canvasvar_AutomationLine.get() ); + set_line_color( ARDOUR_UI::config()->canvasvar_AutomationLine.get() ); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { (*i)->show_color (false, !points_visible); } @@ -1161,7 +1007,7 @@ AutomationLine::show_selection () for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - (*i)->selected = false; + (*i)->set_selected(false); for (list::iterator r = time.begin(); r != time.end(); ++r) { double rstart, rend; @@ -1170,7 +1016,7 @@ AutomationLine::show_selection () rend = trackview.editor.frame_to_unit ((*r).end); if ((*i)->get_x() >= rstart && (*i)->get_x() <= rend) { - (*i)->selected = true; + (*i)->set_selected(true); break; } } @@ -1192,9 +1038,9 @@ AutomationLine::list_changed () } void -AutomationLine::reset_callback (const AutomationList& events) +AutomationLine::reset_callback (const Evoral::ControlList& events) { - ALPoints tmp_points; + ALPoints tmp_points; uint32_t npoints = events.size(); if (npoints == 0) { @@ -1208,18 +1054,25 @@ AutomationLine::reset_callback (const AutomationList& events) AutomationList::const_iterator ai; - for (ai = events.const_begin(); ai != events.const_end(); ++ai) { - + for (ai = events.begin(); ai != events.end(); ++ai) { + double translated_y = (*ai)->value; model_to_view_y (translated_y); - tmp_points.push_back (ALPoint (trackview.editor.frame_to_unit ((*ai)->when), - _y_position + _height - (translated_y * _height))); + add_model_point (tmp_points, (*ai)->when, translated_y); } determine_visible_control_points (tmp_points); } + +void +AutomationLine::add_model_point (ALPoints& tmp_points, double frame, double yfract) +{ + tmp_points.push_back (ALPoint (trackview.editor.frame_to_unit (frame), + _height - (yfract * _height))); +} + void AutomationLine::reset () { @@ -1229,15 +1082,15 @@ AutomationLine::reset () return; } - alist.apply_to_points (*this, &AutomationLine::reset_callback); + alist->apply_to_points (*this, &AutomationLine::reset_callback); } void AutomationLine::clear () { /* parent must create command */ - XMLNode &before = get_state(); - alist.clear(); + 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 (); @@ -1251,7 +1104,14 @@ AutomationLine::change_model (AutomationList::iterator i, double x, double y) void AutomationLine::change_model_range (AutomationList::iterator start, AutomationList::iterator end, double xdelta, float ydelta) { - alist.move_range (start, end, xdelta, ydelta); + alist->move_range (start, end, xdelta, ydelta); +} + +void +AutomationLine::set_list(boost::shared_ptr list) +{ + alist = list; + queue_reset(); } void @@ -1260,6 +1120,7 @@ AutomationLine::show_all_control_points () points_visible = true; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { + (*i)->show_color((_interpolation != AutomationList::Discrete), false); (*i)->show (); (*i)->set_visible (true); } @@ -1268,25 +1129,93 @@ AutomationLine::show_all_control_points () void AutomationLine::hide_all_but_selected_control_points () { + if (alist->interpolation() == AutomationList::Discrete) + return; + points_visible = false; for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { - if (!(*i)->selected) { + if (!(*i)->selected()) { (*i)->set_visible (false); } } } + +void +AutomationLine::track_entered() +{ + if (alist->interpolation() != AutomationList::Discrete) + show_all_control_points(); +} + +void +AutomationLine::track_exited() +{ + if (alist->interpolation() != AutomationList::Discrete) { + hide_all_but_selected_control_points(); + } +} XMLNode & AutomationLine::get_state (void) { /* function as a proxy for the model */ - return alist.get_state(); + return alist->get_state(); } int AutomationLine::set_state (const XMLNode &node) { /* function as a proxy for the model */ - return alist.set_state (node); + return alist->set_state (node); +} + +void +AutomationLine::view_to_model_y (double& y) +{ + /* TODO: This should be more generic ... */ + if (alist->parameter().type() == GainAutomation) { + y = slider_position_to_gain (y); + y = max (0.0, y); + y = min (2.0, y); + } else if (alist->parameter().type() == PanAutomation) { + // vertical coordinate axis reversal + y = 1.0 - y; + } else if (alist->parameter().type() == PluginAutomation) { + y = y * (double)(alist->get_max_y()- alist->get_min_y()) + alist->get_min_y(); + } else { + y = (int)(y * alist->parameter().max()); + } +} + +void +AutomationLine::model_to_view_y (double& y) +{ + /* TODO: This should be more generic ... */ + if (alist->parameter().type() == GainAutomation) { + y = gain_to_slider_position (y); + } else if (alist->parameter().type() == PanAutomation) { + // vertical coordinate axis reversal + y = 1.0 - y; + } else if (alist->parameter().type() == PluginAutomation) { + y = (y - alist->get_min_y()) / (double)(alist->get_max_y()- alist->get_min_y()); + } else { + y = y / (double)alist->parameter().max(); /* ... like this */ + } } + + +void +AutomationLine::set_interpolation(AutomationList::InterpolationStyle style) +{ + _interpolation = style; + + if (style == AutomationList::Discrete) { + show_all_control_points(); + line->hide(); + } else { + hide_all_but_selected_control_points(); + line->show(); + } +} +