use crate::color::*;
use crate::geometry::*;
use crate::graphics::*;
use std::io;
pub trait Painter {
fn paint(&mut self, drawing: Drawing) -> io::Result<()>;
fn get_area(&self) -> Window;
fn get_size(&self) -> Point {
self.get_area().size
}
fn fill(&mut self, c: Color) -> io::Result<()> {
let area = self.get_area();
self.paint(
" ".repeat(area.size.area() as usize)
.as_drawing()
.size(area.size)
.bg(c),
)?;
Ok(())
}
}
impl<'a, T> Painter for &'a mut T
where
T: Painter + ?Sized + 'a,
{
fn paint(&mut self, drawing: Drawing) -> io::Result<()> {
Painter::paint(*self, drawing)
}
fn get_area(&self) -> Window {
Painter::get_area(*self)
}
}
pub struct PainterScope<P> {
painter: P,
scope: Window,
style: Style,
}
impl<P> PainterScope<P> {
pub fn new(painter: P, scope: Window, style: Style) -> Self {
PainterScope {
painter,
scope,
style,
}
}
}
impl<P> Painter for PainterScope<P>
where
P: Painter,
{
fn paint(&mut self, mut drawing: Drawing) -> io::Result<()> {
drawing.style = drawing.style.or(&self.style);
drawing.scope.position += self.scope.position;
drawing.scope = &drawing.scope & &self.scope;
drawing.scope.position -= self.painter.get_area().position;
self.painter.paint(drawing)
}
fn get_area(&self) -> Window {
self.scope
}
}
#[test]
fn test_painter_fill() {
#[derive(Default, Debug)]
struct FakePainter {
drawing: Option<Drawing>,
window: Window,
painters: Vec<Box<FakePainter>>,
}
impl FakePainter {}
impl Painter for FakePainter {
fn paint(&mut self, drawing: Drawing) -> io::Result<()> {
self.drawing = Some(drawing);
Ok(())
}
fn get_area(&self) -> Window {
self.window
}
}
let mut sut = FakePainter::default();
sut.window = window(point(x(0), y(0)), point(x(3), y(4)));
sut.fill(WHITE);
assert_eq!(
sut.drawing,
Some(" ".as_drawing().width(3).height(4).bg(WHITE))
);
sut.window = window(point(x(5), y(3)), point(x(3), y(4)));
sut.fill(RED);
assert_eq!(
sut.drawing,
Some(" ".as_drawing().width(3).height(4).bg(RED))
);
}