tuigui/widgets/
label.rs

1use crate::preludes::widget_creation::*;
2
3#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
4pub enum LabelStyle {
5    Single(Style),
6    PerLine(Vec<Style>),
7}
8
9#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10/// Label widget (literally just text)
11pub struct Label {
12    /// The label that is shown
13    pub label: String,
14    /// The style of the label content
15    pub style: LabelStyle,
16    /// Whether or not the label is allowed to expand infinitely on the X (columns) axis
17    pub expand_empty_cols: bool,
18    /// Minumum size for the label
19    required_size: Size,
20    /// Widget data
21    widget_data: WidgetData,
22}
23
24impl Label {
25    /// Create new label widget
26    pub fn new<S: ToString>(label: S, style: LabelStyle, expand_empty_cols: bool) -> Self {
27        let mut lbl = Self {
28            label: label.to_string(),
29            style,
30            expand_empty_cols,
31            required_size: Size::zero(),
32            widget_data: WidgetData::new(),
33        };
34
35        lbl.adjust_size_needed();
36
37        return lbl;
38    }
39
40    /// Set label text
41    pub fn set_label<S: ToString>(&mut self, label: S) {
42        self.label = label.to_string();
43        self.adjust_size_needed();
44    }
45
46    fn adjust_size_needed(&mut self) {
47        let mut cols: u16 = 0;
48        let mut rows: u16 = 0;
49
50        for line in self.label.trim().lines() {
51            rows += 1;
52
53            let char_count: u16 = line.chars().count() as u16;
54
55            if char_count > cols {
56                cols = char_count;
57            }
58        }
59
60        self.required_size = Size::new(cols, rows);
61    }
62}
63
64impl Widget for Label {
65    fn draw(&mut self, canvas: &mut Canvas, _state_frame: Option<&EventStateFrame>) {
66        for (i_line, line) in self.label.trim().lines().enumerate() {
67            for (i, c) in line.chars().enumerate() {
68                canvas.set(Position::new(i as i16, i_line as i16), Some(Content::Styled(c, match self.style {
69                    LabelStyle::Single(ref style) => style.clone(),
70                    LabelStyle::PerLine(ref styles) => styles.get(i_line).unwrap_or(&styles[styles.len() - 1]).clone(),
71                })));
72            }
73        }
74    }
75
76    fn widget_info(&self) -> WidgetInfo {
77        WidgetInfo {
78            size_info: WidgetSizeInfo::Dynamic {
79                min: Some(self.required_size),
80                max: Some(Size::new(match self.expand_empty_cols {
81                    true => u16::MAX,
82                    false => self.required_size.cols,
83                }, self.required_size.rows)),
84            }
85        }
86    }
87
88    fn widget_data(&mut self) -> &mut WidgetData {
89        return &mut self.widget_data;
90    }
91}