use crate::layout::{BBox, Pos};
use crate::text::{Glyph, TextStyle, Theme};
use crate::{Result, Screen};
use textwrap::wrap;
pub struct Cells<'a> {
screen: &'a mut Screen,
bbox: BBox,
clip: BBox,
}
impl<'a> Cells<'a> {
pub fn new(screen: &'a mut Screen, bbox: BBox) -> Self {
let clip = bbox;
Self { screen, bbox, clip }
}
pub fn width(&self) -> u16 {
self.clip.width()
}
pub fn height(&self) -> u16 {
self.clip.height()
}
pub fn clip(&mut self, inset: Option<BBox>) {
if let Some(inset) = inset {
let col = self.bbox.left() + inset.left();
let row = self.bbox.top() + inset.top();
let width = inset.width();
let height = inset.height();
self.clip = self.bbox.clip(BBox::new(col, row, width, height));
} else {
self.clip = self.bbox;
}
}
pub fn fill(&mut self, glyph: &Glyph) -> Result<()> {
let bbox = self.clip;
let fill_width = bbox.width() / glyph.width() as u16;
if bbox.height() > 0 && fill_width > 0 {
self.move_to(0, 0)?;
for row in 0..bbox.height() {
self.move_to(0, row)?;
for _ in 0..fill_width {
glyph.print(self.screen)?;
}
}
}
Ok(())
}
pub fn theme(&self) -> &Theme {
self.screen.theme()
}
pub fn set_style(&mut self, st: TextStyle) -> Result<()> {
self.screen.set_style(st)
}
pub fn move_to(&mut self, col: u16, row: u16) -> Result<()> {
let col = self.clip.left() + col;
let row = self.clip.top() + row;
self.screen.move_to(col, row)
}
pub fn move_right(&mut self, col: u16) -> Result<()> {
self.screen.move_right(col)
}
pub fn print_char(&mut self, ch: char) -> Result<()> {
self.screen.print_char(ch)
}
pub fn print_str(&mut self, st: &str) -> Result<()> {
self.screen.print_str(st)
}
pub fn print_text(&mut self, text: &str, offset: Pos) -> Result<()> {
assert_eq!(offset.col, 0, "FIXME");
let top = usize::from(offset.row);
let width = usize::from(self.width());
let height = usize::from(self.height());
for (row, txt) in
wrap(text, width).iter().skip(top).take(height).enumerate()
{
let row = row as u16; self.move_to(0, row)?;
self.print_str(txt)?;
}
Ok(())
}
}