|
|
@ -91,7 +91,7 @@ pub(crate) struct Interaction { |
|
|
|
/// A widget interested in drags that has a mouse press on it.
|
|
|
|
pub drag_id: Option<Id>, |
|
|
|
|
|
|
|
pub kb_focus: KbFocus, |
|
|
|
pub focus: Focus, |
|
|
|
|
|
|
|
/// HACK: windows have low priority on dragging.
|
|
|
|
/// This is so that if you drag a slider in a window,
|
|
|
@ -111,7 +111,7 @@ pub(crate) struct Interaction { |
|
|
|
|
|
|
|
/// Keeps tracks of what widget has keyboard focus
|
|
|
|
#[derive(Clone, Debug, Default)] |
|
|
|
pub(crate) struct KbFocus { |
|
|
|
pub(crate) struct Focus { |
|
|
|
/// The widget with keyboard focus (i.e. a text input field).
|
|
|
|
id: Option<Id>, |
|
|
|
|
|
|
@ -121,11 +121,11 @@ pub(crate) struct KbFocus { |
|
|
|
/// Give focus to this widget next frame
|
|
|
|
id_next_frame: Option<Id>, |
|
|
|
|
|
|
|
/// If set, the next widget that is interested in kb_focus will automatically get it.
|
|
|
|
/// If set, the next widget that is interested in focus will automatically get it.
|
|
|
|
/// Probably because the user pressed Tab.
|
|
|
|
give_to_next: bool, |
|
|
|
|
|
|
|
/// The last widget interested in kb focus.
|
|
|
|
/// The last widget interested in focus.
|
|
|
|
last_interested: Option<Id>, |
|
|
|
|
|
|
|
/// Set at the beginning of the frame, set to `false` when "used".
|
|
|
@ -158,11 +158,11 @@ impl Interaction { |
|
|
|
self.drag_id = None; |
|
|
|
} |
|
|
|
|
|
|
|
self.kb_focus.begin_frame(new_input); |
|
|
|
self.focus.begin_frame(new_input); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl KbFocus { |
|
|
|
impl Focus { |
|
|
|
/// Which widget currently has keyboard focus?
|
|
|
|
pub fn focused(&self) -> Option<Id> { |
|
|
|
self.id |
|
|
@ -206,22 +206,22 @@ impl KbFocus { |
|
|
|
|
|
|
|
pub(crate) fn end_frame(&mut self, used_ids: &epaint::ahash::AHashMap<Id, Pos2>) { |
|
|
|
if let Some(id) = self.id { |
|
|
|
// Allow calling `request_kb_focus` one frame and not using it until next frame
|
|
|
|
let recently_gained_kb_focus = self.id_previous_frame != Some(id); |
|
|
|
// Allow calling `request_focus` one frame and not using it until next frame
|
|
|
|
let recently_gained_focus = self.id_previous_frame != Some(id); |
|
|
|
|
|
|
|
if !recently_gained_kb_focus && !used_ids.contains_key(&id) { |
|
|
|
// Dead-mans-switch: the widget with kb focus has disappeared!
|
|
|
|
if !recently_gained_focus && !used_ids.contains_key(&id) { |
|
|
|
// Dead-mans-switch: the widget with focus has disappeared!
|
|
|
|
self.id = None; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub(crate) fn had_kb_focus_last_frame(&self, id: Id) -> bool { |
|
|
|
pub(crate) fn had_focus_last_frame(&self, id: Id) -> bool { |
|
|
|
self.id_previous_frame == Some(id) |
|
|
|
} |
|
|
|
|
|
|
|
fn interested_in_kb_focus(&mut self, id: Id) { |
|
|
|
if self.give_to_next && !self.had_kb_focus_last_frame(id) { |
|
|
|
fn interested_in_focus(&mut self, id: Id) { |
|
|
|
if self.give_to_next && !self.had_focus_last_frame(id) { |
|
|
|
self.id = Some(id); |
|
|
|
self.give_to_next = false; |
|
|
|
} else if self.id == Some(id) { |
|
|
@ -261,7 +261,7 @@ impl Memory { |
|
|
|
used_ids: &epaint::ahash::AHashMap<Id, Pos2>, |
|
|
|
) { |
|
|
|
self.areas.end_frame(); |
|
|
|
self.interaction.kb_focus.end_frame(used_ids); |
|
|
|
self.interaction.focus.end_frame(used_ids); |
|
|
|
self.drag_value.end_frame(input); |
|
|
|
} |
|
|
|
|
|
|
@ -269,43 +269,44 @@ impl Memory { |
|
|
|
self.areas.layer_id_at(pos, resize_interact_radius_side) |
|
|
|
} |
|
|
|
|
|
|
|
pub(crate) fn had_kb_focus_last_frame(&self, id: Id) -> bool { |
|
|
|
self.interaction.kb_focus.id_previous_frame == Some(id) |
|
|
|
pub(crate) fn had_focus_last_frame(&self, id: Id) -> bool { |
|
|
|
self.interaction.focus.id_previous_frame == Some(id) |
|
|
|
} |
|
|
|
|
|
|
|
/// True if the given widget had keyboard focus last frame, but not this one.
|
|
|
|
pub fn lost_kb_focus(&self, id: Id) -> bool { |
|
|
|
self.had_kb_focus_last_frame(id) && !self.has_kb_focus(id) |
|
|
|
pub(crate) fn lost_focus(&self, id: Id) -> bool { |
|
|
|
self.had_focus_last_frame(id) && !self.has_focus(id) |
|
|
|
} |
|
|
|
|
|
|
|
/// True if the given widget has keyboard focus this frame, but didn't last frame.
|
|
|
|
pub fn gained_kb_focus(&self, id: Id) -> bool { |
|
|
|
!self.had_kb_focus_last_frame(id) && self.has_kb_focus(id) |
|
|
|
pub(crate) fn gained_focus(&self, id: Id) -> bool { |
|
|
|
!self.had_focus_last_frame(id) && self.has_focus(id) |
|
|
|
} |
|
|
|
|
|
|
|
pub fn has_kb_focus(&self, id: Id) -> bool { |
|
|
|
self.interaction.kb_focus.id == Some(id) |
|
|
|
pub(crate) fn has_focus(&self, id: Id) -> bool { |
|
|
|
self.interaction.focus.id == Some(id) |
|
|
|
} |
|
|
|
|
|
|
|
pub fn request_kb_focus(&mut self, id: Id) { |
|
|
|
self.interaction.kb_focus.id = Some(id); |
|
|
|
/// Give keyboard focus to a specific widget
|
|
|
|
pub fn request_focus(&mut self, id: Id) { |
|
|
|
self.interaction.focus.id = Some(id); |
|
|
|
} |
|
|
|
|
|
|
|
pub fn surrender_kb_focus(&mut self, id: Id) { |
|
|
|
if self.interaction.kb_focus.id == Some(id) { |
|
|
|
self.interaction.kb_focus.id = None; |
|
|
|
pub fn surrender_focus(&mut self, id: Id) { |
|
|
|
if self.interaction.focus.id == Some(id) { |
|
|
|
self.interaction.focus.id = None; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Register this widget as being interested in getting keyboard focus.
|
|
|
|
/// This will allow the user to select it with tab and shift-tab.
|
|
|
|
pub fn interested_in_kb_focus(&mut self, id: Id) { |
|
|
|
self.interaction.kb_focus.interested_in_kb_focus(id); |
|
|
|
pub(crate) fn interested_in_focus(&mut self, id: Id) { |
|
|
|
self.interaction.focus.interested_in_focus(id); |
|
|
|
} |
|
|
|
|
|
|
|
/// Stop editing of active `TextEdit` (if any).
|
|
|
|
pub fn stop_text_input(&mut self) { |
|
|
|
self.interaction.kb_focus.id = None; |
|
|
|
self.interaction.focus.id = None; |
|
|
|
} |
|
|
|
|
|
|
|
pub fn is_anything_being_dragged(&self) -> bool { |
|
|
|