Slide: keep reversed neighbours' source ranges correct (#548)

This commit is contained in:
MarekSpodBiedry committed 2026-10-10 09:14:35 +02:00
1 parent 7bd7621262
commit 1ccb51fb78
2 files changed
+37 -3

No files matched your search

+18 -3
View File
@@ -799,7 +799,10 @@ pub fn slide(seq: &mut Sequence, clip: ClipId, delta: Tick, ctx: &mut EditCtx) -
let mut d = delta;
if let Some(p) = &prev {
d = d.max(-(p.duration - ctx.min_duration));
if let Some(m) = media_len(ctx, p) {
if p.reverse {
// a reversed neighbour grows by pulling earlier media in front of its source In
d = d.min(Tick((head(ctx, p).0 as f64 / p.speed.abs()).floor() as i64));
} else if let Some(m) = media_len(ctx, p) {
d = d.min(Tick(((m - p.source_out()).0 as f64 / p.speed.abs()).floor() as i64));
}
} else {
@@ -807,7 +810,14 @@ pub fn slide(seq: &mut Sequence, clip: ClipId, delta: Tick, ctx: &mut EditCtx) -
}
if let Some(n) = &next {
d = d.min(n.duration - ctx.min_duration);
d = d.max(-Tick((head(ctx, n).0 as f64 / n.speed.abs()).floor() as i64));
if n.reverse {
// a reversed neighbour grows leftwards by pulling later media behind its source Out
if let Some(m) = media_len(ctx, n) {
d = d.max(-Tick(((m - n.source_out()).0 as f64 / n.speed.abs()).floor() as i64));
}
} else {
d = d.max(-Tick((head(ctx, n).0 as f64 / n.speed.abs()).floor() as i64));
}
} else {
d = d.min(neighbours(tr, clip).1 - it.end());
}
@@ -819,12 +829,17 @@ pub fn slide(seq: &mut Sequence, clip: ClipId, delta: Tick, ctx: &mut EditCtx) -
if let Some(p) = prev {
let pi = t.item_mut(p.id).ok_or(EditError::NoItem(p.id))?;
pi.duration += d;
if p.reverse {
pi.source_in -= src_of(d, p.speed);
}
}
if let Some(n) = next {
let ni = t.item_mut(n.id).ok_or(EditError::NoItem(n.id))?;
ni.start += d;
ni.duration -= d;
ni.source_in += src_of(d, n.speed);
if !n.reverse {
ni.source_in += src_of(d, n.speed);
}
}
let me = t.item_mut(clip).ok_or(EditError::NoItem(clip))?;
me.start += d;
+19
View File
@@ -359,6 +359,25 @@ fn roll_slip_slide() {
fx.seq.check().unwrap();
}
#[test]
fn slide_keeps_reversed_neighbours_content() {
let mut fx = Fx::new();
let v1 = fx.v(0);
let a = fx.put(v1, 0, 30, 20);
let b = fx.put(v1, 30, 30, 50);
let c = fx.put(v1, 60, 30, 70);
for id in [a, c] {
fx.seq.find_item_mut(id).unwrap().1.reverse = true;
}
let mut n = fx.next;
slide(&mut fx.seq, b, f(10), &mut Fx::ctx(&mut n)).unwrap();
assert_eq!(fx.spans(v1), vec![(0, 40), (40, 30), (70, 20)]);
assert_eq!(fx.seq.find_item(a).unwrap().1.source_in, f(10));
assert_eq!(fx.seq.find_item(b).unwrap().1.source_in, f(50));
assert_eq!(fx.seq.find_item(c).unwrap().1.source_in, f(70));
fx.seq.check().unwrap();
}
#[test]
fn transitions_stay_on_their_cuts() {
let mut fx = Fx::new();