mermaid_cli/tui/state/
ui.rs1use ratatui::layout::{Constraint, Direction, Flex, Layout, Rect};
6use ratatui::text::Line;
7use rustc_hash::FxHashMap;
8
9use crate::tui::theme::Theme;
10use crate::tui::widgets::{ChatState, InputState};
11
12pub struct LayoutCache {
14 cached: Option<(u16, u16, u16, u16, u16, Vec<Rect>)>,
15}
16
17impl LayoutCache {
18 fn new() -> Self {
19 Self { cached: None }
20 }
21
22 pub fn get_main_layout(
23 &mut self,
24 area: Rect,
25 input_height: u16,
26 status_line_height: u16,
27 attachment_height: u16,
28 ) -> Vec<Rect> {
29 if let Some((w, h, ih, sh, ah, ref rects)) = self.cached
30 && w == area.width
31 && h == area.height
32 && ih == input_height
33 && sh == status_line_height
34 && ah == attachment_height
35 {
36 return rects.clone();
37 }
38
39 let layout = Layout::default()
40 .direction(Direction::Vertical)
41 .margin(0)
42 .spacing(0)
43 .flex(Flex::Start)
44 .constraints([
45 Constraint::Min(10),
46 Constraint::Length(status_line_height),
47 Constraint::Length(attachment_height),
48 Constraint::Length(input_height),
49 Constraint::Length(2),
50 ])
51 .split(area);
52
53 let layout_vec = layout.to_vec();
54 self.cached = Some((
55 area.width,
56 area.height,
57 input_height,
58 status_line_height,
59 attachment_height,
60 layout_vec.clone(),
61 ));
62 layout_vec
63 }
64}
65
66pub struct UIState {
68 pub chat_state: ChatState,
70 pub input_state: InputState,
72 pub theme: Theme,
74 pub selected_message: Option<usize>,
76 pub attachment_focused: bool,
78 pub selected_attachment: usize,
80 pub attachment_area_y: Option<u16>,
82 pub layout_cache: LayoutCache,
84 pub markdown_cache: FxHashMap<u64, Vec<Line<'static>>>,
86}
87
88impl UIState {
89 pub fn new() -> Self {
91 Self {
92 chat_state: ChatState::default(),
93 input_state: InputState::default(),
94 theme: Theme::dark(),
95 selected_message: None,
96 attachment_focused: false,
97 selected_attachment: 0,
98 attachment_area_y: None,
99 layout_cache: LayoutCache::new(),
100 markdown_cache: FxHashMap::default(),
101 }
102 }
103}
104
105impl Default for UIState {
106 fn default() -> Self {
107 Self::new()
108 }
109}