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}