message_passing/
message-passing.rs1use 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}