diff options
Diffstat (limited to 'src/app.rs')
-rw-r--r-- | src/app.rs | 60 |
1 files changed, 53 insertions, 7 deletions
@@ -38,6 +38,12 @@ struct Grid { | |||
38 | color: Color, | 38 | color: Color, |
39 | } | 39 | } |
40 | 40 | ||
41 | #[derive(Debug, Default, Copy, Clone)] | ||
42 | struct Symmetry { | ||
43 | x: Option<u32>, | ||
44 | y: Option<u32>, | ||
45 | } | ||
46 | |||
41 | impl Grid { | 47 | impl Grid { |
42 | fn new() -> Self { | 48 | fn new() -> Self { |
43 | Self { | 49 | Self { |
@@ -99,6 +105,44 @@ impl<'ctx> AppState<'ctx> { | |||
99 | self.grid.enabled = !self.grid.enabled; | 105 | self.grid.enabled = !self.grid.enabled; |
100 | } | 106 | } |
101 | 107 | ||
108 | fn cycle_symmetry(&mut self) { | ||
109 | let Symmetry { x, y } = self.symmetry; | ||
110 | self.symmetry = match (x, y) { | ||
111 | (None, None) => Symmetry { | ||
112 | x: Some(self.width() / 2), | ||
113 | y: None, | ||
114 | }, | ||
115 | (_, None) => Symmetry { | ||
116 | x: None, | ||
117 | y: Some(self.height() / 2), | ||
118 | }, | ||
119 | (None, y) => Symmetry { | ||
120 | x: Some(self.width() / 2), | ||
121 | y, | ||
122 | }, | ||
123 | (Some(_), Some(_)) => Symmetry { x: None, y: None }, | ||
124 | } | ||
125 | } | ||
126 | |||
127 | fn apply_symmetry(&self, figure: &[MapPoint]) -> Vec<MapPoint> { | ||
128 | let Symmetry { x, y } = self.symmetry; | ||
129 | match (x, y) { | ||
130 | (None, None) => vec![], | ||
131 | (Some(line), None) => self.pixmap.mirror_figure(figure, line, Axis::X), | ||
132 | (None, Some(line)) => self.pixmap.mirror_figure(figure, line, Axis::Y), | ||
133 | (Some(x), Some(y)) => { | ||
134 | let along_x = self.pixmap.mirror_figure(figure, x, Axis::X); | ||
135 | let along_y = self.pixmap.mirror_figure(figure, y, Axis::Y); | ||
136 | let reflected = self.pixmap.reflect_figure(figure, (x, y).into()); | ||
137 | along_x | ||
138 | .into_iter() | ||
139 | .chain(along_y) | ||
140 | .chain(reflected) | ||
141 | .collect() | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
102 | fn paint_point<P: Into<Point>>( | 146 | fn paint_point<P: Into<Point>>( |
103 | &mut self, | 147 | &mut self, |
104 | center: P, | 148 | center: P, |
@@ -106,21 +150,24 @@ impl<'ctx> AppState<'ctx> { | |||
106 | ) -> Result<Vec<ModifyRecord>, ()> { | 150 | ) -> Result<Vec<ModifyRecord>, ()> { |
107 | let radius = self.brush_size as u32; | 151 | let radius = self.brush_size as u32; |
108 | let center = self.idx_at_coord(center).ok_or(())?; | 152 | let center = self.idx_at_coord(center).ok_or(())?; |
109 | let mut circle_modify_record = vec![]; | 153 | let mut modify_record = vec![]; |
110 | for point in self.pixmap.get_circle(center, radius) { | 154 | let circle = self.pixmap.get_circle(center, radius); |
155 | let sym_circle = self.apply_symmetry(&circle); | ||
156 | for point in circle.into_iter().chain(sym_circle) { | ||
111 | let old_val = self.pixmap.set(point, val); | 157 | let old_val = self.pixmap.set(point, val); |
112 | circle_modify_record.push(ModifyRecord::new(point, old_val, val)); | 158 | modify_record.push(ModifyRecord::new(point, old_val, val)); |
113 | } | 159 | } |
114 | Ok(circle_modify_record) | 160 | Ok(modify_record) |
115 | } | 161 | } |
116 | 162 | ||
117 | fn paint_line<P: Into<Point>>(&mut self, start: P, end: P) -> Result<Vec<ModifyRecord>, ()> { | 163 | fn paint_line<P: Into<Point>>(&mut self, start: P, end: P) -> Result<Vec<ModifyRecord>, ()> { |
118 | let start = self.idx_at_coord(start).ok_or(())?; | 164 | let start = self.idx_at_coord(start).ok_or(())?; |
119 | let end = self.idx_at_coord(end).ok_or(())?; | 165 | let end = self.idx_at_coord(end).ok_or(())?; |
120 | let line_coords = self.pixmap.get_line(start, end); | 166 | let line = self.pixmap.get_line(start, end); |
167 | let sym_line = self.apply_symmetry(&line); | ||
121 | let mut line_modify_record = vec![]; | 168 | let mut line_modify_record = vec![]; |
122 | let val = self.active_color; | 169 | let val = self.active_color; |
123 | for point in line_coords { | 170 | for point in line.into_iter().chain(sym_line) { |
124 | let circle_around_point = self.pixmap.get_circle(point, self.brush_size as u32); | 171 | let circle_around_point = self.pixmap.get_circle(point, self.brush_size as u32); |
125 | for c in circle_around_point { | 172 | for c in circle_around_point { |
126 | let old_val = self.pixmap.set(c, val); | 173 | let old_val = self.pixmap.set(c, val); |
@@ -292,7 +339,6 @@ impl<'ctx> AppState<'ctx> { | |||
292 | self.canvas.present(); | 339 | self.canvas.present(); |
293 | 340 | ||
294 | let mut event_pump = self.context.event_pump().unwrap(); | 341 | let mut event_pump = self.context.event_pump().unwrap(); |
295 | |||
296 | 'running: loop { | 342 | 'running: loop { |
297 | let mouse = event_pump.mouse_state(); | 343 | let mouse = event_pump.mouse_state(); |
298 | for event in event_pump.poll_iter() { | 344 | for event in event_pump.poll_iter() { |