From 9d54bb08e7fcef4eaf687316a619e40178be315f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 4 Jun 2021 09:15:36 -0600 Subject: [PATCH] remove almost all of RegionRippleDrag, collapsing down to just collecting additional RegionViews that need to be moved during the drag --- gtk2_ardour/editor_drag.cc | 213 +++++------------------------------- gtk2_ardour/editor_drag.h | 22 +--- gtk2_ardour/editor_mouse.cc | 4 +- 3 files changed, 37 insertions(+), 202 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 2b7279bc73..a249d7942c 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -1222,6 +1222,10 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) #endif } + if (first_move) { + collect_views (); + } + for (list::iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = i->view; @@ -2299,118 +2303,37 @@ RegionSpliceDrag::aborted (bool) /*** * ripple mode... + * very similar to a regular region move drag, except that on first move we + * collect all regionviews after the selected regions on appropriate playlists + * and visually drag them too. */ -void -RegionRippleDrag::add_all_after_to_views(TimeAxisView *tav, samplepos_t where, const RegionSelection &exclude, bool drag_in_progress) -{ - - boost::shared_ptr rl = tav->playlist()->regions_with_start_within (Evoral::Range(where, max_samplepos)); - - RouteTimeAxisView* rtv = dynamic_cast(tav); - RegionSelection to_ripple; - for (RegionList::iterator i = rl->begin(); i != rl->end(); ++i) { - if ((*i)->position() >= where) { - to_ripple.push_back (rtv->view()->find_view(*i)); - } - } - - for (RegionSelection::reverse_iterator i = to_ripple.rbegin(); i != to_ripple.rend(); ++i) { - if (!exclude.contains (*i)) { - // the selection has already been added to _views - - if (drag_in_progress) { - // do the same things that RegionMotionDrag::motion does when - // first_move is true, for the region views that we're adding - // to _views this time - - (*i)->drag_start(); - ArdourCanvas::Item* rvg = (*i)->get_canvas_group(); - Duple rv_canvas_offset = rvg->item_to_canvas (Duple (0,0)); - Duple dmg_canvas_offset = _editor->_drag_motion_group->canvas_origin (); - rvg->reparent (_editor->_drag_motion_group); - - // we only need to move in the y direction - Duple fudge = rv_canvas_offset - dmg_canvas_offset; - fudge.x = 0; - rvg->move (fudge); - - } - _views.push_back (DraggingView (*i, this, tav)); - } - } -} - -void -RegionRippleDrag::remove_unselected_from_views(samplecnt_t amount, bool move_regions) -{ - ThawList thawlist; - - for (std::list::iterator i = _views.begin(); i != _views.end(); ) { - // we added all the regions after the selection - - std::list::iterator to_erase = i++; - if (!_editor->selection->regions.contains (to_erase->view)) { - // restore the non-selected regions to their original playlist & positions, - // and then ripple them back by the length of the regions that were dragged away - // do the same things as RegionMotionDrag::aborted - - RegionView *rv = to_erase->view; - TimeAxisView* tv = &(rv->get_time_axis_view ()); - RouteTimeAxisView* rtv = dynamic_cast (tv); - assert (rtv); - - // plonk them back onto their own track - rv->get_canvas_group()->reparent(rtv->view()->canvas_item()); - rv->get_canvas_group()->set_y_position (0); - rv->drag_end (); - - if (move_regions) { - thawlist.add (rv->region ()); - // move the underlying region to match the view - rv->region()->set_position (rv->region()->position() + amount); - } else { - // restore the view to match the underlying region's original position - rv->move(-amount, 0); // second parameter is y delta - seems 0 is OK - } - - rv->set_height (rtv->view()->child_height ()); - _views.erase (to_erase); - } - } - thawlist.release (); -} - bool RegionRippleDrag::y_movement_allowed (int delta_track, double delta_layer, int skip_invisible) const { return false; } -RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) - : RegionMoveDrag (e, i, p, v, false) +RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool copy) + : RegionMoveDrag (e, i, p, v, false, copy) { DEBUG_TRACE (DEBUG::Drags, "New RegionRippleDrag\n"); - // compute length of selection - RegionSelection selected_regions = _editor->selection->regions; - selection_length = selected_regions.end_sample() - selected_regions.start(); - - prev_tav = NULL; - prev_amount = 0; - exclude = new RegionList; - for (RegionSelection::iterator i =selected_regions.begin(); i != selected_regions.end(); ++i) { - exclude->push_back((*i)->region()); - } +} +void +RegionRippleDrag::collect_views () +{ // also add regions before start of selection to exclude, to be consistent with how Mixbus does ripple RegionSelection copy; - selected_regions.by_position(copy); // get selected regions sorted by position into copy + _editor->selection->regions.by_position (copy); // get selected regions sorted by position into copy std::set > playlists = copy.playlists(); std::set >::const_iterator pi; for (pi = playlists.begin(); pi != playlists.end(); ++pi) { + // find ripple start point on each applicable playlist + RegionView *first_selected_on_this_track = NULL; for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) { if ((*i)->region()->playlist() == (*pi)) { @@ -2420,101 +2343,25 @@ RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView } } assert (first_selected_on_this_track); // we should always find the region in one of the playlists... - add_all_after_to_views ( - &first_selected_on_this_track->get_time_axis_view(), - first_selected_on_this_track->region()->position(), - selected_regions, false); - } + const samplepos_t where = first_selected_on_this_track->region()->position(); + TimeAxisView* tav = &first_selected_on_this_track->get_time_axis_view(); - orig_tav = NULL; -} + boost::shared_ptr rl = (*pi)->regions_with_start_within (Evoral::Range(where, max_samplepos)); + RouteTimeAxisView* rtv = dynamic_cast(tav); + RegionSelection to_ripple; -void -RegionRippleDrag::motion (GdkEvent* event, bool first_move) -{ - /* Which trackview is this ? */ - - pair const tvp = _editor->trackview_by_y_position (current_pointer_y ()); - RouteTimeAxisView* tv = dynamic_cast (tvp.first); - - /* The region motion is only processed if the pointer is over - an audio track. - */ - - if (!tv || !tv->is_track()) { - /* To make sure we hide the verbose canvas cursor when the mouse is - not held over an audiotrack. - */ - _editor->verbose_cursor()->hide (); - return; - } - - samplepos_t where = adjusted_current_sample (event); - assert (where >= 0); - MusicSample after (0, 0); - double delta = compute_x_delta (event, &after); - - samplecnt_t amount = _editor->pixel_to_sample (delta); - - // selection encompasses multiple tracks - just drag - // cross-track drags are forbidden - RegionMoveDrag::motion(event, first_move); - - if (!_x_constrained) { - prev_amount += amount; - } - - _last_position = after; -} - -void -RegionRippleDrag::finished (GdkEvent* event, bool movement_occurred) -{ - if (!movement_occurred) { - - /* just a click */ - - if (was_double_click() && !_views.empty()) { - DraggingView dv = _views.front(); - _editor->edit_region (dv.view); + for (RegionList::iterator i = rl->begin(); i != rl->end(); ++i) { + if ((*i)->position() >= where) { + to_ripple.push_back (rtv->view()->find_view(*i)); + } } - return; + for (RegionSelection::reverse_iterator i = to_ripple.rbegin(); i != to_ripple.rend(); ++i) { + if (!_editor->selection->regions.contains (*i)) { + _views.push_back (DraggingView (*i, this, tav)); + } + } } - - _editor->begin_reversible_command(_("Ripple drag")); - - // remove the regions being rippled from the dragging view, updating them to - // their new positions - - // selection spanned multiple tracks - all will need adding to undo record - - std::set > playlists = _editor->selection->regions.playlists(); - std::set >::const_iterator pi; - - for (pi = playlists.begin(); pi != playlists.end(); ++pi) { - (*pi)->clear_changes(); - (*pi)->clear_owned_changes(); - (*pi)->freeze(); - } - - remove_unselected_from_views (prev_amount); - - for (pi = playlists.begin(); pi != playlists.end(); ++pi) { - (*pi)->thaw(); - (*pi)->rdiff_and_add_command (_editor->session()); - } - - // other modified playlists are added to undo by RegionMoveDrag::finished() - RegionMoveDrag::finished (event, movement_occurred); - _editor->commit_reversible_command(); -} - -void -RegionRippleDrag::aborted (bool movement_occurred) -{ - RegionMoveDrag::aborted (movement_occurred); - _views.clear (); } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 5439823408..a8479a43ba 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -418,6 +418,8 @@ public: virtual void finished (GdkEvent *, bool); virtual void aborted (bool); + virtual void collect_views () {} + /** @return true if the regions being `moved' came from somewhere on the canvas; * false if they came from outside (e.g. from the region list). */ @@ -527,26 +529,12 @@ public: class RegionRippleDrag : public RegionMoveDrag { public: - RegionRippleDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &); - ~RegionRippleDrag () { delete exclude; } + RegionRippleDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool copy); + + void collect_views (); - void motion (GdkEvent *, bool); - void finished (GdkEvent *, bool); - void aborted (bool); protected: bool y_movement_allowed (int delta_track, double delta_layer, int skip_invisible = 0) const; - -private: - TimeAxisView *prev_tav; // where regions were most recently dragged from - TimeAxisView *orig_tav; // where drag started - ARDOUR::samplecnt_t prev_amount; - ARDOUR::samplepos_t prev_position; - ARDOUR::samplecnt_t selection_length; - ARDOUR::RegionList *exclude; - void add_all_after_to_views (TimeAxisView *tav, ARDOUR::samplepos_t where, const RegionSelection &exclude, bool drag_in_progress); - void remove_unselected_from_views (ARDOUR::samplecnt_t amount, bool move_regions); - - std::list > _orig_tav_ripples; }; /** "Drag" to cut a region (action only on button release) */ diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index e5bcb2578a..a4722b5645 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2583,7 +2583,7 @@ Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region return; case Ripple: case RippleAll: - _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer())); + _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer(), false)); break; default: _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false)); @@ -2606,7 +2606,7 @@ Editor::add_region_copy_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* r return; case Ripple: case RippleAll: - _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer())); + _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer(), true)); break; default: _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, true));