1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
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)) ); }