From f9dda0f77e018142cee46e2a9ccf7b03b5ab8f21 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 28 Mar 2021 16:31:48 +0530 Subject: restructure Brush enum --- src/app.rs | 101 ++++++++++++++++++++++++++++------------------------------- src/brush.rs | 61 +++++++++++++++++++++--------------- 2 files changed, 83 insertions(+), 79 deletions(-) diff --git a/src/app.rs b/src/app.rs index 42e63de..ea1e893 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,6 @@ use crate::{ bitmap::{positive_angle_with_x, MapPoint, Pixmap}, - brush::Brush, + brush::{Brush, CircleBrush, LineBrush}, command::CommandBox, consts::{colors::*, FONT_PATH}, dither, @@ -8,7 +8,7 @@ use crate::{ message::Message, rect, symmetry::Symmetry, - undo::{ModifyRecord, OpKind, Operation, UndoStack}, + undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, utils::{draw_text, is_copy_event, is_paste_event}, }; @@ -39,7 +39,7 @@ pub struct AppState<'ctx, 'file> { pub canvas: Canvas, pub command_box: CommandBox, pub context: &'ctx Sdl, - pub current_operation: Operation, + pub current_operation: Vec, pub dither_level: u8, pub file_name: Option<&'file Path>, pub grid: Grid, @@ -52,7 +52,7 @@ pub struct AppState<'ctx, 'file> { pub start: Point, pub symmetry: Symmetry, pub ttf_context: &'ctx Sdl2TtfContext, - pub undo_stack: UndoStack, + pub undo_stack: UndoStack, pub zoom: u8, } @@ -146,7 +146,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { center: P, val: bool, brush_size: u8, - ) -> Result, ()> { + ) -> Result, ()> { let radius = brush_size as u32; let center = self.idx_at_coord(center).ok_or(())?; let dither_level = self.dither_level; @@ -162,7 +162,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { .filter(|&pt| dither::bayer(dither_level, pt)) { let old_val = self.pixmap.set(point, val); - modify_record.push(ModifyRecord::new(point, old_val, val)); + modify_record.push(PaintRecord::new(point, old_val, val)); } Ok(modify_record) } @@ -173,7 +173,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { end: P, val: bool, brush_size: u8, - ) -> Result, ()> { + ) -> Result, ()> { let MapPoint { x, y } = start; let end = self.idx_at_coord(end).ok_or(())?; let dither_level = self.dither_level; @@ -189,23 +189,29 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { .filter(|&pt| dither::bayer(dither_level, pt)) { let old_val = self.pixmap.set(c, val); - line_modify_record.push(ModifyRecord::new(c, old_val, val)); + line_modify_record.push(PaintRecord::new(c, old_val, val)); } } Ok(line_modify_record) } - pub fn apply_operation(&mut self, op: Operation, op_kind: OpKind) { - for ModifyRecord { - point, - old_val, - val, - } in op.into_iter() - { - if self.pixmap.contains(point) { + pub fn apply_operation(&mut self, operation: ModifyRecord, op_kind: OpKind) { + match operation { + ModifyRecord::Paint(paints) => { + for PaintRecord { point, old, new } in paints { + if self.pixmap.contains(point) { + match op_kind { + OpKind::Undo => self.pixmap.set(point, old), + OpKind::Redo => self.pixmap.set(point, new), + }; + } + } + } + ModifyRecord::Invert => self.pixmap.invert(), + ModifyRecord::Brush { old, new } => { match op_kind { - OpKind::Undo => self.pixmap.set(point, old_val), - OpKind::Redo => self.pixmap.set(point, val), + OpKind::Undo => self.brush = old, + OpKind::Redo => self.brush = new, }; } } @@ -216,9 +222,9 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { let op = self .current_operation .drain(..) - .filter(|v| !v.old_val == v.val) + .filter(|v| !v.old == v.new) .collect::>(); - self.undo_stack.push(op); + self.undo_stack.push(ModifyRecord::Paint(op)); } } @@ -258,16 +264,6 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { ); } - // pub fn increase_brush_size(&mut self) { - // self.brush_size += 1; - // } - - // pub fn decrease_brush_size(&mut self) { - // if self.brush_size > 0 { - // self.brush_size -= 1; - // } - // } - pub fn reduce_intensity(&mut self) { if self.dither_level > 0 { self.dither_level -= 1; @@ -293,13 +289,6 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { } self.command_box.hist_append(); - // if let Some(path) = self.command_box.text.strip_prefix("(save ") { - // let image = self.export(); - // let encoded = image.encode().unwrap(); - // let mut buffer = File::create(path).unwrap(); - // buffer.write_all(&encoded[..]).unwrap(); - // self.command_box.hist_append(); - // } self.command_box.clear(); self.mode = Mode::Draw; } @@ -425,7 +414,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { } } match self.brush { - Brush::Line { start, size, .. } => { + Brush::Line(LineBrush { start, size, .. }) => { let size = self.zoom as u32 * size as u32; if let (Some(from), Some(to)) = (start, pt) { let line = self.pixmap.get_line(from, to.into()); @@ -629,10 +618,16 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { // toggle grid Keycode::Tab => self.toggle_grid(), // invert canvas - Keycode::I => self.pixmap.invert(), + Keycode::I => { + self.pixmap.invert(); + self.undo_stack.push(ModifyRecord::Invert); + } // line drawing Keycode::F => { - if matches!(self.brush, Brush::Line { extend: false, .. }) { + if matches!( + self.brush, + Brush::Line(LineBrush { extend: false, .. }) + ) { self.brush = Brush::line(0, true); } else { self.brush = Brush::line(0, false); @@ -675,31 +670,31 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { _ => self.active_color, }; match self.brush { - Brush::Circle { size } => { + Brush::Circle(CircleBrush { size }) => { if let Ok(o) = self.paint_point(pt, val, size) { self.current_operation.extend(o); } } - Brush::Line { + Brush::Line(LineBrush { size, start, extend, - } => { + }) => { if start.is_none() { - self.brush = Brush::Line { + self.brush = Brush::Line(LineBrush { size, start: contact, extend, - }; + }); } else if let Ok(o) = self.paint_line(start.unwrap(), pt, val, size) { self.current_operation.extend(o); - self.brush = Brush::Line { + self.brush = Brush::Line(LineBrush { size, start: if extend { contact } else { None }, extend, - }; + }); } } Brush::Fill => { @@ -715,12 +710,12 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { self.current_operation.extend( operation .into_iter() - .map(|point| ModifyRecord { + .map(|point| PaintRecord { point, - old_val: target, - val: self.active_color, + old: target, + new: self.active_color, }) - .collect::>(), + .collect::>(), ) } } @@ -732,8 +727,8 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { x, y, mousestate, .. } => { let size = match self.brush { - Brush::Circle { size } => size, - Brush::Line { size, .. } => size, + Brush::Circle(CircleBrush { size }) => size, + Brush::Line(LineBrush { size, .. }) => size, _ => continue, }; if mousestate.is_mouse_button_pressed(MouseButton::Left) { diff --git a/src/brush.rs b/src/brush.rs index 1a365b1..8ff0cda 100644 --- a/src/brush.rs +++ b/src/brush.rs @@ -4,29 +4,36 @@ use crate::bitmap::MapPoint; #[derive(Debug, Copy, Clone)] pub enum Brush { - Line { - size: u8, - start: Option, - extend: bool, - }, - Circle { - size: u8, - }, - RectSelect { - start: MapPoint, - end: MapPoint, - }, + Line(LineBrush), + Circle(CircleBrush), + RectSelect(RectSelectBrush), Fill, - Custom { - size: u8, - }, + Custom { size: u8 }, +} + +#[derive(Debug, Copy, Clone)] +pub struct LineBrush { + pub size: u8, + pub start: Option, + pub extend: bool, +} + +#[derive(Debug, Copy, Clone)] +pub struct CircleBrush { + pub size: u8, +} + +#[derive(Debug, Copy, Clone)] +pub struct RectSelectBrush { + pub start: MapPoint, + pub end: MapPoint, } impl Brush { pub fn grow(&mut self) { match self { - Brush::Line { ref mut size, .. } => *size += 1, - Brush::Circle { ref mut size, .. } => *size += 1, + Brush::Line(LineBrush { ref mut size, .. }) => *size += 1, + Brush::Circle(CircleBrush { ref mut size, .. }) => *size += 1, Brush::Custom { ref mut size, .. } => *size += 1, _ => (), } @@ -34,23 +41,23 @@ impl Brush { pub fn shrink(&mut self) { match self { - Brush::Line { ref mut size, .. } => *size = size.saturating_sub(1), - Brush::Circle { ref mut size, .. } => *size = size.saturating_sub(1), + Brush::Line(LineBrush { ref mut size, .. }) => *size = size.saturating_sub(1), + Brush::Circle(CircleBrush { ref mut size, .. }) => *size = size.saturating_sub(1), Brush::Custom { ref mut size, .. } => *size = size.saturating_sub(1), _ => (), } } pub fn new(size: u8) -> Self { - Brush::Circle { size } + Brush::Circle(CircleBrush { size }) } pub fn line(size: u8, extend: bool) -> Self { - Brush::Line { + Brush::Line(LineBrush { size, start: None, extend, - } + }) } pub fn is_line(&self) -> bool { @@ -59,8 +66,8 @@ impl Brush { pub fn size(&self) -> Option { match self { - Brush::Line { size, .. } => Some(size.clone()), - Brush::Circle { size } => Some(size.clone()), + Brush::Line(LineBrush { size, .. }) => Some(size.clone()), + Brush::Circle(CircleBrush { size }) => Some(size.clone()), _ => None, } } @@ -69,8 +76,10 @@ impl Brush { impl fmt::Display for Brush { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Brush::Line { extend, .. } => write!(f, "LINE{}", if *extend { "+" } else { "" }), - Brush::Circle { .. } => write!(f, "CIRCLE"), + Brush::Line(LineBrush { extend, .. }) => { + write!(f, "LINE{}", if *extend { "+" } else { "" }) + } + Brush::Circle(..) => write!(f, "CIRCLE"), Brush::RectSelect { .. } => write!(f, "SELECT"), Brush::Fill => write!(f, "FILL"), Brush::Custom { .. } => write!(f, "CUSTOM"), -- cgit v1.2.3