diff --git a/crates/engine/src/commands/time.rs b/crates/engine/src/commands/time.rs index 81197602..f98ea5ed 100644 --- a/crates/engine/src/commands/time.rs +++ b/crates/engine/src/commands/time.rs @@ -43,12 +43,17 @@ pub fn parse_display_time(s: &Session, comp: &Comp, text: &str, current: i64) -> let relative = text.trim().starts_with('+') || text.trim().starts_with('-'); if relative { Ok(parsed) + } else if st.time_display == TimeDisplayStyle::Frames + && let Ok(frame) = text.trim().parse::() + { + // Displayed digits are a plain frame count (00100 is frame 100, not 1 s) plus + // Start Numbering Frames At. + Ok(frame.saturating_sub(st.frame_start)) } else if st.time_display == TimeDisplayStyle::Frames { - // Displayed digits are composition frame plus Start Numbering Frames At. - Ok(parsed - st.frame_start) + Ok(parsed.saturating_sub(st.frame_start)) } else { // Displayed timecode includes the composition Start Timecode offset. - Ok(parsed - fr.frame_at(comp.display_start)) + Ok(parsed.saturating_sub(fr.frame_at(comp.display_start))) } } } diff --git a/crates/engine/src/tests_timeline.rs b/crates/engine/src/tests_timeline.rs index 88f7b9bd..a741f5ad 100644 --- a/crates/engine/src/tests_timeline.rs +++ b/crates/engine/src/tests_timeline.rs @@ -413,11 +413,7 @@ fn time_set_snaps_to_the_nearest_frame_and_ae_timecode() { #[test] fn time_set_keeps_the_frame_shown_in_the_current_time_field() { let mut s = Session::default(); - s.execute( - "comp.new", - json!({"name": "Example", "width": 64, "height": 64, "frameRate": 30, "duration": 0.6, "startTimecode": "0:00:00:05"}), - ) - .unwrap(); + s.execute("comp.new", json!({"name": "Example", "width": 64, "height": 64, "frameRate": 30, "duration": 0.6, "startTimecode": "0:00:00:05"})).unwrap(); let r = s.execute("time.set", json!({"frame": 0})).unwrap(); assert_eq!(r["display"], "0:00:00:05"); let r = s.execute("time.set", json!({"timecode": "0:00:00:05"})).unwrap(); @@ -433,6 +429,17 @@ fn time_set_keeps_the_frame_shown_in_the_current_time_field() { assert_eq!(r["frame"], 13); } +/// Frames display style: typed digits are a frame count, so 00100 is frame 100, not 1 s (#530). +#[test] +fn time_set_reads_frames_style_digits_as_a_frame_count() { + let mut s = Session::default(); + s.execute("comp.new", json!({"name": "Long", "width": 64, "height": 64, "frameRate": 30, "duration": 10})).unwrap(); + s.execute("file.projectSettings", json!({"timeDisplay": "frames"})).unwrap(); + let r = s.execute("time.set", json!({"timecode": "00100"})).unwrap(); + assert_eq!(r["frame"], 100); + assert_eq!(r["display"], "00100"); +} + #[test] fn separate_dimensions_split_and_rejoin() { let (mut s, l) = setup();