diff options
author | Colin Fletcher <colin.m.fletcher@googlemail.com> | 2014-07-01 19:10:47 +0100 |
---|---|---|
committer | Colin Fletcher <colin.m.fletcher@googlemail.com> | 2014-07-01 19:10:47 +0100 |
commit | e5e12acc5698090f2c0c614385e457cc0b46fbb0 (patch) | |
tree | 3f4f28baba25f4e276d669d98ff485f7c51aa0b1 /gtk2_ardour | |
parent | 23e7cf10191270d70357ccf0ed9294f020c7b7ab (diff) | |
parent | da65f3778c66dd2935709445c9a5dbd225296439 (diff) |
Merge branch 'ripple-mode-cc' into cairocanvas
Fix up merge conflicts in
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
Also fix up compile errors.
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/editor.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 301 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.h | 34 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 17 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 23 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 23 |
9 files changed, 386 insertions, 28 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index a837a5a429..6f8db99da0 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2825,12 +2825,6 @@ Editor::setup_toolbar () mouse_mode_box->pack_start (*mouse_mode_align, false, false); - edit_mode_strings.push_back (edit_mode_to_string (Slide)); - if (!Profile->get_sae()) { - edit_mode_strings.push_back (edit_mode_to_string (Splice)); - } - edit_mode_strings.push_back (edit_mode_to_string (Lock)); - edit_mode_selector.set_name ("mouse mode button"); edit_mode_selector.set_size_request (65, -1); edit_mode_selector.add_elements (ArdourButton::Inset); @@ -3047,6 +3041,7 @@ Editor::build_edit_mode_menu () edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_to_string(Slide), sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Slide))); edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_to_string(Splice), sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Splice))); + edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_to_string(Ripple), sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Ripple))); edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_to_string(Lock), sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Lock))); } @@ -3358,10 +3353,11 @@ Editor::cycle_edit_mode () if (Profile->get_sae()) { Config->set_edit_mode (Lock); } else { - Config->set_edit_mode (Splice); + Config->set_edit_mode (Ripple); } break; case Splice: + case Ripple: Config->set_edit_mode (Lock); break; case Lock: diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 3013e36051..d6e38cee41 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1626,7 +1626,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void edit_mode_selection_done ( ARDOUR::EditMode m ); void build_edit_mode_menu (); Gtk::VBox edit_mode_box; - std::vector<std::string> edit_mode_strings; void set_edit_mode (ARDOUR::EditMode); void cycle_edit_mode (); @@ -2102,6 +2101,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD friend class RegionDrag; friend class RegionMoveDrag; friend class RegionSpliceDrag; + friend class RegionRippleDrag; friend class TrimDrag; friend class MeterMarkerDrag; friend class TempoMarkerDrag; diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 1d19aca9c4..27fab388be 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -482,6 +482,7 @@ Editor::register_actions () ActionManager::register_action (editor_actions, "cycle-edit-point-with-marker", _("Change Edit Point Including Marker"), sigc::bind (sigc::mem_fun (*this, &Editor::cycle_edit_point), true)); if (!Profile->get_sae()) { ActionManager::register_action (editor_actions, "set-edit-splice", _("Splice"), sigc::bind (sigc::mem_fun (*this, &Editor::set_edit_mode), Splice)); + ActionManager::register_action (editor_actions, "set-edit-ripple", _("Ripple"), bind (mem_fun (*this, &Editor::set_edit_mode), Ripple)); } ActionManager::register_action (editor_actions, "set-edit-slide", _("Slide"), sigc::bind (sigc::mem_fun (*this, &Editor::set_edit_mode), Slide)); ActionManager::register_action (editor_actions, "set-edit-lock", _("Lock"), sigc::bind (sigc::mem_fun (*this, &Editor::set_edit_mode), Lock)); diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 647abae153..339249260e 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -893,6 +893,9 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties())); playlist->clear_changes (); playlist->add_region (copy, pos); + if (Config->get_edit_mode() == Ripple) + playlist->ripple (pos, copy->length(), copy); + _session->add_command (new StatefulDiffCommand (playlist)); break; } diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index c4000ddd45..9ad867bbcb 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -595,7 +595,6 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r } } - _last_frame_position = *pending_region_position; } return dx; @@ -668,6 +667,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) /* Work out the change in x */ framepos_t pending_region_position; double const x_delta = compute_x_delta (event, &pending_region_position); + _last_frame_position = pending_region_position; /* Verify change in y */ if (!y_movement_allowed (delta_time_axis_view, delta_layer)) { @@ -1281,7 +1281,7 @@ RegionMoveDrag::remove_region_from_playlist ( playlist->clear_changes (); } - playlist->remove_region (region); + playlist->remove_region (region); // should be no need to ripple; we better already have rippled the playlist in RegionRippleDrag } @@ -1451,6 +1451,12 @@ RegionInsertDrag::finished (GdkEvent *, bool) _editor->begin_reversible_command (Operations::insert_region); playlist->clear_changes (); playlist->add_region (_primary->region (), _last_frame_position); + + // Mixbus doesn't seem to ripple when inserting regions from the list: should we? yes, probably + if (Config->get_edit_mode() == Ripple) { + playlist->ripple (_last_frame_position, _primary->region()->length(), _primary->region()); + } + _editor->session()->add_command (new StatefulDiffCommand (playlist)); _editor->commit_reversible_command (); @@ -1493,7 +1499,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) if (!tv || !tv->is_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is - not held over and audiotrack. + not held over an audio track. */ _editor->verbose_cursor()->hide (); return; @@ -1509,10 +1515,8 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) dir = -1; } - RegionSelection copy (_editor->selection->regions); - - RegionSelectionByPosition cmp; - copy.sort (cmp); + RegionSelection copy; + _editor->selection->regions.by_position(copy); framepos_t const pf = adjusted_current_frame (event); @@ -1561,6 +1565,289 @@ RegionSpliceDrag::aborted (bool) /* XXX: TODO */ } +/*** + * ripple mode... + */ + +void +RegionRippleDrag::add_all_after_to_views(TimeAxisView *tav, framepos_t where, const RegionSelection &exclude, bool drag_in_progress) +{ + RegionSelection to_ripple; + TrackViewList tracks; + tracks.push_back (tav); + _editor->get_regions_after (to_ripple, where, tracks); + + for (RegionSelection::iterator i = to_ripple.begin(); i != to_ripple.end(); ++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); + + // XXX without the following, things jump in the y direction during drags + // with it, they jump in the x direction + // so we need to do the move in the y direction only + // rvg->move (rv_canvas_offset - dmg_canvas_offset); + std::cerr << "rv_canvas_offset = " << rv_canvas_offset << ", dmg_canvas_offset = " << dmg_canvas_offset << std::endl; + 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(framecnt_t amount, bool move_regions) +{ + + for (std::list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ) { + // we added all the regions after the selection + + std::list<DraggingView>::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<RouteTimeAxisView*> (tv); + assert (rtv); + + std::cerr << "rtv = " << rtv->name() << std::endl; + + // 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) { + // 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); + } + } +} + +bool +RegionRippleDrag::y_movement_allowed (int delta_track, double delta_layer) const +{ + if (RegionMotionDrag::y_movement_allowed (delta_track, delta_layer)) { + if (delta_track) { + return allow_moves_across_tracks; + } else { + return true; + } + } + return false; +} + +RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v) + : RegionMoveDrag (e, i, p, v, false, false) +{ + DEBUG_TRACE (DEBUG::Drags, "New RegionRippleDrag\n"); + // compute length of selection + RegionSelection selected_regions = _editor->selection->regions; + selection_length = selected_regions.end_frame() - selected_regions.start(); + + // we'll only allow dragging to another track in ripple mode if all the regions + // being dragged start off on the same track + allow_moves_across_tracks = (selected_regions.playlists().size() == 1); + 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()); + } + + // 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 + + std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists = copy.playlists(); + std::set<boost::shared_ptr<ARDOUR::Playlist> >::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)) { + // region is on this playlist - it's the first, because they're sorted + first_selected_on_this_track = *i; + break; + } + } + 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() + first_selected_on_this_track->region()->length(), + selected_regions, false); + } + + if (allow_moves_across_tracks) { + orig_tav = &(*selected_regions.begin())->get_time_axis_view(); + } else { + orig_tav = NULL; + } + +} + +void +RegionRippleDrag::motion (GdkEvent* event, bool first_move) +{ + /* Which trackview is this ? */ + + pair<TimeAxisView*, double> const tvp = _editor->trackview_by_y_position (current_pointer_y ()); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*> (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; + } + + framepos_t where = adjusted_current_frame (event); + assert (where >= 0); + framepos_t after; + double delta = compute_x_delta (event, &after); + + framecnt_t amount = _editor->pixel_to_sample (delta); + + if (allow_moves_across_tracks) { + // all the originally selected regions were on the same track + + framecnt_t adjust = 0; + if (prev_tav && tv != prev_tav) { + // dragged onto a different track + // remove the unselected regions from _views, restore them to their original positions + // and add the regions after the drop point on the new playlist to _views instead. + // undo the effect of rippling the previous playlist, and include the effect of removing + // the dragged region(s) from this track + std::cerr << "dragged from " << prev_tav->name() << " to " << tv->name() << std::endl; + + remove_unselected_from_views (prev_amount, false); + // ripple previous playlist according to the regions that have been removed onto the new playlist + prev_tav->playlist()->ripple(prev_position, -selection_length, exclude); + prev_amount = 0; + + // move just the selected regions + RegionMoveDrag::motion(event, first_move); + + // ensure that the ripple operation on the new playlist inserts selection_length time + adjust = selection_length; + // ripple the new current playlist + tv->playlist()->ripple (where, amount+adjust, exclude); + + // add regions after point where drag entered this track to subsequent ripples + add_all_after_to_views (tv, where, _editor->selection->regions, true); + + } else { + // motion on same track + RegionMoveDrag::motion(event, first_move); + } + prev_tav = tv; + + // remember what we've done to this playlist so we can undo it if the selection is dragged to another track + prev_position = where; + } else { + // selection encompasses multiple tracks - just drag + // cross-track drags are forbidden + RegionMoveDrag::motion(event, first_move); + } + + if (!_x_constrained) { + prev_amount += amount; + } + + _last_frame_position = after; +} + +void +RegionRippleDrag::finished (GdkEvent* event, bool movement_occurred) +{ + if (!movement_occurred) { + return; + } + + _editor->begin_reversible_command(_("Ripple drag")); + + // remove the regions being rippled from the dragging view, updating them to + // their new positions + remove_unselected_from_views (prev_amount, true); + + if (allow_moves_across_tracks) { + if (orig_tav) { + // if regions were dragged across tracks, we've rippled any later + // regions on the track the regions were dragged off, so we need + // to add the original track to the undo record + std::cerr << "adding orig_tav " << orig_tav->name() << " to undo" << std::endl; + orig_tav->playlist()->clear_changes(); + vector<Command*> cmds; + orig_tav->playlist()->rdiff (cmds); + _editor->session()->add_commands (cmds); + } + if (prev_tav && prev_tav != orig_tav) { + std::cerr << "adding prev_tav " << prev_tav->name() << " to undo" << std::endl; + prev_tav->playlist()->clear_changes(); + vector<Command*> cmds; + prev_tav->playlist()->rdiff (cmds); + _editor->session()->add_commands (cmds); + } else if (prev_tav) { + std::cerr << "prev_tav == orig_tav" << std::endl; + } + } else { + // selection spanned multiple tracks - all will need adding to undo record + + std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists = _editor->selection->regions.playlists(); + std::set<boost::shared_ptr<ARDOUR::Playlist> >::const_iterator pi; + + for (pi = playlists.begin(); pi != playlists.end(); ++pi) { + + std::cerr << "adding playlist with selection " << (*pi)->name() << " to undo" << std::endl; + (*pi)->clear_changes(); + vector<Command*> cmds; + (*pi)->rdiff (cmds); + _editor->session()->add_commands (cmds); + } + + } + + + // 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 (); +} + + RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v) : Drag (e, i), _view (dynamic_cast<MidiTimeAxisView*> (v)) diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 476d98a2d4..d9eda5685a 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -316,7 +316,7 @@ public: protected: double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *); - bool y_movement_allowed (int, double) const; + virtual bool y_movement_allowed (int, double) const; bool _brushing; ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged @@ -349,9 +349,11 @@ public: void setup_pointer_frame_offset (); -private: +protected: typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > PlaylistSet; + void add_stateful_diff_commands_for_playlists (PlaylistSet const &); +private: void finished_no_copy ( bool const, bool const, @@ -378,7 +380,6 @@ private: PlaylistSet& modified_playlists ); - void add_stateful_diff_commands_for_playlists (PlaylistSet const &); void collect_new_region_view (RegionView *); RouteTimeAxisView* create_destination_time_axis (boost::shared_ptr<ARDOUR::Region>, TimeAxisView* original); @@ -412,6 +413,33 @@ public: void aborted (bool); }; +/** Region drag in ripple mode */ + +class RegionRippleDrag : public RegionMoveDrag +{ +public: + RegionRippleDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &); + ~RegionRippleDrag () { delete exclude; } + + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); +protected: + bool y_movement_allowed (int delta_track, double delta_layer) const; + +private: + TimeAxisView *prev_tav; // where regions were most recently dragged from + TimeAxisView *orig_tav; // where drag started + framecnt_t prev_amount; + framepos_t prev_position; + framecnt_t selection_length; + bool allow_moves_across_tracks; // only if all selected regions are on one track + ARDOUR::RegionList *exclude; + void add_all_after_to_views (TimeAxisView *tav, framepos_t where, const RegionSelection &exclude, bool drag_in_progress); + void remove_unselected_from_views (framecnt_t amount, bool move_regions); + +}; + /** Drags to create regions */ class RegionCreateDrag : public Drag { diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 634e383fa9..fffb67c46d 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2400,10 +2400,17 @@ Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region return; } - if (Config->get_edit_mode() == Splice) { - _drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer())); - } else { - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false)); + switch (Config->get_edit_mode()) { + case Splice: + _drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer())); + break; + case Ripple: + _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer())); + break; + default: + _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false)); + break; + } } @@ -2428,7 +2435,7 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* return; } - if (Config->get_edit_mode() == Splice) { + if (Config->get_edit_mode() == Splice || Config->get_edit_mode() == Ripple) { return; } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 4882ac1fc3..45568bdb3c 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2110,6 +2110,8 @@ Editor::unhide_ranges () } } +/* INSERT/REPLACE */ + void Editor::insert_region_list_selection (float times) { @@ -2142,6 +2144,9 @@ Editor::insert_region_list_selection (float times) begin_reversible_command (_("insert region")); playlist->clear_changes (); playlist->add_region ((RegionFactory::create (region, true)), get_preferred_edit_position(), times); + if (Config->get_edit_mode() == Ripple) + playlist->ripple (get_preferred_edit_position(), region->length() * times, boost::shared_ptr<Region>()); + _session->add_command(new StatefulDiffCommand (playlist)); commit_reversible_command (); } @@ -3726,7 +3731,7 @@ Editor::can_cut_copy () const /** Cut, copy or clear selected regions, automation points or a time range. - * @param op Operation (Cut, Copy or Clear) + * @param op Operation (Delete, Cut, Copy or Clear) */ void Editor::cut_copy (CutCopyOp op) @@ -3762,7 +3767,7 @@ Editor::cut_copy (CutCopyOp op) } } - if ( op != Clear ) //"Delete" doesn't change copy/paste buf + if ( op != Delete ) //"Delete" doesn't change copy/paste buf cut_buffer->clear (); if (entered_marker) { @@ -4002,10 +4007,11 @@ Editor::remove_clicked_region () boost::shared_ptr<Playlist> playlist = clicked_routeview->playlist(); - begin_reversible_command (_("remove region")); playlist->clear_changes (); playlist->clear_owned_changes (); playlist->remove_region (clicked_regionview->region()); + if (Config->get_edit_mode() == Ripple) + playlist->ripple (clicked_regionview->region()->position(), -clicked_regionview->region()->length(), boost::shared_ptr<Region>()); /* We might have removed regions, which alters other regions' layering_index, so we need to do a recursive diff here. @@ -4068,6 +4074,9 @@ Editor::remove_selected_regions () playlist->clear_owned_changes (); playlist->freeze (); playlist->remove_region (*rl); + if (Config->get_edit_mode() == Ripple) + playlist->ripple ((*rl)->position(), -(*rl)->length(), boost::shared_ptr<Region>()); + } vector<boost::shared_ptr<Playlist> >::iterator pl; @@ -4197,12 +4206,16 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs) switch (op) { case Delete: pl->remove_region (r); + if (Config->get_edit_mode() == Ripple) + pl->ripple (r->position(), -r->length(), boost::shared_ptr<Region>()); break; case Cut: _xx = RegionFactory::create (r); npl->add_region (_xx, r->position() - first_position); pl->remove_region (r); + if (Config->get_edit_mode() == Ripple) + pl->ripple (r->position(), -r->length(), boost::shared_ptr<Region>()); break; case Copy: @@ -4211,7 +4224,9 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs) break; case Clear: - pl->remove_region (r); + pl->remove_region (r); + if (Config->get_edit_mode() == Ripple) + pl->ripple (r->position(), -r->length(), boost::shared_ptr<Region>()); break; } diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index e6a8f59be0..55dbec5f8b 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -1413,6 +1413,10 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) switch (op) { case Delete: if (playlist->cut (time) != 0) { + if (Config->get_edit_mode() == Ripple) + playlist->ripple(time.start(), -time.length(), NULL); + // no need to exclude any regions from rippling here + vector<Command*> cmds; playlist->rdiff (cmds); _session->add_commands (cmds); @@ -1424,6 +1428,10 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) case Cut: if ((what_we_got = playlist->cut (time)) != 0) { _editor.get_cut_buffer().add (what_we_got); + if (Config->get_edit_mode() == Ripple) + playlist->ripple(time.start(), -time.length(), NULL); + // no need to exclude any regions from rippling here + vector<Command*> cmds; playlist->rdiff (cmds); _session->add_commands (cmds); @@ -1439,6 +1447,9 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) case Clear: if ((what_we_got = playlist->cut (time)) != 0) { + if (Config->get_edit_mode() == Ripple) + playlist->ripple(time.start(), -time.length(), NULL); + // no need to exclude any regions from rippling here vector<Command*> cmds; playlist->rdiff (cmds); @@ -1473,8 +1484,18 @@ RouteTimeAxisView::paste (framepos_t pos, float times, Selection& selection, siz DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("modified paste to %1\n", pos)); } - pl->clear_changes (); + pl->clear_changes (); + if (Config->get_edit_mode() == Ripple) { + std::pair<framepos_t, framepos_t> extent = (*p)->get_extent(); + framecnt_t amount = extent.second - extent.first; + pl->ripple(pos, amount * times, boost::shared_ptr<Region>()); + } pl->paste (*p, pos, times); + + vector<Command*> cmds; + pl->rdiff (cmds); + _session->add_commands (cmds); + _session->add_command (new StatefulDiffCommand (pl)); return true; |