refactor: move used_ids and tooltip_rect from Memory to FrameState
This commit is contained in:
parent
029a85c1fc
commit
83b75b117e
3 changed files with 39 additions and 28 deletions
|
@ -15,7 +15,7 @@ use crate::*;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
|
pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
let tooltip_rect = ctx.memory().tooltip_rect;
|
let tooltip_rect = ctx.frame_state().tooltip_rect;
|
||||||
|
|
||||||
let window_pos = if let Some(tooltip_rect) = tooltip_rect {
|
let window_pos = if let Some(tooltip_rect) = tooltip_rect {
|
||||||
tooltip_rect.left_bottom()
|
tooltip_rect.left_bottom()
|
||||||
|
@ -36,7 +36,7 @@ pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
let response = show_popup(ctx, id, window_pos, add_contents);
|
let response = show_popup(ctx, id, window_pos, add_contents);
|
||||||
|
|
||||||
let tooltip_rect = tooltip_rect.unwrap_or_else(Rect::nothing);
|
let tooltip_rect = tooltip_rect.unwrap_or_else(Rect::nothing);
|
||||||
ctx.memory().tooltip_rect = Some(tooltip_rect.union(response.rect));
|
ctx.frame_state().tooltip_rect = Some(tooltip_rect.union(response.rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show some text at the current mouse position (if any).
|
/// Show some text at the current mouse position (if any).
|
||||||
|
|
|
@ -26,9 +26,14 @@ struct Options {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// State that is collected during a frame and then cleared
|
/// State that is collected during a frame and then cleared.
|
||||||
|
/// Short-term (single frame) memory.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct FrameState {
|
pub(crate) struct FrameState {
|
||||||
|
/// All `Id`s that were used this frame.
|
||||||
|
/// Used to debug `Id` clashes of widgets.
|
||||||
|
pub(crate) used_ids: ahash::AHashMap<Id, Pos2>,
|
||||||
|
|
||||||
/// Starts off as the screen_rect, shrinks as panels are added.
|
/// Starts off as the screen_rect, shrinks as panels are added.
|
||||||
/// The `CentralPanel` does not change this.
|
/// The `CentralPanel` does not change this.
|
||||||
/// This is the area available to Window's.
|
/// This is the area available to Window's.
|
||||||
|
@ -41,17 +46,24 @@ pub(crate) struct FrameState {
|
||||||
/// How much space is used by panels.
|
/// How much space is used by panels.
|
||||||
used_by_panels: Rect,
|
used_by_panels: Rect,
|
||||||
|
|
||||||
|
/// If a tooltip has been shown this frame, where was it?
|
||||||
|
/// This is used to prevent multiple tooltips to cover each other.
|
||||||
|
/// Initialized to `None` at the start of each frame.
|
||||||
|
pub(crate) tooltip_rect: Option<Rect>,
|
||||||
|
|
||||||
|
/// Cleared by the first `ScrollArea` that makes use of it.
|
||||||
pub(crate) scroll_delta: Vec2,
|
pub(crate) scroll_delta: Vec2,
|
||||||
pub(crate) scroll_target: Option<(f32, Align)>,
|
pub(crate) scroll_target: Option<(f32, Align)>,
|
||||||
// TODO: move some things from `Memory` to here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FrameState {
|
impl Default for FrameState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
used_ids: Default::default(),
|
||||||
available_rect: Rect::invalid(),
|
available_rect: Rect::invalid(),
|
||||||
unused_rect: Rect::invalid(),
|
unused_rect: Rect::invalid(),
|
||||||
used_by_panels: Rect::invalid(),
|
used_by_panels: Rect::invalid(),
|
||||||
|
tooltip_rect: None,
|
||||||
scroll_delta: Vec2::zero(),
|
scroll_delta: Vec2::zero(),
|
||||||
scroll_target: None,
|
scroll_target: None,
|
||||||
}
|
}
|
||||||
|
@ -60,11 +72,23 @@ impl Default for FrameState {
|
||||||
|
|
||||||
impl FrameState {
|
impl FrameState {
|
||||||
fn begin_frame(&mut self, input: &InputState) {
|
fn begin_frame(&mut self, input: &InputState) {
|
||||||
self.available_rect = input.screen_rect();
|
let Self {
|
||||||
self.unused_rect = input.screen_rect();
|
used_ids,
|
||||||
self.used_by_panels = Rect::nothing();
|
available_rect,
|
||||||
self.scroll_delta = input.scroll_delta;
|
unused_rect,
|
||||||
self.scroll_target = None;
|
used_by_panels,
|
||||||
|
tooltip_rect,
|
||||||
|
scroll_delta,
|
||||||
|
scroll_target,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
used_ids.clear();
|
||||||
|
*available_rect = input.screen_rect();
|
||||||
|
*unused_rect = input.screen_rect();
|
||||||
|
*used_by_panels = Rect::nothing();
|
||||||
|
*tooltip_rect = None;
|
||||||
|
*scroll_delta = input.scroll_delta;
|
||||||
|
*scroll_target = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How much space is still available after panels has been added.
|
/// How much space is still available after panels has been added.
|
||||||
|
@ -166,7 +190,7 @@ impl CtxRef {
|
||||||
/// If the given [`Id`] is not unique, an error will be printed at the given position.
|
/// If the given [`Id`] is not unique, an error will be printed at the given position.
|
||||||
/// Call this for [`Id`]:s that need interaction or persistence.
|
/// Call this for [`Id`]:s that need interaction or persistence.
|
||||||
pub(crate) fn register_interaction_id(&self, id: Id, new_pos: Pos2) {
|
pub(crate) fn register_interaction_id(&self, id: Id, new_pos: Pos2) {
|
||||||
let prev_pos = self.memory().used_ids.insert(id, new_pos);
|
let prev_pos = self.frame_state().used_ids.insert(id, new_pos);
|
||||||
if let Some(prev_pos) = prev_pos {
|
if let Some(prev_pos) = prev_pos {
|
||||||
if prev_pos.distance(new_pos) < 0.1 {
|
if prev_pos.distance(new_pos) < 0.1 {
|
||||||
// Likely same Widget being interacted with twice, which is fine.
|
// Likely same Widget being interacted with twice, which is fine.
|
||||||
|
@ -590,7 +614,7 @@ impl Context {
|
||||||
self.request_repaint();
|
self.request_repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.memory().end_frame();
|
self.memory().end_frame(&self.frame_state().used_ids);
|
||||||
|
|
||||||
let mut output: Output = std::mem::take(&mut self.output());
|
let mut output: Output = std::mem::take(&mut self.output());
|
||||||
if self.repaint_requests.load(SeqCst) > 0 {
|
if self.repaint_requests.load(SeqCst) > 0 {
|
||||||
|
|
|
@ -19,11 +19,6 @@ use crate::{
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
/// All `Id`s that were used this frame.
|
|
||||||
/// Used to debug `Id` clashes of widgets.
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
|
||||||
pub(crate) used_ids: ahash::AHashMap<Id, Pos2>,
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
pub(crate) interaction: Interaction,
|
pub(crate) interaction: Interaction,
|
||||||
|
|
||||||
|
@ -39,7 +34,7 @@ pub struct Memory {
|
||||||
pub(crate) window_interaction: Option<window::WindowInteraction>,
|
pub(crate) window_interaction: Option<window::WindowInteraction>,
|
||||||
|
|
||||||
/// For temporary edit of e.g. a slider value.
|
/// For temporary edit of e.g. a slider value.
|
||||||
/// Couples with `kb_focus_id`.
|
/// Couples with [`Interaction::kb_focus_id`].
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
pub(crate) temp_edit_string: Option<String>,
|
pub(crate) temp_edit_string: Option<String>,
|
||||||
|
|
||||||
|
@ -54,12 +49,6 @@ pub struct Memory {
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
popup: Option<Id>,
|
popup: Option<Id>,
|
||||||
|
|
||||||
/// If a tooltip has been shown this frame, where was it?
|
|
||||||
/// This is used to prevent multiple tooltips to cover each other.
|
|
||||||
/// Initialized to `None` at the start of each frame.
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
|
||||||
pub(crate) tooltip_rect: Option<Rect>,
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
everything_is_visible: bool,
|
everything_is_visible: bool,
|
||||||
}
|
}
|
||||||
|
@ -162,16 +151,14 @@ impl Memory {
|
||||||
prev_input: &crate::input::InputState,
|
prev_input: &crate::input::InputState,
|
||||||
new_input: &crate::input::RawInput,
|
new_input: &crate::input::RawInput,
|
||||||
) {
|
) {
|
||||||
self.used_ids.clear();
|
|
||||||
self.interaction.begin_frame(prev_input, new_input);
|
self.interaction.begin_frame(prev_input, new_input);
|
||||||
self.tooltip_rect = None;
|
|
||||||
|
|
||||||
if !prev_input.mouse.down {
|
if !prev_input.mouse.down {
|
||||||
self.window_interaction = None;
|
self.window_interaction = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn end_frame(&mut self) {
|
pub(crate) fn end_frame(&mut self, used_ids: &ahash::AHashMap<Id, Pos2>) {
|
||||||
self.areas.end_frame();
|
self.areas.end_frame();
|
||||||
|
|
||||||
if let Some(kb_focus_id) = self.interaction.kb_focus_id {
|
if let Some(kb_focus_id) = self.interaction.kb_focus_id {
|
||||||
|
@ -179,8 +166,8 @@ impl Memory {
|
||||||
let recently_gained_kb_focus =
|
let recently_gained_kb_focus =
|
||||||
self.interaction.kb_focus_id_previous_frame != Some(kb_focus_id);
|
self.interaction.kb_focus_id_previous_frame != Some(kb_focus_id);
|
||||||
|
|
||||||
if !recently_gained_kb_focus && !self.used_ids.contains_key(&kb_focus_id) {
|
if !recently_gained_kb_focus && !used_ids.contains_key(&kb_focus_id) {
|
||||||
// Dead-mans-switch: the widget with kb focus has dissappeared!
|
// Dead-mans-switch: the widget with kb focus has disappeared!
|
||||||
self.interaction.kb_focus_id = None;
|
self.interaction.kb_focus_id = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue