Skip to main content

promkit_widgets/
text.rs

1use promkit_core::{Pane, PaneFactory, grapheme::StyledGraphemes};
2
3#[path = "text/text.rs"]
4mod inner;
5pub use inner::Text;
6pub mod config;
7pub use config::Config;
8
9/// Represents the state of a text-based component within the application.
10///
11/// This state encapsulates the properties and
12/// behaviors specific to text handling,
13#[derive(Clone, Default)]
14pub struct State {
15    /// The text to be rendered.
16    pub text: Text,
17    /// Configuration for rendering and behavior.
18    pub config: Config,
19}
20
21impl State {
22    pub fn replace(&mut self, state: Self) {
23        *self = state;
24    }
25
26    pub fn replace_text(&mut self, text: Vec<StyledGraphemes>) {
27        self.text.replace_contents(text);
28    }
29}
30
31impl PaneFactory for State {
32    fn create_pane(&self, width: u16, height: u16) -> Pane {
33        let height = match self.config.lines {
34            Some(lines) => lines.min(height as usize),
35            None => height as usize,
36        };
37
38        let matrix = self
39            .text
40            .items()
41            .iter()
42            .enumerate()
43            .filter(|(i, _)| *i >= self.text.position() && *i < self.text.position() + height)
44            .map(|(_, item)| {
45                if let Some(style) = &self.config.style {
46                    item.clone().apply_style(*style)
47                } else {
48                    item.clone()
49                }
50            })
51            .fold((vec![], 0), |(mut acc, pos), item| {
52                let rows = item.matrixify(width as usize, height, 0).0;
53                if pos < self.text.position() + height {
54                    acc.extend(rows);
55                }
56                (acc, pos + 1)
57            });
58
59        Pane::new(matrix.0, 0)
60    }
61}