From cb9bc8698dd4afbc97f95265d0a90f8acd6e4a5a Mon Sep 17 00:00:00 2001 From: Thomas Hansen <31554741+thomas992@users.noreply.github.com> Date: Sun, 3 Jul 2022 09:25:35 -0400 Subject: [PATCH] Browser Hotkey Conflicts (#1697) * code hotkey to N, move superscript hotkey to Y ctrl A S D F G H are all taken, CTRL Q is traditionally to remove formatting and should be reserved for that. CTRL W E R T are also all taken. CTRL Z X C V are taken so all of the first 4/5 keys of each row except Q are inaccessible. * strike through conflict, update text * fixed underline command * added ALTSHIFT, browser documentation * underline ALTSHIFT Q it leaves the Q character which is considered a bug but before this pull underline was not working entirely so this is progress * update text * ALTSHIFT is treated as a command * added eighth command, ALTSHIFT+W adds two spaces * CTRL+Y to toggle case on text_edit demo * better code * Revised Menu * fix dead link * Update lib.rs * Update easy_mark_editor.rs * Update egui/src/data/input.rs Co-authored-by: Emil Ernerfeldt * update * reverted variables used for debugging * fixed labels hotkey conflict * comments * fmt * cargo fmt * Nice hotkey menu Co-authored-by: Emil Ernerfeldt --- eframe/src/web/events.rs | 2 +- egui-winit/src/lib.rs | 2 +- egui/src/data/input.rs | 43 +++++++++------ egui_demo_lib/src/demo/text_edit.rs | 4 +- .../src/easy_mark/easy_mark_editor.rs | 55 ++++++++++++++----- 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/eframe/src/web/events.rs b/eframe/src/web/events.rs index 153fc7b47..27c1cc2e1 100644 --- a/eframe/src/web/events.rs +++ b/eframe/src/web/events.rs @@ -51,7 +51,7 @@ pub fn install_document_events(runner_container: &AppRunnerContainer) -> Result< "keydown", |event: web_sys::KeyboardEvent, mut runner_lock| { if event.is_composing() || event.key_code() == 229 { - // https://www.fxsitecompat.dev/en-CA/docs/2018/keydown-and-keyup-events-are-now-fired-during-ime-composition/ + // https://web.archive.org/web/20200526195704/https://www.fxsitecompat.dev/en-CA/docs/2018/keydown-and-keyup-events-are-now-fired-during-ime-composition/ return; } diff --git a/egui-winit/src/lib.rs b/egui-winit/src/lib.rs index dceb287b7..536fffe76 100644 --- a/egui-winit/src/lib.rs +++ b/egui-winit/src/lib.rs @@ -200,7 +200,7 @@ impl State { let is_mac_cmd = cfg!(target_os = "macos") && (self.egui_input.modifiers.ctrl || self.egui_input.modifiers.mac_cmd); - if is_printable_char(*ch) && !is_mac_cmd { + if is_printable_char(*ch) && !is_mac_cmd && !self.egui_input.modifiers.alt { self.egui_input .events .push(egui::Event::Text(ch.to_string())); diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index 75eaca29d..6bd28d4d5 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -323,6 +323,13 @@ impl Modifiers { mac_cmd: false, command: false, }; + pub const ALT_SHIFT: Self = Self { + alt: true, + ctrl: false, + shift: true, + mac_cmd: false, + command: false, + }; /// The Mac ⌘ Command key pub const MAC_CMD: Self = Self { alt: false, @@ -429,7 +436,7 @@ impl std::ops::BitOr for Modifiers { /// plus a few that are useful for detecting keyboard shortcuts. /// /// Many keys are omitted because they are not always physical keys (depending on keyboard language), e.g. `;` and `§`, -/// and are therefor unsuitable as keyboard shortcuts if you want your app to be portable. +/// and are therefore unsuitable as keyboard shortcuts if you want your app to be portable. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum Key { @@ -474,37 +481,37 @@ pub enum Key { A, // Used for cmd+A (select All) B, - C, - D, - E, - F, - G, - H, - I, - J, + C, // |CMD COPY| + D, // |CMD BOOKMARK| + E, // |CMD SEARCH| + F, // |CMD FIND firefox & chrome| + G, // |CMD FIND chrome| + H, // |CMD History| + I, // italics + J, // |CMD SEARCH firefox/DOWNLOAD chrome| K, // Used for ctrl+K (delete text after cursor) L, M, N, - O, - P, + O, // |CMD OPEN| + P, // |CMD PRINT| Q, - R, - S, - T, + R, // |CMD REFRESH| + S, // |CMD SAVE| + T, // |CMD TAB| U, // Used for ctrl+U (delete text before cursor) - V, + V, // |CMD PASTE| W, // Used for ctrl+W (delete previous word) - X, + X, // |CMD CUT| Y, - Z, // Used for cmd+Z (undo) + Z, // |CMD UNDO| // The function keys: F1, F2, F3, F4, - F5, + F5, // |CMD REFRESH| F6, F7, F8, diff --git a/egui_demo_lib/src/demo/text_edit.rs b/egui_demo_lib/src/demo/text_edit.rs index b15de5ba8..c1aaa1f23 100644 --- a/egui_demo_lib/src/demo/text_edit.rs +++ b/egui_demo_lib/src/demo/text_edit.rs @@ -62,12 +62,12 @@ impl super::View for TextEdit { ui.add_enabled( anything_selected, - egui::Label::new("Press ctrl+T to toggle the case of selected text (cmd+T on Mac)"), + egui::Label::new("Press ctrl+Y to toggle the case of selected text (cmd+Y on Mac)"), ); if ui .input_mut() - .consume_key(egui::Modifiers::COMMAND, egui::Key::T) + .consume_key(egui::Modifiers::COMMAND, egui::Key::Y) { if let Some(text_cursor_range) = output.cursor_range { use egui::TextBuffer as _; diff --git a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs index 488b7ef42..6ab66542c 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -45,15 +45,12 @@ impl EasyMarkEditor { pub fn ui(&mut self, ui: &mut egui::Ui) { egui::Grid::new("controls").show(ui, |ui| { + let _ = ui.button("Hotkeys").on_hover_ui(nested_hotkeys_ui); + ui.checkbox(&mut self.show_rendered, "Show rendered"); ui.checkbox(&mut self.highlight_editor, "Highlight editor"); egui::reset_button(ui, self); ui.end_row(); - - ui.checkbox(&mut self.show_rendered, "Show rendered"); }); - - ui.label("Use ctrl/cmd + key to toggle: B: *strong* C: `code` I: /italics/ L: $lowered$ R: ^raised^ S: ~strikethrough~ U: _underline_"); - ui.separator(); if self.show_rendered { @@ -109,20 +106,43 @@ impl EasyMarkEditor { } } +fn nested_hotkeys_ui(ui: &mut egui::Ui) { + let _ = ui.label("CTRL+B *bold*"); + let _ = ui.label("CTRL+N `code`"); + let _ = ui.label("CTRL+I /italics/"); + let _ = ui.label("CTRL+L $subscript$"); + let _ = ui.label("CTRL+Y ^superscript^"); + let _ = ui.label("ALT+SHIFT+Q ~strikethrough~"); + let _ = ui.label("ALT+SHIFT+W _underline_"); + let _ = ui.label("ALT+SHIFT+E two spaces"); // Placeholder for tab indent +} + fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRange) -> bool { let mut any_change = false; - for (key, surrounding) in [ - (Key::B, "*"), // *bold* - (Key::C, "`"), // `code` - (Key::I, "/"), // /italics/ - (Key::L, "$"), // $subscript$ - (Key::R, "^"), // ^superscript^ - (Key::S, "~"), // ~strikethrough~ - (Key::U, "_"), // _underline_ + if ui + .input_mut() + .consume_key(egui::Modifiers::ALT_SHIFT, Key::E) + { + // This is a placeholder till we can indent the active line + any_change = true; + let [primary, _secondary] = ccursor_range.sorted(); + + let advance = code.insert_text(" ", primary.index); + ccursor_range.primary.index += advance; + ccursor_range.secondary.index += advance; + } + for (modifier, key, surrounding) in [ + (egui::Modifiers::COMMAND, Key::B, "*"), // *bold* + (egui::Modifiers::COMMAND, Key::N, "`"), // `code` + (egui::Modifiers::COMMAND, Key::I, "/"), // /italics/ + (egui::Modifiers::COMMAND, Key::L, "$"), // $subscript$ + (egui::Modifiers::COMMAND, Key::Y, "^"), // ^superscript^ + (egui::Modifiers::ALT_SHIFT, Key::Q, "~"), // ~strikethrough~ + (egui::Modifiers::ALT_SHIFT, Key::W, "_"), // _underline_ ] { - if ui.input_mut().consume_key(egui::Modifiers::COMMAND, key) { - toggle_surrounding(code, ccursor_range, surrounding); + if ui.input_mut().consume_key(modifier, key) { any_change = true; + toggle_surrounding(code, ccursor_range, surrounding); }; } any_change @@ -222,6 +242,11 @@ The style characters are chosen to be similar to what they are representing: # TODO - Sub-headers (`## h2`, `### h3` etc) +- Hotkey Editor +- International keyboard algorithm for non-letter keys +- ALT+SHIFT+Num1 is not a functioning hotkey +- Tab Indent Increment/Decrement CTRL+], CTRL+[ + - Images - we want to be able to optionally specify size (width and\/or height) - centering of images is very desirable