#include <climits>
#include <vector>
-#include <fstream>
#include "boost/shared_ptr.hpp"
#include "control_point.h"
#include "gui_thread.h"
#include "rgb_macros.h"
-#include "ardour_ui.h"
#include "public_editor.h"
#include "selection.h"
#include "time_axis_view.h"
#include "point_selection.h"
#include "automation_time_axis.h"
+#include "ui_config.h"
#include "ardour/event_type_map.h"
#include "ardour/session.h"
#include "ardour/value_as_string.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
, _parent_group (parent)
, _offset (0)
, _maximum_time (max_framepos)
+ , _fill (false)
, _desc (desc)
{
if (converter) {
} else {
_our_time_converter = true;
}
-
+
_visible = Line;
update_pending = false;
}
} else if (_visible & SelectedControlPoints) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
- if ((*i)->get_selected()) {
+ if ((*i)->selected()) {
(*i)->show ();
} else {
(*i)->hide ();
AutomationLine::hide ()
{
/* leave control points setting unchanged, we are just hiding the
- overall line
+ overall line
*/
-
+
set_visibility (AutomationLine::VisibleAspects (_visible & ~Line));
}
(*i)->set_size (bsz);
}
+ if (_fill) {
+ line->set_fill_y1 (_height);
+ } else {
+ line->set_fill_y1 (0);
+ }
reset ();
}
}
{
_line_color = color;
line->set_outline_color (color);
+
+ ArdourCanvas::SVAModifier mod = UIConfiguration::instance().modifier ("automation line fill");
+
+ line->set_fill_color ((color & 0xffffff00) + mod.a()*255);
}
void
_drag_points.clear ();
_drag_points.push_back (cp);
- if (cp->get_selected ()) {
+ if (cp->selected ()) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
- if (*i != cp && (*i)->get_selected()) {
+ if (*i != cp && (*i)->selected()) {
_drag_points.push_back (*i);
}
}
bool operator() (ControlPoint const * a, ControlPoint const * b) const {
if (floateq (a->get_x(), b->get_x(), 1)) {
return a->view_index() < b->view_index();
- }
+ }
return a->get_x() < b->get_x();
}
};
AutomationLine::ContiguousControlPoints::ContiguousControlPoints (AutomationLine& al)
- : line (al), before_x (0), after_x (DBL_MAX)
+ : line (al), before_x (0), after_x (DBL_MAX)
{
}
if (sz > 0 && sz < line.npoints()) {
const TempoMap& map (e.session()->tempo_map());
- /* determine the limits on x-axis motion for this
+ /* determine the limits on x-axis motion for this
contiguous range of control points
*/
before_x = line.nth (front()->view_index() - 1)->get_x();
const framepos_t pos = e.pixel_to_sample(before_x);
- const Meter& meter = map.meter_at (pos);
- const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate())
+ const Meter& meter = map.meter_at_frame (pos);
+ const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at_frame (pos), e.session()->frame_rate())
/ (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar()) );
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
after_x = line.nth (back()->view_index() + 1)->get_x();
const framepos_t pos = e.pixel_to_sample(after_x);
- const Meter& meter = map.meter_at (pos);
- const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate())
+ const Meter& meter = map.meter_at_frame (pos);
+ const framecnt_t len = ceil (meter.frames_per_bar (map.tempo_at_frame (pos), e.session()->frame_rate())
/ (Timecode::BBT_Time::ticks_per_beat * meter.divisions_per_bar()));
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
}
}
-double
-AutomationLine::ContiguousControlPoints::clamp_dx (double dx)
+double
+AutomationLine::ContiguousControlPoints::clamp_dx (double dx)
{
if (empty()) {
return dx;
/* get the maximum distance we can move any of these points along the x-axis
*/
-
+
double tx; /* possible position a point would move to, given dx */
ControlPoint* cp;
-
+
if (dx > 0) {
/* check the last point, since we're moving later in time */
cp = back();
cp = front();
}
- tx = cp->get_x() + dx; // new possible position if we just add the motion
+ tx = cp->get_x() + dx; // new possible position if we just add the motion
tx = max (tx, before_x); // can't move later than following point
tx = min (tx, after_x); // can't move earlier than preceeding point
- return tx - cp->get_x ();
+ return tx - cp->get_x ();
}
-void
-AutomationLine::ContiguousControlPoints::move (double dx, double dy)
+void
+AutomationLine::ContiguousControlPoints::move (double dx, double dy)
{
for (std::list<ControlPoint*>::iterator i = begin(); i != end(); ++i) {
(*i)->move_to ((*i)->get_x() + dx, (*i)->get_y() - line.height() * dy, ControlPoint::Full);
if (!_drag_had_movement) {
- /* "first move" ... do some stuff that we don't want to do if
+ /* "first move" ... do some stuff that we don't want to do if
no motion ever took place, but need to do before we handle
motion.
*/
-
+
/* partition the points we are dragging into (potentially several)
* set(s) of contiguous points. this will not happen with a normal
* drag, but if the user does a discontiguous selection, it can.
*/
-
+
uint32_t expected_view_index = 0;
CCP contig;
-
+
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
if (i == _drag_points.begin() || (*i)->view_index() != expected_view_index) {
contig.reset (new ContiguousControlPoints (*this));
(*ccp)->compute_x_bounds (trackview.editor());
}
_drag_had_movement = true;
- }
+ }
/* OK, now on to the stuff related to *this* motion event. First, for
* each contiguous range, figure out the maximum x-axis motion we are
* allowed (because of neighbouring points that are not moving.
- *
- * if we are moving forwards with push, we don't need to do this,
+ *
+ * if we are moving forwards with push, we don't need to do this,
* since all later points will move too.
*/
}
/* clamp y */
-
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
double const y = ((_height - (*i)->get_y()) / _height) + dy;
if (y < 0) {
if (dx || dy) {
/* and now move each section */
-
+
for (vector<CCP>::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) {
(*ccp)->move (dx, dy);
}
line->set_steps (line_points, is_stepped());
}
}
-
+ double const result_frac = _last_drag_fraction + dy;
_drag_distance += dx;
_drag_x += dx;
- _last_drag_fraction = fraction;
+ _last_drag_fraction = result_frac;
did_push = with_push;
- return pair<double, float> (_drag_x + dx, _last_drag_fraction + dy);
+ return pair<double, float> (_drag_x + dx, result_frac);
}
/** Should be called to indicate the end of a drag */
trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
+ trackview.editor ().get_selection ().clear_points ();
alist->erase (cp.model());
-
+
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
/* model_when is relative to the start of the source, so we just need to add on the origin_b here
(as it is the session frame position of the start of the source)
*/
-
+
framepos_t const session_frames_when = _time_converter->to (model_when) + _time_converter->origin_b ();
if (session_frames_when >= start && session_frames_when <= end && (*i)->get_y() >= bot_track && (*i)->get_y() <= top_track) {
void
AutomationLine::set_colors ()
{
- set_line_color (ARDOUR_UI::config()->color ("automation line"));
+ set_line_color (UIConfiguration::instance().color ("automation line"));
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->set_color ();
}
np = events.size();
Evoral::ControlList& e = const_cast<Evoral::ControlList&> (events);
-
+
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
double tx = (*ai)->when;
_name) << endmsg;
continue;
}
-
+
if (tx >= max_framepos || tx < 0 || tx >= _maximum_time) {
continue;
}
-
+
/* convert x-coordinate to a canvas unit coordinate (this takes
* zoom and scroll into account).
*/
-
+
tx = trackview.editor().sample_to_pixel_unrounded (tx);
-
+
/* convert from canonical view height (0..1.0) to actual
* height coordinates (using X11's top-left rooted system)
*/
/* TODO: This should be more generic (use ParameterDescriptor)
* or better yet: Controllable -> set_interface();
*/
+
if ( alist->parameter().type() == GainAutomation
|| alist->parameter().type() == EnvelopeAutomation
|| (_desc.logarithmic && _desc.lower == 0. && _desc.upper > _desc.lower)) {
} else if (alist->parameter().type() == PanAzimuthAutomation ||
alist->parameter().type() == PanElevationAutomation) {
y = 1.0 - y;
+ y = max ((double) _desc.lower, y);
+ y = min ((double) _desc.upper, y);
} else if (alist->parameter().type() == PanWidthAutomation) {
y = 2.0 * y - 1.0;
+ y = max ((double) _desc.lower, y);
+ y = min ((double) _desc.upper, y);
} else {
y = y * (double)(alist->get_max_y() - alist->get_min_y()) + alist->get_min_y();
if (_desc.integer_step) {
} else if (_desc.toggled) {
y = (y > 0.5) ? 1.0 : 0.0;
}
+ y = max ((double) _desc.lower, y);
+ y = min ((double) _desc.upper, y);
}
}
if ( alist->parameter().type() == GainAutomation
|| alist->parameter().type() == EnvelopeAutomation
|| (_desc.logarithmic && _desc.lower == 0. && _desc.upper > _desc.lower)) {
- y = gain_to_slider_position_with_max (y, Config->get_max_gain());
+ y = gain_to_slider_position_with_max (y, _desc.upper);
} else if (alist->parameter().type() == TrimAutomation
|| (_desc.logarithmic && _desc.lower * _desc.upper > 0 && _desc.upper > _desc.lower)) {
const double lower_db = accurate_coefficient_to_dB (_desc.lower);
}
void
-AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty,
+AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty,
AutomationList::iterator model, uint32_t npoints)
{
ControlPoint::ShapeType shape;