diff options
-rw-r--r-- | src/app.rs | 642 |
1 files changed, 327 insertions, 315 deletions
@@ -28,6 +28,7 @@ use std::{ | |||
28 | }; | 28 | }; |
29 | 29 | ||
30 | use obi::{CompressionType, Image}; | 30 | use obi::{CompressionType, Image}; |
31 | use sdl2::mouse::MouseState; | ||
31 | use sdl2::{ | 32 | use sdl2::{ |
32 | event::Event, | 33 | event::Event, |
33 | keyboard::{Keycode, Mod}, | 34 | keyboard::{Keycode, Mod}, |
@@ -73,6 +74,11 @@ pub struct AppState<'ctx> { | |||
73 | pub pan_start: Point, | 74 | pub pan_start: Point, |
74 | } | 75 | } |
75 | 76 | ||
77 | enum HandleEventOutcome { | ||
78 | Normal, | ||
79 | Break, | ||
80 | } | ||
81 | |||
76 | // private actions on appstate | 82 | // private actions on appstate |
77 | impl<'ctx> AppState<'ctx> { | 83 | impl<'ctx> AppState<'ctx> { |
78 | fn pan<P: Into<Point>>(&mut self, direction: P) { | 84 | fn pan<P: Into<Point>>(&mut self, direction: P) { |
@@ -737,354 +743,360 @@ impl<'ctx> AppState<'ctx> { | |||
737 | 'running: loop { | 743 | 'running: loop { |
738 | let mouse = event_pump.mouse_state(); | 744 | let mouse = event_pump.mouse_state(); |
739 | self.mouse = (mouse.x(), mouse.y()); | 745 | self.mouse = (mouse.x(), mouse.y()); |
746 | let event = event_pump.wait_event(); | ||
747 | match self.handle_event(mouse, event) { | ||
748 | HandleEventOutcome::Normal => {} | ||
749 | HandleEventOutcome::Break => break, | ||
750 | } | ||
740 | for event in event_pump.poll_iter() { | 751 | for event in event_pump.poll_iter() { |
741 | if let Event::KeyDown { | 752 | match self.handle_event(mouse, event) { |
742 | keycode: Some(Keycode::Num9), | 753 | HandleEventOutcome::Normal => {} |
743 | keymod, | 754 | HandleEventOutcome::Break => break 'running, |
744 | .. | ||
745 | } = event | ||
746 | { | ||
747 | if keymod == Mod::LSHIFTMOD || keymod == Mod::RSHIFTMOD { | ||
748 | self.mode = Mode::Command; | ||
749 | } | ||
750 | } | 755 | } |
751 | match self.mode { | 756 | } |
752 | Mode::Draw => { | 757 | self.cache(); |
753 | match event { | 758 | self.redraw(); |
754 | Event::KeyDown { | 759 | } |
755 | keycode: Some(k), | 760 | } |
756 | keymod: Mod::NOMOD, | 761 | |
757 | .. | 762 | #[must_use] |
758 | } => { | 763 | fn handle_event(&mut self, mouse: MouseState, event: Event) -> HandleEventOutcome { |
759 | match k { | 764 | if let Event::KeyDown { |
760 | // pan | 765 | keycode: Some(Keycode::Num9), |
761 | Keycode::W => self.pan((0, 10)), | 766 | keymod, |
762 | Keycode::A => self.pan((10, 0)), | 767 | .. |
763 | Keycode::S => self.pan((0, -10)), | 768 | } = event |
764 | Keycode::D => self.pan((-10, 0)), | 769 | { |
765 | // zoom | 770 | if keymod == Mod::LSHIFTMOD || keymod == Mod::RSHIFTMOD { |
766 | // Keycode::C if keymod == Mod::LSHIFTMOD => { | 771 | self.mode = Mode::Command; |
767 | // self.center_grid(); | 772 | } |
768 | // } | 773 | } |
769 | Keycode::C => { | 774 | match self.mode { |
770 | let cursor = (mouse.x(), mouse.y()); | 775 | Mode::Draw => { |
771 | self.zoom_in(cursor); | 776 | match event { |
772 | } | 777 | Event::KeyDown { |
773 | Keycode::Z => { | 778 | keycode: Some(k), |
774 | let cursor = (mouse.x(), mouse.y()); | 779 | keymod: Mod::NOMOD, |
775 | self.zoom_out(cursor); | 780 | .. |
776 | } | 781 | } => { |
777 | // brush ops | 782 | match k { |
778 | Keycode::Q => self.brush.shrink(), | 783 | // pan |
779 | Keycode::E => self.brush.grow(), | 784 | Keycode::W => self.pan((0, 10)), |
780 | Keycode::Num1 => self.reduce_intensity(), | 785 | Keycode::A => self.pan((10, 0)), |
781 | Keycode::Num3 => self.increase_intensity(), | 786 | Keycode::S => self.pan((0, -10)), |
782 | // flip color | 787 | Keycode::D => self.pan((-10, 0)), |
783 | Keycode::X => self.change_active_color(), | 788 | // zoom |
784 | // toggle grid | 789 | // Keycode::C if keymod == Mod::LSHIFTMOD => { |
785 | Keycode::Tab => self.toggle_grid(), | 790 | // self.center_grid(); |
786 | // invert canvas | 791 | // } |
787 | Keycode::I => { | 792 | Keycode::C => { |
788 | self.pixmap.invert(); | 793 | let cursor = (mouse.x(), mouse.y()); |
789 | self.undo_stack.push(ModifyRecord::Invert); | 794 | self.zoom_in(cursor); |
790 | } | 795 | } |
791 | // cycle through brushes | 796 | Keycode::Z => { |
792 | Keycode::F => self.cycle_brush(), | 797 | let cursor = (mouse.x(), mouse.y()); |
793 | // change rect select active end | 798 | self.zoom_out(cursor); |
794 | Keycode::O => { | 799 | } |
795 | match &mut self.brush { | 800 | // brush ops |
796 | Brush::RectSelect(RectSelectBrush { | 801 | Keycode::Q => self.brush.shrink(), |
797 | active_end, | 802 | Keycode::E => self.brush.grow(), |
798 | .. | 803 | Keycode::Num1 => self.reduce_intensity(), |
799 | }) => *active_end = !*active_end, | 804 | Keycode::Num3 => self.increase_intensity(), |
800 | _ => (), | 805 | // flip color |
801 | }; | 806 | Keycode::X => self.change_active_color(), |
802 | } | 807 | // toggle grid |
803 | Keycode::V => self.cycle_symmetry(), | 808 | Keycode::Tab => self.toggle_grid(), |
804 | // undo | 809 | // invert canvas |
805 | Keycode::U => { | 810 | Keycode::I => { |
806 | if let Some(op) = self.undo_stack.undo() { | 811 | self.pixmap.invert(); |
807 | self.apply_operation(op, OpKind::Undo); | 812 | self.undo_stack.push(ModifyRecord::Invert); |
808 | } | 813 | } |
809 | } | 814 | // cycle through brushes |
810 | // redo | 815 | Keycode::F => self.cycle_brush(), |
811 | Keycode::R => { | 816 | // change rect select active end |
812 | if let Some(op) = self.undo_stack.redo() { | 817 | Keycode::O => { |
813 | self.apply_operation(op, OpKind::Redo); | 818 | match &mut self.brush { |
814 | } | 819 | Brush::RectSelect(RectSelectBrush { active_end, .. }) => { |
815 | } | 820 | *active_end = !*active_end |
816 | Keycode::Escape => { | ||
817 | match self.brush { | ||
818 | Brush::RectSelect(_) => self.brush = Brush::rect(), | ||
819 | _ => (), | ||
820 | } | ||
821 | continue; | ||
822 | } | 821 | } |
823 | _ => (), | 822 | _ => (), |
823 | }; | ||
824 | } | ||
825 | Keycode::V => self.cycle_symmetry(), | ||
826 | // undo | ||
827 | Keycode::U => { | ||
828 | if let Some(op) = self.undo_stack.undo() { | ||
829 | self.apply_operation(op, OpKind::Undo); | ||
824 | } | 830 | } |
825 | } | 831 | } |
826 | Event::KeyDown { | 832 | // redo |
827 | keycode: Some(k), | 833 | Keycode::R => { |
828 | keymod, | 834 | if let Some(op) = self.undo_stack.redo() { |
829 | .. | 835 | self.apply_operation(op, OpKind::Redo); |
830 | } if self.keybinds.contains_key(&Keybind::new(k, keymod)) => { | 836 | } |
831 | let body = | ||
832 | // clone here because body can modify itself | ||
833 | self.keybinds.get(&Keybind::new(k, keymod)).unwrap().clone(); | ||
834 | self.eval_expr(&body); | ||
835 | } | 837 | } |
836 | Event::KeyDown { | 838 | Keycode::Escape => { |
837 | keycode: Some(k), .. | 839 | match self.brush { |
838 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | 840 | Brush::RectSelect(_) => self.brush = Brush::rect(), |
839 | self.brush = Brush::line( | 841 | _ => (), |
840 | self.cache | 842 | } |
841 | .borrow() | 843 | return HandleEventOutcome::Normal; |
842 | .as_ref() | ||
843 | .map(|c| c.last_brush.size().unwrap_or(0)) | ||
844 | .unwrap_or(0), | ||
845 | true, | ||
846 | ); | ||
847 | } | 844 | } |
848 | Event::KeyUp { | 845 | _ => (), |
849 | keycode: Some(k), .. | 846 | } |
850 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | 847 | } |
851 | self.brush = Brush::new( | 848 | Event::KeyDown { |
852 | self.cache | 849 | keycode: Some(k), |
853 | .borrow() | 850 | keymod, |
854 | .as_ref() | 851 | .. |
855 | .map(|c| c.last_brush.size().unwrap_or(0)) | 852 | } if self.keybinds.contains_key(&Keybind::new(k, keymod)) => { |
856 | .unwrap_or(0), | 853 | let body = |
857 | ); | 854 | // clone here because body can modify itself |
855 | self.keybinds.get(&Keybind::new(k, keymod)).unwrap().clone(); | ||
856 | self.eval_expr(&body); | ||
857 | } | ||
858 | Event::KeyDown { | ||
859 | keycode: Some(k), .. | ||
860 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | ||
861 | self.brush = Brush::line( | ||
862 | self.cache | ||
863 | .borrow() | ||
864 | .as_ref() | ||
865 | .map(|c| c.last_brush.size().unwrap_or(0)) | ||
866 | .unwrap_or(0), | ||
867 | true, | ||
868 | ); | ||
869 | } | ||
870 | Event::KeyUp { | ||
871 | keycode: Some(k), .. | ||
872 | } if k == Keycode::LCtrl || k == Keycode::RCtrl => { | ||
873 | self.brush = Brush::new( | ||
874 | self.cache | ||
875 | .borrow() | ||
876 | .as_ref() | ||
877 | .map(|c| c.last_brush.size().unwrap_or(0)) | ||
878 | .unwrap_or(0), | ||
879 | ); | ||
880 | } | ||
881 | Event::MouseButtonDown { | ||
882 | x, | ||
883 | y, | ||
884 | mouse_btn: MouseButton::Middle, | ||
885 | .. | ||
886 | } => self.pan_start = Point::from((x, y)), | ||
887 | // start of operation | ||
888 | Event::MouseButtonDown { | ||
889 | x, y, mouse_btn, .. | ||
890 | } => { | ||
891 | let pt = (x, y); | ||
892 | let contact = self.idx_at_coord(pt).map(MapPoint::from); | ||
893 | let val = match mouse_btn { | ||
894 | MouseButton::Right => !self.active_color, | ||
895 | _ => self.active_color, | ||
896 | }; | ||
897 | match self.brush { | ||
898 | Brush::Circle(CircleBrush { size }) => { | ||
899 | if let Ok(o) = self.paint_point(pt, val, size) { | ||
900 | self.current_operation.extend(o); | ||
901 | } | ||
858 | } | 902 | } |
859 | Event::MouseButtonDown { | 903 | Brush::Line(LineBrush { |
860 | x, | 904 | size, |
861 | y, | 905 | start, |
862 | mouse_btn: MouseButton::Middle, | 906 | extend, |
863 | .. | 907 | }) => { |
864 | } => self.pan_start = Point::from((x, y)), | 908 | if let Some(s) = start { |
865 | // start of operation | 909 | if let Ok(o) = self.paint_line(s, pt, val, size) { |
866 | Event::MouseButtonDown { | 910 | self.current_operation.extend(o); |
867 | x, y, mouse_btn, .. | 911 | self.brush = Brush::Line(LineBrush { |
868 | } => { | 912 | size, |
869 | let pt = (x, y); | 913 | start: if extend { contact } else { None }, |
870 | let contact = self.idx_at_coord(pt).map(MapPoint::from); | 914 | extend, |
871 | let val = match mouse_btn { | 915 | }); |
872 | MouseButton::Right => !self.active_color, | ||
873 | _ => self.active_color, | ||
874 | }; | ||
875 | match self.brush { | ||
876 | Brush::Circle(CircleBrush { size }) => { | ||
877 | if let Ok(o) = self.paint_point(pt, val, size) { | ||
878 | self.current_operation.extend(o); | ||
879 | } | ||
880 | } | 916 | } |
881 | Brush::Line(LineBrush { | 917 | } else { |
918 | self.brush = Brush::Line(LineBrush { | ||
882 | size, | 919 | size, |
883 | start, | 920 | start: contact, |
884 | extend, | 921 | extend, |
885 | }) => { | 922 | }); |
886 | if let Some(s) = start { | 923 | } |
887 | if let Ok(o) = self.paint_line(s, pt, val, size) { | 924 | } |
888 | self.current_operation.extend(o); | 925 | Brush::RectSelect(RectSelectBrush { |
889 | self.brush = Brush::Line(LineBrush { | 926 | start, |
890 | size, | 927 | end, |
891 | start: if extend { contact } else { None }, | 928 | active_end, |
892 | extend, | 929 | }) => { |
893 | }); | 930 | if start.is_none() { |
894 | } | 931 | self.brush = Brush::RectSelect(RectSelectBrush { |
895 | } else { | 932 | start: contact, |
896 | self.brush = Brush::Line(LineBrush { | 933 | end, |
897 | size, | 934 | active_end, |
898 | start: contact, | 935 | }); |
899 | extend, | 936 | } else if end.is_none() || active_end { |
900 | }); | 937 | self.brush = Brush::RectSelect(RectSelectBrush { |
901 | } | ||
902 | } | ||
903 | Brush::RectSelect(RectSelectBrush { | ||
904 | start, | 938 | start, |
939 | end: contact, | ||
940 | active_end, | ||
941 | }); | ||
942 | } else { | ||
943 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
944 | start: contact, | ||
905 | end, | 945 | end, |
906 | active_end, | 946 | active_end, |
907 | }) => { | 947 | }); |
908 | if start.is_none() { | 948 | }; |
909 | self.brush = Brush::RectSelect(RectSelectBrush { | 949 | } |
910 | start: contact, | 950 | Brush::Fill => { |
911 | end, | 951 | if let Some(c) = contact { |
912 | active_end, | 952 | // this `get` is unchecked because contact is checked |
913 | }); | 953 | // to be within pixmap |
914 | } else if end.is_none() || active_end { | 954 | let target = self.pixmap.get(c); |
915 | self.brush = Brush::RectSelect(RectSelectBrush { | 955 | let replacement = self.active_color; |
916 | start, | 956 | let operation = self.pixmap.flood_fill(c, target, replacement); |
917 | end: contact, | 957 | for o in operation.iter() { |
918 | active_end, | 958 | // this `set` is unchecked because the returned |
919 | }); | 959 | // value of flood_fill is checked to be within pixmap |
920 | } else { | 960 | self.pixmap.set(*o, replacement); |
921 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
922 | start: contact, | ||
923 | end, | ||
924 | active_end, | ||
925 | }); | ||
926 | }; | ||
927 | } | ||
928 | Brush::Fill => { | ||
929 | if let Some(c) = contact { | ||
930 | // this `get` is unchecked because contact is checked | ||
931 | // to be within pixmap | ||
932 | let target = self.pixmap.get(c); | ||
933 | let replacement = self.active_color; | ||
934 | let operation = | ||
935 | self.pixmap.flood_fill(c, target, replacement); | ||
936 | for o in operation.iter() { | ||
937 | // this `set` is unchecked because the returned | ||
938 | // value of flood_fill is checked to be within pixmap | ||
939 | self.pixmap.set(*o, replacement); | ||
940 | } | ||
941 | self.current_operation.extend( | ||
942 | operation | ||
943 | .into_iter() | ||
944 | .map(|point| PaintRecord { | ||
945 | point, | ||
946 | old: target, | ||
947 | new: replacement, | ||
948 | }) | ||
949 | .collect::<Vec<PaintRecord>>(), | ||
950 | ) | ||
951 | } | ||
952 | } | 961 | } |
953 | _ => {} | 962 | self.current_operation.extend( |
963 | operation | ||
964 | .into_iter() | ||
965 | .map(|point| PaintRecord { | ||
966 | point, | ||
967 | old: target, | ||
968 | new: replacement, | ||
969 | }) | ||
970 | .collect::<Vec<PaintRecord>>(), | ||
971 | ) | ||
954 | } | 972 | } |
955 | } | 973 | } |
956 | // click and drag | 974 | _ => {} |
957 | Event::MouseMotion { | 975 | } |
958 | x, y, mousestate, .. | 976 | } |
959 | } => { | 977 | // click and drag |
960 | if mousestate.is_mouse_button_pressed(MouseButton::Left) { | 978 | Event::MouseMotion { |
961 | match self.brush { | 979 | x, y, mousestate, .. |
962 | Brush::RectSelect(RectSelectBrush { | 980 | } => { |
981 | if mousestate.is_mouse_button_pressed(MouseButton::Left) { | ||
982 | match self.brush { | ||
983 | Brush::RectSelect(RectSelectBrush { | ||
984 | start, | ||
985 | end, | ||
986 | active_end, | ||
987 | }) => { | ||
988 | if active_end { | ||
989 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
963 | start, | 990 | start, |
991 | end: self.idx_at_coord((x, y)).map(MapPoint::from), | ||
992 | active_end, | ||
993 | }); | ||
994 | } else { | ||
995 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
996 | start: self.idx_at_coord((x, y)).map(MapPoint::from), | ||
964 | end, | 997 | end, |
965 | active_end, | 998 | active_end, |
966 | }) => { | 999 | }); |
967 | if active_end { | ||
968 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
969 | start, | ||
970 | end: self | ||
971 | .idx_at_coord((x, y)) | ||
972 | .map(MapPoint::from), | ||
973 | active_end, | ||
974 | }); | ||
975 | } else { | ||
976 | self.brush = Brush::RectSelect(RectSelectBrush { | ||
977 | start: self | ||
978 | .idx_at_coord((x, y)) | ||
979 | .map(MapPoint::from), | ||
980 | end, | ||
981 | active_end, | ||
982 | }); | ||
983 | } | ||
984 | } | ||
985 | Brush::Circle(CircleBrush { size }) => { | ||
986 | let pt = (x, y); | ||
987 | let val = self.active_color; | ||
988 | if let Ok(o) = self.paint_point(pt, val, size) { | ||
989 | self.current_operation.extend(o); | ||
990 | } | ||
991 | } | ||
992 | _ => (), | ||
993 | } | 1000 | } |
994 | } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { | 1001 | } |
995 | match self.brush { | 1002 | Brush::Circle(CircleBrush { size }) => { |
996 | Brush::Circle(CircleBrush { size }) | 1003 | let pt = (x, y); |
997 | | Brush::Line(LineBrush { size, .. }) => { | 1004 | let val = self.active_color; |
998 | let pt = (x, y); | 1005 | if let Ok(o) = self.paint_point(pt, val, size) { |
999 | let val = !self.active_color; | 1006 | self.current_operation.extend(o); |
1000 | if let Ok(o) = self.paint_point(pt, val, size) { | ||
1001 | self.current_operation.extend(o); | ||
1002 | } | ||
1003 | } | ||
1004 | _ => (), | ||
1005 | } | 1007 | } |
1006 | } else if mousestate.is_mouse_button_pressed(MouseButton::Middle) { | ||
1007 | let pan_end = Point::from((x, y)); | ||
1008 | let shift = pan_end - self.pan_start; | ||
1009 | self.start += shift; | ||
1010 | self.pan_start = pan_end; | ||
1011 | } | 1008 | } |
1009 | _ => (), | ||
1012 | } | 1010 | } |
1013 | // end of operation | 1011 | } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { |
1014 | Event::MouseButtonUp { .. } => self.commit_operation(), | 1012 | match self.brush { |
1015 | Event::Quit { .. } => { | 1013 | Brush::Circle(CircleBrush { size }) |
1016 | break 'running; | 1014 | | Brush::Line(LineBrush { size, .. }) => { |
1015 | let pt = (x, y); | ||
1016 | let val = !self.active_color; | ||
1017 | if let Ok(o) = self.paint_point(pt, val, size) { | ||
1018 | self.current_operation.extend(o); | ||
1019 | } | ||
1020 | } | ||
1021 | _ => (), | ||
1017 | } | 1022 | } |
1018 | _ => {} | 1023 | } else if mousestate.is_mouse_button_pressed(MouseButton::Middle) { |
1024 | let pan_end = Point::from((x, y)); | ||
1025 | let shift = pan_end - self.pan_start; | ||
1026 | self.start += shift; | ||
1027 | self.pan_start = pan_end; | ||
1019 | } | 1028 | } |
1020 | } | 1029 | } |
1021 | Mode::Command => { | 1030 | // end of operation |
1022 | if let Event::KeyDown { | 1031 | Event::MouseButtonUp { .. } => self.commit_operation(), |
1023 | keycode, keymod, .. | 1032 | Event::Quit { .. } => { |
1024 | } = event | 1033 | return HandleEventOutcome::Break; |
1025 | { | 1034 | } |
1026 | let video = self.context.video().unwrap(); | 1035 | _ => {} |
1027 | let clipboard = video.clipboard(); | 1036 | } |
1028 | if is_copy_event(keycode, keymod) { | 1037 | } |
1029 | clipboard | 1038 | Mode::Command => { |
1030 | .set_clipboard_text(&self.command_box.text) | 1039 | if let Event::KeyDown { |
1031 | .unwrap(); | 1040 | keycode, keymod, .. |
1032 | } else if is_paste_event(keycode, keymod) | 1041 | } = event |
1033 | && clipboard.has_clipboard_text() | 1042 | { |
1034 | { | 1043 | let video = self.context.video().unwrap(); |
1035 | self.command_box | 1044 | let clipboard = video.clipboard(); |
1036 | .push_str(&clipboard.clipboard_text().unwrap()); | 1045 | if is_copy_event(keycode, keymod) { |
1037 | } | 1046 | clipboard |
1047 | .set_clipboard_text(&self.command_box.text) | ||
1048 | .unwrap(); | ||
1049 | } else if is_paste_event(keycode, keymod) && clipboard.has_clipboard_text() { | ||
1050 | self.command_box | ||
1051 | .push_str(&clipboard.clipboard_text().unwrap()); | ||
1052 | } | ||
1053 | } | ||
1054 | match event { | ||
1055 | Event::KeyDown { | ||
1056 | keycode: Some(k), | ||
1057 | keymod, | ||
1058 | .. | ||
1059 | } => match k { | ||
1060 | Keycode::Backspace => self.command_box.backspace(), | ||
1061 | Keycode::Delete => self.command_box.delete(), | ||
1062 | Keycode::Left => self.command_box.backward(), | ||
1063 | Keycode::Right => self.command_box.forward(), | ||
1064 | Keycode::Up => self.command_box.hist_prev(), | ||
1065 | Keycode::Down => self.command_box.hist_next(), | ||
1066 | Keycode::Return => self.eval_command(), | ||
1067 | Keycode::Tab if keymod == Mod::LSHIFTMOD => { | ||
1068 | self.command_box.complete(&self.lisp_env, true) | ||
1038 | } | 1069 | } |
1039 | match event { | 1070 | Keycode::Tab => self.command_box.complete(&self.lisp_env, false), |
1040 | Event::KeyDown { | 1071 | Keycode::Escape => { |
1041 | keycode: Some(k), | 1072 | self.command_box.clear(); |
1042 | keymod, | 1073 | self.message.text.clear(); |
1043 | .. | 1074 | self.mode = Mode::Draw; |
1044 | } => match k { | ||
1045 | Keycode::Backspace => self.command_box.backspace(), | ||
1046 | Keycode::Delete => self.command_box.delete(), | ||
1047 | Keycode::Left => self.command_box.backward(), | ||
1048 | Keycode::Right => self.command_box.forward(), | ||
1049 | Keycode::Up => self.command_box.hist_prev(), | ||
1050 | Keycode::Down => self.command_box.hist_next(), | ||
1051 | Keycode::Return => self.eval_command(), | ||
1052 | Keycode::Tab if keymod == Mod::LSHIFTMOD => { | ||
1053 | self.command_box.complete(&self.lisp_env, true) | ||
1054 | } | ||
1055 | Keycode::Tab => self.command_box.complete(&self.lisp_env, false), | ||
1056 | Keycode::Escape => { | ||
1057 | self.command_box.clear(); | ||
1058 | self.message.text.clear(); | ||
1059 | self.mode = Mode::Draw; | ||
1060 | } | ||
1061 | _ if keymod == Mod::LCTRLMOD => match k { | ||
1062 | Keycode::A => self.command_box.cursor_start(), | ||
1063 | Keycode::E => self.command_box.cursor_end(), | ||
1064 | Keycode::F => self.command_box.forward(), | ||
1065 | Keycode::B => self.command_box.backward(), | ||
1066 | Keycode::K => self.command_box.delete_to_end(), | ||
1067 | Keycode::U => self.command_box.delete_to_start(), | ||
1068 | _ => (), | ||
1069 | }, | ||
1070 | // how does one handle alt keys | ||
1071 | _ if keymod == Mod::LALTMOD => match k { | ||
1072 | Keycode::B => self.command_box.cursor_back_word(), | ||
1073 | Keycode::F => self.command_box.cursor_forward_word(), | ||
1074 | _ => (), | ||
1075 | }, | ||
1076 | _ => (), | ||
1077 | }, | ||
1078 | Event::TextInput { text, .. } => { | ||
1079 | self.command_box.push_str(&text[..]); | ||
1080 | } | ||
1081 | _ => (), | ||
1082 | } | 1075 | } |
1076 | _ if keymod == Mod::LCTRLMOD => match k { | ||
1077 | Keycode::A => self.command_box.cursor_start(), | ||
1078 | Keycode::E => self.command_box.cursor_end(), | ||
1079 | Keycode::F => self.command_box.forward(), | ||
1080 | Keycode::B => self.command_box.backward(), | ||
1081 | Keycode::K => self.command_box.delete_to_end(), | ||
1082 | Keycode::U => self.command_box.delete_to_start(), | ||
1083 | _ => (), | ||
1084 | }, | ||
1085 | // how does one handle alt keys | ||
1086 | _ if keymod == Mod::LALTMOD => match k { | ||
1087 | Keycode::B => self.command_box.cursor_back_word(), | ||
1088 | Keycode::F => self.command_box.cursor_forward_word(), | ||
1089 | _ => (), | ||
1090 | }, | ||
1091 | _ => (), | ||
1092 | }, | ||
1093 | Event::TextInput { text, .. } => { | ||
1094 | self.command_box.push_str(&text[..]); | ||
1083 | } | 1095 | } |
1096 | _ => (), | ||
1084 | } | 1097 | } |
1085 | } | 1098 | } |
1086 | self.cache(); | ||
1087 | self.redraw(); | ||
1088 | } | 1099 | } |
1100 | HandleEventOutcome::Normal | ||
1089 | } | 1101 | } |
1090 | } | 1102 | } |