diff options
author | Akshay <[email protected]> | 2021-04-11 11:01:32 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-04-12 11:02:49 +0100 |
commit | abcf2b32777ffb934788e3219cacc2bbc048b6a3 (patch) | |
tree | d310c7d2c69531a4583dac7ab34705f6ae5c12c7 | |
parent | b0685c1638044b85dc7e8b07555a7b639b54d69a (diff) |
add `selection-start` and `selection-end` primitives
l--------- | .direnv/flake-profile | 2 | ||||
-rw-r--r-- | .direnv/flake-profile.rc | 4 | ||||
-rw-r--r-- | flake.nix | 104 | ||||
-rw-r--r-- | src/app.rs | 89 | ||||
-rw-r--r-- | src/lisp/eval.rs | 13 | ||||
-rw-r--r-- | src/lisp/expr.rs | 6 | ||||
-rw-r--r-- | src/lisp/number.rs | 7 | ||||
-rw-r--r-- | src/lisp/prelude.rs | 38 | ||||
-rw-r--r-- | src/utils.rs | 5 |
9 files changed, 165 insertions, 103 deletions
diff --git a/.direnv/flake-profile b/.direnv/flake-profile index caea00d..5d2798d 120000 --- a/.direnv/flake-profile +++ b/.direnv/flake-profile | |||
@@ -1 +1 @@ | |||
/nix/store/9dsqn6si93g5gs60rlka4xjcx36m5jyj-nix-shell-env \ No newline at end of file | /nix/store/w4hwpczf7xldw1qvgmwc63j4yzrr14nh-nix-shell-env \ No newline at end of file | ||
diff --git a/.direnv/flake-profile.rc b/.direnv/flake-profile.rc index 81165b8..40c99ee 100644 --- a/.direnv/flake-profile.rc +++ b/.direnv/flake-profile.rc | |||
@@ -32,7 +32,7 @@ NIX_CC=/nix/store/ca37d3qrydh0wpw40kswsx30j8dyzxh2-gcc-wrapper-10.2.0 | |||
32 | export NIX_CC | 32 | export NIX_CC |
33 | NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1 | 33 | NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1 |
34 | export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu | 34 | export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu |
35 | NIX_CFLAGS_COMPILE=' -frandom-seed=9dsqn6si93 -isystem /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include -isystem /nix/store/5sphs39wg8gyy5pcrcml5pyj1wrn9jil-libGL-1.3.2-dev/include -isystem /nix/store/skwk7hmzwpjvhgjf1y633l01p114xc6n-libglvnd-1.3.2-dev/include -isystem /nix/store/3y6j0k82fdp3ifnq655yv1ad1ih7r70j-libX11-1.7.0-dev/include -isystem /nix/store/vjimy2jlifszmmms664373jdw0yiz4ln-xorgproto-2020.1/include -isystem /nix/store/6xg7mhwh2k7i27r44lx679diwd7ahq6d-libxcb-1.14-dev/include -isystem /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include -isystem /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include -isystem /nix/store/5sphs39wg8gyy5pcrcml5pyj1wrn9jil-libGL-1.3.2-dev/include -isystem /nix/store/skwk7hmzwpjvhgjf1y633l01p114xc6n-libglvnd-1.3.2-dev/include -isystem /nix/store/3y6j0k82fdp3ifnq655yv1ad1ih7r70j-libX11-1.7.0-dev/include -isystem /nix/store/vjimy2jlifszmmms664373jdw0yiz4ln-xorgproto-2020.1/include -isystem /nix/store/6xg7mhwh2k7i27r44lx679diwd7ahq6d-libxcb-1.14-dev/include -isystem /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include' | 35 | NIX_CFLAGS_COMPILE=' -frandom-seed=w4hwpczf7x -isystem /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include -isystem /nix/store/5sphs39wg8gyy5pcrcml5pyj1wrn9jil-libGL-1.3.2-dev/include -isystem /nix/store/skwk7hmzwpjvhgjf1y633l01p114xc6n-libglvnd-1.3.2-dev/include -isystem /nix/store/3y6j0k82fdp3ifnq655yv1ad1ih7r70j-libX11-1.7.0-dev/include -isystem /nix/store/vjimy2jlifszmmms664373jdw0yiz4ln-xorgproto-2020.1/include -isystem /nix/store/6xg7mhwh2k7i27r44lx679diwd7ahq6d-libxcb-1.14-dev/include -isystem /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include -isystem /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include -isystem /nix/store/5sphs39wg8gyy5pcrcml5pyj1wrn9jil-libGL-1.3.2-dev/include -isystem /nix/store/skwk7hmzwpjvhgjf1y633l01p114xc6n-libglvnd-1.3.2-dev/include -isystem /nix/store/3y6j0k82fdp3ifnq655yv1ad1ih7r70j-libX11-1.7.0-dev/include -isystem /nix/store/vjimy2jlifszmmms664373jdw0yiz4ln-xorgproto-2020.1/include -isystem /nix/store/6xg7mhwh2k7i27r44lx679diwd7ahq6d-libxcb-1.14-dev/include -isystem /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include' |
36 | export NIX_CFLAGS_COMPILE | 36 | export NIX_CFLAGS_COMPILE |
37 | NIX_ENFORCE_NO_NATIVE=1 | 37 | NIX_ENFORCE_NO_NATIVE=1 |
38 | export NIX_ENFORCE_NO_NATIVE | 38 | export NIX_ENFORCE_NO_NATIVE |
@@ -67,7 +67,7 @@ RUST_BACKTRACE=1 | |||
67 | export RUST_BACKTRACE | 67 | export RUST_BACKTRACE |
68 | RUST_LOG=info | 68 | RUST_LOG=info |
69 | export RUST_LOG | 69 | export RUST_LOG |
70 | RUST_SRC_PATH=/nix/store/wfv522w143y3yxx8ap3fkpjk9cnh1w3a-rust-lib-src | 70 | RUST_SRC_PATH=/nix/store/znf8wv5xxzrbq7jq0bxmjxsimgnbxnn8-rust-src-1.53.0-nightly-2021-03-30-74874a690/lib/rustlib/src/rust/library |
71 | export RUST_SRC_PATH | 71 | export RUST_SRC_PATH |
72 | SDL2_PATH='/nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2 /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2 /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2' | 72 | SDL2_PATH='/nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2 /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2 /nix/store/gkqv9ia81dmmjqcn46ih5yirbzjy7s9p-SDL2-2.0.14-dev/include/SDL2 /nix/store/qx325fjgyhy5cql0fkbkzzbi9dpd2cb8-SDL2_ttf-2.0.15/include/SDL2' |
73 | export SDL2_PATH | 73 | export SDL2_PATH |
@@ -6,9 +6,9 @@ | |||
6 | url = "github:mozilla/nixpkgs-mozilla"; | 6 | url = "github:mozilla/nixpkgs-mozilla"; |
7 | flake = false; | 7 | flake = false; |
8 | }; | 8 | }; |
9 | gitignore = { | 9 | gitignore = { |
10 | url = "github:hercules-ci/gitignore"; | 10 | url = "github:hercules-ci/gitignore"; |
11 | flake=false; | 11 | flake = false; |
12 | }; | 12 | }; |
13 | flake-compat = { | 13 | flake-compat = { |
14 | url = "github:edolstra/flake-compat"; | 14 | url = "github:edolstra/flake-compat"; |
@@ -17,59 +17,57 @@ | |||
17 | }; | 17 | }; |
18 | 18 | ||
19 | outputs = { self, nixpkgs, utils, naersk, mozillapkgs, gitignore, ... }: | 19 | outputs = { self, nixpkgs, utils, naersk, mozillapkgs, gitignore, ... }: |
20 | utils.lib.eachDefaultSystem (system: | 20 | utils.lib.eachDefaultSystem (system: |
21 | let | 21 | let |
22 | pkgs = nixpkgs.legacyPackages."${system}"; | 22 | pkgs = nixpkgs.legacyPackages."${system}"; |
23 | inherit (import gitignore { inherit (pkgs) lib; }) gitignoreSource; | 23 | inherit (import gitignore { inherit (pkgs) lib; }) gitignoreSource; |
24 | |||
25 | # Get a specific rust version | ||
26 | mozilla = pkgs.callPackage (mozillapkgs + "/package-set.nix") {}; | ||
27 | 24 | ||
28 | rust = (mozilla.rustChannelOf { | 25 | # Get a specific rust version |
29 | date = "2021-03-31"; | 26 | mozilla = pkgs.callPackage (mozillapkgs + "/package-set.nix") { }; |
30 | channel = "nightly"; | 27 | chanspec = { |
31 | sha256 = "oK5ebje09MRn988saJMT3Zze/tRE7u9zTeFPV1CEeLc="; # set zeros after modifying channel or date | 28 | date = "2021-03-31"; |
32 | }).rust; | 29 | channel = "nightly"; |
30 | sha256 = "oK5ebje09MRn988saJMT3Zze/tRE7u9zTeFPV1CEeLc="; # set zeros after modifying channel or date | ||
31 | }; | ||
33 | 32 | ||
34 | rust-src = (mozilla.rustChannelOf { | 33 | rustChannel = mozilla.rustChannelOf chanspec; |
35 | date = "2021-03-31"; | 34 | rust = rustChannel.rust; |
36 | channel = "nightly"; | 35 | rust-src = rustChannel.rust-src; |
37 | sha256 = "oK5ebje09MRn988saJMT3Zze/tRE7u9zTeFPV1CEeLc="; # set zeros after modifying channel or date | ||
38 | }).rust-src; | ||
39 | 36 | ||
40 | naersk-lib = naersk.lib."${system}".override { | 37 | naersk-lib = naersk.lib."${system}".override { |
41 | cargo = rust; | 38 | cargo = rust; |
42 | rustc = rust; | 39 | rustc = rust; |
43 | }; | 40 | }; |
44 | 41 | ||
45 | nativeBuildInputs = with pkgs; [ | 42 | nativeBuildInputs = with pkgs; [ |
46 | SDL2 | 43 | SDL2 |
47 | SDL2_ttf | 44 | SDL2_ttf |
48 | ]; | 45 | ]; |
49 | 46 | ||
50 | in rec { | 47 | in |
51 | packages.my-project = naersk-lib.buildPackage { | 48 | rec { |
52 | pname = "sdl-tests"; | 49 | packages.my-project = naersk-lib.buildPackage { |
53 | version = "0.1.0"; | 50 | pname = "sdl-tests"; |
54 | root = gitignoreSource ./.; | 51 | version = "0.1.0"; |
55 | inherit nativeBuildInputs; | 52 | root = gitignoreSource ./.; |
56 | }; | 53 | inherit nativeBuildInputs; |
57 | defaultPackage = packages.my-project; | 54 | }; |
58 | apps.my-project = utils.lib.mkApp { | 55 | defaultPackage = packages.my-project; |
59 | drv = packages.my-project; | 56 | apps.my-project = utils.lib.mkApp { |
60 | }; | 57 | drv = packages.my-project; |
61 | defaultApp = apps.my-project; | 58 | }; |
62 | devShell = pkgs.mkShell { | 59 | defaultApp = apps.my-project; |
63 | nativeBuildInputs = nativeBuildInputs ++ (with pkgs; [ | 60 | devShell = pkgs.mkShell { |
64 | rust | 61 | nativeBuildInputs = nativeBuildInputs ++ [ |
65 | rust-src | 62 | rust |
66 | rust-analyzer | 63 | rust-src |
67 | rustfmt | 64 | pkgs.rust-analyzer |
68 | cargo | 65 | pkgs.rustfmt |
69 | ]); | 66 | pkgs.cargo |
70 | RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; | 67 | ]; |
71 | RUST_LOG="info"; | 68 | RUST_SRC_PATH = "${rust-src}/lib/rustlib/src/rust/library"; |
72 | RUST_BACKTRACE=1; | 69 | RUST_LOG = "info"; |
73 | }; | 70 | RUST_BACKTRACE = 1; |
74 | }); | 71 | }; |
72 | }); | ||
75 | } | 73 | } |
@@ -1,5 +1,5 @@ | |||
1 | use crate::{ | 1 | use 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 | ||
313 | impl From<i64> for LispExpr { | ||
314 | fn from(num: i64) -> Self { | ||
315 | LispExpr::Number(num.into()) | ||
316 | } | ||
317 | } | ||
318 | |||
313 | impl<'a> TryFrom<&'a LispExpr> for &'a LispNumber { | 319 | impl<'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 @@ | |||
1 | use std::{ | 1 | use 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 | |||
118 | impl 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 @@ | |||
1 | use crate::{ | 1 | use 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 | ||
17 | use std::convert::TryInto; | 17 | use 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 @@ | |||
1 | use crate::{ | 1 | use 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 | } |