1use std::any::Any;
2
3use ratatui::{buffer::Buffer, layout::Rect};
4
5use crate::{
6 core::{InputEvent, RenderComponent},
7 windows::{alerts::AlertManager, menu::Menu},
8};
9
10pub trait AsAny {
11 fn as_any(&self) -> &dyn Any;
12}
13
14pub trait Render: AsAny {
15 fn render(&mut self, render_props: &RenderProps, buff: &mut Buffer, area: Rect);
16 fn into_component(self) -> RenderComponent
17 where
18 Self: Sized + 'static,
19 {
20 RenderComponent::new(self)
21 }
22
23 fn get_menu(&self) -> Option<Menu> {
24 None
25 }
26}
27
28pub trait FocusableRender: Render {
29 fn render(&mut self, render_props: &RenderProps, buff: &mut Buffer, area: Rect);
30
31 #[allow(unused_variables)]
32 fn render_footer(&mut self, render_props: &RenderProps, buff: &mut Buffer, area: Rect) {}
33
34 fn get_menu(&self) -> Option<Menu> {
35 None
36 }
37}
38
39impl<T: FocusableRender> Render for T {
40 fn render(&mut self, render_props: &RenderProps, buff: &mut Buffer, area: Rect) {
41 FocusableRender::render(self, render_props, buff, area)
42 }
43
44 fn into_component(self) -> RenderComponent
45 where
46 Self: Sized + 'static,
47 {
48 RenderComponent::new_focusable(self)
49 }
50
51 fn get_menu(&self) -> Option<Menu> {
52 FocusableRender::get_menu(self)
53 }
54}
55
56impl<T: Render + 'static> AsAny for T {
57 fn as_any(&self) -> &dyn Any {
58 self
59 }
60}
61
62impl<T: Render + 'static> From<T> for RenderComponent {
63 fn from(value: T) -> Self {
64 value.into_component()
65 }
66}
67
68pub trait RenderFactory {
69 fn render(&mut self) -> RenderComponent;
70}
71
72#[derive(Debug)]
73pub struct RenderProps<'a> {
74 pub is_focused: bool,
75 pub event: Option<InputEvent>,
76 pub event_buffer: Vec<InputEvent>,
77 pub alerts: &'a AlertManager,
78}
79
80pub trait RenderTimed {
81 fn is_visible(&self) -> bool;
82}