Skip to main content

rab/tui/components/
dynamic_lines.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3
4use crate::tui::Component;
5
6/// A component that wraps a `Vec<String>` buffer that can be updated dynamically.
7/// Used for sections whose content changes each frame (pending text, status, etc.).
8pub struct DynamicLines {
9    lines: RefCell<Vec<String>>,
10}
11
12/// A Component wrapper around `Rc<DynamicLines>` for shared ownership.
13pub struct RcDynamicLines(pub Rc<DynamicLines>);
14
15impl Component for RcDynamicLines {
16    fn render(&self, width: usize) -> Vec<String> {
17        self.0.render(width)
18    }
19
20    fn invalidate(&mut self) {
21        // DynamicLines uses RefCell internally, so we can invalidate through Rc
22        self.0.clear_cache();
23    }
24}
25
26impl Clone for RcDynamicLines {
27    fn clone(&self) -> Self {
28        Self(self.0.clone())
29    }
30}
31
32impl DynamicLines {
33    pub fn new() -> Self {
34        Self {
35            lines: RefCell::new(Vec::new()),
36        }
37    }
38
39    /// Set the lines for this component.
40    pub fn set_lines(&self, new_lines: Vec<String>) {
41        *self.lines.borrow_mut() = new_lines;
42    }
43
44    /// Clear the lines.
45    pub fn clear(&self) {
46        self.lines.borrow_mut().clear();
47    }
48
49    /// Clear cached state (for Component::invalidate).
50    pub fn clear_cache(&self) {
51        // No cache to clear — always reads from current buffer.
52    }
53}
54
55impl Default for DynamicLines {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61impl Component for DynamicLines {
62    fn render(&self, _width: usize) -> Vec<String> {
63        self.lines.borrow().clone()
64    }
65
66    fn invalidate(&mut self) {
67        // No cache — always returns current buffer
68    }
69}