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
/* fills.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! Components that just fill a space (with a colour, typically, or possibly
//! with a more interesting pattern.

// Imports ===================================================================
use avrox_display::gfx::{Area, patterns, Renderable, RenderPlane};
use avrox_display::gfx::pixels::Monochromatic;
use avrox_display::gfx::Point;
use avrox_display::GfxResult;
use avr_oxide::OxideResult::Ok;

// Declarations ==============================================================
/// Just always return the same solid colour
pub struct SolidFill<PIX: Clone>(PIX);

pub type GraphicsPatternFunction<PIX> = fn(Point) -> GfxResult<PIX>;

/// Fill with a procedurally generated pattern
pub struct FunctionFill<PIX> {
  function: GraphicsPatternFunction<PIX>
}

/// A fill that renders a 50% on/off crosshatch pattern
pub fn crosshatch_fill() -> FunctionFill<Monochromatic> {
  FunctionFill {
    function: patterns::crosshatch
  }
}

/// A fill that renders alternating on/off horizontal lines
pub fn horizontal_pinstripe_fill() -> FunctionFill<Monochromatic> {
  FunctionFill {
    function: patterns::horizontal_pinstripe
  }
}

/// A fill that renders alternating on/off vertical lines
pub fn vertical_pinstripe_fill() -> FunctionFill<Monochromatic> {
  FunctionFill {
    function: patterns::vertical_pinstripe
  }
}




// Code ======================================================================
impl<PIX: Clone> SolidFill<PIX> {
  pub fn new(pix: PIX) -> Self {
    SolidFill(pix)
  }
}

impl<PIX> FunctionFill<PIX>{
  pub fn new(function: GraphicsPatternFunction<PIX>) -> Self {
    FunctionFill {
      function
    }
  }
}


impl<PIX> Renderable for FunctionFill<PIX> {
  type PIXEL = PIX;

  fn get_pixel_at<P: RenderPlane>(&self, coord: Point) -> GfxResult<Self::PIXEL> {
    (self.function)(coord)
  }

  // Fills are always static (we are very much not in the market for
  // animations.  Not over an I2C bus ;-)).
  fn has_changes<P: RenderPlane>(&self) -> bool {
    false
  }
}

impl<PIX> Renderable for SolidFill<PIX>
  where
    PIX: Clone
{
  type PIXEL = PIX;

  fn get_pixel_at<P: RenderPlane>(&self, _coord: Point) -> GfxResult<Self::PIXEL> {
    Ok(self.0.clone())
  }

  fn has_changes<P: RenderPlane>(&self) -> bool {
    false
  }

  fn get_change_area<P: RenderPlane>(&self) -> GfxResult<Option<Area>> {
    Ok(None)
  }
}
// Tests =====================================================================
#[cfg(test)]
mod tests {

}