graphic design tool
git clone https://git.lucas.co/cce-designer.git
feat: Ctrl+Up rewinds the playbar to the start frame and pauses it
A frame_start command in the Playbar context: stops a moving timeline in
either direction and lands the playhead on the start frame; from a stop it
is a plain jump. Ctrl+Up was unbound.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
src/app.rs | 8 ++++++++
src/command.rs | 4 ++++
src/main.rs | 37 +++++++++++++++++++++++++++++++++++++
src/shortcut.rs | 1 +
4 files changed, 50 insertions(+)
diff --git a/src/app.rs b/src/app.rs
index 941391f..90bf050 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -6953,6 +6953,14 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
let pb = self.slots.playbar.inner_mut();
pb.current_frame = (pb.current_frame.round() + step).clamp(pb.start_frame, pb.end_frame);
}
+ // Rewind: pause whatever is playing and land on the start frame.
+ // The scene rebuild follows from tick_frame's last_sim_frame
+ // diff, as for the steps above.
+ Action::FrameStart => {
+ let pb = self.slots.playbar.inner_mut();
+ pb.playing = false;
+ pb.current_frame = pb.start_frame;
+ }
}
if settings_changed {
self.save_settings();
diff --git a/src/command.rs b/src/command.rs
index c4fb609..c6b0a29 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -208,6 +208,10 @@ pub const COMMANDS: &[Command] = &[
Command { id: "play_pause_reverse", label: "Play / Pause Reverse", context: Context::Playbar, run: Run::Key(Action::PlayPauseReverse), default_chord: Some("Down") },
Command { id: "frame_next", label: "Next Frame", context: Context::Playbar, run: Run::Key(Action::FrameNext), default_chord: Some("Right") },
Command { id: "frame_prev", label: "Previous Frame", context: Context::Playbar, run: Run::Key(Action::FramePrev), default_chord: Some("Left") },
+ // Ctrl+Up rewinds: stops a moving timeline and lands on the start frame,
+ // the way a transport's stop-to-start does — one press whatever the
+ // timeline is doing.
+ Command { id: "frame_start", label: "Go To Start Frame", context: Context::Playbar, run: Run::Key(Action::FrameStart), default_chord: Some("Ctrl+Up") },
];
pub fn by_id(id: &str) -> Option<&'static Command> {
diff --git a/src/main.rs b/src/main.rs
index 8c161f9..05edda4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1384,6 +1384,43 @@ mod tests {
assert_eq!(m.match_command(&plain, &Key::Named(NamedKey::ArrowDown)), Some("play_pause_reverse"));
}
+ /// Ctrl+Up rewinds: a moving timeline stops and the playhead lands on
+ /// the start frame, from wherever it was and in either direction; from a
+ /// stop it is simply a jump to the start.
+ #[test]
+ fn ctrl_up_rewinds_to_the_start_frame_and_pauses() {
+ use crate::command::by_id;
+ let cmd = by_id("frame_start").expect("no frame_start command");
+ assert_eq!(cmd.default_chord, Some("Ctrl+Up"));
+ assert_eq!(cmd.context, crate::command::Context::Playbar);
+
+ let mut state = State::new(false);
+ {
+ let pb = state.slots.playbar.inner_mut();
+ pb.start_frame = 1.0;
+ pb.end_frame = 48.0;
+ pb.current_frame = 17.5;
+ pb.playing = true;
+ pb.reversed = true;
+ }
+ assert!(state.run_command("frame_start"));
+ {
+ let pb = state.slots.playbar.inner();
+ assert!(!pb.playing, "a moving timeline stops");
+ assert_eq!(pb.current_frame, 1.0, "and lands on the start frame");
+ }
+ // Stopped, mid-timeline: a plain jump.
+ state.slots.playbar.inner_mut().current_frame = 30.0;
+ state.run_command("frame_start");
+ assert_eq!(state.slots.playbar.inner().current_frame, 1.0);
+ assert!(!state.slots.playbar.inner().playing);
+ // Whatever the start frame is.
+ state.slots.playbar.inner_mut().start_frame = 5.0;
+ state.slots.playbar.inner_mut().current_frame = 30.0;
+ state.run_command("frame_start");
+ assert_eq!(state.slots.playbar.inner().current_frame, 5.0);
+ }
+
/// Either play toggle pauses a moving timeline; direction only chooses
/// what starts from a stop — and the reverse tick runs the frame counter
/// down, wrapping start→end.
diff --git a/src/shortcut.rs b/src/shortcut.rs
index 1719b7c..d677b1a 100644
--- a/src/shortcut.rs
+++ b/src/shortcut.rs
@@ -36,6 +36,7 @@ pub enum Action {
PlayPauseReverse,
FrameNext,
FramePrev,
+ FrameStart,
Undo,
Redo,
/// Open the command palette — a command like any other, so it is