tuigui 0.23.0

An easy-to-use, highly extensible, and speedy TUI library.
Documentation
use crate::preludes::widget_creation::*;

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum LabelStyle {
    Single(Style),
    PerLine(Vec<Style>),
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
/// Label widget (literally just text)
pub struct Label {
    /// The label that is shown
    pub label: String,
    /// The style of the label content
    pub style: LabelStyle,
    /// Whether or not the label is allowed to expand infinitely on the X (columns) axis
    pub expand_empty_cols: bool,
    /// Minumum size for the label
    required_size: Size,
    /// Widget data
    widget_data: WidgetData,
}

impl Label {
    /// Create new label widget
    pub fn new<S: ToString>(label: S, style: LabelStyle, expand_empty_cols: bool) -> Self {
        let mut lbl = Self {
            label: label.to_string(),
            style,
            expand_empty_cols,
            required_size: Size::zero(),
            widget_data: WidgetData::new(),
        };

        lbl.adjust_size_needed();

        return lbl;
    }

    /// Set label text
    pub fn set_label<S: ToString>(&mut self, label: S) {
        self.label = label.to_string();
        self.adjust_size_needed();
    }

    fn adjust_size_needed(&mut self) {
        let mut cols: u16 = 0;
        let mut rows: u16 = 0;

        for line in self.label.trim().lines() {
            rows += 1;

            let char_count: u16 = line.chars().count() as u16;

            if char_count > cols {
                cols = char_count;
            }
        }

        self.required_size = Size::new(cols, rows);
    }
}

impl Widget for Label {
    fn draw(&mut self, canvas: &mut Canvas, _state_frame: Option<&EventStateFrame>) {
        for (i_line, line) in self.label.trim().lines().enumerate() {
            for (i, c) in line.chars().enumerate() {
                canvas.set(Position::new(i as i16, i_line as i16), Some(Content::Styled(c, match self.style {
                    LabelStyle::Single(ref style) => style.clone(),
                    LabelStyle::PerLine(ref styles) => styles.get(i_line).unwrap_or(&styles[styles.len() - 1]).clone(),
                })));
            }
        }
    }

    fn widget_info(&self) -> WidgetInfo {
        WidgetInfo {
            size_info: WidgetSizeInfo::Dynamic {
                min: Some(self.required_size),
                max: Some(Size::new(match self.expand_empty_cols {
                    true => u16::MAX,
                    false => self.required_size.cols,
                }, self.required_size.rows)),
            }
        }
    }

    fn widget_data(&mut self) -> &mut WidgetData {
        return &mut self.widget_data;
    }
}