Skip to main content

message_passing/
message-passing.rs

1use anathema::backend::Backend;
2use anathema::backend::tui::TuiBackend;
3use anathema::component::{Children, Component, Context, MouseEvent};
4use anathema::runtime::Runtime;
5use anathema::state::{List, State, Value};
6use anathema::templates::Document;
7
8pub struct Index;
9
10impl Component for Index {
11    type Message = ();
12    type State = ();
13
14    fn on_mouse(
15        &mut self,
16        mouse: MouseEvent,
17        _: &mut Self::State,
18        mut children: Children<'_, '_>,
19        mut context: Context<'_, '_, Self::State>,
20    ) {
21        if mouse.left_down() {
22            children
23                .elements()
24                .at_position(mouse.pos())
25                .by_attribute("id", "button")
26                .first(|_, attr| {
27                    let Some(value) = attr.get_as::<&str>("id").map(|s| s.to_string()) else { return };
28                    context.components.by_name("messages").send(value);
29                });
30        }
31    }
32}
33
34#[derive(Default, State)]
35pub struct MessagesState {
36    messages: Value<List<String>>,
37    message_count: Value<usize>,
38}
39
40#[derive(Default)]
41pub struct Messages;
42
43impl Component for Messages {
44    type Message = String;
45    type State = MessagesState;
46
47    fn on_message(
48        &mut self,
49        message: Self::Message,
50        state: &mut Self::State,
51        _: Children<'_, '_>,
52        _: Context<'_, '_, Self::State>,
53    ) {
54        if state.messages.len() > 20 {
55            state.messages.pop_front();
56        }
57        let message_count = state.message_count.copy_value() + 1;
58        state.message_count.set(message_count);
59        state.messages.push_back(format!("{message_count} {message}"));
60    }
61}
62
63fn main() {
64    let doc = Document::new("@index");
65    let mut backend = TuiBackend::builder()
66        .enable_raw_mode()
67        .enable_mouse()
68        .hide_cursor()
69        .clear()
70        .finish()
71        .unwrap();
72    backend.finalize();
73
74    let mut builder = Runtime::builder(doc, &backend);
75
76    builder
77        .default::<Messages>("messages", "examples/templates/message-passing/messages.aml")
78        .expect("failed to register messages component");
79
80    builder
81        .component(
82            "index",
83            "examples/templates/message-passing/message_passing.aml",
84            Index,
85            (),
86        )
87        .expect("failed to register index component");
88
89    _ = builder.finish(&mut backend, |runtime, backend| runtime.run(backend));
90}