#include <pbd/memento_command.h>
#include <pbd/stacktrace.h>
-#include <ardour/automation_event.h>
-#include <ardour/curve.h>
+#include <ardour/automation_list.h>
#include <ardour/dB.h>
+#include <evoral/Curve.hpp>
#include "simplerect.h"
#include "automation_line.h"
using namespace Editing;
using namespace Gnome; // for Canvas
-AutomationLine::AutomationLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> al)
+AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> al)
: trackview (tv),
_name (name),
alist (al),
no_draw = false;
_visible = true;
terminal_points_can_slide = true;
- _y_position = 0;
_height = 0;
group = new ArdourCanvas::Group (parent);
}
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<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->set_size (bsz);
}
- changed = true;
- }
- if (changed) {
reset ();
}
}
y = max (0.0, y);
y = min (1.0, y);
- y = _y_position + _height - (y * _height);
+ y = _height - (y * _height);
if (cp.can_slide()) {
*/
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;
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
}
} else {
view_to_model_y(fraction);
- if (alist->parameter().type() == MidiCCAutomation)
+ if (EventTypeMap::instance().is_integer(alist->parameter())) {
snprintf (buf, sizeof (buf), "%d", (int)fraction);
- else
+ } else {
snprintf (buf, sizeof (buf), "%.2f", fraction);
+ }
}
return buf;
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;
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) {
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);
/* 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;
/* 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<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
}
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) {
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 ()
{
AutomationLine::clear ()
{
/* parent must create command */
- XMLNode &before = get_state();
+ XMLNode &before = get_state();
alist->clear();
trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, &before, &get_state()));
trackview.editor.current_session()->commit_reversible_command ();
alist->move_range (start, end, xdelta, ydelta);
}
+void
+AutomationLine::set_list(boost::shared_ptr<ARDOUR::AutomationList> list)
+{
+ alist = list;
+ queue_reset();
+}
+
void
AutomationLine::show_all_control_points ()
{
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);
} else if (alist->parameter().type() == PanAutomation) {
// vertical coordinate axis reversal
y = 1.0 - y;
- } else if (alist->parameter().type() == MidiCCAutomation) {
- y = (int)(y * 127.0);
} 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() == MidiCCAutomation) {
- y = y / 127.0;
} 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 */
}
}