Show: a first animation set to With/After Previous plays when the slide appears (#631)

This commit is contained in:
Nikita Rakitin
2026-10-14 04:47:09 +03:00
parent 457406a7a5
commit 679ce03da4
+43 -6
View File
@@ -168,13 +168,13 @@ impl Show {
}
/// On entering a slide: auto-play its first step when it begins With/After Previous.
/// `ShowState` already starts such a step when it enters the slide (#631: asking it for the
/// next step again finished the step at once, so the slide appeared fully built), so only
/// its clock starts here. Autoplay previews start an On Click first step themselves.
fn after_enter(&mut self, doc: &Presentation, now: f64) {
let auto = self.timeline(doc).step_is_auto(0);
if auto || self.autoplay {
let a = self.state.next(doc);
if matches!(a, ShowAction::PlayStep(_)) {
self.step_start = now;
}
let started = self.state.playing || (self.autoplay && matches!(self.state.next(doc), ShowAction::PlayStep(_)));
if started {
self.step_start = now;
}
}
}
@@ -885,4 +885,41 @@ mod tests {
assert_eq!(tr.from, Some(0));
assert!(show.tex.is_none(), "the new slide gets a texture of its own instead of overwriting the old one");
}
fn deck_with_first_animation(start: deckcraft_model::anim::AnimStart) -> Presentation {
let mut s = deckcraft_engine::Session::with_new();
s.execute("slide.new", &json!({})).unwrap();
let mut doc = Presentation::clone(&s.active().unwrap().doc);
let slide = std::sync::Arc::make_mut(&mut doc.slides[1]);
let shape = slide.shapes[0].id;
slide.animations = vec![deckcraft_model::anim::Animation { shape, start, duration_ms: 3000, ..Default::default() }];
doc
}
#[test]
fn a_first_animation_after_or_with_previous_plays_when_the_slide_appears() {
// #631: it was started twice and the second start finished it, so the slide appeared
// fully built.
use deckcraft_model::anim::AnimStart;
for start in [AnimStart::AfterPrevious, AnimStart::WithPrevious] {
let doc = deck_with_first_animation(start);
// Starting the show on the slide.
let mut show = Show::new(&doc, 1, false, false);
show.after_enter(&doc, 5.0);
assert_eq!((show.state.step, show.state.playing), (0, true), "{start:?} from the start");
assert_eq!(show.step_start, 5.0);
// Arriving from the slide before.
let mut show = Show::new(&doc, 0, false, false);
let a = show.state.next(&doc);
assert!(matches!(a, ShowAction::Slide(1)));
assert!(show.apply(a, &doc, 7.0));
assert_eq!((show.state.step, show.state.playing), (0, true), "{start:?} on arrival");
}
// On Click still waits for the click.
let doc = deck_with_first_animation(AnimStart::OnClick);
let mut show = Show::new(&doc, 1, false, false);
show.after_enter(&doc, 5.0);
assert_eq!((show.state.step, show.state.playing), (0, false));
assert!(matches!(show.state.next(&doc), ShowAction::PlayStep(0)));
}
}