mode/
mode.rs

1/**
2This is an example implementing a simple mode-based keybinding input using
3conditional widget rendering. This simple example waits for the user to push 'k'
4and then shows that they are in the 'keybindings' mode. Then, when pressing 'q'
5the program will exit. The user can also go back to the 'none' mode by pressing 'esc'
6*/
7use std::io;
8
9use ascii_forge::prelude::*;
10use ascii_forge::widgets::border::Border;
11use widget_forge::prelude::*;
12
13#[derive(Clone, Copy, PartialEq, Eq)]
14pub enum AppState {
15    None,
16    Keybinds,
17}
18
19pub struct Data {
20    state: AppState,
21    should_exit: bool,
22}
23
24impl Default for Data {
25    fn default() -> Self {
26        Self {
27            state: AppState::None,
28            should_exit: false,
29        }
30    }
31}
32
33// This test will update the state to exit when the user pushes 'q'
34fn quit_test(w: &mut Window, d: &mut Data) {
35    if event!(w, Event::Key(e) => e.code == KeyCode::Char('q')) {
36        d.should_exit = true;
37    }
38}
39
40// This test will enter the user into the correct mode when pressing 'k'
41fn keybinds_test(w: &mut Window, d: &mut Data) {
42    if event!(w, Event::Key(e) => e.code == KeyCode::Char('k')) {
43        d.state = AppState::Keybinds;
44    }
45}
46
47// This test will take the user back to the 'none' mode if they press a key
48fn back_test(w: &mut Window, d: &mut Data) {
49    if event!(w, Event::Key(e) => e.code == KeyCode::Esc) {
50        d.state = AppState::None;
51    }
52}
53
54// This will render the state info to the screen
55fn render_state(w: &mut Window, d: &mut Data) {
56    let text = match d.state {
57        AppState::None => "None".stylize(),
58        AppState::Keybinds => "Keybinds".green(),
59    };
60
61    let center = vec2(w.size().x / 2, w.size().y / 2);
62
63    render!(w,
64        vec2(center.x - 12, center.y - 5) => [Border::square(24, 10)],
65        vec2(center.x - text.content().len() as u16 / 2, center.y) => [text]
66    );
67}
68
69pub fn main() -> io::Result<()> {
70    let window = Window::init()?;
71    handle_panics();
72    Scene::new(window, Data::default())
73        .insert_widget(render_state)
74        .insert_conditional_widgets(|_w, d| d.state == AppState::None, (keybinds_test,))
75        .insert_conditional_widgets(
76            |_w, d| d.state == AppState::Keybinds,
77            (quit_test, back_test),
78        )
79        .run(100, |scene| !scene.data_mut().should_exit)?;
80    Ok(())
81}