use std::rc::Rc;
use std::cell::RefCell;
use crate::Widget;
use crate::common::{BoundingBox, Dimensions, Position};
pub struct CanvasWidget {
bounding_box: BoundingBox,
buffer: Box<[Box<[char]>]>
}
impl CanvasWidget {
pub fn new(x: i32, y: i32, width: u32, height: u32) -> Rc<RefCell<Self>> {
let bounding_box = BoundingBox::new(
Position::new(x, y),
Dimensions::new(width, height)
);
let mut buffer_vec = vec![];
let row_vec = vec![' '; width as usize];
for _ in 0..height {
buffer_vec.push(
row_vec.clone().into_boxed_slice()
);
}
return Rc::new(RefCell::new(Self {
bounding_box,
buffer: buffer_vec.into_boxed_slice()
}));
}
pub fn get_width(&self) -> u32 {
return self.get_bounding_box().get_width();
}
pub fn get_height(&self) -> u32 {
return self.get_bounding_box().get_height();
}
pub fn set_char(&mut self, c: char, x: i32, y: i32) {
if self.get_bounding_box().get_width() <= x as u32 ||
self.get_bounding_box().get_height() <= y as u32 ||
x < 0 ||
y < 0
{
return;
}
else {
self.buffer[y as usize][x as usize] = c;
}
}
pub fn clear(&mut self, c: char) {
for y in 0..self.get_bounding_box().get_height() {
for x in 0..self.get_bounding_box().get_width() {
self.buffer[y as usize][x as usize] = c;
}
}
}
}
impl Widget for CanvasWidget {
fn draw(
&mut self,
positioning_algorithm: &Box<dyn crate::PositioningAlgorithm>,
display_buffer: &mut crate::DisplayBuffer
) {
let abs_pos = positioning_algorithm.calculate_position(
self.bounding_box.get_position()
);
for y in 0..self.get_bounding_box().get_height() {
for x in 0..self.get_bounding_box().get_width() {
display_buffer.set_char(
self.buffer[y as usize][x as usize],
x as i32 + abs_pos.get_x(),
y as i32 + abs_pos.get_y()
);
}
}
}
fn get_bounding_box(&self) -> crate::common::BoundingBox {
return self.bounding_box;
}
}