Initial steps towards usable range-based automation editing.
TODO: needs undo. only works in top quarter of automation lane. selection model feels weird sometimes. needs to show gain curve when you are using Range tool
This commit is contained in:
@@ -4239,6 +4239,14 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
||||
}
|
||||
}
|
||||
|
||||
//if user is selecting a range on an automation track, bail out here before we get to the grouped stuff,
|
||||
// because the grouped stuff will start working on tracks (routeTAVs), and end up removing this
|
||||
AutomationTimeAxisView *atest = dynamic_cast<AutomationTimeAxisView *>(_editor->clicked_axisview);
|
||||
if (atest) {
|
||||
_editor->selection->add (atest);
|
||||
break;
|
||||
}
|
||||
|
||||
/* select all tracks within the rectangle that we've marked out so far */
|
||||
TrackViewList new_selection;
|
||||
TrackViewList& all_tracks (_editor->track_views);
|
||||
@@ -4991,8 +4999,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
|
||||
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
|
||||
|
||||
the_list->add (p, the_list->eval (p));
|
||||
the_list->add (q, the_list->eval (q));
|
||||
the_list->editor_add (p, the_list->eval (p));
|
||||
the_list->editor_add (q, the_list->eval (q));
|
||||
}
|
||||
|
||||
/* same thing for the end */
|
||||
@@ -5017,8 +5025,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
|
||||
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
|
||||
|
||||
the_list->add (p, the_list->eval (p));
|
||||
the_list->add (q, the_list->eval (q));
|
||||
the_list->editor_add (p, the_list->eval (p));
|
||||
the_list->editor_add (q, the_list->eval (q));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -776,19 +776,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
/* grab selection for moving */
|
||||
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event);
|
||||
} else {
|
||||
double const y = event->button.y;
|
||||
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
|
||||
if (tvp.first) {
|
||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
||||
if ( get_smart_mode() && atv) {
|
||||
/* smart "join" mode: drag automation */
|
||||
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
|
||||
} else {
|
||||
/* this was debated, but decided the more common action was to
|
||||
make a new selection */
|
||||
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
||||
}
|
||||
}
|
||||
/* this was debated, but decided the more common action was to
|
||||
make a new selection */
|
||||
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1048,45 +1038,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
|
||||
case SelectionItem:
|
||||
{
|
||||
if ( get_smart_mode() ) {
|
||||
/* we're in "smart" joined mode, and we've clicked on a Selection */
|
||||
double const y = event->button.y;
|
||||
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
|
||||
if (tvp.first) {
|
||||
/* if we're over an automation track, start a drag of its data */
|
||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
||||
if (atv) {
|
||||
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
|
||||
}
|
||||
|
||||
/* if we're over a track and a region, and in the `object' part of a region,
|
||||
put a selection around the region and drag both
|
||||
*/
|
||||
/* RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
|
||||
if (rtv && _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
|
||||
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (rtv->route ());
|
||||
if (t) {
|
||||
boost::shared_ptr<Playlist> pl = t->playlist ();
|
||||
if (pl) {
|
||||
|
||||
boost::shared_ptr<Region> r = pl->top_region_at (canvas_event_sample (event));
|
||||
if (r) {
|
||||
RegionView* rv = rtv->view()->find_view (r);
|
||||
clicked_selection = select_range (rv->region()->position(),
|
||||
rv->region()->last_frame()+1);
|
||||
_drags->add (new SelectionDrag (this, item, SelectionDrag::SelectionMove));
|
||||
list<RegionView*> rvs;
|
||||
rvs.push_back (rv);
|
||||
_drags->add (new RegionMoveDrag (this, item, rv, rvs, false, false));
|
||||
_drags->start_grab (event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1118,6 +1069,17 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
if (arv) {
|
||||
_drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down);
|
||||
_drags->start_grab (event);
|
||||
} else {
|
||||
double const y = event->button.y;
|
||||
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
|
||||
if (tvp.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);
|
||||
_drags->start_grab (event);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
|
||||
@@ -185,12 +185,12 @@ Editor::set_selected_track_as_side_effect (Selection::Operation op)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clicked_routeview) {
|
||||
return;
|
||||
RouteGroup* group = NULL;
|
||||
if (clicked_routeview) {
|
||||
group = clicked_routeview->route()->route_group();
|
||||
}
|
||||
|
||||
bool had_tracks = !selection->tracks.empty();
|
||||
RouteGroup* group = clicked_routeview->route()->route_group();
|
||||
RouteGroup& arg (_session->all_route_group());
|
||||
|
||||
switch (op) {
|
||||
|
||||
@@ -121,7 +121,9 @@ public:
|
||||
|
||||
virtual bool clamp_value (double& /*when*/, double& /*value*/) const { return true; }
|
||||
|
||||
virtual void add (double when, double value, bool with_guards=true);
|
||||
virtual void add (double when, double value, bool with_guards=true);
|
||||
virtual void editor_add (double when, double value);
|
||||
|
||||
void fast_simple_add (double when, double value);
|
||||
|
||||
void erase_range (double start, double end);
|
||||
|
||||
@@ -443,6 +443,39 @@ ControlList::in_write_pass () const
|
||||
return _in_write_pass;
|
||||
}
|
||||
|
||||
void
|
||||
ControlList::editor_add (double when, double value)
|
||||
{
|
||||
/* this is for making changes from a graphical line editor
|
||||
*/
|
||||
|
||||
if (!clamp_value (when, value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_events.empty()) {
|
||||
|
||||
/* as long as the point we're adding is not at zero,
|
||||
* add an "anchor" point there.
|
||||
*/
|
||||
|
||||
if (when >= 1) {
|
||||
_events.insert (_events.end(), new ControlEvent (0, _default_value));
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
|
||||
}
|
||||
}
|
||||
|
||||
ControlEvent cp (when, 0.0f);
|
||||
iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %1\n", when, value));
|
||||
_events.insert (i, new ControlEvent (when, value));
|
||||
|
||||
mark_dirty ();
|
||||
|
||||
maybe_signal_changed ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ControlList::add (double when, double value, bool with_guards)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user