aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.rs89
-rw-r--r--src/lisp/eval.rs13
-rw-r--r--src/lisp/expr.rs6
-rw-r--r--src/lisp/number.rs7
-rw-r--r--src/lisp/prelude.rs38
-rw-r--r--src/utils.rs5
6 files changed, 111 insertions, 47 deletions
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 @@
1use crate::{ 1use crate::{
2 bitmap::{positive_angle_with_x, abs_difference, Axis, MapPoint, Pixmap}, 2 bitmap::{abs_difference, positive_angle_with_x, Axis, MapPoint, Pixmap},
3 brush::{Brush, CircleBrush, LineBrush, RectSelectBrush}, 3 brush::{Brush, CircleBrush, LineBrush, RectSelectBrush},
4 cache::Cache, 4 cache::Cache,
5 command::CommandBox, 5 command::CommandBox,
@@ -458,27 +458,34 @@ impl<'ctx> AppState<'ctx> {
458 "{:.width$}°", 458 "{:.width$}°",
459 angle, 459 angle,
460 width = if (angle - ANGLE).abs() < 1e-3 { 3 } else { 0 } 460 width = if (angle - ANGLE).abs() < 1e-3 { 3 } else { 0 }
461 ), 461 ),
462 PINK, 462 PINK,
463 (self.mouse.0 + size as i32, self.mouse.1 + size as i32), 463 (self.mouse.0 + size as i32, self.mouse.1 + size as i32),
464 ); 464 );
465 for MapPoint { x, y } in line.into_iter() { 465 for MapPoint { x, y } in line.into_iter() {
466 self.canvas.set_draw_color(PINK); 466 self.canvas.set_draw_color(PINK);
467 self.canvas 467 self.canvas
468 .fill_rect(Rect::new( 468 .fill_rect(Rect::new(
469 x as i32 * cs as i32 + self.start.x(), 469 x as i32 * cs as i32 + self.start.x(),
470 y as i32 * cs as i32 + self.start.y(), 470 y as i32 * cs as i32 + self.start.y(),
471 cs, 471 cs,
472 cs, 472 cs,
473 )) 473 ))
474 .unwrap(); 474 .unwrap();
475 } 475 }
476 } 476 }
477 } 477 }
478 Brush::RectSelect(RectSelectBrush { start: Some(s), end: Some(e), active_end }) => { 478 Brush::RectSelect(RectSelectBrush {
479 start: Some(s),
480 end: Some(e),
481 ..
482 }) => {
479 self.canvas.set_draw_color(PINK); 483 self.canvas.set_draw_color(PINK);
480 let (width, height) = (abs_difference(s.x, e.x), abs_difference(s.y, e.y)); 484 let (width, height) = (abs_difference(s.x, e.x), abs_difference(s.y, e.y));
481 let MapPoint{x: start_x, y: start_y} = utils::rect_coords(s, e).0; 485 let MapPoint {
486 x: start_x,
487 y: start_y,
488 } = utils::rect_coords(s, e).0;
482 let start_loc_x = self.start.x() + (start_x * cs) as i32; 489 let start_loc_x = self.start.x() + (start_x * cs) as i32;
483 let start_loc_y = self.start.y() + (start_y * cs) as i32; 490 let start_loc_y = self.start.y() + (start_y * cs) as i32;
484 draw_text( 491 draw_text(
@@ -488,11 +495,11 @@ impl<'ctx> AppState<'ctx> {
488 PINK, 495 PINK,
489 (start_loc_x, start_loc_y - 20), 496 (start_loc_x, start_loc_y - 20),
490 ); 497 );
491 self.canvas.draw_rect( 498 self.canvas
492 rect!(start_loc_x, start_loc_y, width * cs, height * cs) 499 .draw_rect(rect!(start_loc_x, start_loc_y, width * cs, height * cs))
493 ).unwrap(); 500 .unwrap();
494 } 501 }
495 _ => () 502 _ => (),
496 } 503 }
497 } 504 }
498 505
@@ -748,7 +755,7 @@ impl<'ctx> AppState<'ctx> {
748 Keycode::Escape => { 755 Keycode::Escape => {
749 match self.brush { 756 match self.brush {
750 Brush::RectSelect(_) => self.brush = Brush::rect(), 757 Brush::RectSelect(_) => self.brush = Brush::rect(),
751 _ => () 758 _ => (),
752 } 759 }
753 continue; 760 continue;
754 } 761 }
@@ -879,42 +886,50 @@ impl<'ctx> AppState<'ctx> {
879 } => { 886 } => {
880 if mousestate.is_mouse_button_pressed(MouseButton::Left) { 887 if mousestate.is_mouse_button_pressed(MouseButton::Left) {
881 match self.brush { 888 match self.brush {
882 Brush::RectSelect(RectSelectBrush{start, end, active_end}) => { 889 Brush::RectSelect(RectSelectBrush {
890 start,
891 end,
892 active_end,
893 }) => {
883 if active_end { 894 if active_end {
884 self.brush = Brush::RectSelect(RectSelectBrush{ 895 self.brush = Brush::RectSelect(RectSelectBrush {
885 start, 896 start,
886 end: self.idx_at_coord((x, y)).map(MapPoint::from), 897 end: self
887 active_end 898 .idx_at_coord((x, y))
899 .map(MapPoint::from),
900 active_end,
888 }); 901 });
889 } else { 902 } else {
890 self.brush = Brush::RectSelect(RectSelectBrush{ 903 self.brush = Brush::RectSelect(RectSelectBrush {
891 start: self.idx_at_coord((x, y)).map(MapPoint::from), 904 start: self
905 .idx_at_coord((x, y))
906 .map(MapPoint::from),
892 end, 907 end,
893 active_end 908 active_end,
894 }); 909 });
895 } 910 }
896 }, 911 }
897 Brush::Circle(CircleBrush { size }) 912 Brush::Circle(CircleBrush { size })
898 | Brush::Line(LineBrush { size, .. }) => { 913 | Brush::Line(LineBrush { size, .. }) => {
899 let pt = (x, y); 914 let pt = (x, y);
900 let val = self.active_color; 915 let val = self.active_color;
901 if let Ok(o) = self.paint_point(pt, val, size) { 916 if let Ok(o) = self.paint_point(pt, val, size) {
902 self.current_operation.extend(o); 917 self.current_operation.extend(o);
903 } 918 }
904 }, 919 }
905 _ => () 920 _ => (),
906 } 921 }
907 } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { 922 } else if mousestate.is_mouse_button_pressed(MouseButton::Right) {
908 match self.brush { 923 match self.brush {
909 Brush::Circle(CircleBrush { size }) 924 Brush::Circle(CircleBrush { size })
910 | Brush::Line(LineBrush { size, .. }) => { 925 | Brush::Line(LineBrush { size, .. }) => {
911 let pt = (x, y); 926 let pt = (x, y);
912 let val = !self.active_color; 927 let val = !self.active_color;
913 if let Ok(o) = self.paint_point(pt, val, size) { 928 if let Ok(o) = self.paint_point(pt, val, size) {
914 self.current_operation.extend(o); 929 self.current_operation.extend(o);
915 } 930 }
916 }, 931 }
917 _ => () 932 _ => (),
918 } 933 }
919 } 934 }
920 } 935 }
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
217 217
218 pub fn eval_for(&mut self, args: &[LispExpr]) -> Result<LispExpr, LispError> { 218 pub fn eval_for(&mut self, args: &[LispExpr]) -> Result<LispExpr, LispError> {
219 let arity = Arity::Exact(2); 219 let arity = Arity::Exact(2);
220 let valid_binding_stmt = |expr: &LispExpr| 220 let valid_binding_stmt = |expr: &LispExpr| {
221 matches!( 221 matches!(
222 expr, 222 expr,
223 LispExpr::List(v) 223 LispExpr::List(v)
224 if v.len() == 2 224 if v.len() == 2
225 && matches!(v[0], LispExpr::Ident(_))); 225 && matches!(v[0], LispExpr::Ident(_)))
226 };
226 227
227 if !arity.check(args) { 228 if !arity.check(args) {
228 Err(arity.to_error()) 229 Err(arity.to_error())
@@ -258,8 +259,8 @@ where
258 } 259 }
259 _ => { 260 _ => {
260 error!("invalid for loop args"); 261 error!("invalid for loop args");
261 Err(EvalError::BadForm.into()) 262 Err(EvalError::BadForm.into())
262 }, 263 }
263 } 264 }
264 } 265 }
265 } 266 }
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<LispExpr> for LispNumber {
310 } 310 }
311} 311}
312 312
313impl From<i64> for LispExpr {
314 fn from(num: i64) -> Self {
315 LispExpr::Number(num.into())
316 }
317}
318
313impl<'a> TryFrom<&'a LispExpr> for &'a LispNumber { 319impl<'a> TryFrom<&'a LispExpr> for &'a LispNumber {
314 type Error = LispError; 320 type Error = LispError;
315 fn try_from(value: &'a LispExpr) -> Result<Self, Self::Error> { 321 fn try_from(value: &'a LispExpr) -> Result<Self, Self::Error> {
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 @@
1use std::{ 1use std::{
2 cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}, 2 cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
3 convert::From,
3 fmt, 4 fmt,
4 ops::{Add, Mul, Sub}, 5 ops::{Add, Mul, Sub},
5}; 6};
@@ -113,3 +114,9 @@ impl fmt::Display for LispNumber {
113 } 114 }
114 } 115 }
115} 116}
117
118impl From<i64> for LispNumber {
119 fn from(target: i64) -> Self {
120 LispNumber::Integer(target)
121 }
122}
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 @@
1use crate::{ 1use crate::{
2 bitmap::MapPoint, 2 bitmap::MapPoint,
3 brush::Brush, 3 brush::{Brush, RectSelectBrush},
4 grid::GridKind, 4 grid::GridKind,
5 guide::Guide, 5 guide::Guide,
6 lisp::{ 6 lisp::{
@@ -11,7 +11,7 @@ use crate::{
11 }, 11 },
12 primitive, 12 primitive,
13 undo::PaintRecord, 13 undo::PaintRecord,
14 utils::load_script, 14 utils::{load_script, rect_coords},
15}; 15};
16 16
17use std::convert::TryInto; 17use std::convert::TryInto;
@@ -437,6 +437,40 @@ pub fn new_env() -> Result<Environment, LispError> {
437 } 437 }
438 }); 438 });
439 439
440 primitive!(env, Arity::Exact(0), "selection-start", |_, app| {
441 if let Brush::RectSelect(RectSelectBrush {
442 start: Some(s),
443 end: Some(e),
444 ..
445 }) = app.brush
446 {
447 let pt = rect_coords(s, e).0;
448 Ok(LispExpr::DottedList(vec![
449 (pt.x as i64).into(),
450 (pt.y as i64).into(),
451 ]))
452 } else {
453 Err(EvalError::CustomInternal("No active selection!").into())
454 }
455 });
456
457 primitive!(env, Arity::Exact(0), "selection-end", |_, app| {
458 if let Brush::RectSelect(RectSelectBrush {
459 start: Some(s),
460 end: Some(e),
461 ..
462 }) = app.brush
463 {
464 let pt = rect_coords(s, e).1;
465 Ok(LispExpr::DottedList(vec![
466 (pt.x as i64).into(),
467 (pt.y as i64).into(),
468 ]))
469 } else {
470 Err(EvalError::CustomInternal("No active selection!").into())
471 }
472 });
473
440 primitive!(env, Arity::Exact(2), "range", |args, _| { 474 primitive!(env, Arity::Exact(2), "range", |args, _| {
441 if type_match!( 475 if type_match!(
442 args, 476 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 @@
1use crate::{ 1use crate::{
2 app::AppState, 2 app::AppState,
3 consts::FONT_PATH,
4 bitmap::{abs_difference, MapPoint}, 3 bitmap::{abs_difference, MapPoint},
4 consts::FONT_PATH,
5 lisp::{ 5 lisp::{
6 error::{EvalError, LispError, ParseError}, 6 error::{EvalError, LispError, ParseError},
7 eval::Evaluator, 7 eval::Evaluator,
@@ -143,7 +143,8 @@ pub fn rect_coords(s: MapPoint, e: MapPoint) -> (MapPoint, MapPoint) {
143 (e.x, s.y) 143 (e.x, s.y)
144 } else { 144 } else {
145 (e.x, e.y) 145 (e.x, e.y)
146 }.into(); 146 }
147 .into();
147 let end_loc = start_loc + (width, height).into(); 148 let end_loc = start_loc + (width, height).into();
148 (start_loc, end_loc) 149 (start_loc, end_loc)
149} 150}