1use crate::layout::{BBox, Pos};
6use crate::text::{Glyph, TextStyle, Theme};
7use crate::{Result, Screen};
8use textwrap::wrap;
9
10pub struct Cells<'a> {
14 screen: &'a mut Screen,
16 bbox: BBox,
18 clip: BBox,
20}
21
22impl<'a> Cells<'a> {
23 pub fn new(screen: &'a mut Screen, bbox: BBox) -> Self {
25 let clip = bbox;
26 Self { screen, bbox, clip }
27 }
28
29 pub fn width(&self) -> u16 {
31 self.clip.width()
32 }
33
34 pub fn height(&self) -> u16 {
36 self.clip.height()
37 }
38
39 pub fn clip(&mut self, inset: Option<BBox>) {
41 if let Some(inset) = inset {
42 let col = self.bbox.left() + inset.left();
43 let row = self.bbox.top() + inset.top();
44 let width = inset.width();
45 let height = inset.height();
46 self.clip = self.bbox.clip(BBox::new(col, row, width, height));
47 } else {
48 self.clip = self.bbox;
49 }
50 }
51
52 pub fn fill(&mut self, glyph: &Glyph) -> Result<()> {
54 let bbox = self.clip;
55 let fill_width = bbox.width() / glyph.width() as u16;
56 if bbox.height() > 0 && fill_width > 0 {
57 self.move_to(0, 0)?;
58 for row in 0..bbox.height() {
59 self.move_to(0, row)?;
60 for _ in 0..fill_width {
61 glyph.print(self.screen)?;
62 }
63 }
64 }
65 Ok(())
66 }
67
68 pub fn theme(&self) -> &Theme {
70 self.screen.theme()
71 }
72
73 pub fn set_style(&mut self, st: TextStyle) -> Result<()> {
75 self.screen.set_style(st)
76 }
77
78 pub fn move_to(&mut self, col: u16, row: u16) -> Result<()> {
80 let col = self.clip.left() + col;
81 let row = self.clip.top() + row;
82 self.screen.move_to(col, row)
83 }
84
85 pub fn move_right(&mut self, col: u16) -> Result<()> {
87 self.screen.move_right(col)
88 }
89
90 pub fn print_char(&mut self, ch: char) -> Result<()> {
92 self.screen.print_char(ch)
94 }
95
96 pub fn print_str(&mut self, st: &str) -> Result<()> {
98 self.screen.print_str(st)
100 }
101
102 pub fn print_text(&mut self, text: &str, offset: Pos) -> Result<()> {
115 assert_eq!(offset.col, 0, "FIXME");
116 let top = usize::from(offset.row);
117 let width = usize::from(self.width());
118 let height = usize::from(self.height());
119 for (row, txt) in
120 wrap(text, width).iter().skip(top).take(height).enumerate()
121 {
122 let row = row as u16; self.move_to(0, row)?;
124 self.print_str(txt)?;
125 }
126 Ok(())
127 }
128}