agent_tui/daemon/
terminal_state.rs1use crate::core::{Component, Element, component_to_element, find_element_by_ref};
2use crate::terminal::{CursorPosition, ScreenBuffer, VirtualTerminal};
3
4pub struct TerminalState {
9 terminal: VirtualTerminal,
10 cached_elements: Vec<Element>,
11}
12
13impl TerminalState {
14 pub fn new(cols: u16, rows: u16) -> Self {
15 Self {
16 terminal: VirtualTerminal::new(cols, rows),
17 cached_elements: Vec::new(),
18 }
19 }
20
21 pub fn process(&self, data: &[u8]) {
22 self.terminal.process(data);
23 }
24
25 pub fn screen_text(&self) -> String {
26 self.terminal.screen_text()
27 }
28
29 pub fn screen_buffer(&self) -> ScreenBuffer {
30 self.terminal.screen_buffer()
31 }
32
33 pub fn cursor(&self) -> CursorPosition {
34 self.terminal.cursor()
35 }
36
37 pub fn size(&self) -> (u16, u16) {
38 self.terminal.size()
39 }
40
41 pub fn resize(&mut self, cols: u16, rows: u16) {
42 self.terminal.resize(cols, rows);
43 }
44
45 pub fn clear(&mut self) {
46 self.terminal.clear();
47 }
48
49 pub fn detect_elements(&mut self, cursor: &CursorPosition) -> &[Element] {
50 let buffer = self.terminal.screen_buffer();
51 let components = crate::core::analyze(&buffer, cursor);
52
53 self.cached_elements = components
54 .iter()
55 .filter(|c| c.role.is_interactive())
56 .enumerate()
57 .map(|(i, c)| component_to_element(c, i, cursor.row, cursor.col))
58 .collect();
59
60 &self.cached_elements
61 }
62
63 pub fn cached_elements(&self) -> &[Element] {
64 &self.cached_elements
65 }
66
67 pub fn find_element(&self, element_ref: &str) -> Option<&Element> {
68 find_element_by_ref(&self.cached_elements, element_ref)
69 }
70
71 pub fn analyze_screen(&self, cursor: &CursorPosition) -> Vec<Component> {
72 let buffer = self.terminal.screen_buffer();
73 crate::core::analyze(&buffer, cursor)
74 }
75}