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)) {
|
||||
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 {
|
||||
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 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).
|
||||
|
|
|
@ -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)]
|
||||
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.
|
||||
/// The `CentralPanel` does not change this.
|
||||
/// This is the area available to Window's.
|
||||
|
@ -41,17 +46,24 @@ pub(crate) struct FrameState {
|
|||
/// How much space is used by panels.
|
||||
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_target: Option<(f32, Align)>,
|
||||
// TODO: move some things from `Memory` to here
|
||||
}
|
||||
|
||||
impl Default for FrameState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
used_ids: Default::default(),
|
||||
available_rect: Rect::invalid(),
|
||||
unused_rect: Rect::invalid(),
|
||||
used_by_panels: Rect::invalid(),
|
||||
tooltip_rect: None,
|
||||
scroll_delta: Vec2::zero(),
|
||||
scroll_target: None,
|
||||
}
|
||||
|
@ -60,11 +72,23 @@ impl Default for FrameState {
|
|||
|
||||
impl FrameState {
|
||||
fn begin_frame(&mut self, input: &InputState) {
|
||||
self.available_rect = input.screen_rect();
|
||||
self.unused_rect = input.screen_rect();
|
||||
self.used_by_panels = Rect::nothing();
|
||||
self.scroll_delta = input.scroll_delta;
|
||||
self.scroll_target = None;
|
||||
let Self {
|
||||
used_ids,
|
||||
available_rect,
|
||||
unused_rect,
|
||||
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.
|
||||
|
@ -166,7 +190,7 @@ impl CtxRef {
|
|||
/// 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.
|
||||
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 prev_pos.distance(new_pos) < 0.1 {
|
||||
// Likely same Widget being interacted with twice, which is fine.
|
||||
|
@ -590,7 +614,7 @@ impl Context {
|
|||
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());
|
||||
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", serde(default))]
|
||||
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))]
|
||||
pub(crate) interaction: Interaction,
|
||||
|
||||
|
@ -39,7 +34,7 @@ pub struct Memory {
|
|||
pub(crate) window_interaction: Option<window::WindowInteraction>,
|
||||
|
||||
/// 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))]
|
||||
pub(crate) temp_edit_string: Option<String>,
|
||||
|
||||
|
@ -54,12 +49,6 @@ pub struct Memory {
|
|||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
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))]
|
||||
everything_is_visible: bool,
|
||||
}
|
||||
|
@ -162,16 +151,14 @@ impl Memory {
|
|||
prev_input: &crate::input::InputState,
|
||||
new_input: &crate::input::RawInput,
|
||||
) {
|
||||
self.used_ids.clear();
|
||||
self.interaction.begin_frame(prev_input, new_input);
|
||||
self.tooltip_rect = None;
|
||||
|
||||
if !prev_input.mouse.down {
|
||||
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();
|
||||
|
||||
if let Some(kb_focus_id) = self.interaction.kb_focus_id {
|
||||
|
@ -179,8 +166,8 @@ impl Memory {
|
|||
let recently_gained_kb_focus =
|
||||
self.interaction.kb_focus_id_previous_frame != Some(kb_focus_id);
|
||||
|
||||
if !recently_gained_kb_focus && !self.used_ids.contains_key(&kb_focus_id) {
|
||||
// Dead-mans-switch: the widget with kb focus has dissappeared!
|
||||
if !recently_gained_kb_focus && !used_ids.contains_key(&kb_focus_id) {
|
||||
// Dead-mans-switch: the widget with kb focus has disappeared!
|
||||
self.interaction.kb_focus_id = None;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue