Compare commits
5 Commits
e739191ae2
...
cb85a0a521
Author | SHA1 | Date |
---|---|---|
Ben Loftis | cb85a0a521 | |
Ben Loftis | e0f9f11dfc | |
Ben Loftis | cd332a2af0 | |
Ben Loftis | 3a174ff914 | |
Ben Loftis | c98561e95c |
|
@ -503,13 +503,7 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
|
||||||
|
|
||||||
if (front()->view_index() > 0) {
|
if (front()->view_index() > 0) {
|
||||||
before_x = line.nth (front()->view_index() - 1)->get_x();
|
before_x = line.nth (front()->view_index() - 1)->get_x();
|
||||||
|
before_x += e.sample_to_pixel_unrounded (64);
|
||||||
const samplepos_t pos = e.pixel_to_sample(before_x);
|
|
||||||
const TempoMetric& metric = map->metric_at (pos);
|
|
||||||
const samplecnt_t len = ceil (metric.samples_per_bar (pos) / (Temporal::ticks_per_beat * metric.meter().divisions_per_bar()));
|
|
||||||
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
|
|
||||||
|
|
||||||
before_x += one_tick_in_pixels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if our last point has a point after it in the line,
|
/* if our last point has a point after it in the line,
|
||||||
|
@ -518,13 +512,7 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
|
||||||
|
|
||||||
if (back()->view_index() < (line.npoints() - 1)) {
|
if (back()->view_index() < (line.npoints() - 1)) {
|
||||||
after_x = line.nth (back()->view_index() + 1)->get_x();
|
after_x = line.nth (back()->view_index() + 1)->get_x();
|
||||||
|
after_x -= e.sample_to_pixel_unrounded (64);
|
||||||
const samplepos_t pos = e.pixel_to_sample(after_x);
|
|
||||||
const TempoMetric& metric = map->metric_at (pos);
|
|
||||||
const samplecnt_t len = ceil (metric.samples_per_bar (pos) / (Temporal::ticks_per_beat * metric.meter().divisions_per_bar()));
|
|
||||||
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
|
|
||||||
|
|
||||||
after_x -= one_tick_in_pixels;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,10 +638,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool
|
||||||
|
|
||||||
if (dx < 0 || ((dx > 0) && !with_push)) {
|
if (dx < 0 || ((dx > 0) && !with_push)) {
|
||||||
for (vector<CCP>::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) {
|
for (vector<CCP>::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) {
|
||||||
double dxt = (*ccp)->clamp_dx (dx);
|
dx = (*ccp)->clamp_dx (dx);
|
||||||
if (fabs (dxt) < fabs (dx)) {
|
|
||||||
dx = dxt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6393,12 +6393,13 @@ NoteDrag::aborted (bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Make an AutomationRangeDrag for lines in an AutomationTimeAxisView */
|
/** Make an AutomationRangeDrag for lines in an AutomationTimeAxisView */
|
||||||
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<TimelineRange> const & r)
|
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, float initial_value, list<TimelineRange> const & r)
|
||||||
: Drag (editor, atv->base_item (), editor->default_time_domain()) /* XXX NUTEMPO FIX TIME DOMAIN */
|
: Drag (editor, atv->base_item (), editor->default_time_domain()) /* XXX NUTEMPO FIX TIME DOMAIN */
|
||||||
, _ranges (r)
|
, _ranges (r)
|
||||||
, _y_origin (atv->y_position())
|
, _y_origin (atv->y_position())
|
||||||
, _y_height (atv->effective_height()) // or atv->lines()->front()->height() ?!
|
, _y_height (atv->effective_height()) // or atv->lines()->front()->height() ?!
|
||||||
, _nothing_to_drag (false)
|
, _nothing_to_drag (false)
|
||||||
|
, _initial_value (initial_value)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
||||||
setup (atv->lines ());
|
setup (atv->lines ());
|
||||||
|
@ -6486,6 +6487,10 @@ AutomationRangeDrag::y_fraction (double global_y) const
|
||||||
double
|
double
|
||||||
AutomationRangeDrag::value (boost::shared_ptr<AutomationList> list, timepos_t const & x) const
|
AutomationRangeDrag::value (boost::shared_ptr<AutomationList> list, timepos_t const & x) const
|
||||||
{
|
{
|
||||||
|
if (list->size () == 0) {
|
||||||
|
return _initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
const double v = list->eval(x);
|
const double v = list->eval(x);
|
||||||
return _integral ? rint(v) : v;
|
return _integral ? rint(v) : v;
|
||||||
}
|
}
|
||||||
|
@ -6562,9 +6567,14 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move)
|
||||||
p.set_time_domain (the_list->time_domain());
|
p.set_time_domain (the_list->time_domain());
|
||||||
q.set_time_domain (the_list->time_domain());
|
q.set_time_domain (the_list->time_domain());
|
||||||
|
|
||||||
|
/* get start&end values to use for guard points *before* we add points to the list */
|
||||||
|
/* in the case where no data exists on the line, p_value = q_value = initial_value */
|
||||||
|
float p_value = value (the_list, p);
|
||||||
|
float q_value = value (the_list, q);
|
||||||
|
|
||||||
XMLNode &before = the_list->get_state();
|
XMLNode &before = the_list->get_state();
|
||||||
bool const add_p = the_list->editor_add (p, value (the_list, p), false);
|
bool const add_p = the_list->editor_add (p, p_value, false);
|
||||||
bool const add_q = the_list->editor_add (q, value (the_list, q), false);
|
bool const add_q = the_list->editor_add (q, q_value, false);
|
||||||
|
|
||||||
if (add_p || add_q) {
|
if (add_p || add_q) {
|
||||||
_editor->session()->add_command (
|
_editor->session()->add_command (
|
||||||
|
|
|
@ -1362,7 +1362,7 @@ private:
|
||||||
class AutomationRangeDrag : public Drag
|
class AutomationRangeDrag : public Drag
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::TimelineRange> const &);
|
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, float initial_value, std::list<ARDOUR::TimelineRange> const &);
|
||||||
AutomationRangeDrag (Editor *, std::list<RegionView*> const &, std::list<ARDOUR::TimelineRange> const &, double y_origin, double y_height);
|
AutomationRangeDrag (Editor *, std::list<RegionView*> const &, std::list<ARDOUR::TimelineRange> const &, double y_origin, double y_height);
|
||||||
|
|
||||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
|
@ -1394,6 +1394,7 @@ private:
|
||||||
double _y_height;
|
double _y_height;
|
||||||
bool _nothing_to_drag;
|
bool _nothing_to_drag;
|
||||||
bool _integral;
|
bool _integral;
|
||||||
|
float_t _initial_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Drag of one edge of an xfade
|
/** Drag of one edge of an xfade
|
||||||
|
|
|
@ -1214,8 +1214,10 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
/* handle automation lanes first */
|
/* handle automation lanes first */
|
||||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
||||||
if (atv) {
|
if (atv) {
|
||||||
/* smart "join" mode: drag automation */
|
/* if there's no line yet, AutomationRangeDrag will need to be told what the initial value of this control is */
|
||||||
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
|
float init_value = atv->control()->get_value();
|
||||||
|
|
||||||
|
_drags->set (new AutomationRangeDrag (this, atv, init_value, selection->time), event, _cursors->up_down);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
|
if (dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
|
||||||
|
|
|
@ -562,9 +562,7 @@ ControlList::add_guard_point (timepos_t const & time, timecnt_t const & offset)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (offset <= timecnt_t());
|
if (offset.is_negative()) {
|
||||||
|
|
||||||
if (!offset.is_zero()) {
|
|
||||||
/* check if there are points between when + offset .. when */
|
/* check if there are points between when + offset .. when */
|
||||||
ControlEvent cp (when + offset, 0.0);
|
ControlEvent cp (when + offset, 0.0);
|
||||||
iterator s;
|
iterator s;
|
||||||
|
@ -577,6 +575,19 @@ ControlList::add_guard_point (timepos_t const & time, timecnt_t const & offset)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* check if there are points between when + offset .. when */
|
||||||
|
ControlEvent cp (when + offset, 0.0);
|
||||||
|
iterator s;
|
||||||
|
iterator e;
|
||||||
|
if ((s = upper_bound (_events.begin(), _events.end(), &cp, time_comparator)) != _events.end()) {
|
||||||
|
cp.when = when;
|
||||||
|
e = upper_bound (_events.begin(), _events.end(), &cp, time_comparator);
|
||||||
|
if (s != e) {
|
||||||
|
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 add_guard_point, none added, found event between %2 and %3\n", this, when.earlier (offset), when));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't do this again till the next write pass,
|
/* don't do this again till the next write pass,
|
||||||
|
@ -1890,7 +1901,7 @@ ControlList::cut_copy_clear (timepos_t const & start_time, timepos_t const & end
|
||||||
|
|
||||||
double val = unlocked_eval (start);
|
double val = unlocked_eval (start);
|
||||||
|
|
||||||
if (op == 0) { // cut
|
if (op != 1) { // cut/clear
|
||||||
if (start > _events.front()->when) {
|
if (start > _events.front()->when) {
|
||||||
_events.insert (s, (new ControlEvent (start, val)));
|
_events.insert (s, (new ControlEvent (start, val)));
|
||||||
}
|
}
|
||||||
|
@ -1920,15 +1931,12 @@ ControlList::cut_copy_clear (timepos_t const & start_time, timepos_t const & end
|
||||||
|
|
||||||
if (e == _events.end() || (*e)->when != end) {
|
if (e == _events.end() || (*e)->when != end) {
|
||||||
|
|
||||||
/* only add a boundary point if there is a point after "end"
|
if (op != 1) { // cut/clear
|
||||||
*/
|
|
||||||
|
|
||||||
if (op == 0 && (e != _events.end() && end < (*e)->when)) { // cut
|
|
||||||
_events.insert (e, new ControlEvent (end, end_value));
|
_events.insert (e, new ControlEvent (end, end_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op != 2 && (e != _events.end() && end < (*e)->when)) { // cut/copy
|
if (op != 2) { // cut/copy
|
||||||
nal->_events.push_back (new ControlEvent (timepos_t (start.distance (start)), end_value));
|
nal->_events.push_back (new ControlEvent (timepos_t (start.distance (end)), end_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1970,6 +1978,11 @@ ControlList::paste (const ControlList& alist, timepos_t const & time)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* when pasting a range of automation, first add guard points so the automation data before and after this range is retained */
|
||||||
|
const ControlEvent* last = alist.back();
|
||||||
|
add_guard_point (time, -GUARD_POINT_DELTA);
|
||||||
|
add_guard_point (time + last->when, GUARD_POINT_DELTA);
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||||
iterator where;
|
iterator where;
|
||||||
|
|
Loading…
Reference in New Issue