ez_tui/components/mock/
indicator.rs1use crate::types::palette::EzPalette;
2use crate::{AttrValue, Attribute, MockComponent, MockProps, Props, Theme};
3use eztui_derive::MockProps;
4use ratatui::buffer::Buffer;
5use ratatui::layout::Rect;
6use ratatui::prelude::Alignment;
7use ratatui::style::Style;
8use ratatui::text::Line;
9use ratatui::widgets::{Paragraph, Widget};
10use std::fmt::Debug;
11
12#[derive(Debug, MockProps)]
14pub struct IndicatorMock {
15 props: Props,
16 styles: Vec<Style>,
17 current_style: usize,
18}
19
20impl IndicatorMock {
21 #[must_use]
23 pub fn with_palette(name: String, palette: &EzPalette) -> Self {
24 let style1 = Style::new().fg(palette.c900).bg(palette.c100);
25 let style2 = Style::new().fg(palette.c100).bg(palette.c900);
26 Self::init(name, style1, style2)
27 }
28 #[must_use]
30 pub fn with_palettes(name: String, palette_a: &EzPalette, palette_b: &EzPalette) -> Self {
31 let style1 = Style::new().fg(palette_a.c100).bg(palette_a.c900);
32 let style2 = Style::new().fg(palette_b.c900).bg(palette_b.c100);
33 Self::init(name, style1, style2)
34 }
35
36 fn init(name: String, style1: Style, style2: Style) -> Self {
37 let mut cpt = IndicatorMock {
38 props: Props::default(),
39 styles: vec![style1, style2],
40 current_style: 0,
41 };
42 cpt.props_mut().expect("self has props").set(
43 Attribute::Title,
44 AttrValue::Title((name, Alignment::Center)),
45 );
46 let style = cpt.styles[0];
47 cpt.props_mut()
48 .expect("self has props")
49 .set(Attribute::Style, AttrValue::Style(style));
50 cpt
51 }
52
53 pub fn cycle(&mut self) {
55 let new = self.current_style.wrapping_add(1);
56 self.current_style = if new >= self.styles.len() { 0 } else { new };
57 if let Some(style) = self.styles.get(self.current_style) {
58 let x = *style;
59 if let Some(props) = self.props_mut() {
60 props.set(Attribute::Style, AttrValue::Style(x));
61 }
62 }
63 }
64}
65
66impl MockComponent for IndicatorMock {
67 fn draw(&mut self, area: Rect, buf: &mut Buffer, _: &Theme) {
68 let (label, alignement) = self
69 .props()
70 .expect("self has props")
71 .get(Attribute::Title)
72 .and_then(|o| o.as_title().cloned())
73 .map_or((String::new(), Alignment::Center), |(title, align)| {
74 (format!(" {title} "), align)
75 });
76 let style = self
77 .props()
78 .expect("self has props")
79 .get(Attribute::Style)
80 .and_then(|o| o.as_style())
81 .unwrap_or_default();
82 Paragraph::new(Line::from(label).alignment(alignement).style(style))
83 .centered()
84 .render(area, buf);
85 }
86}