use crate::component::{Component, EventCx, LayoutCx, MeasureCx};
use crate::event::Event;
use crate::geom::{Rect, Size};
use crate::layout::Constraint;
use crate::render::RenderCx;
use crate::style::{Style, TextWrap};
pub struct Label {
text: String,
style: Style,
id: Option<String>,
class: Option<String>,
}
impl Label {
pub fn new(text: impl Into<String>) -> Self {
Self {
text: text.into(),
style: Style::default(),
id: None,
class: None,
}
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn id(mut self, id: impl Into<String>) -> Self {
self.id = Some(id.into());
self
}
pub fn class(mut self, class: impl Into<String>) -> Self {
self.class = Some(class.into());
self
}
}
impl Component for Label {
fn render(&self, cx: &mut RenderCx) {
match cx.wrap {
TextWrap::None => {
let tw: u16 = self.text.chars().map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0) as u16).sum();
cx.cursor.x = cx.cursor.x.saturating_add(cx.align_offset(tw));
cx.text(&self.text);
}
TextWrap::Char => cx.line(&self.text),
}
}
fn measure(&self, constraint: Constraint, _cx: &mut MeasureCx) -> Size {
let max_w = constraint.max.width.max(1);
let mut line_width: u16 = 0;
let mut lines: u16 = 1;
for c in self.text.chars() {
let w = unicode_width::UnicodeWidthChar::width(c).unwrap_or(0) as u16;
if line_width + w > max_w {
lines += 1;
line_width = w;
} else {
line_width += w;
}
}
Size {
width: max_w.min(
self.text
.chars()
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0) as u16)
.sum(),
),
height: lines,
}
}
fn layout(&mut self, _rect: Rect, _cx: &mut LayoutCx) {
}
fn style(&self) -> Style {
self.style.clone()
}
fn id(&self) -> Option<&str> {
self.id.as_deref()
}
fn class(&self) -> Option<&str> {
self.class.as_deref()
}
fn focusable(&self) -> bool {
false
}
fn event(&mut self, _event: &Event, _cx: &mut EventCx) {}
}