Roll: reversed clips take the cut from the opposite source end (#526)

This commit is contained in:
MarekSpodBiedry committed 2026-10-10 09:14:03 +02:00
1 parent 7bd7621262
commit 0c66f5ffd3
2 files changed
+35 -4

No files matched your search

+17 -4
View File
@@ -751,10 +751,19 @@ pub fn roll(seq: &mut Sequence, left: ClipId, right: ClipId, delta: Tick, ctx: &
let mut d = delta;
// left out-point limits
d = d.max(-(l.duration - ctx.min_duration)).min(r.duration - ctx.min_duration);
if let Some(m) = media_len(ctx, l) {
// a reversed clip consumes media from the opposite end, so its media limit is the other one
if l.reverse {
d = d.min(Tick((head(ctx, l).0 as f64 / l.speed.abs()).floor() as i64));
} else if let Some(m) = media_len(ctx, l) {
d = d.min(Tick(((m - l.source_out()).0 as f64 / l.speed.abs()).floor() as i64));
}
d = d.max(-Tick((head(ctx, r).0 as f64 / r.speed.abs()).floor() as i64));
if r.reverse {
if let Some(m) = media_len(ctx, r) {
d = d.max(-Tick(((m - r.source_out()).0 as f64 / r.speed.abs()).floor() as i64));
}
} else {
d = d.max(-Tick((head(ctx, r).0 as f64 / r.speed.abs()).floor() as i64));
}
if d == Tick::ZERO {
return Ok(d);
}
@@ -762,15 +771,19 @@ pub fn roll(seq: &mut Sequence, left: ClipId, right: ClipId, delta: Tick, ctx: &
let before = seq.clone();
{
let (_, l) = seq.find_item_mut(left).ok_or(EditError::NoItem(left))?;
if l.reverse {
l.source_in -= src_of(d, ls);
}
l.duration += d;
}
{
let (_, r) = seq.find_item_mut(right).ok_or(EditError::NoItem(right))?;
r.start += d;
r.duration -= d;
r.source_in += src_of(d, rs);
if !r.reverse {
r.source_in += src_of(d, rs);
}
}
let _ = ls;
transitions_follow_cuts(&before, seq);
Ok(d)
}
+18
View File
@@ -673,3 +673,21 @@ fn shorter_head_closes_the_stretch_after_the_cut_on_sync_locked_tracks() {
assert_eq!(fx.spans(v1), vec![(0, 10), (10, 10), (20, 10)], "unchanged on failure");
}
}
#[test]
fn roll_reversed_clips_keeps_media_mapping() {
let mut fx = Fx::new();
let v = fx.v(0);
let mut a = fx.item(0, 30, 20);
a.reverse = true;
let mut b = fx.item(30, 30, 50);
b.reverse = true;
let (ia, ib) = (a.id, b.id);
fx.seq.track_mut(v).unwrap().items.extend([a, b]);
let mut n = 0;
roll(&mut fx.seq, ia, ib, f(10), &mut Fx::ctx(&mut n)).unwrap();
let (_, l) = fx.seq.find_item(ia).unwrap();
assert_eq!((l.start, l.duration, l.source_in), (f(0), f(40), f(10)));
let (_, r) = fx.seq.find_item(ib).unwrap();
assert_eq!((r.start, r.duration, r.source_in), (f(40), f(20), f(50)));
}