diff options
-rw-r--r-- | src/app.rs | 51 | ||||
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/message.rs | 42 |
3 files changed, 84 insertions, 13 deletions
@@ -2,7 +2,10 @@ use crate::{ | |||
2 | bitmap::{MapPoint, Pixmap}, | 2 | bitmap::{MapPoint, Pixmap}, |
3 | command::CommandBox, | 3 | command::CommandBox, |
4 | consts::{colors::*, FONT_PATH}, | 4 | consts::{colors::*, FONT_PATH}, |
5 | dither, rect, | 5 | dither, |
6 | lisp::{env, lex::Lexer, parse::Parser, Environment}, | ||
7 | message::Message, | ||
8 | rect, | ||
6 | symmetry::Symmetry, | 9 | symmetry::Symmetry, |
7 | undo::{ModifyRecord, OpKind, Operation, UndoStack}, | 10 | undo::{ModifyRecord, OpKind, Operation, UndoStack}, |
8 | utils::{draw_text, is_copy_event, is_paste_event}, | 11 | utils::{draw_text, is_copy_event, is_paste_event}, |
@@ -274,6 +277,18 @@ impl<'ctx> AppState<'ctx> { | |||
274 | } | 277 | } |
275 | 278 | ||
276 | fn eval_command(&mut self) { | 279 | fn eval_command(&mut self) { |
280 | let lisp_expr = &self.command_box.text; | ||
281 | let mut parser = Parser::new(Lexer::new(lisp_expr, 0)); | ||
282 | let res = parser.parse_single_expr(); | ||
283 | match env::eval(&res.unwrap(), self) { | ||
284 | Ok(val) => { | ||
285 | self.message.text = format!("{}", val); | ||
286 | } | ||
287 | Err(_) => { | ||
288 | self.message.text = format!("Lisp Error!"); | ||
289 | } | ||
290 | } | ||
291 | |||
277 | if let Some(path) = self.command_box.text.strip_prefix("(save ") { | 292 | if let Some(path) = self.command_box.text.strip_prefix("(save ") { |
278 | let image = self.export(); | 293 | let image = self.export(); |
279 | let encoded = image.encode().unwrap(); | 294 | let encoded = image.encode().unwrap(); |
@@ -345,22 +360,31 @@ impl<'ctx> AppState<'ctx> { | |||
345 | } | 360 | } |
346 | 361 | ||
347 | fn draw_command_box(&mut self) { | 362 | fn draw_command_box(&mut self) { |
348 | if self.command_box.is_empty() { | ||
349 | self.mode = Mode::Draw; | ||
350 | return; | ||
351 | } | ||
352 | let (winsize_x, winsize_y) = self.canvas.window().size(); | 363 | let (winsize_x, winsize_y) = self.canvas.window().size(); |
353 | let cmd_height: u32 = 20; | 364 | let cmd_height: u32 = 20; |
354 | let cmd_width = winsize_x; | 365 | let cmd_width = winsize_x; |
355 | self.canvas.set_draw_color(WHITE); | 366 | self.canvas.set_draw_color(BLACK); |
356 | self.canvas | 367 | self.canvas |
357 | .fill_rect(rect!(0, winsize_y - cmd_height, cmd_width, cmd_height)) | 368 | .fill_rect(rect!(0, winsize_y - cmd_height, cmd_width, cmd_height)) |
358 | .unwrap(); | 369 | .unwrap(); |
370 | if self.command_box.is_empty() { | ||
371 | self.mode = Mode::Draw; | ||
372 | // show msg | ||
373 | draw_text( | ||
374 | &mut self.canvas, | ||
375 | self.ttf_context, | ||
376 | &self.message.text[..], | ||
377 | WHITE, | ||
378 | (0, winsize_y - cmd_height), | ||
379 | ); | ||
380 | return; | ||
381 | } | ||
382 | // show repl | ||
359 | draw_text( | 383 | draw_text( |
360 | &mut self.canvas, | 384 | &mut self.canvas, |
361 | self.ttf_context, | 385 | self.ttf_context, |
362 | &self.command_box.text[..], | 386 | &self.command_box.text[..], |
363 | BLACK, | 387 | WHITE, |
364 | (0, winsize_y - cmd_height), | 388 | (0, winsize_y - cmd_height), |
365 | ); | 389 | ); |
366 | 390 | ||
@@ -438,11 +462,11 @@ impl<'ctx> AppState<'ctx> { | |||
438 | .draw_line((line_coord, 0), (line_coord, winsize_y as i32)) | 462 | .draw_line((line_coord, 0), (line_coord, winsize_y as i32)) |
439 | .unwrap(); | 463 | .unwrap(); |
440 | } | 464 | } |
441 | if self.mode == Mode::Draw { | 465 | // if self.mode == Mode::Draw { |
442 | self.draw_statusline(); | 466 | // self.draw_statusline(); |
443 | } else { | 467 | // } else { |
444 | self.draw_command_box(); | 468 | self.draw_command_box(); |
445 | } | 469 | // } |
446 | self.draw_mouse(); | 470 | self.draw_mouse(); |
447 | } | 471 | } |
448 | 472 | ||
@@ -493,12 +517,14 @@ impl<'ctx> AppState<'ctx> { | |||
493 | grid: Grid::new(), | 517 | grid: Grid::new(), |
494 | last_point: None, | 518 | last_point: None, |
495 | mode: Mode::Draw, | 519 | mode: Mode::Draw, |
520 | message: Message::new().text(" "), | ||
496 | mouse: (0, 0), | 521 | mouse: (0, 0), |
497 | pixmap, | 522 | pixmap, |
498 | start: Point::new(60, 60), | 523 | start: Point::new(60, 60), |
499 | symmetry: Default::default(), | 524 | symmetry: Default::default(), |
500 | ttf_context, | 525 | ttf_context, |
501 | undo_stack: UndoStack::new(), | 526 | undo_stack: UndoStack::new(), |
527 | lisp_env: env::with_prelude(), | ||
502 | zoom: 5, | 528 | zoom: 5, |
503 | } | 529 | } |
504 | } | 530 | } |
@@ -700,6 +726,7 @@ impl<'ctx> AppState<'ctx> { | |||
700 | Keycode::Return => self.eval_command(), | 726 | Keycode::Return => self.eval_command(), |
701 | Keycode::Escape => { | 727 | Keycode::Escape => { |
702 | self.command_box.clear(); | 728 | self.command_box.clear(); |
729 | self.message.text = format!(" "); | ||
703 | self.mode = Mode::Draw; | 730 | self.mode = Mode::Draw; |
704 | } | 731 | } |
705 | _ => (), | 732 | _ => (), |
diff --git a/src/main.rs b/src/main.rs index ebdf793..197b200 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -3,6 +3,8 @@ mod bitmap; | |||
3 | mod command; | 3 | mod command; |
4 | mod consts; | 4 | mod consts; |
5 | mod dither; | 5 | mod dither; |
6 | mod lisp; | ||
7 | mod message; | ||
6 | mod symmetry; | 8 | mod symmetry; |
7 | mod undo; | 9 | mod undo; |
8 | mod utils; | 10 | mod utils; |
@@ -22,7 +24,7 @@ pub fn main() { | |||
22 | let ttf_context = sdl2::ttf::init().unwrap(); | 24 | let ttf_context = sdl2::ttf::init().unwrap(); |
23 | let args: Vec<_> = env::args().collect(); | 25 | let args: Vec<_> = env::args().collect(); |
24 | if args.len() < 2 { | 26 | if args.len() < 2 { |
25 | AppState::init(200, 200, &sdl_context, &ttf_context, None).run(); | 27 | AppState::init(160, 160, &sdl_context, &ttf_context, None).run(); |
26 | return; | 28 | return; |
27 | } else { | 29 | } else { |
28 | let path = args.get(1).unwrap(); | 30 | let path = args.get(1).unwrap(); |
diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..d1032cf --- /dev/null +++ b/src/message.rs | |||
@@ -0,0 +1,42 @@ | |||
1 | #[derive(Debug)] | ||
2 | pub struct Message { | ||
3 | pub text: String, | ||
4 | pub kind: MessageKind, | ||
5 | } | ||
6 | |||
7 | impl Message { | ||
8 | pub fn new() -> Self { | ||
9 | Self { | ||
10 | text: String::new(), | ||
11 | kind: MessageKind::Info, | ||
12 | } | ||
13 | } | ||
14 | pub fn kind(mut self, kind: MessageKind) -> Self { | ||
15 | self.kind = kind; | ||
16 | self | ||
17 | } | ||
18 | pub fn text<S: AsRef<str>>(mut self, text: S) -> Self { | ||
19 | self.text = text.as_ref().into(); | ||
20 | self | ||
21 | } | ||
22 | } | ||
23 | |||
24 | #[derive(Debug, Copy, Clone)] | ||
25 | pub enum MessageKind { | ||
26 | Error, | ||
27 | Info, | ||
28 | Hint, | ||
29 | LispResult, | ||
30 | } | ||
31 | |||
32 | impl<T> From<T> for Message | ||
33 | where | ||
34 | T: AsRef<str>, | ||
35 | { | ||
36 | fn from(item: T) -> Self { | ||
37 | return Message { | ||
38 | text: item.as_ref().into(), | ||
39 | kind: MessageKind::Info, | ||
40 | }; | ||
41 | } | ||
42 | } | ||