Skip to main content

repame_shell/
shortcuts.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3
4use repose_core::input::{Key, Modifiers};
5use repose_core::shortcuts::{self, Action};
6
7pub fn game_shortcut_map(
8    pause: &'static str,
9    restart: &'static str,
10    confirm: &'static str,
11) -> shortcuts::ShortcutMap {
12    shortcuts::ShortcutMap::new()
13        .bind(Key::Escape, Modifiers::default(), action_for(pause))
14        .bind(
15            Key::Character('r'),
16            Modifiers::default(),
17            action_for(restart),
18        )
19        .bind(Key::Enter, Modifiers::default(), action_for(confirm))
20}
21
22fn action_for(name: &'static str) -> Action {
23    Action::Custom(name.into())
24}
25
26#[derive(Default)]
27pub struct ShortcutEdges {
28    pub pause: bool,
29    pub restart: bool,
30    pub confirm: bool,
31}
32
33pub type SharedEdges = Rc<RefCell<ShortcutEdges>>;
34
35pub fn shared_edges() -> SharedEdges {
36    Rc::new(RefCell::new(ShortcutEdges::default()))
37}
38
39pub fn shortcut_handler(
40    edges: &SharedEdges,
41    pause: &'static str,
42    restart: &'static str,
43    confirm: &'static str,
44) -> shortcuts::Handler {
45    let inner = edges.clone();
46    Rc::new(move |action| {
47        let mut e = inner.borrow_mut();
48        match action {
49            Action::Custom(key) if key.as_ref() == pause => {
50                e.pause = true;
51                true
52            }
53            Action::Custom(key) if key.as_ref() == restart => {
54                e.restart = true;
55                true
56            }
57            Action::Custom(key) if key.as_ref() == confirm => {
58                e.confirm = true;
59                true
60            }
61            _ => false,
62        }
63    })
64}
65
66/// Compose the game map + edges handler once in the root view
67/// (mount-once under the hood: safe to call every frame on desktop,
68/// web, and Android-with-keyboard alike). One call per game; no
69/// per-key duplication at call sites.
70pub fn install_game_shortcuts(
71    edges: &SharedEdges,
72    pause: &'static str,
73    restart: &'static str,
74    confirm: &'static str,
75) {
76    let _ = shortcuts::InstallShortcutMap(game_shortcut_map(pause, restart, confirm));
77    let _ = shortcuts::InstallShortcutHandler(shortcut_handler(edges, pause, restart, confirm));
78}
79
80/// Overwrite the process-global default shortcut map (tests and headless
81/// compose without a runner use this path).
82pub fn install_map(map: shortcuts::ShortcutMap) {
83    shortcuts::set_default_map(map);
84}
85
86/// Install only the action handler into long-lived `edges`
87/// (tests and headless compose without a runner use this path).
88pub fn install_handler_into(
89    edges: &SharedEdges,
90    pause: &'static str,
91    restart: &'static str,
92    confirm: &'static str,
93) {
94    shortcuts::set(Some(shortcut_handler(edges, pause, restart, confirm)));
95}
96
97pub fn take(edges: &SharedEdges) -> (bool, bool, bool) {
98    let mut e = edges.borrow_mut();
99    (
100        std::mem::take(&mut e.pause),
101        std::mem::take(&mut e.restart),
102        std::mem::take(&mut e.confirm),
103    )
104}