ratatui_kit/render/
tree.rs1use futures::{FutureExt, future::select};
2use std::io::{self};
3
4use crate::{
5 component::{ComponentHelperExt, InstantiatedComponent},
6 context::{ContextStack, SystemContext},
7 element::ElementExt,
8 props::AnyProps,
9 terminal::Terminal,
10};
11
12use super::ComponentDrawer;
13
14pub struct Tree<'a> {
15 root_component: InstantiatedComponent,
16 props: AnyProps<'a>,
17 system_context: SystemContext,
18}
19
20impl<'a> Tree<'a> {
21 pub(crate) fn new(mut props: AnyProps<'a>, helper: Box<dyn ComponentHelperExt>) -> Self {
22 Tree {
23 root_component: InstantiatedComponent::new(props.borrow(), helper),
24 props,
25 system_context: SystemContext::new(),
26 }
27 }
28
29 fn render(&mut self, terminal: &mut Terminal) -> io::Result<()> {
30 let mut component_context_stack = ContextStack::root(&mut self.system_context);
31 self.root_component
32 .update(terminal, &mut component_context_stack, self.props.borrow());
33
34 terminal
35 .draw(|frame| {
36 let area = frame.area();
37 let mut drawer = ComponentDrawer { frame, area };
38 self.root_component.draw(&mut drawer);
39 })
40 .expect("Failed to draw the terminal");
41 terminal.events()?;
42 Ok(())
43 }
44
45 async fn render_loop(&mut self, terminal: &mut Terminal) -> io::Result<()> {
46 loop {
47 self.render(terminal)?;
48 if self.system_context.should_exit() || terminal.received_ctrl_c() {
49 break;
50 }
51 select(self.root_component.wait().boxed(), terminal.wait().boxed()).await;
52 if terminal.received_ctrl_c() {
53 break;
54 }
55 }
56 Ok(())
57 }
58}
59
60pub(crate) fn render<E: ElementExt>(mut element: E, mut terminal: Terminal) -> io::Result<()> {
61 let helper = element.helper();
62 let mut tree = Tree::new(element.props_mut(), helper);
63 tree.render(&mut terminal)?;
64 Ok(())
65}
66
67pub(crate) async fn render_loop<E: ElementExt>(
68 mut element: E,
69 mut terminal: Terminal,
70) -> io::Result<()> {
71 let helper = element.helper();
72 let mut tree = Tree::new(element.props_mut(), helper);
73 tree.render_loop(&mut terminal).await?;
74 Ok(())
75}