twitter_tool/ui_framework/
mod.rs1use crate::ui_framework::bounding_box::BoundingBox;
2use anyhow::Result;
3use crossterm::event::KeyEvent;
4use std::io::Stdout;
5
6pub mod bounding_box;
7pub mod scroll_buffer;
8
9pub trait Render {
10 fn should_render(&self) -> bool;
13
14 fn invalidate(&mut self);
17
18 fn render(&mut self, stdout: &mut Stdout, bounding_box: BoundingBox) -> Result<()>;
21
22 fn get_cursor(&self) -> (u16, u16);
23}
24
25pub trait Input {
26 fn handle_focus(&mut self);
27
28 fn handle_key_event(&mut self, event: &KeyEvent) -> bool;
31}
32
33pub struct Component<T: Render + Input> {
34 pub bounding_box: BoundingBox,
35 pub component: T,
36}
37
38impl<T: Render + Input> Component<T> {
39 pub fn new(component: T) -> Self {
40 Self {
41 bounding_box: BoundingBox::default(),
42 component,
43 }
44 }
45
46 pub fn render_if_necessary(&mut self, stdout: &mut Stdout) -> Result<()> {
47 if self.component.should_render() {
48 self.component.render(stdout, self.bounding_box)?;
49 }
50 Ok(())
51 }
52
53 pub fn get_cursor(&self) -> (u16, u16) {
54 let BoundingBox { left, top, .. } = self.bounding_box;
55 let relative = self.component.get_cursor();
56 (left + relative.0, top + relative.1)
57 }
58}