1use crate::*;
2
3#[derive(Clone, Copy)]
4pub struct Tile<S> {
5 state: S,
6 sprite_id: SpriteId,
7 origin: Point,
8 columns: usize,
9 rows: usize,
10 sprite_size: Size,
11 invalidate: bool,
12}
13
14impl<S> Tile<S>
15where
16 S: Copy + PartialEq + Into<Glyph>,
17{
18 pub fn new<SI: Into<SpriteId>>(
19 sprite_id: SI,
20 state: S,
21 origin: Point,
22 sprite_size: Size,
23 columns: usize,
24 rows: usize,
25 ) -> Self {
26 Self {
27 origin,
28 state,
29 columns,
30 rows,
31 sprite_size,
32 sprite_id: sprite_id.into(),
33 invalidate: true,
34 }
35 }
36}
37
38impl<S> Widget<S> for Tile<S>
39where
40 S: Copy + PartialEq + Into<Glyph>,
41{
42 fn invalidate(&mut self) {
43 self.invalidate = true;
44 }
45
46 fn update(&mut self, state: S) {
47 if self.state != state {
48 self.state = state;
49 self.invalidate = true;
50 }
51 }
52
53 fn render<D: Display>(&mut self, display: &mut D) {
54 if self.invalidate {
55 let glyph = self.state.into();
56 for x in 0..self.columns {
57 for y in 0..self.rows {
58 let origin = Point::new(
59 self.origin.x + self.sprite_size.width * x as u8,
60 self.origin.y + self.sprite_size.height * y as u8,
61 );
62 display.render(RenderRequest::new(origin, self.sprite_id, glyph));
63 }
64 }
65 self.invalidate = false;
66 }
67 }
68}