significant overhaul of automation region/lines to update during tempo map drags etc
This commit is contained in:
parent
e2c5a0777b
commit
a928e35efb
|
@ -91,6 +91,14 @@ AutomationLine::AutomationLine (const string& name,
|
||||||
const ParameterDescriptor& desc)
|
const ParameterDescriptor& desc)
|
||||||
: trackview (tv)
|
: trackview (tv)
|
||||||
, _name (name)
|
, _name (name)
|
||||||
|
, _height (0)
|
||||||
|
, _visible (Line)
|
||||||
|
, terminal_points_can_slide (true)
|
||||||
|
, update_pending (false)
|
||||||
|
, have_reset_timeout (false)
|
||||||
|
, have_redisplay_timeout (false)
|
||||||
|
, no_draw (false)
|
||||||
|
, _is_boolean (false)
|
||||||
, alist (al)
|
, alist (al)
|
||||||
, _parent_group (parent)
|
, _parent_group (parent)
|
||||||
, _offset (0)
|
, _offset (0)
|
||||||
|
@ -98,15 +106,6 @@ AutomationLine::AutomationLine (const string& name,
|
||||||
, _fill (false)
|
, _fill (false)
|
||||||
, _desc (desc)
|
, _desc (desc)
|
||||||
{
|
{
|
||||||
_visible = Line;
|
|
||||||
|
|
||||||
update_pending = false;
|
|
||||||
have_timeout = false;
|
|
||||||
no_draw = false;
|
|
||||||
_is_boolean = false;
|
|
||||||
terminal_points_can_slide = true;
|
|
||||||
_height = 0;
|
|
||||||
|
|
||||||
group = new ArdourCanvas::Container (&parent, ArdourCanvas::Duple(0, 1.5));
|
group = new ArdourCanvas::Container (&parent, ArdourCanvas::Duple(0, 1.5));
|
||||||
CANVAS_DEBUG_NAME (group, "region gain envelope group");
|
CANVAS_DEBUG_NAME (group, "region gain envelope group");
|
||||||
|
|
||||||
|
@ -258,7 +257,7 @@ AutomationLine::set_height (guint32 h)
|
||||||
} else {
|
} else {
|
||||||
line->set_fill_y1 (0);
|
line->set_fill_y1 (0);
|
||||||
}
|
}
|
||||||
reset ();
|
redisplay (true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,8 +410,7 @@ AutomationLine::string_to_fraction (string const & s) const
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
model_to_view_coord_y (v);
|
return model_to_view_coord_y (v);
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start dragging a single point, possibly adding others if the supplied point is selected and there
|
/** Start dragging a single point, possibly adding others if the supplied point is selected and there
|
||||||
|
@ -554,7 +552,7 @@ AutomationLine::ContiguousControlPoints::move (double dx, double dvalue)
|
||||||
double view_y = 1.0 - (*i)->get_y() / line.height();
|
double view_y = 1.0 - (*i)->get_y() / line.height();
|
||||||
line.view_to_model_coord_y (view_y);
|
line.view_to_model_coord_y (view_y);
|
||||||
line.apply_delta (view_y, dvalue);
|
line.apply_delta (view_y, dvalue);
|
||||||
line.model_to_view_coord_y (view_y);
|
view_y = line.model_to_view_coord_y (view_y);
|
||||||
view_y = (1.0 - view_y) * line.height();
|
view_y = (1.0 - view_y) * line.height();
|
||||||
|
|
||||||
(*i)->move_to ((*i)->get_x() + dx, view_y, ControlPoint::Full);
|
(*i)->move_to ((*i)->get_x() + dx, view_y, ControlPoint::Full);
|
||||||
|
@ -782,7 +780,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
||||||
/* convert to absolute time on timeline */
|
/* convert to absolute time on timeline */
|
||||||
const timepos_t absolute_time = model_time + get_origin();
|
const timepos_t absolute_time = model_time + get_origin();
|
||||||
|
|
||||||
/* now convert it back to match the view_x (RegioView pixel pos) */
|
/* now convert it back to match the view_x (RegionView pixel pos) */
|
||||||
const double model_x = trackview.editor().time_to_pixel_unrounded (absolute_time.earlier (_offset).earlier (get_origin ()));
|
const double model_x = trackview.editor().time_to_pixel_unrounded (absolute_time.earlier (_offset).earlier (get_origin ()));
|
||||||
|
|
||||||
if (view_x != model_x) {
|
if (view_x != model_x) {
|
||||||
|
@ -811,7 +809,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
||||||
alist->modify (cp.model(), model_time, view_y);
|
alist->modify (cp.model(), model_time, view_y);
|
||||||
|
|
||||||
/* convert back from model to view y for clamping position (for integer/boolean/etc) */
|
/* convert back from model to view y for clamping position (for integer/boolean/etc) */
|
||||||
model_to_view_coord_y (view_y);
|
view_y = model_to_view_coord_y (view_y);
|
||||||
const double point_y = _height - (view_y * _height);
|
const double point_y = _height - (view_y * _height);
|
||||||
if (point_y != cp.get_y()) {
|
if (point_y != cp.get_y()) {
|
||||||
cp.move_to (cp.get_x(), point_y, ControlPoint::Full);
|
cp.move_to (cp.get_x(), point_y, ControlPoint::Full);
|
||||||
|
@ -968,6 +966,105 @@ AutomationLine::list_changed ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationLine::tempo_map_changed ()
|
||||||
|
{
|
||||||
|
if (alist->time_domain() != Temporal::BeatTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
redisplay (true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationLine::redisplay (bool view_only, bool with_y)
|
||||||
|
{
|
||||||
|
have_redisplay_timeout = false;
|
||||||
|
|
||||||
|
if (view_only) {
|
||||||
|
|
||||||
|
|
||||||
|
for (std::vector<ControlPoint *>::iterator i = control_points.begin(); i != control_points.end(); i++) {
|
||||||
|
|
||||||
|
AutomationList::iterator ai ((*i)->model());
|
||||||
|
|
||||||
|
/* drop points outside our range */
|
||||||
|
|
||||||
|
if (((*ai)->when < _offset)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*ai)->when >= _maximum_time) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we do not need to recompute the y coordinate here */
|
||||||
|
|
||||||
|
double ty;
|
||||||
|
timecnt_t tx;
|
||||||
|
|
||||||
|
if (!with_y) {
|
||||||
|
|
||||||
|
/* re-use existing y-coordinate */
|
||||||
|
|
||||||
|
ty = (*i)->get_y();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* convert to absolute position */
|
||||||
|
|
||||||
|
ty = model_to_view_coord_y ((*ai)->value);
|
||||||
|
|
||||||
|
if (isnan_local (ty)) {
|
||||||
|
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
|
||||||
|
_name) << endmsg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ty = _height - (ty * _height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tx is currently the distance of this point from
|
||||||
|
* _offset, which may be either:
|
||||||
|
*
|
||||||
|
* a) zero, for an automation line not connected to a
|
||||||
|
* region
|
||||||
|
*
|
||||||
|
* b) some non-zero value, corresponding to the start
|
||||||
|
* of the region within its source(s). Remember that
|
||||||
|
* this start is an offset within the source, not a
|
||||||
|
* position on the timeline.
|
||||||
|
*
|
||||||
|
* We need to convert tx to a global position, and to
|
||||||
|
* do that we need to measure the distance from the
|
||||||
|
* result of get_origin(), which tells ut the timeline
|
||||||
|
* position of _offset
|
||||||
|
*/
|
||||||
|
|
||||||
|
tx = model_to_view_coord_x ((*ai)->when);
|
||||||
|
|
||||||
|
/* convert x-coordinate to a canvas unit coordinate (this takes
|
||||||
|
* zoom and scroll into account).
|
||||||
|
*/
|
||||||
|
|
||||||
|
double px = trackview.editor().duration_to_pixels_unrounded (tx);
|
||||||
|
|
||||||
|
(*i)->move_to (px, ty);
|
||||||
|
|
||||||
|
reset_line_coords (**i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_points.size() > 1) {
|
||||||
|
line->set_steps (line_points, is_stepped());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
reset ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationLine::reset_callback (const Evoral::ControlList& events)
|
AutomationLine::reset_callback (const Evoral::ControlList& events)
|
||||||
{
|
{
|
||||||
|
@ -997,11 +1094,17 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
||||||
|
|
||||||
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
|
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
|
||||||
|
|
||||||
double ty = (*ai)->value;
|
/* drop points outside our range */
|
||||||
|
|
||||||
/* convert from model coordinates to canonical view coordinates */
|
if (((*ai)->when < _offset)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
timepos_t tx = model_to_view_coord (**ai, ty);
|
if ((*ai)->when >= _maximum_time) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ty = model_to_view_coord_y ((*ai)->value);
|
||||||
|
|
||||||
if (isnan_local (ty)) {
|
if (isnan_local (ty)) {
|
||||||
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
|
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
|
||||||
|
@ -1009,21 +1112,22 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx >= timepos_t::max (tx.time_domain()) || tx.is_negative () || tx >= _maximum_time) {
|
ty = _height - (ty * _height);
|
||||||
continue;
|
|
||||||
}
|
/* convert from model coordinates to canonical view coordinates */
|
||||||
|
|
||||||
|
timecnt_t tx = model_to_view_coord_x ((*ai)->when);
|
||||||
|
|
||||||
/* convert x-coordinate to a canvas unit coordinate (this takes
|
/* convert x-coordinate to a canvas unit coordinate (this takes
|
||||||
* zoom and scroll into account).
|
* zoom and scroll into account).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double px = trackview.editor().time_to_pixel_unrounded (tx);
|
double px = trackview.editor().duration_to_pixels_unrounded (tx);
|
||||||
|
|
||||||
/* convert from canonical view height (0..1.0) to actual
|
/* convert from canonical view height (0..1.0) to actual
|
||||||
* height coordinates (using X11's top-left rooted system)
|
* height coordinates (using X11's top-left rooted system)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ty = _height - (ty * _height);
|
|
||||||
|
|
||||||
add_visible_control_point (vp, pi, px, ty, ai, np);
|
add_visible_control_point (vp, pi, px, ty, ai, np);
|
||||||
|
|
||||||
|
@ -1072,7 +1176,7 @@ AutomationLine::reset ()
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Automation, "\t\tLINE RESET\n");
|
DEBUG_TRACE (DEBUG::Automation, "\t\tLINE RESET\n");
|
||||||
update_pending = false;
|
update_pending = false;
|
||||||
have_timeout = false;
|
have_reset_timeout = false;
|
||||||
|
|
||||||
if (no_draw) {
|
if (no_draw) {
|
||||||
return;
|
return;
|
||||||
|
@ -1097,10 +1201,10 @@ AutomationLine::queue_reset ()
|
||||||
if (trackview.editor().session()->transport_rolling() && alist->automation_write()) {
|
if (trackview.editor().session()->transport_rolling() && alist->automation_write()) {
|
||||||
/* automation write pass ... defer to a timeout */
|
/* automation write pass ... defer to a timeout */
|
||||||
/* redraw in 1/4 second */
|
/* redraw in 1/4 second */
|
||||||
if (!have_timeout) {
|
if (!have_reset_timeout) {
|
||||||
DEBUG_TRACE (DEBUG::Automation, "\tqueue timeout\n");
|
DEBUG_TRACE (DEBUG::Automation, "\tqueue timeout\n");
|
||||||
Glib::signal_timeout().connect (sigc::bind_return (sigc::mem_fun (*this, &AutomationLine::reset), false), 250);
|
Glib::signal_timeout().connect (sigc::bind_return (sigc::mem_fun (*this, &AutomationLine::reset), false), 250);
|
||||||
have_timeout = true;
|
have_reset_timeout = true;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_TRACE (DEBUG::Automation, "\ttimeout already queued, change ignored\n");
|
DEBUG_TRACE (DEBUG::Automation, "\ttimeout already queued, change ignored\n");
|
||||||
}
|
}
|
||||||
|
@ -1109,6 +1213,26 @@ AutomationLine::queue_reset ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationLine::queue_redisplay (bool for_height)
|
||||||
|
{
|
||||||
|
/* this must be called from the GUI thread */
|
||||||
|
|
||||||
|
if (trackview.editor().session()->transport_rolling() && alist->automation_write()) {
|
||||||
|
/* automation write pass ... defer to a timeout */
|
||||||
|
/* redraw in 1/4 second */
|
||||||
|
if (!have_redisplay_timeout) {
|
||||||
|
DEBUG_TRACE (DEBUG::Automation, "\tqueue timeout\n");
|
||||||
|
Glib::signal_timeout().connect (sigc::bind_return (sigc::bind (sigc::mem_fun (*this, &AutomationLine::redisplay), true, for_height), true), 250);
|
||||||
|
have_redisplay_timeout = true;
|
||||||
|
} else {
|
||||||
|
DEBUG_TRACE (DEBUG::Automation, "\ttimeout already queued, change ignored\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
redisplay (true, for_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationLine::clear ()
|
AutomationLine::clear ()
|
||||||
{
|
{
|
||||||
|
@ -1229,8 +1353,8 @@ AutomationLine::apply_delta (double& val, double delta) const
|
||||||
val = _desc.apply_delta (val, delta);
|
val = _desc.apply_delta (val, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
double
|
||||||
AutomationLine::model_to_view_coord_y (double& y) const
|
AutomationLine::model_to_view_coord_y (double y) const
|
||||||
{
|
{
|
||||||
if (alist->default_interpolation () != alist->interpolation()) {
|
if (alist->default_interpolation () != alist->interpolation()) {
|
||||||
switch (alist->interpolation()) {
|
switch (alist->interpolation()) {
|
||||||
|
@ -1239,8 +1363,7 @@ AutomationLine::model_to_view_coord_y (double& y) const
|
||||||
assert (alist->default_interpolation () == AutomationList::Linear);
|
assert (alist->default_interpolation () == AutomationList::Linear);
|
||||||
break;
|
break;
|
||||||
case AutomationList::Linear:
|
case AutomationList::Linear:
|
||||||
y = (y - _desc.lower) / (_desc.upper - _desc.lower);
|
return (y - _desc.lower) / (_desc.upper - _desc.lower);
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
/* types that default to linear, can't be use
|
/* types that default to linear, can't be use
|
||||||
* Logarithmic or Exponential interpolation.
|
* Logarithmic or Exponential interpolation.
|
||||||
|
@ -1250,15 +1373,22 @@ AutomationLine::model_to_view_coord_y (double& y) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y = _desc.to_interface (y);
|
return _desc.to_interface (y);
|
||||||
}
|
}
|
||||||
|
|
||||||
timepos_t
|
timecnt_t
|
||||||
AutomationLine::model_to_view_coord (Evoral::ControlEvent const & ev, double& y) const
|
AutomationLine::model_to_view_coord_x (timepos_t const & when) const
|
||||||
{
|
{
|
||||||
Temporal::timepos_t w (ev.when);
|
/* @param when is a distance (with implicit origin) from the start of the
|
||||||
model_to_view_coord_y (y);
|
* source. So we subtract the offset (from the region if this is
|
||||||
return (w).earlier (_offset);
|
* related to a region; zero otherwise) to get the distance (again,
|
||||||
|
* implicit origin) from the start of the line.
|
||||||
|
*
|
||||||
|
* Then we construct a timecnt_t from this duration, and the origin of
|
||||||
|
* the line on the timeline.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return timecnt_t (when.earlier (_offset), get_origin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when our list has announced that its interpolation style has changed */
|
/** Called when our list has announced that its interpolation style has changed */
|
||||||
|
@ -1374,10 +1504,6 @@ AutomationLine::session_position (timepos_t const & when) const
|
||||||
void
|
void
|
||||||
AutomationLine::set_offset (timepos_t const & off)
|
AutomationLine::set_offset (timepos_t const & off)
|
||||||
{
|
{
|
||||||
if (_offset == off) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_offset = off;
|
_offset = off;
|
||||||
reset ();
|
reset ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,9 @@ public:
|
||||||
|
|
||||||
virtual Temporal::timepos_t get_origin () const;
|
virtual Temporal::timepos_t get_origin () const;
|
||||||
|
|
||||||
|
void redisplay (bool view_only, bool with_y);
|
||||||
void queue_reset ();
|
void queue_reset ();
|
||||||
|
void queue_redisplay (bool for_height);
|
||||||
void reset ();
|
void reset ();
|
||||||
void clear ();
|
void clear ();
|
||||||
void set_fill (bool f) { _fill = f; } // owner needs to call set_height
|
void set_fill (bool f) { _fill = f; } // owner needs to call set_height
|
||||||
|
@ -114,6 +116,7 @@ public:
|
||||||
void set_height (guint32);
|
void set_height (guint32);
|
||||||
|
|
||||||
bool get_uses_gain_mapping () const;
|
bool get_uses_gain_mapping () const;
|
||||||
|
void tempo_map_changed ();
|
||||||
|
|
||||||
TimeAxisView& trackview;
|
TimeAxisView& trackview;
|
||||||
|
|
||||||
|
@ -126,9 +129,11 @@ public:
|
||||||
std::string fraction_to_string (double) const;
|
std::string fraction_to_string (double) const;
|
||||||
std::string delta_to_string (double) const;
|
std::string delta_to_string (double) const;
|
||||||
double string_to_fraction (std::string const &) const;
|
double string_to_fraction (std::string const &) const;
|
||||||
|
|
||||||
void view_to_model_coord_y (double &) const;
|
void view_to_model_coord_y (double &) const;
|
||||||
Temporal::timepos_t model_to_view_coord (Evoral::ControlEvent const &, double& y) const;
|
|
||||||
void model_to_view_coord_y (double &) const;
|
double model_to_view_coord_y (double) const;
|
||||||
|
Temporal::timecnt_t model_to_view_coord_x (Temporal::timepos_t const &) const;
|
||||||
|
|
||||||
double compute_delta (double from, double to) const;
|
double compute_delta (double from, double to) const;
|
||||||
void apply_delta (double& val, double delta) const;
|
void apply_delta (double& val, double delta) const;
|
||||||
|
@ -175,7 +180,8 @@ protected:
|
||||||
|
|
||||||
bool terminal_points_can_slide;
|
bool terminal_points_can_slide;
|
||||||
bool update_pending;
|
bool update_pending;
|
||||||
bool have_timeout;
|
bool have_reset_timeout;
|
||||||
|
bool have_redisplay_timeout;
|
||||||
bool no_draw;
|
bool no_draw;
|
||||||
bool _is_boolean;
|
bool _is_boolean;
|
||||||
/** true if we did a push at any point during the current drag */
|
/** true if we did a push at any point during the current drag */
|
||||||
|
|
|
@ -103,6 +103,7 @@ AutomationRegionView::create_line (boost::shared_ptr<ARDOUR::AutomationList> lis
|
||||||
_line->set_height ((uint32_t)rint(trackview.current_height() - 2.5 - NAME_HIGHLIGHT_SIZE));
|
_line->set_height ((uint32_t)rint(trackview.current_height() - 2.5 - NAME_HIGHLIGHT_SIZE));
|
||||||
_line->set_visibility (AutomationLine::VisibleAspects (AutomationLine::Line|AutomationLine::ControlPoints));
|
_line->set_visibility (AutomationLine::VisibleAspects (AutomationLine::Line|AutomationLine::ControlPoints));
|
||||||
_line->set_maximum_time (timepos_t (_region->length()));
|
_line->set_maximum_time (timepos_t (_region->length()));
|
||||||
|
std::cerr << "Set line offset to " << _region->start() << std::endl;
|
||||||
_line->set_offset (_region->start ());
|
_line->set_offset (_region->start ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,11 +292,10 @@ AutomationRegionView::reset_width_dependent_items (double pixel_width)
|
||||||
RegionView::reset_width_dependent_items(pixel_width);
|
RegionView::reset_width_dependent_items(pixel_width);
|
||||||
|
|
||||||
if (_line) {
|
if (_line) {
|
||||||
_line->reset();
|
_line->reset ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
|
AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +314,16 @@ AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationRegionView::tempo_map_changed ()
|
||||||
|
{
|
||||||
|
if (_line) {
|
||||||
|
_line->tempo_map_changed ();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_position (_region->position(), 0, 0);
|
||||||
|
set_duration (_region->length(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationRegionView::entered ()
|
AutomationRegionView::entered ()
|
||||||
|
|
|
@ -68,6 +68,8 @@ public:
|
||||||
void set_height (double);
|
void set_height (double);
|
||||||
void reset_width_dependent_items(double pixel_width);
|
void reset_width_dependent_items(double pixel_width);
|
||||||
|
|
||||||
|
void tempo_map_changed ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void create_line(boost::shared_ptr<ARDOUR::AutomationList> list);
|
void create_line(boost::shared_ptr<ARDOUR::AutomationList> list);
|
||||||
bool set_position(Temporal::timepos_t const & pos, void* src, double* ignored);
|
bool set_position(Temporal::timepos_t const & pos, void* src, double* ignored);
|
||||||
|
|
|
@ -1176,7 +1176,7 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
||||||
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
|
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
|
||||||
timepos_t when = (*x)->when;
|
timepos_t when = (*x)->when;
|
||||||
double val = (*x)->value;
|
double val = (*x)->value;
|
||||||
line.model_to_view_coord (**x, val);
|
line.model_to_view_coord_y (val);
|
||||||
(*x)->when = when;
|
(*x)->when = when;
|
||||||
(*x)->value = val;
|
(*x)->value = val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,8 @@ public:
|
||||||
/** @return All AutomationLines associated with this view */
|
/** @return All AutomationLines associated with this view */
|
||||||
std::list<boost::shared_ptr<AutomationLine> > lines () const;
|
std::list<boost::shared_ptr<AutomationLine> > lines () const;
|
||||||
|
|
||||||
|
AutomationStreamView* automation_view() const { return _view; }
|
||||||
|
|
||||||
void set_selected_points (PointSelection&);
|
void set_selected_points (PointSelection&);
|
||||||
void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list<Selectable *>&, bool within = false);
|
void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list<Selectable *>&, bool within = false);
|
||||||
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
|
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
|
||||||
|
|
|
@ -133,7 +133,13 @@ void
|
||||||
ControlPoint::set_size (double sz)
|
ControlPoint::set_size (double sz)
|
||||||
{
|
{
|
||||||
_size = sz;
|
_size = sz;
|
||||||
move_to (_x, _y, _shape);
|
move_to (_x, _y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ControlPoint::move_to (double x, double y)
|
||||||
|
{
|
||||||
|
move_to (x, y, _shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
End
|
End
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void move_to (double x, double y);
|
||||||
void move_to (double x, double y, ShapeType);
|
void move_to (double x, double y, ShapeType);
|
||||||
void reset (double x, double y, ARDOUR::AutomationList::iterator, uint32_t, ShapeType);
|
void reset (double x, double y, ARDOUR::AutomationList::iterator, uint32_t, ShapeType);
|
||||||
double get_x() const { return _x; }
|
double get_x() const { return _x; }
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "canvas/item.h"
|
#include "canvas/item.h"
|
||||||
#include "canvas/line_set.h"
|
#include "canvas/line_set.h"
|
||||||
|
|
||||||
|
#include "automation_streamview.h"
|
||||||
#include "bbt_marker_dialog.h"
|
#include "bbt_marker_dialog.h"
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "marker.h"
|
#include "marker.h"
|
||||||
|
@ -899,21 +900,32 @@ Editor::mid_tempo_per_track_update (TimeAxisView& tav)
|
||||||
{
|
{
|
||||||
MidiTimeAxisView* mtav = dynamic_cast<MidiTimeAxisView*> (&tav);
|
MidiTimeAxisView* mtav = dynamic_cast<MidiTimeAxisView*> (&tav);
|
||||||
|
|
||||||
if (!mtav) {
|
if (mtav) {
|
||||||
return;
|
MidiStreamView* msv = mtav->midi_view();
|
||||||
|
|
||||||
|
if (msv) {
|
||||||
|
msv->foreach_regionview (sigc::mem_fun (*this, &Editor::mid_tempo_per_region_update));
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeAxisView::Children kids (tav.get_child_list());
|
||||||
|
|
||||||
|
for (TimeAxisView::Children::iterator ct = kids.begin(); ct != kids.end(); ++ct) {
|
||||||
|
|
||||||
|
boost::shared_ptr<AutomationTimeAxisView> atav = boost::dynamic_pointer_cast<AutomationTimeAxisView> (*ct);
|
||||||
|
|
||||||
|
if (atav) {
|
||||||
|
AutomationStreamView* asv = atav->automation_view ();
|
||||||
|
|
||||||
|
if (asv) {
|
||||||
|
asv->foreach_regionview (sigc::mem_fun (*this, &Editor::mid_tempo_per_region_update));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiStreamView* msv = mtav->midi_view();
|
|
||||||
|
|
||||||
if (!msv) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msv->foreach_regionview (sigc::mem_fun (*this, &Editor::mid_tempo_per_region_update));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::mid_tempo_per_region_update (RegionView* rv)
|
Editor::mid_tempo_per_region_update (RegionView* rv)
|
||||||
{
|
{
|
||||||
rv->redisplay (true);
|
rv->tempo_map_changed ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,10 @@ public:
|
||||||
_redisplay (view_only);
|
_redisplay (view_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void tempo_map_changed () {
|
||||||
|
_redisplay (true);
|
||||||
|
}
|
||||||
|
|
||||||
struct DisplaySuspender {
|
struct DisplaySuspender {
|
||||||
DisplaySuspender (RegionView& rv, bool just_view = false) : region_view (rv), view_only (just_view) {
|
DisplaySuspender (RegionView& rv, bool just_view = false) : region_view (rv), view_only (just_view) {
|
||||||
region_view.disable_display ();
|
region_view.disable_display ();
|
||||||
|
|
Loading…
Reference in New Issue