summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorColin Fletcher <colin.m.fletcher@googlemail.com>2014-07-01 19:10:47 +0100
committerColin Fletcher <colin.m.fletcher@googlemail.com>2014-07-01 19:10:47 +0100
commite5e12acc5698090f2c0c614385e457cc0b46fbb0 (patch)
tree3f4f28baba25f4e276d669d98ff485f7c51aa0b1 /gtk2_ardour
parent23e7cf10191270d70357ccf0ed9294f020c7b7ab (diff)
parentda65f3778c66dd2935709445c9a5dbd225296439 (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.cc10
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_actions.cc1
-rw-r--r--gtk2_ardour/editor_audio_import.cc3
-rw-r--r--gtk2_ardour/editor_drag.cc301
-rw-r--r--gtk2_ardour/editor_drag.h34
-rw-r--r--gtk2_ardour/editor_mouse.cc17
-rw-r--r--gtk2_ardour/editor_ops.cc23
-rw-r--r--gtk2_ardour/route_time_axis.cc23
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;