From c4354e2d8d51cc9fc12dce9ad2d5736e400a8de4 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 4 Apr 2021 15:39:17 +0530 Subject: basic support for adding guides --- src/app.rs | 8 ++++++-- src/bitmap.rs | 30 +++++++++++++++++++++++++++++- src/guide.rs | 22 ++++++++++++++++++---- src/lisp/expr.rs | 14 ++++++++------ src/lisp/prelude.rs | 15 +++++++++++++++ 5 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/app.rs b/src/app.rs index 4a4e2cc..243b196 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,22 +1,24 @@ use crate::{ - bitmap::{positive_angle_with_x, MapPoint, Pixmap}, + bitmap::{positive_angle_with_x, Axis, MapPoint, Pixmap}, brush::{Brush, CircleBrush, LineBrush}, cache::Cache, command::CommandBox, consts::{colors::*, FONT_PATH, RC_PATH, STDLIB_PATH}, dither, error::AppError, + guide::Guide, lisp::{eval, lex::Lexer, parse::Parser, prelude, EnvList}, message::Message, rect, symmetry::Symmetry, undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, - utils::{draw_text, handle_error, is_copy_event, is_paste_event, load_script}, + utils::{self, draw_text, handle_error, is_copy_event, is_paste_event, load_script}, widget::{Container, HorAlign, Offset, Size, VertAlign}, }; use std::{ cell::RefCell, + collections::HashMap, convert::From, fs::File, io::prelude::*, @@ -52,6 +54,7 @@ pub struct AppState<'ctx> { pub current_operation: Vec, pub dither_level: u8, pub file_name: Option, + pub guides: HashMap, pub grid: Grid, pub lisp_env: EnvList, pub message: Message, @@ -604,6 +607,7 @@ impl<'ctx> AppState<'ctx> { command_box: CommandBox::new(), context, cache: RefCell::new(None), + guides: HashMap::new(), current_operation: Vec::new(), dither_level: 16, 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::{ ops::{Add, Sub}, }; +use crate::lisp::{error::EvalError, expr::LispExpr}; + #[derive(Debug)] pub struct Pixmap { pub width: u32, @@ -71,12 +73,38 @@ impl Sub for MapPoint { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Axis { X, Y, } +impl Into for Axis { + fn into(self) -> LispExpr { + LispExpr::Quote( + Box::new(LispExpr::Ident(match self { + Self::X => "X".into(), + Self::Y => "Y".into(), + })), + 1, + ) + } +} + +impl TryFrom<&LispExpr> for Axis { + type Error = EvalError; + fn try_from(value: &LispExpr) -> Result { + match value { + LispExpr::Ident(id) => match id.as_ref() { + "x" => Ok(Axis::X), + "y" => Ok(Axis::Y), + _ => Err(EvalError::TypeMismatch), + }, + _ => Err(EvalError::TypeMismatch), + } + } +} + #[derive(Debug, Copy, Clone)] pub enum Quadrant { 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 @@ -use crate::bitmap::Axis; +use crate::{ + bitmap::Axis, + lisp::{expr::LispExpr, number::LispNumber}, +}; -#[derive(Debug)] +use std::convert::Into; + +#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)] pub struct Guide { - axis: Axis, - offset: u32, + pub axis: Axis, + pub offset: u32, +} + +impl Into for Guide { + fn into(self) -> LispExpr { + LispExpr::List(vec![ + self.axis.into(), + LispExpr::Number(LispNumber::Integer(self.offset as i64)), + ]) + } } 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 @@ use std::{cmp::PartialEq, convert::TryFrom, fmt}; -use crate::app::AppState; -use crate::lisp::{ - error::{EvalError, LispError}, - eval::lookup, - number::LispNumber, - EnvList, +use crate::{ + app::AppState, + lisp::{ + error::{EvalError, LispError}, + eval::lookup, + number::LispNumber, + EnvList, + }, }; #[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 @@ use crate::{ bitmap::MapPoint, brush::Brush, + guide::Guide, lisp::{ error::{EvalError, LispError}, expr::{Arity, LispExpr}, @@ -413,5 +414,19 @@ pub fn new_env() -> Result { return Ok(LispExpr::Unit); }); + primitive!(env, Arity::Exact(2), "add-guide!", |args, app| { + match args { + [axis, LispExpr::Number(LispNumber::Integer(offset))] => { + let guide = Guide { + axis: axis.try_into()?, + offset: *offset as u32, + }; + app.guides.insert(guide, true); + return Ok(LispExpr::Unit); + } + _ => return Err(EvalError::TypeMismatch.into()), + } + }); + Ok(env) } -- cgit v1.2.3