aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-28 08:28:58 +0100
committerAkshay <[email protected]>2021-03-28 08:28:58 +0100
commite18777e32448f465748535690666055c179d5d5f (patch)
tree4211900a8cc2f5642dac459a92fca7eac8bf36e6 /src/app.rs
parent3e249a2086e7763a366d4cad70bd3c8e7dc9181f (diff)
add better brush drawing feedback
Diffstat (limited to 'src/app.rs')
-rw-r--r--src/app.rs107
1 files changed, 69 insertions, 38 deletions
diff --git a/src/app.rs b/src/app.rs
index 7bca6ba..42e63de 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,5 +1,5 @@
1use crate::{ 1use crate::{
2 bitmap::{MapPoint, Pixmap}, 2 bitmap::{positive_angle_with_x, MapPoint, Pixmap},
3 brush::Brush, 3 brush::Brush,
4 command::CommandBox, 4 command::CommandBox,
5 consts::{colors::*, FONT_PATH}, 5 consts::{colors::*, FONT_PATH},
@@ -35,7 +35,6 @@ pub enum Mode {
35 35
36pub struct AppState<'ctx, 'file> { 36pub struct AppState<'ctx, 'file> {
37 pub active_color: bool, 37 pub active_color: bool,
38 pub brush_size: u8,
39 pub brush: Brush, 38 pub brush: Brush,
40 pub canvas: Canvas<Window>, 39 pub canvas: Canvas<Window>,
41 pub command_box: CommandBox, 40 pub command_box: CommandBox,
@@ -146,8 +145,9 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
146 &mut self, 145 &mut self,
147 center: P, 146 center: P,
148 val: bool, 147 val: bool,
148 brush_size: u8,
149 ) -> Result<Vec<ModifyRecord>, ()> { 149 ) -> Result<Vec<ModifyRecord>, ()> {
150 let radius = self.brush_size as u32; 150 let radius = brush_size as u32;
151 let center = self.idx_at_coord(center).ok_or(())?; 151 let center = self.idx_at_coord(center).ok_or(())?;
152 let dither_level = self.dither_level; 152 let dither_level = self.dither_level;
153 153
@@ -172,6 +172,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
172 start: MapPoint, 172 start: MapPoint,
173 end: P, 173 end: P,
174 val: bool, 174 val: bool,
175 brush_size: u8,
175 ) -> Result<Vec<ModifyRecord>, ()> { 176 ) -> Result<Vec<ModifyRecord>, ()> {
176 let MapPoint { x, y } = start; 177 let MapPoint { x, y } = start;
177 let end = self.idx_at_coord(end).ok_or(())?; 178 let end = self.idx_at_coord(end).ok_or(())?;
@@ -182,7 +183,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
182 183
183 let mut line_modify_record = vec![]; 184 let mut line_modify_record = vec![];
184 for point in line.into_iter().chain(sym_line) { 185 for point in line.into_iter().chain(sym_line) {
185 let circle_around_point = self.pixmap.get_circle(point, self.brush_size as u32, true); 186 let circle_around_point = self.pixmap.get_circle(point, brush_size as u32, true);
186 for c in circle_around_point 187 for c in circle_around_point
187 .into_iter() 188 .into_iter()
188 .filter(|&pt| dither::bayer(dither_level, pt)) 189 .filter(|&pt| dither::bayer(dither_level, pt))
@@ -257,15 +258,15 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
257 ); 258 );
258 } 259 }
259 260
260 pub fn increase_brush_size(&mut self) { 261 // pub fn increase_brush_size(&mut self) {
261 self.brush_size += 1; 262 // self.brush_size += 1;
262 } 263 // }
263 264
264 pub fn decrease_brush_size(&mut self) { 265 // pub fn decrease_brush_size(&mut self) {
265 if self.brush_size > 0 { 266 // if self.brush_size > 0 {
266 self.brush_size -= 1; 267 // self.brush_size -= 1;
267 } 268 // }
268 } 269 // }
269 270
270 pub fn reduce_intensity(&mut self) { 271 pub fn reduce_intensity(&mut self) {
271 if self.dither_level > 0 { 272 if self.dither_level > 0 {
@@ -343,9 +344,8 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
343 format!("---, ---") 344 format!("---, ---")
344 }; 345 };
345 let status_text = format!( 346 let status_text = format!(
346 "[DITHER {}][BRUSH {}][SYM {}][PT {}][ACTIVE {}][KIND {}]", 347 "[DITHER {}][SYM {}][PT {}][ACTIVE {}][KIND {}]",
347 self.dither_level, 348 self.dither_level,
348 self.brush_size + 1,
349 self.symmetry, 349 self.symmetry,
350 mouse_coords, 350 mouse_coords,
351 if self.active_color { "WHT" } else { "BLK" }, 351 if self.active_color { "WHT" } else { "BLK" },
@@ -405,22 +405,51 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
405 } 405 }
406 406
407 fn draw_mouse(&mut self) { 407 fn draw_mouse(&mut self) {
408 let brush_size = self.brush_size;
409 let cs = self.zoom as u32; 408 let cs = self.zoom as u32;
410 let pt = self.idx_at_coord(self.mouse); 409 let pt = self.idx_at_coord(self.mouse);
411 if let Some(center) = pt { 410 if matches!(self.brush, Brush::Circle { .. } | Brush::Line { .. }) {
412 let circle = self.pixmap.get_circle(center, brush_size as u32, false); 411 let size = self.brush.size().unwrap();
413 for MapPoint { x, y } in circle.into_iter() { 412 if let Some(center) = pt {
414 self.canvas.set_draw_color(PINK); 413 let circle = self.pixmap.get_circle(center, size as u32, false);
415 self.canvas 414 for MapPoint { x, y } in circle.into_iter() {
416 .fill_rect(Rect::new( 415 self.canvas.set_draw_color(PINK);
417 x as i32 * cs as i32 + self.start.x(), 416 self.canvas
418 y as i32 * cs as i32 + self.start.y(), 417 .fill_rect(Rect::new(
419 cs, 418 x as i32 * cs as i32 + self.start.x(),
420 cs, 419 y as i32 * cs as i32 + self.start.y(),
421 )) 420 cs,
422 .unwrap(); 421 cs,
422 ))
423 .unwrap();
424 }
425 }
426 }
427 match self.brush {
428 Brush::Line { start, size, .. } => {
429 let size = self.zoom as u32 * size as u32;
430 if let (Some(from), Some(to)) = (start, pt) {
431 let line = self.pixmap.get_line(from, to.into());
432 draw_text(
433 &mut self.canvas,
434 self.ttf_context,
435 format!("{}°", positive_angle_with_x(from, to.into())),
436 PINK,
437 (self.mouse.0 as u32 + size, self.mouse.1 as u32 + size),
438 );
439 for MapPoint { x, y } in line.into_iter() {
440 self.canvas.set_draw_color(PINK);
441 self.canvas
442 .fill_rect(Rect::new(
443 x as i32 * cs as i32 + self.start.x(),
444 y as i32 * cs as i32 + self.start.y(),
445 cs,
446 cs,
447 ))
448 .unwrap();
449 }
450 }
423 } 451 }
452 _ => {}
424 } 453 }
425 } 454 }
426 455
@@ -485,9 +514,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
485 ev.push_event(Event::Quit { timestamp: 0u32 }) 514 ev.push_event(Event::Quit { timestamp: 0u32 })
486 .expect("ohno unable to quit"); 515 .expect("ohno unable to quit");
487 } 516 }
488}
489 517
490impl<'ctx, 'file> AppState<'ctx, 'file> {
491 pub fn init( 518 pub fn init(
492 width: u32, 519 width: u32,
493 height: u32, 520 height: u32,
@@ -499,7 +526,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
499 let video_subsystem = context.video().unwrap(); 526 let video_subsystem = context.video().unwrap();
500 527
501 let window = video_subsystem 528 let window = video_subsystem
502 .window("Pixel editor", 200, 200) 529 .window("Pixel editor", 500, 500)
503 .position_centered() 530 .position_centered()
504 .resizable() 531 .resizable()
505 .opengl() 532 .opengl()
@@ -517,8 +544,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
517 let pixmap = Pixmap::new_with(width, height, data); 544 let pixmap = Pixmap::new_with(width, height, data);
518 Self { 545 Self {
519 active_color: true, 546 active_color: true,
520 brush_size: 0, 547 brush: Brush::new(0),
521 brush: Brush::new(),
522 canvas, 548 canvas,
523 command_box: CommandBox::new(), 549 command_box: CommandBox::new(),
524 context, 550 context,
@@ -594,8 +620,8 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
594 self.zoom_out(cursor); 620 self.zoom_out(cursor);
595 } 621 }
596 // brush ops 622 // brush ops
597 Keycode::Q => self.decrease_brush_size(), 623 Keycode::Q => self.brush.shrink(),
598 Keycode::E => self.increase_brush_size(), 624 Keycode::E => self.brush.grow(),
599 Keycode::Num1 => self.reduce_intensity(), 625 Keycode::Num1 => self.reduce_intensity(),
600 Keycode::Num3 => self.increase_intensity(), 626 Keycode::Num3 => self.increase_intensity(),
601 // flip color 627 // flip color
@@ -650,7 +676,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
650 }; 676 };
651 match self.brush { 677 match self.brush {
652 Brush::Circle { size } => { 678 Brush::Circle { size } => {
653 if let Ok(o) = self.paint_point(pt, val) { 679 if let Ok(o) = self.paint_point(pt, val, size) {
654 self.current_operation.extend(o); 680 self.current_operation.extend(o);
655 } 681 }
656 } 682 }
@@ -666,7 +692,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
666 extend, 692 extend,
667 }; 693 };
668 } else if let Ok(o) = 694 } else if let Ok(o) =
669 self.paint_line(start.unwrap(), pt, val) 695 self.paint_line(start.unwrap(), pt, val, size)
670 { 696 {
671 self.current_operation.extend(o); 697 self.current_operation.extend(o);
672 self.brush = Brush::Line { 698 self.brush = Brush::Line {
@@ -705,16 +731,21 @@ impl<'ctx, 'file> AppState<'ctx, 'file> {
705 Event::MouseMotion { 731 Event::MouseMotion {
706 x, y, mousestate, .. 732 x, y, mousestate, ..
707 } => { 733 } => {
734 let size = match self.brush {
735 Brush::Circle { size } => size,
736 Brush::Line { size, .. } => size,
737 _ => continue,
738 };
708 if mousestate.is_mouse_button_pressed(MouseButton::Left) { 739 if mousestate.is_mouse_button_pressed(MouseButton::Left) {
709 let pt = (x, y); 740 let pt = (x, y);
710 let val = self.active_color; 741 let val = self.active_color;
711 if let Ok(o) = self.paint_point(pt, val) { 742 if let Ok(o) = self.paint_point(pt, val, size) {
712 self.current_operation.extend(o); 743 self.current_operation.extend(o);
713 } 744 }
714 } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { 745 } else if mousestate.is_mouse_button_pressed(MouseButton::Right) {
715 let pt = (x, y); 746 let pt = (x, y);
716 let val = !self.active_color; 747 let val = !self.active_color;
717 if let Ok(o) = self.paint_point(pt, val) { 748 if let Ok(o) = self.paint_point(pt, val, size) {
718 self.current_operation.extend(o); 749 self.current_operation.extend(o);
719 } 750 }
720 } 751 }