X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fautomation_line.cc;h=102a3fd29ca172c472ce28a7a981b07f87f5af2b;hb=f93ca1349ce3d56ecd9b90c1b6e88971d46d9952;hp=8754bbc21ab62a36c18662a7d208e30ee4c53673;hpb=e14187aadd574d46c82d8eb0d151b526b84ddcc7;p=ardour.git diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 8754bbc21a..102a3fd29c 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -64,7 +64,7 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv _interpolation = al->interpolation(); points_visible = false; update_pending = false; - _vc_uses_gain_mapping = false; + _uses_gain_mapping = false; no_draw = false; _visible = true; terminal_points_can_slide = true; @@ -84,8 +84,10 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv trackview.session().register_with_memento_command_factory(alist->id(), this); - if (alist->parameter().type() == GainAutomation) - set_verbose_cursor_uses_gain_mapping (true); + if (alist->parameter().type() == GainAutomation || + alist->parameter().type() == EnvelopeAutomation) { + set_uses_gain_mapping (true); + } set_interpolation(alist->interpolation()); } @@ -114,8 +116,9 @@ AutomationLine::queue_reset () void AutomationLine::show () { - if (_interpolation != AutomationList::Discrete) + if (_interpolation != AutomationList::Discrete) { line->show(); + } if (points_visible) { for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -176,10 +179,10 @@ AutomationLine::set_line_color (uint32_t color) } void -AutomationLine::set_verbose_cursor_uses_gain_mapping (bool yn) +AutomationLine::set_uses_gain_mapping (bool yn) { - if (yn != _vc_uses_gain_mapping) { - _vc_uses_gain_mapping = yn; + if (yn != _uses_gain_mapping) { + _uses_gain_mapping = yn; reset (); } } @@ -194,6 +197,41 @@ AutomationLine::nth (uint32_t n) } } +void +AutomationLine::modify_point_y (ControlPoint& cp, double y) +{ + /* clamp y-coord appropriately. y is supposed to be a normalized fraction (0.0-1.0), + and needs to be converted to a canvas unit distance. + */ + + y = max (0.0, y); + y = min (1.0, y); + y = _height - (y * _height); + + double const x = trackview.editor().frame_to_unit ((*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)); + + cp.move_to (x, y, ControlPoint::Full); + reset_line_coords (cp); + + if (line_points.size() > 1) { + line->property_points() = line_points; + } + + alist->freeze (); + sync_model_with_view_point (cp, false, 0); + 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 (); +} + + void AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool with_push) { @@ -219,7 +257,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi already in frames. it needs to be converted to canvas units. */ - x = trackview.editor.frame_to_unit (x); + x = trackview.editor().frame_to_unit (x); /* clamp x position using view coordinates */ @@ -272,7 +310,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); } @@ -344,10 +382,10 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) /* 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)) { + 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); + mr.xval = trackview.editor().unit_to_frame (mr.xval); } /* virtual call: this will do the right thing @@ -592,37 +630,80 @@ AutomationLine::determine_visible_control_points (ALPoints& points) line->property_points() = line_points; - if (_visible && _interpolation != AutomationList::Discrete) + if (_visible && _interpolation != AutomationList::Discrete) { line->show(); + } } - set_selected_points (trackview.editor.get_selection().points); + set_selected_points (trackview.editor().get_selection().points); } string -AutomationLine::get_verbose_cursor_string (double fraction) +AutomationLine::get_verbose_cursor_string (double fraction) const +{ + std::string s = fraction_to_string (fraction); + if (_uses_gain_mapping) { + s += " dB"; + } + + return s; +} + +/** + * @param fraction y fraction + * @return string representation of this value, using dB if appropriate. + */ + +string +AutomationLine::fraction_to_string (double fraction) const { char buf[32]; - if (_vc_uses_gain_mapping) { + if (_uses_gain_mapping) { if (fraction == 0.0) { - snprintf (buf, sizeof (buf), "-inf dB"); + snprintf (buf, sizeof (buf), "-inf"); } else { - snprintf (buf, sizeof (buf), "%.1fdB", coefficient_to_dB (slider_position_to_gain (fraction))); + snprintf (buf, sizeof (buf), "%.1f", coefficient_to_dB (slider_position_to_gain (fraction))); } } else { - view_to_model_y(fraction); - if (((ARDOUR::Parameter)alist->parameter()).is_integer()) + view_to_model_y (fraction); + if (EventTypeMap::instance().is_integer (alist->parameter())) { snprintf (buf, sizeof (buf), "%d", (int)fraction); - else + } else { snprintf (buf, sizeof (buf), "%.2f", fraction); + } } return buf; } + +/** + * @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 +{ + if (s == "-inf") { + return 0; + } + + 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); + } + + return v; +} + bool AutomationLine::invalid_point (ALPoints& p, uint32_t index) { @@ -639,7 +720,7 @@ AutomationLine::invalidate_point (ALPoints& p, uint32_t index) void AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) { - if (trackview.editor.current_session() == 0) { /* how? */ + if (trackview.editor().current_session() == 0) { /* how? */ return; } @@ -651,8 +732,8 @@ 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().current_session()->begin_reversible_command (str); + trackview.editor().current_session()->add_command (new MementoCommand(*alist.get(), &get_state(), 0)); drag_x = x; drag_distance = 0; @@ -699,7 +780,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()) /_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) { @@ -728,9 +809,9 @@ AutomationLine::end_drag (ControlPoint* cp) 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().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 (); } @@ -812,7 +893,7 @@ AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_ /* xval is in frames */ - unit_xval = trackview.editor.frame_to_unit (xval); + unit_xval = trackview.editor().frame_to_unit (xval); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -873,15 +954,15 @@ AutomationLine::remove_point (ControlPoint& cp) model_representation (cp, mr); - trackview.editor.current_session()->begin_reversible_command (_("remove control point")); + trackview.editor().current_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().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 (); + trackview.editor().current_session()->commit_reversible_command (); + trackview.editor().current_session()->set_dirty (); } void @@ -971,8 +1052,8 @@ AutomationLine::set_selected_points (PointSelection& points) double rstart, rend; - rstart = trackview.editor.frame_to_unit ((*r).start); - rend = trackview.editor.frame_to_unit ((*r).end); + 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) { @@ -1002,7 +1083,7 @@ void AutomationLine::set_colors() { void AutomationLine::show_selection () { - TimeSelection& time (trackview.editor.get_selection().time); + TimeSelection& time (trackview.editor().get_selection().time); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { @@ -1011,8 +1092,8 @@ AutomationLine::show_selection () 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); + 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); @@ -1068,7 +1149,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 (frame), _height - (yfract * _height))); } @@ -1090,9 +1171,9 @@ 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().current_session()->add_command (new MementoCommand(*this, &before, &get_state())); + trackview.editor().current_session()->commit_reversible_command (); + trackview.editor().current_session()->set_dirty (); } void @@ -1100,12 +1181,6 @@ 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); -} - void AutomationLine::set_list(boost::shared_ptr list) { @@ -1128,8 +1203,9 @@ AutomationLine::show_all_control_points () void AutomationLine::hide_all_but_selected_control_points () { - if (alist->interpolation() == AutomationList::Discrete) + if (alist->interpolation() == AutomationList::Discrete) { return; + } points_visible = false; @@ -1143,8 +1219,9 @@ AutomationLine::hide_all_but_selected_control_points () void AutomationLine::track_entered() { - if (alist->interpolation() != AutomationList::Discrete) + if (alist->interpolation() != AutomationList::Discrete) { show_all_control_points(); + } } void @@ -1170,10 +1247,11 @@ AutomationLine::set_state (const XMLNode &node) } void -AutomationLine::view_to_model_y (double& y) +AutomationLine::view_to_model_y (double& y) const { /* TODO: This should be more generic ... */ - if (alist->parameter().type() == GainAutomation) { + if (alist->parameter().type() == GainAutomation || + alist->parameter().type() == EnvelopeAutomation) { y = slider_position_to_gain (y); y = max (0.0, y); y = min (2.0, y); @@ -1188,10 +1266,11 @@ AutomationLine::view_to_model_y (double& y) } void -AutomationLine::model_to_view_y (double& y) +AutomationLine::model_to_view_y (double& y) const { /* TODO: This should be more generic ... */ - if (alist->parameter().type() == GainAutomation) { + if (alist->parameter().type() == GainAutomation || + alist->parameter().type() == EnvelopeAutomation) { y = gain_to_slider_position (y); } else if (alist->parameter().type() == PanAutomation) { // vertical coordinate axis reversal