use retroglyph_core::color::Style;
use super::Widget;
use crate::Surface;
use crate::align::Align;
use crate::text::draw_clipped;
#[derive(Clone, Copy, Debug)]
pub struct Text<'a> {
content: &'a str,
style: Style,
align: Align,
}
impl<'a> Text<'a> {
#[must_use]
pub fn new(content: &'a str) -> Self {
Self {
content,
style: Style::new(),
align: Align::Left,
}
}
#[must_use]
pub const fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
#[must_use]
pub const fn align(mut self, align: Align) -> Self {
self.align = align;
self
}
}
impl Widget for Text<'_> {
fn render(&self, surface: &mut Surface<'_>) {
let width = surface.width();
if width == 0 {
return;
}
let _ = draw_clipped(surface, (0, 0), width, self.content, self.align, self.style);
}
}
#[cfg(test)]
mod tests {
use retroglyph_core::color::Color;
use retroglyph_core::grid::{Grid, Pos, Rect};
use super::*;
#[test]
fn prints_the_content_in_the_given_style() {
let area = Rect::new(0, 0, 10, 1);
let mut grid = Grid::new(10, 1);
Text::new("hi")
.style(Style::new().fg(Color::WHITE))
.render(&mut Surface::new(&mut grid, area, 0));
assert_eq!(grid[Pos::new(0, 0)].glyph(), 'h');
assert_eq!(grid[Pos::new(1, 0)].glyph(), 'i');
assert_eq!(grid[Pos::new(0, 0)].style().foreground(), Color::WHITE);
}
#[test]
fn clips_to_area_width() {
let area = Rect::new(0, 0, 5, 1);
let mut grid = Grid::new(5, 1);
Text::new("a much longer message than fits").render(&mut Surface::new(&mut grid, area, 0));
assert_eq!(grid[Pos::new(4, 0)].glyph(), 'c'); }
#[test]
fn right_align_places_text_against_the_right_edge() {
let area = Rect::new(0, 0, 10, 1);
let mut grid = Grid::new(10, 1);
Text::new("hi")
.align(Align::Right)
.render(&mut Surface::new(&mut grid, area, 0));
assert_eq!(grid[Pos::new(8, 0)].glyph(), 'h');
assert_eq!(grid[Pos::new(9, 0)].glyph(), 'i');
assert_eq!(grid[Pos::new(7, 0)].glyph(), ' ');
}
#[test]
fn center_align_centers_text() {
let area = Rect::new(0, 0, 10, 1);
let mut grid = Grid::new(10, 1);
Text::new("hi")
.align(Align::Center)
.render(&mut Surface::new(&mut grid, area, 0));
assert_eq!(grid[Pos::new(4, 0)].glyph(), 'h');
assert_eq!(grid[Pos::new(5, 0)].glyph(), 'i');
}
#[test]
fn zero_width_is_a_no_op() {
let area = Rect::new(0, 0, 0, 1);
let mut grid = Grid::new(1, 1);
Text::new("hi").render(&mut Surface::new(&mut grid, area, 0));
assert_eq!(grid[Pos::new(0, 0)].glyph(), ' ');
}
}