aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-13 17:24:21 +0000
committerAkshay <[email protected]>2021-03-13 17:24:21 +0000
commitef37a6552a71f86eb1e393b61a3bbb5d81815783 (patch)
treed5f3fb74756508941f2d36960b60d52ecf2d52de /src/app.rs
parent4b4ebe84d2cfbb8b0ddf7b678c5fe4cff53e5089 (diff)
factor out line and circle drawing into bitmap
Diffstat (limited to 'src/app.rs')
-rw-r--r--src/app.rs115
1 files changed, 53 insertions, 62 deletions
diff --git a/src/app.rs b/src/app.rs
index c0d3018..3c57f27 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -103,61 +103,30 @@ impl<'ctx> AppState<'ctx> {
103 center: P, 103 center: P,
104 val: bool, 104 val: bool,
105 ) -> Result<Vec<ModifyRecord>, ()> { 105 ) -> Result<Vec<ModifyRecord>, ()> {
106 let radius = self.brush_size; 106 let radius = self.brush_size as u32;
107 if radius == 1 { 107 let center = self.idx_at_coord(center).ok_or(())?;
108 let center_point: Point = center.into(); 108 let mut circle_modify_record = vec![];
109 return Ok(if let Some(pt) = self.idx_at_coord(center_point) { 109 for point in self.pixmap.get_circle(center, radius) {
110 let old_val = self.pixmap.set(pt, val); 110 let old_val = self.pixmap.set(point, val);
111 Ok(ModifyRecord::new(pt, old_val, val)) 111 circle_modify_record.push(ModifyRecord::new(point, old_val, val));
112 } else { 112 }
113 Err(()) 113 Ok(circle_modify_record)
114 } 114 }
115 .map(|x| vec![x])?); 115
116 } else { 116 fn paint_line<P: Into<Point>>(&mut self, start: P, end: P) -> Result<Vec<ModifyRecord>, ()> {
117 if let Some(center_on_grid) = self.idx_at_coord(center) { 117 let start = self.idx_at_coord(start).ok_or(())?;
118 // center_on_grid is now a coordinate on the drawing grid 118 let end = self.idx_at_coord(end).ok_or(())?;
119 let (x0, y0) = (center_on_grid.0 as i64, center_on_grid.1 as i64); 119 let line_coords = self.pixmap.get_line(start, end);
120 let (mut dx, mut dy, mut err) = (radius as i64, 0i64, 1 - radius as i64); 120 let mut line_modify_record = vec![];
121 let mut circle = vec![]; 121 let val = self.active_color;
122 let mut old_vals = vec![]; 122 for point in line_coords {
123 while dx >= dy { 123 let circle_around_point = self.pixmap.get_circle(point, self.brush_size as u32);
124 circle.push((x0 + dx, y0 + dy)); 124 for c in circle_around_point {
125 circle.push((x0 - dx, y0 + dy)); 125 let old_val = self.pixmap.set(c, val);
126 circle.push((x0 + dx, y0 - dy)); 126 line_modify_record.push(ModifyRecord::new(c, old_val, val));
127 circle.push((x0 - dx, y0 - dy));
128 circle.push((x0 + dy, y0 + dx));
129 circle.push((x0 - dy, y0 + dx));
130 circle.push((x0 + dy, y0 - dx));
131 circle.push((x0 - dy, y0 - dx));
132 dy = dy + 1;
133 if err < 0 {
134 err = err + 2 * dy + 1;
135 } else {
136 dx -= 1;
137 err += 2 * (dy - dx) + 1;
138 }
139 }
140 // circle's insides
141 for x in 0..radius as i64 {
142 for y in 0..radius as i64 {
143 if x.pow(2) + y.pow(2) < (radius as i64).pow(2) {
144 circle.push((x0 + x, y0 + y));
145 circle.push((x0 - x, y0 + y));
146 circle.push((x0 + x, y0 - y));
147 circle.push((x0 - x, y0 - y));
148 }
149 }
150 }
151 for circumference_pt in circle {
152 if let Ok(mp) = MapPoint::try_from(circumference_pt) {
153 let old_val = self.pixmap.set(mp, val);
154 old_vals.push(ModifyRecord::new((mp.x, mp.y), old_val, val));
155 }
156 }
157 return Ok(old_vals);
158 } 127 }
159 } 128 }
160 return Err(()); 129 Ok(line_modify_record)
161 } 130 }
162 131
163 fn apply_operation(&mut self, op: Operation, op_kind: OpKind) { 132 fn apply_operation(&mut self, op: Operation, op_kind: OpKind) {
@@ -176,6 +145,17 @@ impl<'ctx> AppState<'ctx> {
176 } 145 }
177 } 146 }
178 147
148 fn commit_operation(&mut self) {
149 if !self.current_operation.is_empty() {
150 let op = self
151 .current_operation
152 .drain(..)
153 .filter(|v| !v.old_val == v.val)
154 .collect::<Vec<_>>();
155 self.undo_stack.push(op);
156 }
157 }
158
179 fn zoom_in(&mut self, p: (i32, i32)) { 159 fn zoom_in(&mut self, p: (i32, i32)) {
180 // attempt to center around cursor 160 // attempt to center around cursor
181 if let Some(p) = self.idx_at_coord(p) { 161 if let Some(p) = self.idx_at_coord(p) {
@@ -192,8 +172,8 @@ impl<'ctx> AppState<'ctx> {
192 self.brush_size += 1; 172 self.brush_size += 1;
193 } 173 }
194 174
195 fn descrease_brush_size(&mut self) { 175 fn decrease_brush_size(&mut self) {
196 if self.brush_size > 1 { 176 if self.brush_size > 0 {
197 self.brush_size -= 1; 177 self.brush_size -= 1;
198 } 178 }
199 } 179 }
@@ -296,7 +276,7 @@ impl<'ctx> AppState<'ctx> {
296 Self { 276 Self {
297 start: Point::new(60, 60), 277 start: Point::new(60, 60),
298 zoom: 5, 278 zoom: 5,
299 brush_size: 1, 279 brush_size: 0,
300 pixmap, 280 pixmap,
301 grid: Grid::new(), 281 grid: Grid::new(),
302 canvas, 282 canvas,
@@ -339,12 +319,25 @@ impl<'ctx> AppState<'ctx> {
339 self.modify(|e| e.zoom_out(cursor)); 319 self.modify(|e| e.zoom_out(cursor));
340 } 320 }
341 // brush ops 321 // brush ops
342 Keycode::Q => self.modify(|e| e.descrease_brush_size()), 322 Keycode::Q => self.decrease_brush_size(),
343 Keycode::E => self.modify(|e| e.increase_brush_size()), 323 Keycode::E => self.increase_brush_size(),
344 // flip color 324 // flip color
345 Keycode::X => self.modify(|e| e.change_active_color()), 325 Keycode::X => self.modify(|e| e.change_active_color()),
346 // toggle grid 326 // toggle grid
347 Keycode::Tab => self.modify(|e| e.toggle_grid()), 327 Keycode::Tab => self.modify(|e| e.toggle_grid()),
328 // line drawing
329 Keycode::F => self.modify(|e| {
330 let end = (mouse.x(), mouse.y()).into();
331 if let Some(start) = e.last_point {
332 if let Ok(o) = e.paint_line(start, end) {
333 e.commit_operation();
334 e.current_operation =
335 o.into_iter().filter(|v| !v.old_val == v.val).collect();
336 e.commit_operation();
337 e.last_point = Some(end);
338 }
339 }
340 }),
348 // exit 341 // exit
349 Keycode::Escape => break 'running, 342 Keycode::Escape => break 'running,
350 // undo & redo 343 // undo & redo
@@ -381,9 +374,7 @@ impl<'ctx> AppState<'ctx> {
381 Event::MouseMotion { 374 Event::MouseMotion {
382 x, y, mousestate, .. 375 x, y, mousestate, ..
383 } => { 376 } => {
384 let is_left = mousestate.is_mouse_button_pressed(MouseButton::Left); 377 if mousestate.is_mouse_button_pressed(MouseButton::Left) {
385 let is_right = mousestate.is_mouse_button_pressed(MouseButton::Right);
386 if is_left {
387 self.modify(|e| { 378 self.modify(|e| {
388 let pt = (x, y); 379 let pt = (x, y);
389 let val = e.active_color; 380 let val = e.active_color;
@@ -391,7 +382,7 @@ impl<'ctx> AppState<'ctx> {
391 e.current_operation.extend(o); 382 e.current_operation.extend(o);
392 } 383 }
393 }); 384 });
394 } else if is_right { 385 } else if mousestate.is_mouse_button_pressed(MouseButton::Right) {
395 self.modify(|e| { 386 self.modify(|e| {
396 let pt = (x, y); 387 let pt = (x, y);
397 let val = !e.active_color; 388 let val = !e.active_color;