promkit_widgets/
checkbox.rs1use promkit_core::{Pane, PaneFactory, grapheme::StyledGraphemes};
2
3#[path = "checkbox/checkbox.rs"]
4mod inner;
5pub use inner::Checkbox;
6pub mod config;
7pub use config::Config;
8
9#[derive(Clone)]
16pub struct State {
17 pub checkbox: Checkbox,
19
20 pub config: Config,
22}
23
24impl PaneFactory for State {
25 fn create_pane(&self, width: u16, height: u16) -> Pane {
26 let f = |idx: usize| -> StyledGraphemes {
27 if self.checkbox.picked_indexes().contains(&idx) {
28 StyledGraphemes::from(format!("{} ", self.config.active_mark))
29 } else {
30 StyledGraphemes::from(format!("{} ", self.config.inactive_mark))
31 }
32 };
33
34 let height = match self.config.lines {
35 Some(lines) => lines.min(height as usize),
36 None => height as usize,
37 };
38
39 let matrix = self
40 .checkbox
41 .items()
42 .iter()
43 .enumerate()
44 .filter(|(i, _)| {
45 *i >= self.checkbox.position() && *i < self.checkbox.position() + height
46 })
47 .map(|(i, item)| {
48 if i == self.checkbox.position() {
49 StyledGraphemes::from_iter([
50 &StyledGraphemes::from(&self.config.cursor),
51 &f(i),
52 item,
53 ])
54 .apply_style(self.config.active_item_style)
55 } else {
56 StyledGraphemes::from_iter([
57 &StyledGraphemes::from(
58 " ".repeat(StyledGraphemes::from(&self.config.cursor).widths()),
59 ),
60 &f(i),
61 item,
62 ])
63 .apply_style(self.config.inactive_item_style)
64 }
65 })
66 .fold((vec![], 0), |(mut acc, pos), item| {
67 let rows = item.matrixify(width as usize, height, 0).0;
68 if pos < self.checkbox.position() + height {
69 acc.extend(rows);
70 }
71 (acc, pos + 1)
72 });
73
74 Pane::new(matrix.0, 0)
75 }
76}