use crate::{
arragement::{Position, Size},
cell::Cell,
widget::Widget,
};
pub struct Frame {
content: Vec<Cell>,
size: Size,
}
impl Frame {
pub fn new(size: Size) -> Frame {
Frame {
content: vec![Cell::default(); size.area().into()],
size,
}
}
pub fn get(&self, position: Position) -> &Cell {
let index = self.index_of(position);
&self.content[index]
}
pub fn get_mut(&mut self, position: Position) -> &mut Cell {
let index = self.index_of(position);
&mut self.content[index]
}
pub fn index_of(&self, position: Position) -> usize {
((position.row * self.size.columns) + position.column).into()
}
pub fn resize(&mut self, size: Size) {
self.content
.resize_with(size.area().into(), Default::default);
}
pub fn diff(&self, other: &Frame) -> Vec<(Cell, Position)> {
let mut diff = Vec::new();
for row in 0..=self.size.rows {
for column in 0..=self.size.columns {
let new_cell = self.content[self.index_of(Position { row, column })];
if new_cell != other.content[other.index_of(Position { row, column })] {
diff.push((new_cell, Position { row, column }))
}
}
}
diff
}
pub fn render_widget(&mut self, widget: impl Widget, position: Position, size: Size) {
if size.area() == 0 {
return;
}
widget.render(&mut self.content, position, size);
}
}