1use anathema::component::*;
2use anathema::prelude::*;
3
4struct App;
5
6#[derive(State)]
7struct AppState {
8 number: Value<i32>,
9}
10
11impl Component for App {
12 type Message = ();
13 type State = AppState;
14
15 const TICKS: bool = false;
16
17 fn on_event(
18 &mut self,
19 event: &mut UserEvent<'_>,
20 state: &mut Self::State,
21 _: Children<'_, '_>,
22 _: Context<'_, '_, Self::State>,
23 ) {
24 if event.name() == "increment" {
25 *state.number.to_mut() += 1;
26 } else if event.name() == "decrement" {
27 *state.number.to_mut() -= 1;
28 }
29 }
30
31 fn accept_focus(&self) -> bool {
32 false
33 }
34}
35
36struct Button;
37
38#[derive(State)]
39struct ButtonState {
40 active: Value<u8>,
41}
42
43impl Component for Button {
44 type Message = ();
45 type State = ButtonState;
46
47 const TICKS: bool = false;
48
49 fn on_blur(&mut self, state: &mut Self::State, _: Children<'_, '_>, _: Context<'_, '_, Self::State>) {
50 state.active.set(0);
51 }
52
53 fn on_focus(&mut self, state: &mut Self::State, _: Children<'_, '_>, _: Context<'_, '_, Self::State>) {
54 state.active.set(1);
55 }
56
57 fn on_mouse(
58 &mut self,
59 mouse: MouseEvent,
60 _: &mut Self::State,
61 mut children: Children<'_, '_>,
62 mut context: Context<'_, '_, Self::State>,
63 ) {
64 let pos = mouse.pos();
65 children.elements().at_position(pos).first(|_, _| {
66 if mouse.left_down() {
67 context.publish("click", ());
68
69 let id = context.attributes.get_as::<i64>("id").unwrap();
70 context.components.by_attribute("id", id).focus();
71 }
72 });
73 }
74
75 fn on_key(
76 &mut self,
77 key: KeyEvent,
78 _: &mut Self::State,
79 _: Children<'_, '_>,
80 mut context: Context<'_, '_, Self::State>,
81 ) {
82 if !matches!(key.state, KeyState::Press) {
83 return;
84 }
85
86 if let KeyCode::Enter = key.code {
87 context.publish("click", ());
88 }
89 }
90}
91
92fn main() {
93 let doc = Document::new("@main");
94
95 let mut backend = TuiBackend::builder()
96 .enable_alt_screen()
97 .enable_raw_mode()
98 .clear()
99 .hide_cursor()
100 .enable_mouse()
101 .finish()
102 .unwrap();
103 backend.finalize();
104
105 let mut builder = Runtime::builder(doc, &backend);
106
107 builder
108 .component(
109 "main",
110 "examples/templates/buttons/buttons.aml",
111 App,
112 AppState { number: 0.into() },
113 )
114 .unwrap();
115
116 builder
117 .prototype(
118 "button",
119 "examples/templates/buttons/button.aml",
120 || Button,
121 || ButtonState { active: 0.into() },
122 )
123 .unwrap();
124
125 builder
126 .finish(&mut backend, |runtime, backend| runtime.run(backend))
127 .unwrap();
128}