iced_pancurses/
sandbox.rs

1use crate::PancursesRenderer;
2use iced_native::{Cache, Container, Element, Length, UserInterface};
3
4pub trait Sandbox: Sized {
5    type Message: std::fmt::Debug + Send + Clone + 'static;
6
7    /// Initializes the Sanbox
8    ///
9    /// Should return the initial state of the sandbox
10    fn new() -> Self;
11
12    /// Handles the dispatch of a message and updates the state of the sandbox
13    ///
14    /// This function should define the update logic.
15    /// All messages produced by user interaction will be handled here.
16    fn update(&mut self, messages: Vec<Self::Message>);
17
18    /// Request drawing the new state of the UI
19    ///
20    /// Returns the root element to display using the renderer
21    fn view(&mut self) -> Element<'_, Self::Message, PancursesRenderer>;
22
23    /// Launches the sandbox and takes ownership of the current thread.
24    ///
25    /// This should be the last thing you execute at the end of the entrypoint of
26    /// your program.
27    fn run() {
28        // Creates the sandbox and its renderer
29        let mut renderer = PancursesRenderer::default();
30        let mut state = Self::new();
31
32        let mut cache = Some(Cache::default());
33
34        loop {
35            renderer.flush();
36            let size = renderer.size();
37            // Consumes the cache and renders the UI to primitives
38            let view: Element<'_, Self::Message, PancursesRenderer> = Container::new(state.view())
39                .width(Length::Units(size.0))
40                .height(Length::Units(size.1))
41                .into();
42            let mut ui = UserInterface::build(view, cache.take().unwrap(), &mut renderer);
43
44            // Displays the new state of the sandbox using the renderer
45            let primitives = ui.draw(&mut renderer);
46            renderer.draw(primitives);
47
48            // Polls pancurses events and apply them on the ui
49            let messages = renderer
50                .handle()
51                .map(|events| ui.update(&renderer, events.into_iter()));
52
53            // Stores back the cache
54            cache = Some(ui.into_cache());
55
56            // Applies updates on the state with given messages if any
57            if let Some(messages) = messages {
58                state.update(messages);
59            }
60        }
61    }
62}