improve rippling of marks to include any in the gap between the primary-dragged region and the one before it

This commit is contained in:
Paul Davis 2021-06-16 19:27:30 -06:00
parent fc5143772b
commit ac1d5bac0a
4 changed files with 69 additions and 46 deletions

View File

@ -586,6 +586,7 @@ public:
bool should_ripple () const;
void do_ripple (boost::shared_ptr<ARDOUR::Playlist>, samplepos_t, samplecnt_t, ARDOUR::RegionList* exclude, bool add_to_command);
void do_ripple (boost::shared_ptr<ARDOUR::Playlist>, samplepos_t, samplecnt_t, boost::shared_ptr<ARDOUR::Region> exclude, bool add_to_command);
void ripple_marks (boost::shared_ptr<ARDOUR::Playlist> target_playlist, samplepos_t at, samplecnt_t distance);
void add_region_marker ();
void clear_region_markers ();

View File

@ -1839,9 +1839,7 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const changed_t
/* Ripple marks & ranges if appropriate */
if (Config->get_edit_mode() == RippleAll) {
XMLNode& before (_editor->session()->locations()->get_state());
_editor->session()->locations()->ripple (extent_min, extent_max - extent_min, false, true);
_editor->session()->add_command (new MementoCommand<Locations> (*_editor->session()->locations(), &before, &_editor->session()->locations()->get_state()));
_editor->ripple_marks (_primary->region()->playlist(), extent_min, extent_max - extent_min);
}
/* If we've created new regions either by copying or moving
@ -2089,14 +2087,6 @@ RegionMoveDrag::finished_no_copy (
_editor->selection->set (new_views);
}
/* Ripple marks & ranges if appropriate */
if (Config->get_edit_mode() == RippleAll) {
XMLNode& before (_editor->session()->locations()->get_state());
_editor->session()->locations()->ripple (extent_min, -drag_delta, false, true);
_editor->session()->add_command (new MementoCommand<Locations> (*_editor->session()->locations(), &before, &_editor->session()->locations()->get_state()));
}
_editor->commit_reversible_command ();
/* We have futzed with the layering of canvas items on our streamviews.

View File

@ -9272,10 +9272,39 @@ Editor::do_ripple (boost::shared_ptr<Playlist> target_playlist, samplepos_t at,
/* Ripple marks & ranges if appropriate */
if (Config->get_edit_mode() == RippleAll) {
XMLNode& before (_session->locations()->get_state());
/* do not move locked markers, do notify */
_session->locations()->ripple (at, distance, false, true);
_session->add_command (new MementoCommand<Locations> (*_session->locations(), &before, &_session->locations()->get_state()));
if (Config->get_edit_mode() != RippleAll) {
cerr << "out here\n";
return;
}
ripple_marks (target_playlist, at, distance);
}
void
Editor::ripple_marks (boost::shared_ptr<Playlist> target_playlist, samplepos_t at, samplecnt_t distance)
{
/* in the target playlist, find the region before the target
* (implicitly given by @param at. Allow all markers that occur between
* the end of the region and @param at to move too. This is
* desired/expected by many (most?) ripple-edit using folk.
*/
boost::shared_ptr<RegionList> rl = target_playlist->region_list();
samplepos_t last_region_end_before_at = 0;
for (RegionList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
samplepos_t region_end = (*r)->position() + (*r)->length();
if (region_end > last_region_end_before_at && region_end < at) {
last_region_end_before_at = region_end;
}
}
if (last_region_end_before_at < at) {
at = last_region_end_before_at + 1;
}
XMLNode& before (_session->locations()->get_state());
/* do not move locked markers, do notify */
_session->locations()->ripple (at, distance, false, true);
_session->add_command (new MementoCommand<Locations> (*_session->locations(), &before, &_session->locations()->get_state()));
}

View File

@ -1616,47 +1616,50 @@ Locations::range_starts_at(samplepos_t pos, samplecnt_t slop, bool incl) const
void
Locations::ripple (samplepos_t at, samplecnt_t distance, bool include_locked, bool notify)
{
LocationList copy;
{
Glib::Threads::RWLock::WriterLock lm (_lock);
copy = locations;
}
for (LocationList::iterator i = locations.begin(); i != locations.end(); ++i) {
for (LocationList::iterator i = copy.begin(); i != copy.end(); ++i) {
/* keep session range markers covering entire region if
a ripple "extends" the session.
*/
if (distance > 0 && (*i)->is_session_range()) {
/* keep session range markers covering entire region if
a ripple "extends" the session.
*/
if (distance > 0 && (*i)->is_session_range()) {
/* Don't move start unless it occurs after the ripple point.
*/
if ((*i)->start() >= at) {
(*i)->set ((*i)->start() + distance, (*i)->end() + distance);
} else {
(*i)->set_end ((*i)->end() + distance);
}
/* Don't move start unless it occurs after the ripple point.
*/
if ((*i)->start() >= at) {
(*i)->set ((*i)->start() + distance, (*i)->end() + distance);
} else {
(*i)->set_end ((*i)->end() + distance);
}
continue;
}
bool locked = (*i)->locked();
if (locked) {
if (!include_locked) {
continue;
}
} else {
(*i)->unlock ();
}
bool locked = (*i)->locked();
if ((*i)->start() >= at) {
(*i)->set_start ((*i)->start() + distance);
if (locked) {
if (!include_locked) {
continue;
}
} else {
(*i)->unlock ();
if (!(*i)->is_mark()) {
(*i)->set_end ((*i)->end() + distance);
}
}
if ((*i)->start() >= at) {
(*i)->set_start ((*i)->start() + distance);
if (!(*i)->is_mark()) {
(*i)->set_end ((*i)->end() + distance);
}
}
if (locked) {
(*i)->lock();
}
if (locked) {
(*i)->lock();
}
}