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