fix(timeline): restore the C++ block length anchors and repair pointer edits
The two BlockCore length setters swapped their anchors relative to the C++ semantics they document, so the ported edit commands produced wrong geometry on the live UI paths: roll edits kept the seam still, slides left negative in-points, and trims wrote the timeline in-point into media_in (playing the wrong media content). Adopt three stored-range primitives in block.rs: - set_length_and_media_out: in fixed, out moves, media untouched (resize, trim-out, gaps growing rightward). - set_length_and_media_in: in fixed, out moves, media_in += old-new (resize-with-media-in, splice right half, ripple trim-in). - set_length_keeping_out (new): out fixed, in moves, media_in += old-new (trim-in body and out-neighbour, slide out-neighbour, ripple trim-in of the trailing block). Point every command at the primitive matching its intent (undopointer, undogeneral, undoripple, undosplit, graphops, cli, nodeops) and fix the two real defects the swap hid: - TrackReplaceBlockWithGapCommand grew a following gap rightward, swallowing whatever followed it: the "dragging one clip moves unrelated clips" regression. The gap now grows leftward over the removed block's span; regression test in domain_test. - The ripple/splice trims now advance media_in instead of rewriting it, and BlockSplitCommand writes both halves' ranges and media explicitly (the second half continues from the split point). Rewrite the KNOWN-SWAP expectations to the correct geometry (roll moves the seam, slide has no negative in-point, insert-gaps grows rightward, resize-with-media-in yields media_in = 20) and add the missing media assertions. TrackSlideCommand documents that the caller positions the sliding blocks (the stored model has no track layout).
This commit is contained in:
@@ -46,16 +46,27 @@ fn block_core_ranges() {
|
||||
core.set_out(Rational::new(9, 1));
|
||||
assert_eq!(core.length(), Rational::new(4, 1));
|
||||
|
||||
// media_out anchored: in shifts so out stays.
|
||||
// `set_length_and_media_out`: the in point (and the media in point)
|
||||
// stays, the out point follows the length.
|
||||
core.media_in = Rational::new(2, 1);
|
||||
core.set_length_and_media_out(Rational::new(3, 1));
|
||||
assert_eq!(core.out(), Rational::new(9, 1), "out stays put");
|
||||
assert_eq!(core.length(), Rational::new(3, 1));
|
||||
assert_eq!(core.in_(), Rational::new(5, 1), "in stays put");
|
||||
assert_eq!(core.out(), Rational::new(8, 1), "out follows the length");
|
||||
assert_eq!(core.media_in, Rational::new(2, 1), "media in untouched");
|
||||
|
||||
// media_in anchored: in stays, out shifts.
|
||||
// `set_length_and_media_in`: the in point stays while the media in
|
||||
// moves with the length (the media out is what stays anchored).
|
||||
core.set_length_and_media_in(Rational::new(4, 1));
|
||||
assert_eq!(core.in_(), Rational::new(6, 1), "in stays put");
|
||||
assert_eq!(core.in_(), Rational::new(5, 1), "in stays put");
|
||||
assert_eq!(core.length(), Rational::new(4, 1));
|
||||
assert_eq!(core.media_in, Rational::new(1, 1), "media in follows the length");
|
||||
|
||||
// `set_length_keeping_out`: the out point (and the media content end)
|
||||
// stays, the in point shifts.
|
||||
core.set_length_keeping_out(Rational::new(2, 1));
|
||||
assert_eq!(core.out(), Rational::new(9, 1), "out stays put");
|
||||
assert_eq!(core.in_(), Rational::new(7, 1), "in shifts");
|
||||
assert_eq!(core.media_in, Rational::new(3, 1), "media in follows the in point");
|
||||
}
|
||||
|
||||
/// block.rs: behavior constructors + node inputs.
|
||||
|
||||
Reference in New Issue
Block a user