From abcf2b32777ffb934788e3219cacc2bbc048b6a3 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 11 Apr 2021 15:31:32 +0530 Subject: add `selection-start` and `selection-end` primitives --- src/app.rs | 89 +++++++++++++++++++++++++++++++---------------------- src/lisp/eval.rs | 13 ++++---- src/lisp/expr.rs | 6 ++++ src/lisp/number.rs | 7 +++++ src/lisp/prelude.rs | 38 +++++++++++++++++++++-- src/utils.rs | 5 +-- 6 files changed, 111 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/app.rs b/src/app.rs index 83e30e8..2e14dbc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,5 @@ use crate::{ - bitmap::{positive_angle_with_x, abs_difference, Axis, MapPoint, Pixmap}, + bitmap::{abs_difference, positive_angle_with_x, Axis, MapPoint, Pixmap}, brush::{Brush, CircleBrush, LineBrush, RectSelectBrush}, cache::Cache, command::CommandBox, @@ -458,27 +458,34 @@ impl<'ctx> AppState<'ctx> { "{:.width$}°", angle, width = if (angle - ANGLE).abs() < 1e-3 { 3 } else { 0 } - ), - PINK, - (self.mouse.0 + size as i32, self.mouse.1 + size as i32), - ); + ), + PINK, + (self.mouse.0 + size as i32, self.mouse.1 + size as i32), + ); for MapPoint { x, y } in line.into_iter() { self.canvas.set_draw_color(PINK); self.canvas .fill_rect(Rect::new( - x as i32 * cs as i32 + self.start.x(), - y as i32 * cs as i32 + self.start.y(), - cs, - cs, - )) + x as i32 * cs as i32 + self.start.x(), + y as i32 * cs as i32 + self.start.y(), + cs, + cs, + )) .unwrap(); } } } - Brush::RectSelect(RectSelectBrush { start: Some(s), end: Some(e), active_end }) => { + Brush::RectSelect(RectSelectBrush { + start: Some(s), + end: Some(e), + .. + }) => { self.canvas.set_draw_color(PINK); let (width, height) = (abs_difference(s.x, e.x), abs_difference(s.y, e.y)); - let MapPoint{x: start_x, y: start_y} = utils::rect_coords(s, e).0; + let MapPoint { + x: start_x, + y: start_y, + } = utils::rect_coords(s, e).0; let start_loc_x = self.start.x() + (start_x * cs) as i32; let start_loc_y = self.start.y() + (start_y * cs) as i32; draw_text( @@ -488,11 +495,11 @@ impl<'ctx> AppState<'ctx> { PINK, (start_loc_x, start_loc_y - 20), ); - self.canvas.draw_rect( - rect!(start_loc_x, start_loc_y, width * cs, height * cs) - ).unwrap(); + self.canvas + .draw_rect(rect!(start_loc_x, start_loc_y, width * cs, height * cs)) + .unwrap(); } - _ => () + _ => (), } } @@ -748,7 +755,7 @@ impl<'ctx> AppState<'ctx> { Keycode::Escape => { match self.brush { Brush::RectSelect(_) => self.brush = Brush::rect(), - _ => () + _ => (), } continue; } @@ -879,42 +886,50 @@ impl<'ctx> AppState<'ctx> { } => { if mousestate.is_mouse_button_pressed(MouseButton::Left) { match self.brush { - Brush::RectSelect(RectSelectBrush{start, end, active_end}) => { + Brush::RectSelect(RectSelectBrush { + start, + end, + active_end, + }) => { if active_end { - self.brush = Brush::RectSelect(RectSelectBrush{ + self.brush = Brush::RectSelect(RectSelectBrush { start, - end: self.idx_at_coord((x, y)).map(MapPoint::from), - active_end + end: self + .idx_at_coord((x, y)) + .map(MapPoint::from), + active_end, }); } else { - self.brush = Brush::RectSelect(RectSelectBrush{ - start: self.idx_at_coord((x, y)).map(MapPoint::from), + self.brush = Brush::RectSelect(RectSelectBrush { + start: self + .idx_at_coord((x, y)) + .map(MapPoint::from), end, - active_end + active_end, }); } - }, - Brush::Circle(CircleBrush { size }) + } + Brush::Circle(CircleBrush { size }) | Brush::Line(LineBrush { size, .. }) => { let pt = (x, y); let val = self.active_color; if let Ok(o) = self.paint_point(pt, val, size) { self.current_operation.extend(o); } - }, - _ => () + } + _ => (), } } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { match self.brush { - Brush::Circle(CircleBrush { size }) - | Brush::Line(LineBrush { size, .. }) => { - let pt = (x, y); - let val = !self.active_color; - if let Ok(o) = self.paint_point(pt, val, size) { - self.current_operation.extend(o); - } - }, - _ => () + Brush::Circle(CircleBrush { size }) + | Brush::Line(LineBrush { size, .. }) => { + let pt = (x, y); + let val = !self.active_color; + if let Ok(o) = self.paint_point(pt, val, size) { + self.current_operation.extend(o); + } + } + _ => (), } } } diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs index 0cf267c..b404662 100644 --- a/src/lisp/eval.rs +++ b/src/lisp/eval.rs @@ -217,12 +217,13 @@ where pub fn eval_for(&mut self, args: &[LispExpr]) -> Result { let arity = Arity::Exact(2); - let valid_binding_stmt = |expr: &LispExpr| + let valid_binding_stmt = |expr: &LispExpr| { matches!( expr, - LispExpr::List(v) - if v.len() == 2 - && matches!(v[0], LispExpr::Ident(_))); + LispExpr::List(v) + if v.len() == 2 + && matches!(v[0], LispExpr::Ident(_))) + }; if !arity.check(args) { Err(arity.to_error()) @@ -258,8 +259,8 @@ where } _ => { error!("invalid for loop args"); - Err(EvalError::BadForm.into()) - }, + Err(EvalError::BadForm.into()) + } } } } diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs index 692f951..d086ecf 100644 --- a/src/lisp/expr.rs +++ b/src/lisp/expr.rs @@ -310,6 +310,12 @@ impl TryFrom for LispNumber { } } +impl From for LispExpr { + fn from(num: i64) -> Self { + LispExpr::Number(num.into()) + } +} + impl<'a> TryFrom<&'a LispExpr> for &'a LispNumber { type Error = LispError; fn try_from(value: &'a LispExpr) -> Result { diff --git a/src/lisp/number.rs b/src/lisp/number.rs index 4824e21..06c6baa 100644 --- a/src/lisp/number.rs +++ b/src/lisp/number.rs @@ -1,5 +1,6 @@ use std::{ cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}, + convert::From, fmt, ops::{Add, Mul, Sub}, }; @@ -113,3 +114,9 @@ impl fmt::Display for LispNumber { } } } + +impl From for LispNumber { + fn from(target: i64) -> Self { + LispNumber::Integer(target) + } +} diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index e24ade5..1d37a32 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs @@ -1,6 +1,6 @@ use crate::{ bitmap::MapPoint, - brush::Brush, + brush::{Brush, RectSelectBrush}, grid::GridKind, guide::Guide, lisp::{ @@ -11,7 +11,7 @@ use crate::{ }, primitive, undo::PaintRecord, - utils::load_script, + utils::{load_script, rect_coords}, }; use std::convert::TryInto; @@ -437,6 +437,40 @@ pub fn new_env() -> Result { } }); + primitive!(env, Arity::Exact(0), "selection-start", |_, app| { + if let Brush::RectSelect(RectSelectBrush { + start: Some(s), + end: Some(e), + .. + }) = app.brush + { + let pt = rect_coords(s, e).0; + Ok(LispExpr::DottedList(vec![ + (pt.x as i64).into(), + (pt.y as i64).into(), + ])) + } else { + Err(EvalError::CustomInternal("No active selection!").into()) + } + }); + + primitive!(env, Arity::Exact(0), "selection-end", |_, app| { + if let Brush::RectSelect(RectSelectBrush { + start: Some(s), + end: Some(e), + .. + }) = app.brush + { + let pt = rect_coords(s, e).1; + Ok(LispExpr::DottedList(vec![ + (pt.x as i64).into(), + (pt.y as i64).into(), + ])) + } else { + Err(EvalError::CustomInternal("No active selection!").into()) + } + }); + primitive!(env, Arity::Exact(2), "range", |args, _| { if type_match!( args, diff --git a/src/utils.rs b/src/utils.rs index 0825c8c..d5d4039 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,7 @@ use crate::{ app::AppState, - consts::FONT_PATH, bitmap::{abs_difference, MapPoint}, + consts::FONT_PATH, lisp::{ error::{EvalError, LispError, ParseError}, eval::Evaluator, @@ -143,7 +143,8 @@ pub fn rect_coords(s: MapPoint, e: MapPoint) -> (MapPoint, MapPoint) { (e.x, s.y) } else { (e.x, e.y) - }.into(); + } + .into(); let end_loc = start_loc + (width, height).into(); (start_loc, end_loc) } -- cgit v1.2.3