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 <emil.ernerfeldt@gmail.com>

* update

* reverted variables used for debugging

* fixed labels hotkey conflict

* comments

* fmt

* cargo fmt

* Nice hotkey menu

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
Thomas Hansen 2022-07-03 09:25:35 -04:00 committed by GitHub
parent 14ae4b24a7
commit cb9bc8698d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 37 deletions

View file

@ -51,7 +51,7 @@ pub fn install_document_events(runner_container: &AppRunnerContainer) -> Result<
"keydown", "keydown",
|event: web_sys::KeyboardEvent, mut runner_lock| { |event: web_sys::KeyboardEvent, mut runner_lock| {
if event.is_composing() || event.key_code() == 229 { 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; return;
} }

View file

@ -200,7 +200,7 @@ impl State {
let is_mac_cmd = cfg!(target_os = "macos") let is_mac_cmd = cfg!(target_os = "macos")
&& (self.egui_input.modifiers.ctrl || self.egui_input.modifiers.mac_cmd); && (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 self.egui_input
.events .events
.push(egui::Event::Text(ch.to_string())); .push(egui::Event::Text(ch.to_string()));

View file

@ -323,6 +323,13 @@ impl Modifiers {
mac_cmd: false, mac_cmd: false,
command: false, command: false,
}; };
pub const ALT_SHIFT: Self = Self {
alt: true,
ctrl: false,
shift: true,
mac_cmd: false,
command: false,
};
/// The Mac ⌘ Command key /// The Mac ⌘ Command key
pub const MAC_CMD: Self = Self { pub const MAC_CMD: Self = Self {
alt: false, alt: false,
@ -429,7 +436,7 @@ impl std::ops::BitOr for Modifiers {
/// plus a few that are useful for detecting keyboard shortcuts. /// 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 `§`, /// 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)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum Key { pub enum Key {
@ -474,37 +481,37 @@ pub enum Key {
A, // Used for cmd+A (select All) A, // Used for cmd+A (select All)
B, B,
C, C, // |CMD COPY|
D, D, // |CMD BOOKMARK|
E, E, // |CMD SEARCH|
F, F, // |CMD FIND firefox & chrome|
G, G, // |CMD FIND chrome|
H, H, // |CMD History|
I, I, // italics
J, J, // |CMD SEARCH firefox/DOWNLOAD chrome|
K, // Used for ctrl+K (delete text after cursor) K, // Used for ctrl+K (delete text after cursor)
L, L,
M, M,
N, N,
O, O, // |CMD OPEN|
P, P, // |CMD PRINT|
Q, Q,
R, R, // |CMD REFRESH|
S, S, // |CMD SAVE|
T, T, // |CMD TAB|
U, // Used for ctrl+U (delete text before cursor) U, // Used for ctrl+U (delete text before cursor)
V, V, // |CMD PASTE|
W, // Used for ctrl+W (delete previous word) W, // Used for ctrl+W (delete previous word)
X, X, // |CMD CUT|
Y, Y,
Z, // Used for cmd+Z (undo) Z, // |CMD UNDO|
// The function keys: // The function keys:
F1, F1,
F2, F2,
F3, F3,
F4, F4,
F5, F5, // |CMD REFRESH|
F6, F6,
F7, F7,
F8, F8,

View file

@ -62,12 +62,12 @@ impl super::View for TextEdit {
ui.add_enabled( ui.add_enabled(
anything_selected, 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 if ui
.input_mut() .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 { if let Some(text_cursor_range) = output.cursor_range {
use egui::TextBuffer as _; use egui::TextBuffer as _;

View file

@ -45,15 +45,12 @@ impl EasyMarkEditor {
pub fn ui(&mut self, ui: &mut egui::Ui) { pub fn ui(&mut self, ui: &mut egui::Ui) {
egui::Grid::new("controls").show(ui, |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"); ui.checkbox(&mut self.highlight_editor, "Highlight editor");
egui::reset_button(ui, self); egui::reset_button(ui, self);
ui.end_row(); 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(); ui.separator();
if self.show_rendered { 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 { fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRange) -> bool {
let mut any_change = false; let mut any_change = false;
for (key, surrounding) in [ if ui
(Key::B, "*"), // *bold* .input_mut()
(Key::C, "`"), // `code` .consume_key(egui::Modifiers::ALT_SHIFT, Key::E)
(Key::I, "/"), // /italics/ {
(Key::L, "$"), // $subscript$ // This is a placeholder till we can indent the active line
(Key::R, "^"), // ^superscript^ any_change = true;
(Key::S, "~"), // ~strikethrough~ let [primary, _secondary] = ccursor_range.sorted();
(Key::U, "_"), // _underline_
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) { if ui.input_mut().consume_key(modifier, key) {
toggle_surrounding(code, ccursor_range, surrounding);
any_change = true; any_change = true;
toggle_surrounding(code, ccursor_range, surrounding);
}; };
} }
any_change any_change
@ -222,6 +242,11 @@ The style characters are chosen to be similar to what they are representing:
# TODO # TODO
- Sub-headers (`## h2`, `### h3` etc) - 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 - Images
- we want to be able to optionally specify size (width and\/or height) - we want to be able to optionally specify size (width and\/or height)
- centering of images is very desirable - centering of images is very desirable