retroglyph_ui/widget/
text.rs1use retroglyph_core::color::Style;
3
4use super::Widget;
5use crate::Align;
6use crate::Surface;
7use crate::text::draw_clipped;
8
9#[derive(Clone, Copy, Debug)]
39pub struct Text<'a> {
40 content: &'a str,
41 style: Style,
42 align: Align,
43}
44
45impl<'a> Text<'a> {
46 #[must_use]
48 pub fn new(content: &'a str) -> Self {
49 Self {
50 content,
51 style: Style::new(),
52 align: Align::Left,
53 }
54 }
55
56 #[must_use]
58 pub const fn style(mut self, style: Style) -> Self {
59 self.style = style;
60 self
61 }
62
63 #[must_use]
65 pub const fn align(mut self, align: Align) -> Self {
66 self.align = align;
67 self
68 }
69}
70
71impl Widget for Text<'_> {
72 fn render(&self, surface: &mut Surface<'_>) {
73 let width = surface.width();
74 if width == 0 {
75 return;
76 }
77 let _ = draw_clipped(surface, (0, 0), width, self.content, self.align, self.style);
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use retroglyph_core::color::Color;
84 use retroglyph_core::grid::{Grid, Pos, Rect};
85
86 use super::*;
87
88 #[test]
89 fn prints_the_content_in_the_given_style() {
90 let area = Rect::new(0, 0, 10, 1);
91 let mut grid = Grid::new(10, 1);
92 Text::new("hi")
93 .style(Style::new().fg(Color::WHITE))
94 .render(&mut Surface::new(&mut grid, area, 0));
95
96 assert_eq!(grid[Pos::new(0, 0)].glyph(), 'h');
97 assert_eq!(grid[Pos::new(1, 0)].glyph(), 'i');
98 assert_eq!(grid[Pos::new(0, 0)].style().foreground(), Color::WHITE);
99 }
100
101 #[test]
102 fn clips_to_area_width() {
103 let area = Rect::new(0, 0, 5, 1);
104 let mut grid = Grid::new(5, 1);
105 Text::new("a much longer message than fits").render(&mut Surface::new(&mut grid, area, 0));
106
107 assert_eq!(grid[Pos::new(4, 0)].glyph(), 'c'); }
109
110 #[test]
111 fn right_align_places_text_against_the_right_edge() {
112 let area = Rect::new(0, 0, 10, 1);
113 let mut grid = Grid::new(10, 1);
114 Text::new("hi")
115 .align(Align::Right)
116 .render(&mut Surface::new(&mut grid, area, 0));
117
118 assert_eq!(grid[Pos::new(8, 0)].glyph(), 'h');
120 assert_eq!(grid[Pos::new(9, 0)].glyph(), 'i');
121 assert_eq!(grid[Pos::new(7, 0)].glyph(), ' ');
122 }
123
124 #[test]
125 fn center_align_centers_text() {
126 let area = Rect::new(0, 0, 10, 1);
127 let mut grid = Grid::new(10, 1);
128 Text::new("hi")
129 .align(Align::Center)
130 .render(&mut Surface::new(&mut grid, area, 0));
131
132 assert_eq!(grid[Pos::new(4, 0)].glyph(), 'h');
134 assert_eq!(grid[Pos::new(5, 0)].glyph(), 'i');
135 }
136
137 #[test]
138 fn zero_width_is_a_no_op() {
139 let area = Rect::new(0, 0, 0, 1);
140 let mut grid = Grid::new(1, 1);
141 Text::new("hi").render(&mut Surface::new(&mut grid, area, 0));
142 assert_eq!(grid[Pos::new(0, 0)].glyph(), ' ');
143 }
144}