From ab3cbca4ba6138403b3332aa3abfb76672b8e012 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 12:41:00 +0000 Subject: [PATCH 01/15] add input_mut --- egui/src/ui.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/egui/src/ui.rs b/egui/src/ui.rs index b5a04c8fc24..8f925bf124c 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -338,6 +338,23 @@ impl Ui { self.ctx().input() } + + /// The [`InputState`] of the [`Context`] associated with this [`Ui`]. + /// Equivalent to `.ctx().input_mut()`. + /// + /// Note that this locks the [`Context`], so be careful with if-let bindings + /// like for [`Self::input()`]. + /// ``` + /// # egui::__run_test_ui(|ui| { + /// ui.input_mut().time = 0.0; + /// # }); + /// ``` + #[inline] + pub fn input_mut(&self) -> RwLockWriteGuard<'_, InputState> { + self.ctx().input_mut() + } + + /// The [`Memory`] of the [`Context`] associated with this ui. /// Equivalent to `.ctx().memory()`. #[inline] From 3c61075b642a2daebd0c897aa2c6f5a1f1c14222 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 17:33:49 +0000 Subject: [PATCH 02/15] Add ignore_key --- egui/src/input_state.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 6395b54fce7..92c56d8ae49 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -192,6 +192,23 @@ impl InputState { self.pointer.wants_repaint() || self.scroll_delta != Vec2::ZERO || !self.events.is_empty() } + // Ignore a key if it was pressed or released this frame. Useful for hotkeys. + // Returns if the key was pressed this frame + pub fn ignore_key(&mut self, ignore_key: Key, modifiers: Modifiers) -> bool { + self.events = std::mem::take(&mut self.events).into_iter().filter(|event| { + !matches!( + event, + Event::Key { + key, + modifiers: _mods, + .. + } if *key == ignore_key && *_mods == modifiers + ) + }).collect(); + + self.keys_down.remove(&ignore_key) + } + /// Was the given key pressed this frame? pub fn key_pressed(&self, desired_key: Key) -> bool { self.num_presses(desired_key) > 0 From b118aa0ce6c34aa89c0f54b572a63fb68b95b4d5 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 17:41:52 +0000 Subject: [PATCH 03/15] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 713a2011fda..125c3a7292f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased - +* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience `InputState::ignore_key` for shortcuts or hotkeys. ### Added ⭐ * Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)): * You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`. From 18defca404cb3fba5c5b9352d4257c1ce2f0feb7 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 17:44:02 +0000 Subject: [PATCH 04/15] style --- egui/src/input_state.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 92c56d8ae49..864177d08a8 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -200,9 +200,9 @@ impl InputState { event, Event::Key { key, - modifiers: _mods, + modifiers: mods, .. - } if *key == ignore_key && *_mods == modifiers + } if *key == ignore_key && *mods == modifiers ) }).collect(); From 7a4c751f285629e221b15ae8df4efc449a3ca77a Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:08:16 +0000 Subject: [PATCH 05/15] commentz --- CHANGELOG.md | 3 ++- egui/src/input_state.rs | 14 +++++++------- egui/src/ui.rs | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 125c3a7292f..df084bed015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased -* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience `InputState::ignore_key` for shortcuts or hotkeys. + ### Added ⭐ +* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). * Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)): * You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`. * Easily change text styles with `Style::text_styles`. diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 864177d08a8..51dc0a60764 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -194,19 +194,19 @@ impl InputState { // Ignore a key if it was pressed or released this frame. Useful for hotkeys. // Returns if the key was pressed this frame - pub fn ignore_key(&mut self, ignore_key: Key, modifiers: Modifiers) -> bool { - self.events = std::mem::take(&mut self.events).into_iter().filter(|event| { + pub fn consume_key(&mut self, key: Key, modifiers: Modifiers) -> bool { + self.events.retain(|event| { !matches!( event, Event::Key { - key, - modifiers: mods, + key: ev_key, + modifiers: ev_mods, .. - } if *key == ignore_key && *mods == modifiers + } if *ev_key == key && *ev_mods == modifiers ) - }).collect(); + }); - self.keys_down.remove(&ignore_key) + self.keys_down.remove(&key) } /// Was the given key pressed this frame? diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 8f925bf124c..015ba483680 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -346,7 +346,7 @@ impl Ui { /// like for [`Self::input()`]. /// ``` /// # egui::__run_test_ui(|ui| { - /// ui.input_mut().time = 0.0; + /// ui.input_mut().consume_key(egui::Key::Enter, egui::Modifiers::default()); /// # }); /// ``` #[inline] From 7b89764a5608ff7794bb9543eacebf73626390a9 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:09:03 +0000 Subject: [PATCH 06/15] grammer --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df084bed015..58f8a08c71e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased ### Added ⭐ -* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). +* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience nethod `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). * Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)): * You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`. * Easily change text styles with `Style::text_styles`. From a7b394cd4e39f54594f501d20d410408c8cbee30 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:09:32 +0000 Subject: [PATCH 07/15] spell it right this time --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f8a08c71e..b8f320176bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased ### Added ⭐ -* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience nethod `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). +* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience method `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). * Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)): * You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`. * Easily change text styles with `Style::text_styles`. From d0d885655066ea5b42de9c1042f6a11b66b3d4b0 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:41:38 +0000 Subject: [PATCH 08/15] oops forgot to changeh ere --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f320176bf..e5d18ad37c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased ### Added ⭐ -* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience method `InputState::ignore_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). +* `Ui::input_mut` to modify how subsequent widgets see the `InputState` and a convenience method `InputState::consume_key` for shortcuts or hotkeys ([#1212](https://github.com/emilk/egui/pull/1212)). * Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)): * You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`. * Easily change text styles with `Style::text_styles`. From 1ef87adbe0a3f9e3eb6f82852f99f7ec7807e2a1 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:42:16 +0000 Subject: [PATCH 09/15] update easy mark editor --- .../src/easy_mark/easy_mark_editor.rs | 65 +++++-------------- 1 file changed, 17 insertions(+), 48 deletions(-) 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 aa1468d9f37..768e2b3e672 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -117,59 +117,28 @@ impl EasyMarkEditor { fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRange) -> bool { let mut any_change = false; - for event in &ui.input().events { - if let Event::Key { + for (key, surrounding) in [ + (Key::B, "*"), + (Key::C, "`"), + (Key::I, "/"), + (Key::R, "~"), + (Key::U, "_"), + ] { + if ui.input_mut().consume_key( key, - pressed: true, - modifiers, - } = event - { - if modifiers.command_only() { - match &key { - // toggle *bold* - Key::B => { - toggle_surrounding(code, ccursor_range, "*"); - any_change = true; - } - // toggle `code` - Key::C => { - toggle_surrounding(code, ccursor_range, "`"); - any_change = true; - } - // toggle /italics/ - Key::I => { - toggle_surrounding(code, ccursor_range, "/"); - any_change = true; - } - // toggle $lowered$ - Key::L => { - toggle_surrounding(code, ccursor_range, "$"); - any_change = true; - } - // toggle ^raised^ - Key::R => { - toggle_surrounding(code, ccursor_range, "^"); - any_change = true; - } - // toggle ~strikethrough~ - Key::S => { - toggle_surrounding(code, ccursor_range, "~"); - any_change = true; - } - // toggle _underline_ - Key::U => { - toggle_surrounding(code, ccursor_range, "_"); - any_change = true; - } - _ => {} - } - } - } + egui::Modifiers { + command: true, + ..Default::default() + }, + ) { + toggle_surrounding(code, ccursor_range, surrounding); + any_change = true; + }; } any_change } -/// E.g. toggle *strong* with `toggle(&mut text, &mut cursor, "*")` +/// E.g. toggle *strong* with `toggle_surrounding(&mut text, &mut cursor, "*")` fn toggle_surrounding( code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRange, From 1aa5f450297ceb37f979489fae67c03649bebba1 Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:51:59 +0000 Subject: [PATCH 10/15] re add comments & superscript to easymark --- egui_demo_lib/src/easy_mark/easy_mark_editor.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) 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 768e2b3e672..c3bb0c2d687 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -118,11 +118,12 @@ impl EasyMarkEditor { fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRange) -> bool { let mut any_change = false; for (key, surrounding) in [ - (Key::B, "*"), - (Key::C, "`"), - (Key::I, "/"), - (Key::R, "~"), - (Key::U, "_"), + (Key::B, "*"), // *bold* + (Key::C, "`"), // `code` + (Key::I, "/"), // /italics/ + (Key::R, "^"), // ^superscript^ + (Key::S, "~"), // ~strikethrough~ + (Key::U, "_"), // _underline_ ] { if ui.input_mut().consume_key( key, From 48dac3a9f367e36bedf3f04b544c9b8f626d9c1c Mon Sep 17 00:00:00 2001 From: cat-state Date: Sat, 5 Feb 2022 18:56:06 +0000 Subject: [PATCH 11/15] oops forgot subscript --- egui_demo_lib/src/easy_mark/easy_mark_editor.rs | 1 + 1 file changed, 1 insertion(+) 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 c3bb0c2d687..bd383ac45d1 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -121,6 +121,7 @@ fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRang (Key::B, "*"), // *bold* (Key::C, "`"), // `code` (Key::I, "/"), // /italics/ + (Key::L, "$"), // $subscript$ (Key::R, "^"), // ^superscript^ (Key::S, "~"), // ~strikethrough~ (Key::U, "_"), // _underline_ From 11050bd821853cc78bfc45b33771a222976a844e Mon Sep 17 00:00:00 2001 From: Cat State Date: Sun, 6 Feb 2022 17:18:50 +0000 Subject: [PATCH 12/15] add builder api + arg order --- egui/src/data/input.rs | 40 ++++++++++++++++++++++++++++++++++++++++ egui/src/input_state.rs | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index 21234b650ef..dd107d404c6 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -264,6 +264,46 @@ pub struct Modifiers { } impl Modifiers { + + pub fn new() -> Self { + Default::default() + } + + pub fn alt(self, value: bool) -> Self { + Self { + alt: value, + ..self + } + } + + pub fn ctrl(self, value: bool) -> Self { + Self { + ctrl: value, + ..self + } + } + + pub fn shift(self, value: bool) -> Self { + Self { + shift: value, + ..self + } + } + + pub fn mac_cmd(self, value: bool) -> Self { + Self { + mac_cmd: value, + ..self + } + } + + pub fn command(self, value: bool) -> Self { + Self { + command: value, + ..self + } + } + #[inline(always)] pub fn is_none(&self) -> bool { self == &Self::default() diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 51dc0a60764..3f5e1cc13ef 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -194,7 +194,7 @@ impl InputState { // Ignore a key if it was pressed or released this frame. Useful for hotkeys. // Returns if the key was pressed this frame - pub fn consume_key(&mut self, key: Key, modifiers: Modifiers) -> bool { + pub fn consume_key(&mut self, modifiers: Modifiers, key: Key) -> bool { self.events.retain(|event| { !matches!( event, From f195c209020b563abdb1ffb52de473c0a4025e2d Mon Sep 17 00:00:00 2001 From: Cat State Date: Sun, 6 Feb 2022 17:21:23 +0000 Subject: [PATCH 13/15] docstring triple slash --- egui/src/input_state.rs | 4 ++-- egui_demo_lib/src/easy_mark/easy_mark_editor.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 3f5e1cc13ef..486cec9d264 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -192,8 +192,8 @@ impl InputState { self.pointer.wants_repaint() || self.scroll_delta != Vec2::ZERO || !self.events.is_empty() } - // Ignore a key if it was pressed or released this frame. Useful for hotkeys. - // Returns if the key was pressed this frame + /// Ignore a key if it was pressed or released this frame. Useful for hotkeys. + /// Returns if the key was pressed this frame pub fn consume_key(&mut self, modifiers: Modifiers, key: Key) -> bool { self.events.retain(|event| { !matches!( 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 bd383ac45d1..a43b412c722 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -127,11 +127,8 @@ fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRang (Key::U, "_"), // _underline_ ] { if ui.input_mut().consume_key( - key, - egui::Modifiers { - command: true, - ..Default::default() - }, + egui::Modifiers::new().command(true), + key ) { toggle_surrounding(code, ccursor_range, surrounding); any_change = true; From 6a9f1ec54b0e2483081bbd6780662852aa7b0147 Mon Sep 17 00:00:00 2001 From: cat-state Date: Mon, 7 Feb 2022 10:51:50 +0000 Subject: [PATCH 14/15] doctest and fmt --- egui/src/data/input.rs | 6 +----- egui/src/ui.rs | 4 +--- egui_demo_lib/src/easy_mark/easy_mark_editor.rs | 8 ++++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index dd107d404c6..29a3458c6bd 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -264,16 +264,12 @@ pub struct Modifiers { } impl Modifiers { - pub fn new() -> Self { Default::default() } pub fn alt(self, value: bool) -> Self { - Self { - alt: value, - ..self - } + Self { alt: value, ..self } } pub fn ctrl(self, value: bool) -> Self { diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 015ba483680..930751a183e 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -338,7 +338,6 @@ impl Ui { self.ctx().input() } - /// The [`InputState`] of the [`Context`] associated with this [`Ui`]. /// Equivalent to `.ctx().input_mut()`. /// @@ -346,7 +345,7 @@ impl Ui { /// like for [`Self::input()`]. /// ``` /// # egui::__run_test_ui(|ui| { - /// ui.input_mut().consume_key(egui::Key::Enter, egui::Modifiers::default()); + /// ui.input_mut().consume_key(egui::Modifiers::default(), egui::Key::Enter); /// # }); /// ``` #[inline] @@ -354,7 +353,6 @@ impl Ui { self.ctx().input_mut() } - /// The [`Memory`] of the [`Context`] associated with this ui. /// Equivalent to `.ctx().memory()`. #[inline] 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 a43b412c722..5a82f3ce105 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -126,10 +126,10 @@ fn shortcuts(ui: &Ui, code: &mut dyn TextBuffer, ccursor_range: &mut CCursorRang (Key::S, "~"), // ~strikethrough~ (Key::U, "_"), // _underline_ ] { - if ui.input_mut().consume_key( - egui::Modifiers::new().command(true), - key - ) { + if ui + .input_mut() + .consume_key(egui::Modifiers::new().command(true), key) + { toggle_surrounding(code, ccursor_range, surrounding); any_change = true; }; From cb4fcd4bb6f24ab86bc2a47d5919894ff963d3e5 Mon Sep 17 00:00:00 2001 From: cat-state <98283595+cat-state@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:47:14 -0500 Subject: [PATCH 15/15] Clarify doc --- egui/src/input_state.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 486cec9d264..ef516bb7388 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -193,7 +193,8 @@ impl InputState { } /// Ignore a key if it was pressed or released this frame. Useful for hotkeys. - /// Returns if the key was pressed this frame + /// Matches on both key press and key release, consuming them and removing them from `self.events`. + /// Returns true if the key was pressed this frame (even if the key release was consumed). pub fn consume_key(&mut self, modifiers: Modifiers, key: Key) -> bool { self.events.retain(|event| { !matches!(