remove RegionRippleDrag
This used to be a distinct kind of drag, but ended up being refactored into something that happens during a regular drag. Has not been used in quite some time.
This commit is contained in:
parent
f679da4e1e
commit
d47b581cbb
|
@ -2488,7 +2488,6 @@ private:
|
||||||
friend class RegionCutDrag;
|
friend class RegionCutDrag;
|
||||||
friend class RegionDrag;
|
friend class RegionDrag;
|
||||||
friend class RegionMoveDrag;
|
friend class RegionMoveDrag;
|
||||||
friend class RegionRippleDrag;
|
|
||||||
friend class TrimDrag;
|
friend class TrimDrag;
|
||||||
friend class BBTRulerDrag;
|
friend class BBTRulerDrag;
|
||||||
friend class MeterMarkerDrag;
|
friend class MeterMarkerDrag;
|
||||||
|
|
|
@ -2286,338 +2286,6 @@ RegionInsertDrag::aborted (bool)
|
||||||
_views.clear ();
|
_views.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* ripple mode...
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
RegionRippleDrag::add_all_after_to_views(TimeAxisView *tav, timepos_t const & where, const RegionSelection &exclude, bool drag_in_progress)
|
|
||||||
{
|
|
||||||
|
|
||||||
boost::shared_ptr<RegionList> rl = tav->playlist()->regions_with_start_within (TimelineRange (where, timepos_t::max (where.time_domain()), 0));
|
|
||||||
|
|
||||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(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->get_drag_motion_group()->canvas_origin ();
|
|
||||||
rvg->reparent (_editor->get_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(timecnt_t const & amount, bool move_regions)
|
|
||||||
{
|
|
||||||
ThawList thawlist;
|
|
||||||
|
|
||||||
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->get_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);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
#warning NUTEMPO ALERT paul test this code in 5.x /* how can this work ... amount used to be in samples but ::move() expect pixels */
|
|
||||||
//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
|
|
||||||
{
|
|
||||||
if (RegionMotionDrag::y_movement_allowed (delta_track, delta_layer, skip_invisible)) {
|
|
||||||
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, TimeDomain td)
|
|
||||||
: RegionMoveDrag (e, i, p, v, false, td)
|
|
||||||
{
|
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New RegionRippleDrag\n");
|
|
||||||
// compute length of selection
|
|
||||||
RegionSelection selected_regions = _editor->get_selection().regions;
|
|
||||||
selection_length = selected_regions.start_time().distance (selected_regions.end_time());
|
|
||||||
|
|
||||||
// Rippling across tracks disabled. Rippling on all tracks is the way to go in the future.
|
|
||||||
allow_moves_across_tracks = false; // (selected_regions.playlists().size() == 1);
|
|
||||||
prev_tav = NULL;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
bool need_time_domain = true;
|
|
||||||
|
|
||||||
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...
|
|
||||||
|
|
||||||
TimeAxisView* tav = &first_selected_on_this_track->get_time_axis_view();
|
|
||||||
|
|
||||||
if (need_time_domain) {
|
|
||||||
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tav);
|
|
||||||
prev_amount = timecnt_t (rtav->route()->time_domain());
|
|
||||||
need_time_domain = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_all_after_to_views (tav, first_selected_on_this_track->region()->position(), selected_regions, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allow_moves_across_tracks) {
|
|
||||||
orig_tav = &(*selected_regions.begin())->get_time_axis_view();
|
|
||||||
for (std::list<DraggingView>::const_iterator it = _views.begin(); it != _views.end(); ++it) {
|
|
||||||
_orig_tav_ripples.push_back((*it).view->region());
|
|
||||||
}
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
timepos_t where = adjusted_current_time (event);
|
|
||||||
assert (!where.is_negative());
|
|
||||||
timepos_t after;
|
|
||||||
double delta = compute_x_delta (event, after);
|
|
||||||
|
|
||||||
timecnt_t amount = timecnt_t (pixel_to_time (delta), grab_time());
|
|
||||||
|
|
||||||
if (allow_moves_across_tracks) {
|
|
||||||
// all the originally selected regions were on the same track
|
|
||||||
|
|
||||||
timecnt_t adjust;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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 = timecnt_t (tv->route()->time_domain());
|
|
||||||
|
|
||||||
// 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->get_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_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_editor->begin_reversible_command(_("Ripple drag"));
|
|
||||||
|
|
||||||
// remove the regions being rippled from the dragging view, updating them to
|
|
||||||
// their new positions
|
|
||||||
|
|
||||||
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
|
|
||||||
orig_tav->playlist()->clear_changes();
|
|
||||||
orig_tav->playlist()->clear_owned_changes();
|
|
||||||
orig_tav->playlist()->freeze ();
|
|
||||||
|
|
||||||
remove_unselected_from_views (prev_amount, true);
|
|
||||||
|
|
||||||
std::list<boost::shared_ptr<Region> >::const_iterator it = _orig_tav_ripples.begin();
|
|
||||||
for (; it != _orig_tav_ripples.end(); ++it) {
|
|
||||||
const boost::shared_ptr<Region> r = *it;
|
|
||||||
bool found = false;
|
|
||||||
for (std::list<DraggingView>::const_iterator it = _views.begin(); it != _views.end(); ++it) {
|
|
||||||
if (it->view->region() == r) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
const timepos_t pos_after = r->position();
|
|
||||||
const timepos_t pos_before = pos_after + selection_length;
|
|
||||||
r->set_position(pos_before);
|
|
||||||
r->clear_changes();
|
|
||||||
r->set_position(pos_after);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
orig_tav->playlist()->thaw ();
|
|
||||||
|
|
||||||
vector<Command*> cmds;
|
|
||||||
orig_tav->playlist()->rdiff (cmds);
|
|
||||||
_editor->session()->add_commands (cmds);
|
|
||||||
}
|
|
||||||
if (prev_tav && prev_tav != orig_tav) {
|
|
||||||
prev_tav->playlist()->clear_changes();
|
|
||||||
vector<Command*> cmds;
|
|
||||||
prev_tav->playlist()->rdiff (cmds);
|
|
||||||
_editor->session()->add_commands (cmds);
|
|
||||||
}
|
|
||||||
} 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) {
|
|
||||||
(*pi)->clear_changes();
|
|
||||||
(*pi)->clear_owned_changes();
|
|
||||||
(*pi)->freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_unselected_from_views (prev_amount, true);
|
|
||||||
|
|
||||||
for (pi = playlists.begin(); pi != playlists.end(); ++pi) {
|
|
||||||
(*pi)->thaw();
|
|
||||||
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)
|
RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v)
|
||||||
: Drag (e, i, e->default_time_domain()),
|
: Drag (e, i, e->default_time_domain()),
|
||||||
_view (dynamic_cast<MidiTimeAxisView*> (v))
|
_view (dynamic_cast<MidiTimeAxisView*> (v))
|
||||||
|
|
|
@ -545,34 +545,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Region drag in ripple mode */
|
|
||||||
|
|
||||||
class RegionRippleDrag : public RegionMoveDrag
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RegionRippleDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, Temporal::TimeDomain Td);
|
|
||||||
~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, int skip_invisible = 0) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TimeAxisView *prev_tav; // where regions were most recently dragged from
|
|
||||||
TimeAxisView *orig_tav; // where drag started
|
|
||||||
Temporal::timecnt_t prev_amount;
|
|
||||||
Temporal::timepos_t prev_position;
|
|
||||||
Temporal::timecnt_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, Temporal::timepos_t const & where, const RegionSelection &exclude, bool drag_in_progress);
|
|
||||||
void remove_unselected_from_views (Temporal::timecnt_t const & amount, bool move_regions);
|
|
||||||
|
|
||||||
std::list<boost::shared_ptr<ARDOUR::Region> > _orig_tav_ripples;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** "Drag" to cut a region (action only on button release) */
|
/** "Drag" to cut a region (action only on button release) */
|
||||||
class RegionCutDrag : public Drag
|
class RegionCutDrag : public Drag
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user