automation-range-drag: if lane is empty, use current value for guard points

* in the case where there are no existing automation points, then
 initiating an automation range drag  (select range, switch to Draw)
 should initialize the line at the current knob position
This commit is contained in:
Ben Loftis 2022-05-15 17:39:52 -05:00
parent cd332a2af0
commit e0f9f11dfc
3 changed files with 19 additions and 6 deletions

View File

@ -6393,12 +6393,13 @@ NoteDrag::aborted (bool)
}
/** 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 */
, _ranges (r)
, _y_origin (atv->y_position())
, _y_height (atv->effective_height()) // or atv->lines()->front()->height() ?!
, _nothing_to_drag (false)
, _initial_value (initial_value)
{
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
setup (atv->lines ());
@ -6486,6 +6487,10 @@ AutomationRangeDrag::y_fraction (double global_y) const
double
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);
return _integral ? rint(v) : v;
}
@ -6562,9 +6567,14 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move)
p.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();
bool const add_p = the_list->editor_add (p, value (the_list, p), false);
bool const add_q = the_list->editor_add (q, value (the_list, q), false);
bool const add_p = the_list->editor_add (p, p_value, false);
bool const add_q = the_list->editor_add (q, q_value, false);
if (add_p || add_q) {
_editor->session()->add_command (

View File

@ -1362,7 +1362,7 @@ private:
class AutomationRangeDrag : public Drag
{
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);
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
@ -1394,6 +1394,7 @@ private:
double _y_height;
bool _nothing_to_drag;
bool _integral;
float_t _initial_value;
};
/** Drag of one edge of an xfade

View File

@ -1214,8 +1214,10 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
/* handle automation lanes first */
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (atv) {
/* smart "join" mode: drag automation */
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
/* if there's no line yet, AutomationRangeDrag will need to be told what the initial value of this control is */
float init_value = atv->control()->get_value();
_drags->set (new AutomationRangeDrag (this, atv, init_value, selection->time), event, _cursors->up_down);
return true;
}
if (dynamic_cast<AutomationRegionView*>(clicked_regionview)) {