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 */ /** 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 (

View File

@ -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

View File

@ -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)) {