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}