diff options
-rw-r--r-- | src/app.rs | 8 | ||||
-rw-r--r-- | src/bitmap.rs | 30 | ||||
-rw-r--r-- | src/guide.rs | 22 | ||||
-rw-r--r-- | src/lisp/expr.rs | 14 | ||||
-rw-r--r-- | src/lisp/prelude.rs | 15 |
5 files changed, 76 insertions, 13 deletions
@@ -1,22 +1,24 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | bitmap::{positive_angle_with_x, MapPoint, Pixmap}, | 2 | bitmap::{positive_angle_with_x, Axis, MapPoint, Pixmap}, |
3 | brush::{Brush, CircleBrush, LineBrush}, | 3 | brush::{Brush, CircleBrush, LineBrush}, |
4 | cache::Cache, | 4 | cache::Cache, |
5 | command::CommandBox, | 5 | command::CommandBox, |
6 | consts::{colors::*, FONT_PATH, RC_PATH, STDLIB_PATH}, | 6 | consts::{colors::*, FONT_PATH, RC_PATH, STDLIB_PATH}, |
7 | dither, | 7 | dither, |
8 | error::AppError, | 8 | error::AppError, |
9 | guide::Guide, | ||
9 | lisp::{eval, lex::Lexer, parse::Parser, prelude, EnvList}, | 10 | lisp::{eval, lex::Lexer, parse::Parser, prelude, EnvList}, |
10 | message::Message, | 11 | message::Message, |
11 | rect, | 12 | rect, |
12 | symmetry::Symmetry, | 13 | symmetry::Symmetry, |
13 | undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, | 14 | undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, |
14 | utils::{draw_text, handle_error, is_copy_event, is_paste_event, load_script}, | 15 | utils::{self, draw_text, handle_error, is_copy_event, is_paste_event, load_script}, |
15 | widget::{Container, HorAlign, Offset, Size, VertAlign}, | 16 | widget::{Container, HorAlign, Offset, Size, VertAlign}, |
16 | }; | 17 | }; |
17 | 18 | ||
18 | use std::{ | 19 | use std::{ |
19 | cell::RefCell, | 20 | cell::RefCell, |
21 | collections::HashMap, | ||
20 | convert::From, | 22 | convert::From, |
21 | fs::File, | 23 | fs::File, |
22 | io::prelude::*, | 24 | io::prelude::*, |
@@ -52,6 +54,7 @@ pub struct AppState<'ctx> { | |||
52 | pub current_operation: Vec<PaintRecord>, | 54 | pub current_operation: Vec<PaintRecord>, |
53 | pub dither_level: u8, | 55 | pub dither_level: u8, |
54 | pub file_name: Option<PathBuf>, | 56 | pub file_name: Option<PathBuf>, |
57 | pub guides: HashMap<Guide, bool>, | ||
55 | pub grid: Grid, | 58 | pub grid: Grid, |
56 | pub lisp_env: EnvList, | 59 | pub lisp_env: EnvList, |
57 | pub message: Message, | 60 | pub message: Message, |
@@ -604,6 +607,7 @@ impl<'ctx> AppState<'ctx> { | |||
604 | command_box: CommandBox::new(), | 607 | command_box: CommandBox::new(), |
605 | context, | 608 | context, |
606 | cache: RefCell::new(None), | 609 | cache: RefCell::new(None), |
610 | guides: HashMap::new(), | ||
607 | current_operation: Vec::new(), | 611 | current_operation: Vec::new(), |
608 | dither_level: 16, | 612 | dither_level: 16, |
609 | file_name, | 613 | file_name, |
diff --git a/src/bitmap.rs b/src/bitmap.rs index 2bf8556..8010a4b 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs | |||
@@ -4,6 +4,8 @@ use std::{ | |||
4 | ops::{Add, Sub}, | 4 | ops::{Add, Sub}, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use crate::lisp::{error::EvalError, expr::LispExpr}; | ||
8 | |||
7 | #[derive(Debug)] | 9 | #[derive(Debug)] |
8 | pub struct Pixmap<T> { | 10 | pub struct Pixmap<T> { |
9 | pub width: u32, | 11 | pub width: u32, |
@@ -71,12 +73,38 @@ impl Sub for MapPoint { | |||
71 | } | 73 | } |
72 | } | 74 | } |
73 | 75 | ||
74 | #[derive(Debug, Copy, Clone)] | 76 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
75 | pub enum Axis { | 77 | pub enum Axis { |
76 | X, | 78 | X, |
77 | Y, | 79 | Y, |
78 | } | 80 | } |
79 | 81 | ||
82 | impl Into<LispExpr> for Axis { | ||
83 | fn into(self) -> LispExpr { | ||
84 | LispExpr::Quote( | ||
85 | Box::new(LispExpr::Ident(match self { | ||
86 | Self::X => "X".into(), | ||
87 | Self::Y => "Y".into(), | ||
88 | })), | ||
89 | 1, | ||
90 | ) | ||
91 | } | ||
92 | } | ||
93 | |||
94 | impl TryFrom<&LispExpr> for Axis { | ||
95 | type Error = EvalError; | ||
96 | fn try_from(value: &LispExpr) -> Result<Self, Self::Error> { | ||
97 | match value { | ||
98 | LispExpr::Ident(id) => match id.as_ref() { | ||
99 | "x" => Ok(Axis::X), | ||
100 | "y" => Ok(Axis::Y), | ||
101 | _ => Err(EvalError::TypeMismatch), | ||
102 | }, | ||
103 | _ => Err(EvalError::TypeMismatch), | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
80 | #[derive(Debug, Copy, Clone)] | 108 | #[derive(Debug, Copy, Clone)] |
81 | pub enum Quadrant { | 109 | pub enum Quadrant { |
82 | I, | 110 | I, |
diff --git a/src/guide.rs b/src/guide.rs index 006566e..85d0594 100644 --- a/src/guide.rs +++ b/src/guide.rs | |||
@@ -1,7 +1,21 @@ | |||
1 | use crate::bitmap::Axis; | 1 | use crate::{ |
2 | bitmap::Axis, | ||
3 | lisp::{expr::LispExpr, number::LispNumber}, | ||
4 | }; | ||
2 | 5 | ||
3 | #[derive(Debug)] | 6 | use std::convert::Into; |
7 | |||
8 | #[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)] | ||
4 | pub struct Guide { | 9 | pub struct Guide { |
5 | axis: Axis, | 10 | pub axis: Axis, |
6 | offset: u32, | 11 | pub offset: u32, |
12 | } | ||
13 | |||
14 | impl Into<LispExpr> for Guide { | ||
15 | fn into(self) -> LispExpr { | ||
16 | LispExpr::List(vec![ | ||
17 | self.axis.into(), | ||
18 | LispExpr::Number(LispNumber::Integer(self.offset as i64)), | ||
19 | ]) | ||
20 | } | ||
7 | } | 21 | } |
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs index 2319601..d2066e7 100644 --- a/src/lisp/expr.rs +++ b/src/lisp/expr.rs | |||
@@ -1,11 +1,13 @@ | |||
1 | use std::{cmp::PartialEq, convert::TryFrom, fmt}; | 1 | use std::{cmp::PartialEq, convert::TryFrom, fmt}; |
2 | 2 | ||
3 | use crate::app::AppState; | 3 | use crate::{ |
4 | use crate::lisp::{ | 4 | app::AppState, |
5 | error::{EvalError, LispError}, | 5 | lisp::{ |
6 | eval::lookup, | 6 | error::{EvalError, LispError}, |
7 | number::LispNumber, | 7 | eval::lookup, |
8 | EnvList, | 8 | number::LispNumber, |
9 | EnvList, | ||
10 | }, | ||
9 | }; | 11 | }; |
10 | 12 | ||
11 | #[derive(Debug, Copy, PartialEq, Clone)] | 13 | #[derive(Debug, Copy, PartialEq, Clone)] |
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index 336dbaf..aebff98 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | bitmap::MapPoint, | 2 | bitmap::MapPoint, |
3 | brush::Brush, | 3 | brush::Brush, |
4 | guide::Guide, | ||
4 | lisp::{ | 5 | lisp::{ |
5 | error::{EvalError, LispError}, | 6 | error::{EvalError, LispError}, |
6 | expr::{Arity, LispExpr}, | 7 | expr::{Arity, LispExpr}, |
@@ -413,5 +414,19 @@ pub fn new_env() -> Result<Environment, LispError> { | |||
413 | return Ok(LispExpr::Unit); | 414 | return Ok(LispExpr::Unit); |
414 | }); | 415 | }); |
415 | 416 | ||
417 | primitive!(env, Arity::Exact(2), "add-guide!", |args, app| { | ||
418 | match args { | ||
419 | [axis, LispExpr::Number(LispNumber::Integer(offset))] => { | ||
420 | let guide = Guide { | ||
421 | axis: axis.try_into()?, | ||
422 | offset: *offset as u32, | ||
423 | }; | ||
424 | app.guides.insert(guide, true); | ||
425 | return Ok(LispExpr::Unit); | ||
426 | } | ||
427 | _ => return Err(EvalError::TypeMismatch.into()), | ||
428 | } | ||
429 | }); | ||
430 | |||
416 | Ok(env) | 431 | Ok(env) |
417 | } | 432 | } |