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:
@@ -90,20 +90,35 @@ impl BlockCore {
|
||||
self.range = TimeRange::new(self.in_(), out);
|
||||
}
|
||||
|
||||
/// Set the length, keeping the media out anchored (C++
|
||||
/// `Block::set_length_and_media_out`): the timeline in-point shifts
|
||||
/// so the out-point stays put, and the media in follows it.
|
||||
/// Set the length, keeping the timeline in-point and the media in-point
|
||||
/// anchored (C++ `Block::set_length_and_media_out`): the out-point
|
||||
/// shifts (and the media out follows it). The stored-range model has no
|
||||
/// track layout to derive the in-point from, so the caller arranges the
|
||||
/// neighbouring blocks explicitly when a different anchor is wanted.
|
||||
pub fn set_length_and_media_out(&mut self, length: Rational) {
|
||||
let out = self.in_() + self.length();
|
||||
self.range = TimeRange::new(out - length, out);
|
||||
self.media_in = self.range.in_();
|
||||
self.range = TimeRange::new(self.in_(), self.in_() + length);
|
||||
}
|
||||
|
||||
/// Set the length, keeping the media in anchored (C++
|
||||
/// `Block::set_length_and_media_in`): the in-point stays, the
|
||||
/// out-point shifts.
|
||||
/// Set the length, keeping the timeline in-point and the MEDIA OUT
|
||||
/// anchored (C++ `Block::set_length_and_media_in`): the media in-point
|
||||
/// moves by `old_length - length` so the media content end stays put
|
||||
/// while the timeline out-point follows the length.
|
||||
pub fn set_length_and_media_in(&mut self, length: Rational) {
|
||||
let delta = self.length() - length;
|
||||
self.range = TimeRange::new(self.in_(), self.in_() + length);
|
||||
self.media_in = self.media_in + delta;
|
||||
}
|
||||
|
||||
/// Set the length, keeping the timeline OUT-point and the media content
|
||||
/// between the two ends anchored: the in-point shifts by the length
|
||||
/// delta and the media in-point follows it, so the media out stays put
|
||||
/// too (the stored-range model's net for a head trim, where the C++
|
||||
/// derives the new in-point from the resized previous block).
|
||||
pub fn set_length_keeping_out(&mut self, length: Rational) {
|
||||
let delta = self.length() - length;
|
||||
let out = self.out();
|
||||
self.range = TimeRange::new(out - length, out);
|
||||
self.media_in = self.media_in + delta;
|
||||
}
|
||||
|
||||
/// Media out (in + length; C++ `Block::media_out`).
|
||||
|
||||
Reference in New Issue
Block a user