diff --git a/egui/src/memory.rs b/egui/src/memory.rs index 7966a9e86..d59af77b2 100644 --- a/egui/src/memory.rs +++ b/egui/src/memory.rs @@ -128,8 +128,12 @@ pub(crate) struct Focus { /// The last widget interested in focus. last_interested: Option, + /// Set at the beginning of the frame, set to `false` when "used". + is_focus_locked: bool, + /// Set at the beginning of the frame, set to `false` when "used". pressed_tab: bool, + /// Set at the beginning of the frame, set to `false` when "used". pressed_shift_tab: bool, } @@ -195,10 +199,12 @@ impl Focus { modifiers, } = event { - if modifiers.shift { - self.pressed_shift_tab = true; - } else { - self.pressed_tab = true; + if !self.is_focus_locked { + if modifiers.shift { + self.pressed_shift_tab = true; + } else { + self.pressed_tab = true; + } } } } @@ -225,11 +231,11 @@ impl Focus { self.id = Some(id); self.give_to_next = false; } else if self.id == Some(id) { - if self.pressed_tab { + if self.pressed_tab && !self.is_focus_locked { self.id = None; self.give_to_next = true; self.pressed_tab = false; - } else if self.pressed_shift_tab { + } else if self.pressed_shift_tab && !self.is_focus_locked { self.id_next_frame = self.last_interested; // frame-delay so gained_focus works self.pressed_shift_tab = false; } @@ -287,14 +293,22 @@ impl Memory { self.interaction.focus.id == Some(id) } + pub(crate) fn lock_focus(&mut self, id: Id) { + if self.had_focus_last_frame(id) && self.has_focus(id) { + self.interaction.focus.is_focus_locked = true; + } + } + /// Give keyboard focus to a specific widget pub fn request_focus(&mut self, id: Id) { self.interaction.focus.id = Some(id); + self.interaction.focus.is_focus_locked = false; } pub fn surrender_focus(&mut self, id: Id) { if self.interaction.focus.id == Some(id) { self.interaction.focus.id = None; + self.interaction.focus.is_focus_locked = false; } } diff --git a/egui/src/widgets/text_edit.rs b/egui/src/widgets/text_edit.rs index 5ff57571d..64d0fba52 100644 --- a/egui/src/widgets/text_edit.rs +++ b/egui/src/widgets/text_edit.rs @@ -383,6 +383,10 @@ impl<'t> TextEdit<'t> { } if ui.memory().has_focus(id) && enabled { + if multiline { + ui.memory().lock_focus(id); + } + let mut cursorp = state .cursorp .map(|cursorp| { @@ -438,6 +442,19 @@ impl<'t> TextEdit<'t> { None } } + Event::Key { + key: Key::Tab, + pressed: true, + .. + } => { + if multiline { + let mut ccursor = delete_selected(text, &cursorp); + insert_text(&mut ccursor, text, "\t"); + Some(CCursorPair::one(ccursor)) + } else { + None + } + } Event::Key { key: Key::Enter, pressed: true,