use super::Rect; use std::io::Write; use crossterm::{ cursor::{MoveDown, MoveTo, MoveToColumn}, queue, terminal, }; use crate::Result; use super::{Cell, Pos}; pub struct View { cells: Vec, width: u16, #[allow(dead_code)] height: u16, } impl View { pub fn new(width: u16, height: u16) -> Self { Self { width, height, cells: vec![Cell::default(); (width * height) as usize], } } pub fn fullscreen() -> Self { let (width, height) = terminal::size().expect("Couldnt detect terminal size"); Self { width, height, cells: vec![Cell::default(); (width * height) as usize], } } pub fn get(&self, pos: Pos) -> Option<&Cell> { self.cells.get((pos.y() * self.width + pos.x()) as usize) } pub fn set(&mut self, pos: Pos, cell: Cell) { self.cells[(pos.y() * self.width + pos.x()) as usize] = cell; } pub fn fill(&mut self, rect: Rect, cell: Cell) { for y in rect.pos.y()..rect.pos.y() + rect.height { for x in rect.pos.x()..rect.pos.x() + rect.width { self.set(Pos::new(x, y), cell); } } } pub fn fill_all(&mut self, cell: Cell) { self.cells.fill(cell); } pub fn merge(&mut self, pos: Pos, view: View) { for (idx, line) in view.cells.chunks(view.width as usize).enumerate() { let start = ((pos.y() + idx as u16) * self.width + pos.x()) as usize; let end = start + line.len(); self.cells.splice(start..end, line.iter().cloned()); } } pub fn render(&mut self, pos: Pos, output: &mut impl Write) -> Result<()> { queue!(output, MoveTo(pos.x(), pos.y()))?; for line in self.cells.chunks(self.width as usize) { for cell in line { cell.render(output)?; } queue!(output, MoveDown(1))?; queue!(output, MoveToColumn(pos.x()))?; } Ok(()) } }