diff options
author | Akshay <[email protected]> | 2021-05-08 16:55:47 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-05-08 16:55:47 +0100 |
commit | 591d2b6167af53ce07b060711a4074f1e19c5f3f (patch) | |
tree | 6299e12574732b063aa57c977104eacf938e4eda /src/app.rs | |
parent | 225351e7c98e91451e0b02fd2b9c3060ebd153a7 (diff) |
add basic user-definable keybinds
Diffstat (limited to 'src/app.rs')
-rw-r--r-- | src/app.rs | 69 |
1 files changed, 47 insertions, 22 deletions
@@ -8,7 +8,8 @@ use crate::{ | |||
8 | error::AppError, | 8 | error::AppError, |
9 | grid::Grid, | 9 | grid::Grid, |
10 | guide::Guide, | 10 | guide::Guide, |
11 | lisp::{eval, lex::Lexer, parse::Parser, prelude, EnvList}, | 11 | keybind::Keybind, |
12 | lisp::{eval, expr::LispExpr, lex::Lexer, parse::Parser, prelude, EnvList}, | ||
12 | message::Message, | 13 | message::Message, |
13 | rect, | 14 | rect, |
14 | symmetry::Symmetry, | 15 | symmetry::Symmetry, |
@@ -59,6 +60,7 @@ pub struct AppState<'ctx> { | |||
59 | pub grid: Grid, | 60 | pub grid: Grid, |
60 | pub minimap: bool, | 61 | pub minimap: bool, |
61 | pub lisp_env: EnvList, | 62 | pub lisp_env: EnvList, |
63 | pub keybinds: HashMap<Keybind, LispExpr>, | ||
62 | pub message: Message, | 64 | pub message: Message, |
63 | pub mode: Mode, | 65 | pub mode: Mode, |
64 | pub mouse: (i32, i32), | 66 | pub mouse: (i32, i32), |
@@ -303,21 +305,23 @@ impl<'ctx> AppState<'ctx> { | |||
303 | } | 305 | } |
304 | } | 306 | } |
305 | 307 | ||
308 | pub fn eval_expr(&mut self, expr: &LispExpr) { | ||
309 | let mut evaluator = eval::Evaluator { | ||
310 | app: self, | ||
311 | context: Vec::new(), | ||
312 | }; | ||
313 | match evaluator.eval(expr) { | ||
314 | Ok(val) => self.message.set_info(format!("{}", val)), | ||
315 | Err(eval_err) => self.message.set_error(format!("{}", eval_err)), | ||
316 | } | ||
317 | } | ||
318 | |||
306 | pub fn eval_command(&mut self) { | 319 | pub fn eval_command(&mut self) { |
307 | let lisp_expr = &self.command_box.text; | 320 | let lisp_expr = &self.command_box.text; |
308 | let mut parser = Parser::new(Lexer::new(lisp_expr)); | 321 | let mut parser = Parser::new(Lexer::new(lisp_expr)); |
309 | let res = parser.parse_single_expr(); | 322 | let res = parser.parse_single_expr(); |
310 | match res { | 323 | match res { |
311 | Ok(expr) => { | 324 | Ok(expr) => self.eval_expr(&expr), |
312 | let mut evaluator = eval::Evaluator { | ||
313 | app: self, | ||
314 | context: Vec::new(), | ||
315 | }; | ||
316 | match evaluator.eval(&expr) { | ||
317 | Ok(val) => self.message.set_info(format!("{}", val)), | ||
318 | Err(eval_err) => self.message.set_error(format!("{}", eval_err)), | ||
319 | } | ||
320 | } | ||
321 | Err(err) => self.message = handle_error(err, &lisp_expr, "repl"), | 325 | Err(err) => self.message = handle_error(err, &lisp_expr, "repl"), |
322 | } | 326 | } |
323 | self.command_box.hist_append(); | 327 | self.command_box.hist_append(); |
@@ -612,11 +616,11 @@ impl<'ctx> AppState<'ctx> { | |||
612 | self.grid | 616 | self.grid |
613 | .draw(&mut self.canvas, self.zoom, &self.start, width, height); | 617 | .draw(&mut self.canvas, self.zoom, &self.start, width, height); |
614 | } | 618 | } |
619 | self.draw_guides(); | ||
620 | self.draw_symmetry(); | ||
615 | if self.minimap { | 621 | if self.minimap { |
616 | self.draw_minimap(); | 622 | self.draw_minimap(); |
617 | } | 623 | } |
618 | self.draw_guides(); | ||
619 | self.draw_symmetry(); | ||
620 | self.draw_statusline(); | 624 | self.draw_statusline(); |
621 | self.draw_command_box(); | 625 | self.draw_command_box(); |
622 | self.draw_brush(); | 626 | self.draw_brush(); |
@@ -663,23 +667,24 @@ impl<'ctx> AppState<'ctx> { | |||
663 | let mut app = Self { | 667 | let mut app = Self { |
664 | active_color: true, | 668 | active_color: true, |
665 | brush: Brush::new(0), | 669 | brush: Brush::new(0), |
670 | cache: RefCell::new(None), | ||
666 | canvas, | 671 | canvas, |
667 | command_box: CommandBox::new(), | 672 | command_box: CommandBox::new(), |
668 | context, | 673 | context, |
669 | cache: RefCell::new(None), | ||
670 | guides: HashMap::new(), | ||
671 | current_operation: Vec::new(), | 674 | current_operation: Vec::new(), |
672 | dither_level: 16, | 675 | dither_level: 16, |
673 | file_name, | 676 | file_name, |
674 | grid: Grid::new(), | 677 | grid: Grid::new(), |
678 | guides: HashMap::new(), | ||
679 | keybinds: HashMap::new(), | ||
675 | lisp_env: vec![prelude::new_env().map_err(AppError::Lisp)?], | 680 | lisp_env: vec![prelude::new_env().map_err(AppError::Lisp)?], |
676 | message: Message::new().text(" "), | 681 | message: Message::new().text(" "), |
677 | mode: Mode::Draw, | ||
678 | minimap: false, | 682 | minimap: false, |
683 | mode: Mode::Draw, | ||
679 | mouse: (0, 0), | 684 | mouse: (0, 0), |
685 | pan_start: Point::new(0, 0), | ||
680 | pixmap, | 686 | pixmap, |
681 | start: Point::new(60, 60), | 687 | start: Point::new(60, 60), |
682 | pan_start: Point::new(0, 0), | ||
683 | symmetry: Default::default(), | 688 | symmetry: Default::default(), |
684 | ttf_context, | 689 | ttf_context, |
685 | undo_stack: UndoStack::new(), | 690 | undo_stack: UndoStack::new(), |
@@ -732,7 +737,7 @@ impl<'ctx> AppState<'ctx> { | |||
732 | match event { | 737 | match event { |
733 | Event::KeyDown { | 738 | Event::KeyDown { |
734 | keycode: Some(k), | 739 | keycode: Some(k), |
735 | keymod, | 740 | keymod: Mod::NOMOD, |
736 | .. | 741 | .. |
737 | } => { | 742 | } => { |
738 | match k { | 743 | match k { |
@@ -742,9 +747,9 @@ impl<'ctx> AppState<'ctx> { | |||
742 | Keycode::S => self.pan((0, -10)), | 747 | Keycode::S => self.pan((0, -10)), |
743 | Keycode::D => self.pan((-10, 0)), | 748 | Keycode::D => self.pan((-10, 0)), |
744 | // zoom | 749 | // zoom |
745 | Keycode::C if keymod == Mod::LSHIFTMOD => { | 750 | // Keycode::C if keymod == Mod::LSHIFTMOD => { |
746 | self.center_grid(); | 751 | // self.center_grid(); |
747 | } | 752 | // } |
748 | Keycode::C => { | 753 | Keycode::C => { |
749 | let cursor = (mouse.x(), mouse.y()); | 754 | let cursor = (mouse.x(), mouse.y()); |
750 | self.zoom_in(cursor); | 755 | self.zoom_in(cursor); |
@@ -799,7 +804,7 @@ impl<'ctx> AppState<'ctx> { | |||
799 | } | 804 | } |
800 | continue; | 805 | continue; |
801 | } | 806 | } |
802 | _ if keymod == Mod::LCTRLMOD || keymod == Mod::RCTRLMOD => { | 807 | Keycode::LCtrl | Keycode::RCtrl => { |
803 | self.brush = Brush::line( | 808 | self.brush = Brush::line( |
804 | self.cache | 809 | self.cache |
805 | .borrow() | 810 | .borrow() |
@@ -812,6 +817,26 @@ impl<'ctx> AppState<'ctx> { | |||
812 | _ => (), | 817 | _ => (), |
813 | } | 818 | } |
814 | } | 819 | } |
820 | Event::KeyDown { | ||
821 | keycode: Some(k), | ||
822 | keymod, | ||
823 | .. | ||
824 | } if self.keybinds.contains_key(&Keybind::new(k, keymod)) => { | ||
825 | let body = self.keybinds.get(&Keybind::new(k, keymod)).unwrap(); | ||
826 | self.eval_expr(&body.clone()); | ||
827 | } | ||
828 | Event::KeyDown { | ||
829 | keycode: Some(k), .. | ||
830 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | ||
831 | self.brush = Brush::line( | ||
832 | self.cache | ||
833 | .borrow() | ||
834 | .as_ref() | ||
835 | .map(|c| c.last_brush.size().unwrap_or(0)) | ||
836 | .unwrap_or(0), | ||
837 | true, | ||
838 | ); | ||
839 | } | ||
815 | Event::KeyUp { | 840 | Event::KeyUp { |
816 | keycode: Some(k), .. | 841 | keycode: Some(k), .. |
817 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | 842 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { |