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)]
pub struct Label {
pub label: String,
pub style: LabelStyle,
pub expand_empty_cols: bool,
required_size: Size,
widget_data: WidgetData,
}
impl Label {
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;
}
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;
}
}