From 3fa06fd032cd6c6c6555881338ffc5fe079fabcb Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 26 Jul 2018 13:56:23 -0700 Subject: [PATCH] dont repeat keypress manually in OSD message --- docs/TODO_phase2.md | 4 +- editor/src/experimental.rs | 2 +- editor/src/plugins/classification.rs | 4 +- editor/src/plugins/color_picker.rs | 13 ++-- editor/src/plugins/floodfill.rs | 6 +- editor/src/plugins/geom_validation.rs | 7 +- editor/src/plugins/road_editor.rs | 10 +-- editor/src/plugins/search.rs | 4 +- editor/src/plugins/selection.rs | 10 ++- editor/src/plugins/sim_controls.rs | 14 ++-- editor/src/plugins/steep.rs | 4 +- editor/src/plugins/stop_sign_editor.rs | 26 +++----- editor/src/plugins/traffic_signal_editor.rs | 14 ++-- editor/src/plugins/warp.rs | 6 +- editor/src/ui.rs | 16 ++--- ezgui/src/input.rs | 8 ++- ezgui/src/keys.rs | 64 ++++++++++++++++++ ezgui/src/lib.rs | 1 + ezgui/src/text_box.rs | 72 ++------------------- 19 files changed, 130 insertions(+), 155 deletions(-) create mode 100644 ezgui/src/keys.rs diff --git a/docs/TODO_phase2.md b/docs/TODO_phase2.md index 3bffb4718e..c5b46658a9 100644 --- a/docs/TODO_phase2.md +++ b/docs/TODO_phase2.md @@ -25,8 +25,6 @@ - be able to change road directions -- basic road edits - - apply edits to live map and recompute everything needed - - multiple edits to a road should work +- tests that edits + reload from scratch are equivalent - undo support! diff --git a/editor/src/experimental.rs b/editor/src/experimental.rs index df0a030a6d..f73ec6d15b 100644 --- a/editor/src/experimental.rs +++ b/editor/src/experimental.rs @@ -42,7 +42,7 @@ impl UI { impl gui::GUI for UI { fn event(&mut self, input: &mut UserInput) -> gui::EventLoopMode { - if input.unimportant_key_pressed(Key::Escape, "Press escape to quit") { + if input.unimportant_key_pressed(Key::Escape, "quit") { process::exit(0); } let speed = 5.0; diff --git a/editor/src/plugins/classification.rs b/editor/src/plugins/classification.rs index c0122b9675..85bf2fcbff 100644 --- a/editor/src/plugins/classification.rs +++ b/editor/src/plugins/classification.rs @@ -18,9 +18,9 @@ impl OsmClassifier { pub fn handle_event(&mut self, input: &mut UserInput) -> bool { let msg = if self.active { - "Press 6 to stop showing OSM classes" + "stop showing OSM classes" } else { - "Press 6 to show OSM classifications" + "to show OSM classifications" }; if input.unimportant_key_pressed(Key::D6, msg) { self.active = !self.active; diff --git a/editor/src/plugins/color_picker.rs b/editor/src/plugins/color_picker.rs index 5a074d5ca0..968f6c8b4c 100644 --- a/editor/src/plugins/color_picker.rs +++ b/editor/src/plugins/color_picker.rs @@ -38,7 +38,7 @@ impl ColorPicker { let mut new_state: Option = None; let active = match self { ColorPicker::Inactive => { - if input.unimportant_key_pressed(Key::D8, "Press 8 to configure colors") { + if input.unimportant_key_pressed(Key::D8, "configure colors") { new_state = Some(ColorPicker::Choosing(menu::Menu::new( Colors::iter().map(|c| c.to_string()).collect(), ))); @@ -64,17 +64,12 @@ impl ColorPicker { ColorPicker::PickingColor(c, orig_color) => { if input.key_pressed( Key::Escape, - &format!( - "Press escape to stop configuring color for {:?} and revert", - c - ), + &format!("stop configuring color for {:?} and revert", c), ) { cs.set(*c, *orig_color); new_state = Some(ColorPicker::Inactive); - } else if input.key_pressed( - Key::Return, - &format!("Press enter to finalize new color for {:?}", c), - ) { + } else if input.key_pressed(Key::Return, &format!("finalize new color for {:?}", c)) + { println!("Setting color for {:?}", c); new_state = Some(ColorPicker::Inactive); } diff --git a/editor/src/plugins/floodfill.rs b/editor/src/plugins/floodfill.rs index 2c550686fc..926f4d02c4 100644 --- a/editor/src/plugins/floodfill.rs +++ b/editor/src/plugins/floodfill.rs @@ -41,13 +41,13 @@ impl Floodfiller { let active = match self { Floodfiller::Inactive => false, Floodfiller::Active { visited, queue } => { - if input.key_pressed(Key::Return, "Press Enter to quit floodfilling") { + if input.key_pressed(Key::Return, "quit floodfilling") { new_state = Some(Floodfiller::Inactive); } else if !queue.is_empty() { - if input.key_pressed(Key::Space, "Press space to step floodfilling forwards") { + if input.key_pressed(Key::Space, "step floodfilling forwards") { step(visited, queue, map); } - if input.key_pressed(Key::Tab, "Press tab to floodfill the rest of the map") { + if input.key_pressed(Key::Tab, "floodfill the rest of the map") { loop { if step(visited, queue, map) { break; diff --git a/editor/src/plugins/geom_validation.rs b/editor/src/plugins/geom_validation.rs index 1f0dfaed98..779e28e308 100644 --- a/editor/src/plugins/geom_validation.rs +++ b/editor/src/plugins/geom_validation.rs @@ -102,9 +102,7 @@ impl Validator { current_problem, } => { // Initialize or advance? - if !current_problem.is_some() - || input.key_pressed(Key::N, "Press N to see the next problem") - { + if !current_problem.is_some() || input.key_pressed(Key::N, "see the next problem") { // TODO do this in a bg thread or something *current_problem = gen.next(); @@ -117,8 +115,7 @@ impl Validator { println!("No more problems!"); new_state = Some(Validator::Inactive); } - } else if input.key_pressed(Key::Escape, "Press Escape to stop looking at problems") - { + } else if input.key_pressed(Key::Escape, "stop looking at problems") { println!("Quit geometry validator"); new_state = Some(Validator::Inactive); } diff --git a/editor/src/plugins/road_editor.rs b/editor/src/plugins/road_editor.rs index 2fee34324e..22c2d31ec6 100644 --- a/editor/src/plugins/road_editor.rs +++ b/editor/src/plugins/road_editor.rs @@ -41,7 +41,7 @@ impl RoadEditor { _ => false, }, RoadEditor::Active(edits) => { - if input.key_pressed(Key::Return, "Press enter to stop editing roads") { + if input.key_pressed(Key::Return, "stop editing roads") { new_state = Some(RoadEditor::Inactive(edits.clone())); } else if let SelectionState::SelectedLane(id, _) = *current_selection { let lane = map.get_l(id); @@ -49,27 +49,27 @@ impl RoadEditor { let reason = EditReason::BasemapWrong; // TODO be able to choose if lane.lane_type != LaneType::Driving - && input.key_pressed(Key::D, "Press D to make this a driving lane") + && input.key_pressed(Key::D, "make this a driving lane") { if edits.change_lane_type(reason, road, lane, LaneType::Driving) { changed = Some((lane.id, LaneType::Driving)); } } if lane.lane_type != LaneType::Parking - && input.key_pressed(Key::P, "Press p to make this a parking lane") + && input.key_pressed(Key::P, "make this a parking lane") { if edits.change_lane_type(reason, road, lane, LaneType::Parking) { changed = Some((lane.id, LaneType::Parking)); } } if lane.lane_type != LaneType::Biking - && input.key_pressed(Key::B, "Press b to make this a bike lane") + && input.key_pressed(Key::B, "make this a bike lane") { if edits.change_lane_type(reason, road, lane, LaneType::Biking) { changed = Some((lane.id, LaneType::Biking)); } } - if input.key_pressed(Key::Backspace, "Press backspace to delete this lane") { + if input.key_pressed(Key::Backspace, "delete this lane") { if edits.delete_lane(road, lane) { println!("Have to reload the map from scratch to pick up this change!"); } diff --git a/editor/src/plugins/search.rs b/editor/src/plugins/search.rs index 1f2ca889e5..96b154c143 100644 --- a/editor/src/plugins/search.rs +++ b/editor/src/plugins/search.rs @@ -42,7 +42,7 @@ impl SearchState { let mut new_state: Option = None; let active = match self { SearchState::Empty => { - if input.unimportant_key_pressed(Key::Slash, "Press / to start searching") { + if input.unimportant_key_pressed(Key::Slash, "start searching") { new_state = Some(SearchState::EnteringSearch(TextBox::new())); true } else { @@ -59,7 +59,7 @@ impl SearchState { SearchState::FilterOSM(filter) => { if input.key_pressed( Key::Return, - &format!("Press enter to clear the current search for {}", filter), + &format!("clear the current search for {}", filter), ) { new_state = Some(SearchState::Empty); } diff --git a/editor/src/plugins/selection.rs b/editor/src/plugins/selection.rs index ed805f2f16..f089637a54 100644 --- a/editor/src/plugins/selection.rs +++ b/editor/src/plugins/selection.rs @@ -68,16 +68,14 @@ impl SelectionState { ) { new_state = Some(SelectionState::TooltipLane(*id)); true - } else if input - .key_pressed(Key::Tab, "Press Tab to cycle through this lane's turns") - { + } else if input.key_pressed(Key::Tab, "cycle through this lane's turns") { let idx = match *current_turn_index { Some(i) => i + 1, None => 0, }; new_state = Some(SelectionState::SelectedLane(*id, Some(idx))); true - } else if input.key_pressed(Key::D, "press D to debug") { + } else if input.key_pressed(Key::D, "debug") { map.get_l(*id).dump_debug(); true } else { @@ -213,7 +211,7 @@ impl Hider { } pub fn event(&mut self, input: &mut UserInput, state: &mut SelectionState) -> bool { - if input.unimportant_key_pressed(Key::K, "Press k to unhide everything") { + if input.unimportant_key_pressed(Key::K, "unhide everything") { println!("Unhiding {} things", self.items.len()); self.items.clear(); return true; @@ -226,7 +224,7 @@ impl Hider { _ => None, }; if let Some(id) = item { - if input.unimportant_key_pressed(Key::H, &format!("Press h to hide {:?}", id)) { + if input.unimportant_key_pressed(Key::H, &format!("hide {:?}", id)) { self.items.insert(id); println!("Hiding {:?}", id); *state = SelectionState::Empty; diff --git a/editor/src/plugins/sim_controls.rs b/editor/src/plugins/sim_controls.rs index f361bf2b3f..8d26c1be13 100644 --- a/editor/src/plugins/sim_controls.rs +++ b/editor/src/plugins/sim_controls.rs @@ -33,31 +33,31 @@ impl SimController { // true if the sim is running pub fn event(&mut self, input: &mut UserInput, map: &Map, control_map: &ControlMap) -> bool { - if input.unimportant_key_pressed(Key::LeftBracket, "Press [ to slow down sim") { + if input.unimportant_key_pressed(Key::LeftBracket, "slow down sim") { self.desired_speed -= ADJUST_SPEED; self.desired_speed = self.desired_speed.max(0.0); } - if input.unimportant_key_pressed(Key::RightBracket, "Press ] to speed up sim") { + if input.unimportant_key_pressed(Key::RightBracket, "speed up sim") { self.desired_speed += ADJUST_SPEED; } - if input.unimportant_key_pressed(Key::O, "Press O to save sim state") { + if input.unimportant_key_pressed(Key::O, "save sim state") { abstutil::write_json("sim_state", &self.sim).expect("Writing sim state failed"); println!("Wrote sim_state"); } - if input.unimportant_key_pressed(Key::P, "Press P to load sim state") { + if input.unimportant_key_pressed(Key::P, "load sim state") { self.sim = abstutil::read_json("sim_state").expect("sim state failed"); } if self.last_step.is_some() { - if input.unimportant_key_pressed(Key::Space, "Press space to pause sim") { + if input.unimportant_key_pressed(Key::Space, "pause sim") { self.last_step = None; self.benchmark = None; self.sim_speed = String::from("paused"); } } else { - if input.unimportant_key_pressed(Key::Space, "Press space to run sim") { + if input.unimportant_key_pressed(Key::Space, "run sim") { self.last_step = Some(Instant::now()); self.benchmark = Some(self.sim.start_benchmark()); - } else if input.unimportant_key_pressed(Key::M, "press M to run one step") { + } else if input.unimportant_key_pressed(Key::M, "run one step") { self.sim.step(map, control_map); } } diff --git a/editor/src/plugins/steep.rs b/editor/src/plugins/steep.rs index 1cd706f9a0..4764273ba6 100644 --- a/editor/src/plugins/steep.rs +++ b/editor/src/plugins/steep.rs @@ -35,9 +35,9 @@ impl SteepnessVisualizer { pub fn handle_event(&mut self, input: &mut UserInput) -> bool { let msg = if self.active { - "Press 5 to stop showing steepness" + "stop showing steepness" } else { - "Press 5 to visualize steepness" + "visualize steepness" }; if input.unimportant_key_pressed(Key::D5, msg) { self.active = !self.active; diff --git a/editor/src/plugins/stop_sign_editor.rs b/editor/src/plugins/stop_sign_editor.rs index 19229703eb..aa1503482a 100644 --- a/editor/src/plugins/stop_sign_editor.rs +++ b/editor/src/plugins/stop_sign_editor.rs @@ -35,45 +35,37 @@ impl StopSignEditor { let active = match self { StopSignEditor::Inactive => false, StopSignEditor::Active(i) => { - if input.key_pressed(Key::Return, "Press enter to quit the editor") { + if input.key_pressed(Key::Return, "quit the editor") { new_state = Some(StopSignEditor::Inactive); } else if let SelectionState::SelectedTurn(id) = *current_selection { if map.get_t(id).parent == *i { let sign = &mut control_map.stop_signs.get_mut(i).unwrap(); match sign.get_priority(id) { TurnPriority::Priority => { - if input.key_pressed(Key::D2, "Press 2 to make this turn yield") { + if input.key_pressed(Key::D2, "make this turn yield") { sign.set_priority(id, TurnPriority::Yield, map); } - if input - .key_pressed(Key::D3, "Press 3 to make this turn always stop") - { + if input.key_pressed(Key::D3, "make this turn always stop") { sign.set_priority(id, TurnPriority::Stop, map); } } TurnPriority::Yield => { if sign.could_be_priority_turn(id, map) - && input.key_pressed( - Key::D1, - "Press 1 to let this turn go immediately", - ) { + && input.key_pressed(Key::D1, "let this turn go immediately") + { sign.set_priority(id, TurnPriority::Priority, map); } - if input - .key_pressed(Key::D3, "Press 3 to make this turn always stop") - { + if input.key_pressed(Key::D3, "make this turn always stop") { sign.set_priority(id, TurnPriority::Stop, map); } } TurnPriority::Stop => { if sign.could_be_priority_turn(id, map) - && input.key_pressed( - Key::D1, - "Press 1 to let this turn go immediately", - ) { + && input.key_pressed(Key::D1, "let this turn go immediately") + { sign.set_priority(id, TurnPriority::Priority, map); } - if input.key_pressed(Key::D2, "Press 2 to make this turn yield") { + if input.key_pressed(Key::D2, "make this turn yield") { sign.set_priority(id, TurnPriority::Yield, map); } } diff --git a/editor/src/plugins/traffic_signal_editor.rs b/editor/src/plugins/traffic_signal_editor.rs index 525e0295bf..9f42fc11c1 100644 --- a/editor/src/plugins/traffic_signal_editor.rs +++ b/editor/src/plugins/traffic_signal_editor.rs @@ -42,7 +42,7 @@ impl TrafficSignalEditor { let active = match self { TrafficSignalEditor::Inactive => false, TrafficSignalEditor::Active { i, current_cycle } => { - if input.key_pressed(Key::Return, "Press enter to quit the editor") { + if input.key_pressed(Key::Return, "quit the editor") { new_state = Some(TrafficSignalEditor::Inactive); } else { // Change cycles @@ -68,17 +68,13 @@ impl TrafficSignalEditor { &mut control_map.traffic_signals.get_mut(&i).unwrap().cycles [*current_cycle]; if cycle.contains(id) { - if input.key_pressed( - Key::Backspace, - "Press Backspace to remove this turn from this cycle", - ) { + if input + .key_pressed(Key::Backspace, "remove this turn from this cycle") + { cycle.remove(id); } } else if !cycle.conflicts_with(id, map) { - if input.key_pressed( - Key::Space, - "Press Space to add this turn to this cycle", - ) { + if input.key_pressed(Key::Space, "add this turn to this cycle") { cycle.add(id); } } diff --git a/editor/src/plugins/warp.rs b/editor/src/plugins/warp.rs index 3721ce64c9..a908a60714 100644 --- a/editor/src/plugins/warp.rs +++ b/editor/src/plugins/warp.rs @@ -22,10 +22,8 @@ impl WarpState { let mut new_state: Option = None; let active = match self { WarpState::Empty => { - if input.unimportant_key_pressed( - Key::J, - "Press J to start searching for something to warp to", - ) { + if input.unimportant_key_pressed(Key::J, "start searching for something to warp to") + { new_state = Some(WarpState::EnteringSearch(TextBox::new())); true } else { diff --git a/editor/src/ui.rs b/editor/src/ui.rs index f10de00df6..3477cdfb51 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -456,35 +456,31 @@ impl gui::GUI for UI { SelectionState::SelectedCar(id) => { // TODO not sure if we should debug like this (pushing the bit down to all the // layers representing an entity) or by using some scary global mutable singleton - if input.unimportant_key_pressed(Key::D, "press D to debug") { + if input.unimportant_key_pressed(Key::D, "debug") { self.sim_ctrl.sim.toggle_debug(id); return gui::EventLoopMode::InputOnly; } } SelectionState::SelectedLane(id, _) => { - if input.key_pressed(Key::F, "Press F to start floodfilling from this lane") { + if input.key_pressed(Key::F, "start floodfilling from this lane") { self.floodfiller = Floodfiller::start(id); return gui::EventLoopMode::InputOnly; } - if input.key_pressed(Key::A, "Press A to start something on this lane") { + if input.key_pressed(Key::A, "start something on this lane") { self.sim_ctrl.sim.start_agent(&self.map, id); return gui::EventLoopMode::InputOnly; } } SelectionState::SelectedIntersection(id) => { if self.control_map.traffic_signals.contains_key(&id) { - if input.key_pressed( - Key::E, - &format!("Press E to edit traffic signal for {:?}", id), - ) { + if input.key_pressed(Key::E, &format!("edit traffic signal for {:?}", id)) { self.traffic_signal_editor = TrafficSignalEditor::start(id); return gui::EventLoopMode::InputOnly; } } if self.control_map.stop_signs.contains_key(&id) { - if input.key_pressed(Key::E, &format!("Press E to edit stop sign for {:?}", id)) - { + if input.key_pressed(Key::E, &format!("edit stop sign for {:?}", id)) { self.stop_sign_editor = StopSignEditor::start(id); return gui::EventLoopMode::InputOnly; } @@ -496,7 +492,7 @@ impl gui::GUI for UI { // Do this one lastish, since it conflicts with lots of other stuff stop_if_done!(self.current_selection_state.event(input, &self.map)); - if input.unimportant_key_pressed(Key::Escape, "Press escape to quit") { + if input.unimportant_key_pressed(Key::Escape, "quit") { let state = EditorState { cam_x: self.canvas.cam_x, cam_y: self.canvas.cam_y, diff --git a/ezgui/src/input.rs b/ezgui/src/input.rs index c0a65ad7c0..c8d967a334 100644 --- a/ezgui/src/input.rs +++ b/ezgui/src/input.rs @@ -1,5 +1,6 @@ // Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0 +use keys::describe_key; use piston::input::{Button, Event, IdleArgs, Key, PressEvent}; use std::collections::HashMap; @@ -110,8 +111,8 @@ impl UserInput { return true; } } - // TODO stringify the key, so we don't have to say what to press! - self.important_actions.push(String::from(action)); + self.important_actions + .push(format!("Press {} to {}", describe_key(key), action)); false } @@ -128,7 +129,8 @@ impl UserInput { return true; } } - self.unimportant_actions.push(String::from(action)); + self.unimportant_actions + .push(format!("Press {} to {}", describe_key(key), action)); false } diff --git a/ezgui/src/keys.rs b/ezgui/src/keys.rs new file mode 100644 index 0000000000..8e7c21415a --- /dev/null +++ b/ezgui/src/keys.rs @@ -0,0 +1,64 @@ +use piston::input::Key; + +pub(crate) fn describe_key(key: Key) -> String { + match key { + Key::Space => "Space".to_string(), + Key::Escape => "Escape".to_string(), + Key::Return => "Enter".to_string(), + Key::Tab => "Tab".to_string(), + Key::Backspace => "Backspace".to_string(), + _ => { + if let Some(c) = key_to_char(key) { + return c.to_string(); + } + format!("{:?}", key) + } + } +} + +// Returns uppercase form +pub(crate) fn key_to_char(key: Key) -> Option { + match key { + Key::Space => Some(' '), + Key::A => Some('A'), + Key::B => Some('B'), + Key::C => Some('C'), + Key::D => Some('D'), + Key::E => Some('E'), + Key::F => Some('F'), + Key::G => Some('G'), + Key::H => Some('H'), + Key::I => Some('I'), + Key::J => Some('J'), + Key::K => Some('K'), + Key::L => Some('L'), + Key::M => Some('M'), + Key::N => Some('N'), + Key::O => Some('O'), + Key::P => Some('P'), + Key::Q => Some('Q'), + Key::R => Some('R'), + Key::S => Some('S'), + Key::T => Some('T'), + Key::U => Some('U'), + Key::V => Some('V'), + Key::W => Some('W'), + Key::X => Some('X'), + Key::Y => Some('Y'), + Key::Z => Some('Z'), + Key::D0 => Some('0'), + Key::D1 => Some('1'), + Key::D2 => Some('2'), + Key::D3 => Some('3'), + Key::D4 => Some('4'), + Key::D5 => Some('5'), + Key::D6 => Some('6'), + Key::D7 => Some('7'), + Key::D8 => Some('8'), + Key::D9 => Some('9'), + Key::Slash => Some('/'), + Key::LeftBracket => Some('['), + Key::RightBracket => Some(']'), + _ => None, + } +} diff --git a/ezgui/src/lib.rs b/ezgui/src/lib.rs index 0fa963abd4..0cb14ed56e 100644 --- a/ezgui/src/lib.rs +++ b/ezgui/src/lib.rs @@ -7,6 +7,7 @@ extern crate piston; pub mod canvas; pub mod input; +mod keys; pub mod menu; pub mod text; pub mod text_box; diff --git a/ezgui/src/text_box.rs b/ezgui/src/text_box.rs index e9c21298be..c7f2183114 100644 --- a/ezgui/src/text_box.rs +++ b/ezgui/src/text_box.rs @@ -1,5 +1,6 @@ // Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0 +use keys::key_to_char; use piston::input::{Button, Event, Key, PressEvent, ReleaseEvent}; // TODO right now, only a single line @@ -55,73 +56,10 @@ impl TextBox { // Insert if let Some(Button::Keyboard(key)) = ev.press_args() { - let new_char = match key { - Key::Space => Some(' '), - Key::A if self.shift_pressed => Some('A'), - Key::B if self.shift_pressed => Some('B'), - Key::C if self.shift_pressed => Some('C'), - Key::D if self.shift_pressed => Some('D'), - Key::E if self.shift_pressed => Some('E'), - Key::F if self.shift_pressed => Some('F'), - Key::G if self.shift_pressed => Some('G'), - Key::H if self.shift_pressed => Some('H'), - Key::I if self.shift_pressed => Some('I'), - Key::J if self.shift_pressed => Some('J'), - Key::K if self.shift_pressed => Some('K'), - Key::L if self.shift_pressed => Some('L'), - Key::M if self.shift_pressed => Some('M'), - Key::N if self.shift_pressed => Some('N'), - Key::O if self.shift_pressed => Some('O'), - Key::P if self.shift_pressed => Some('P'), - Key::Q if self.shift_pressed => Some('Q'), - Key::R if self.shift_pressed => Some('R'), - Key::S if self.shift_pressed => Some('S'), - Key::T if self.shift_pressed => Some('T'), - Key::U if self.shift_pressed => Some('U'), - Key::V if self.shift_pressed => Some('V'), - Key::W if self.shift_pressed => Some('W'), - Key::X if self.shift_pressed => Some('X'), - Key::Y if self.shift_pressed => Some('Y'), - Key::Z if self.shift_pressed => Some('Z'), - Key::A => Some('a'), - Key::B => Some('b'), - Key::C => Some('c'), - Key::D => Some('d'), - Key::E => Some('e'), - Key::F => Some('f'), - Key::G => Some('g'), - Key::H => Some('h'), - Key::I => Some('i'), - Key::J => Some('j'), - Key::K => Some('k'), - Key::L => Some('l'), - Key::M => Some('m'), - Key::N => Some('n'), - Key::O => Some('o'), - Key::P => Some('p'), - Key::Q => Some('q'), - Key::R => Some('r'), - Key::S => Some('s'), - Key::T => Some('t'), - Key::U => Some('u'), - Key::V => Some('v'), - Key::W => Some('w'), - Key::X => Some('x'), - Key::Y => Some('y'), - Key::Z => Some('z'), - Key::D0 => Some('0'), - Key::D1 => Some('1'), - Key::D2 => Some('2'), - Key::D3 => Some('3'), - Key::D4 => Some('4'), - Key::D5 => Some('5'), - Key::D6 => Some('6'), - Key::D7 => Some('7'), - Key::D8 => Some('8'), - Key::D9 => Some('9'), - _ => None, - }; - if let Some(c) = new_char { + if let Some(mut c) = key_to_char(key) { + if !self.shift_pressed { + c = c.to_lowercase().next().unwrap(); + } self.line.insert(self.cursor_x, c); self.cursor_x += 1; }