prototty_grid/
lib.rs

1pub extern crate grid_2d;
2extern crate prototty_render;
3
4use prototty_render::*;
5
6pub trait ColourConversion {
7    type Colour;
8    fn convert_foreground_rgb24(&mut self, rgb24: Rgb24) -> Self::Colour;
9    fn convert_background_rgb24(&mut self, rgb24: Rgb24) -> Self::Colour;
10    fn default_foreground(&mut self) -> Self::Colour;
11    fn default_background(&mut self) -> Self::Colour;
12}
13
14#[derive(Debug, Clone)]
15pub struct CommonCell<C> {
16    pub character: char,
17    pub bold: bool,
18    pub underline: bool,
19    pub foreground_colour: C,
20    pub background_colour: C,
21    foreground_depth: i32,
22    background_depth: i32,
23}
24
25impl<C> CommonCell<C> {
26    fn set_character(&mut self, character: char, depth: i32) {
27        if depth >= self.foreground_depth {
28            self.character = character;
29            self.foreground_depth = depth;
30        }
31    }
32    fn set_bold(&mut self, bold: bool, depth: i32) {
33        if depth >= self.foreground_depth {
34            self.bold = bold;
35            self.foreground_depth = depth;
36        }
37    }
38    fn set_underline(&mut self, underline: bool, depth: i32) {
39        if depth >= self.foreground_depth {
40            self.underline = underline;
41            self.foreground_depth = depth;
42        }
43    }
44    fn set_foreground_colour(&mut self, colour: C, depth: i32) {
45        if depth >= self.foreground_depth {
46            self.foreground_colour = colour;
47            self.foreground_depth = depth;
48        }
49    }
50    fn set_background_colour(&mut self, colour: C, depth: i32) {
51        if depth >= self.background_depth {
52            self.background_colour = colour;
53            self.background_depth = depth;
54        }
55    }
56    fn new_default(foreground_colour: C, background_colour: C) -> Self {
57        Self {
58            character: ' ',
59            bold: false,
60            underline: false,
61            foreground_colour,
62            background_colour,
63            foreground_depth: 0,
64            background_depth: 0,
65        }
66    }
67}
68pub type Iter<'a, C> = grid_2d::GridIter<'a, C>;
69pub type IterMut<'a, C> = grid_2d::GridIterMut<'a, C>;
70pub type Enumerate<'a, C> = grid_2d::GridEnumerate<'a, C>;
71
72#[derive(Debug, Clone)]
73pub struct Grid<C: ColourConversion> {
74    cells: grid_2d::Grid<CommonCell<C::Colour>>,
75    colour_conversion: C,
76}
77
78impl<C: ColourConversion> Grid<C> {
79    pub fn new(size: Size, mut colour_conversion: C) -> Self {
80        let cells = grid_2d::Grid::new_fn(size, |_| {
81            let foreground = colour_conversion.default_foreground();
82            let background = colour_conversion.default_background();
83            CommonCell::new_default(foreground, background)
84        });
85        Self {
86            cells,
87            colour_conversion,
88        }
89    }
90
91    pub fn size(&self) -> Size {
92        self.cells.size()
93    }
94
95    pub fn resize(&mut self, size: Size) {
96        self.cells = grid_2d::Grid::new_fn(size, |_| {
97            let foreground = self.colour_conversion.default_foreground();
98            let background = self.colour_conversion.default_background();
99            CommonCell::new_default(foreground, background)
100        });
101    }
102
103    pub fn clear(&mut self) {
104        for cell in self.cells.iter_mut() {
105            let foreground = self.colour_conversion.default_foreground();
106            let background = self.colour_conversion.default_background();
107            *cell = CommonCell::new_default(foreground, background);
108        }
109    }
110
111    pub fn enumerate(&self) -> Enumerate<CommonCell<C::Colour>> {
112        self.cells.enumerate()
113    }
114
115    pub fn iter(&self) -> Iter<CommonCell<C::Colour>> {
116        self.cells.iter()
117    }
118
119    pub fn iter_mut(&mut self) -> IterMut<CommonCell<C::Colour>> {
120        self.cells.iter_mut()
121    }
122
123    pub fn default_foreground(&mut self) -> C::Colour {
124        self.colour_conversion.default_foreground()
125    }
126
127    pub fn default_background(&mut self) -> C::Colour {
128        self.colour_conversion.default_background()
129    }
130}
131
132impl<C: ColourConversion> ViewGrid for Grid<C> {
133    fn set_cell_absolute(&mut self, coord: Coord, depth: i32, view_cell: ViewCell) {
134        if let Some(cell) = self.cells.get_mut(coord) {
135            if cell.foreground_depth <= depth || cell.background_depth <= depth {
136                if let Some(character) = view_cell.character() {
137                    cell.set_character(character, depth);
138                }
139                if let Some(bold) = view_cell.bold() {
140                    cell.set_bold(bold, depth);
141                }
142                if let Some(underline) = view_cell.underline() {
143                    cell.set_underline(underline, depth);
144                }
145                if let Some(foreground) = view_cell.foreground() {
146                    cell.set_foreground_colour(
147                        self.colour_conversion.convert_foreground_rgb24(foreground),
148                        depth,
149                    );
150                }
151                if let Some(background) = view_cell.background() {
152                    cell.set_background_colour(
153                        self.colour_conversion.convert_background_rgb24(background),
154                        depth,
155                    );
156                }
157            }
158        }
159    }
160
161    fn size(&self) -> Size {
162        self.cells.size()
163    }
164}