Refactor: move FrameState to own file

This commit is contained in:
Emil Ernerfeldt 2021-02-08 23:03:41 +01:00
parent 1c415bd8fe
commit 156d68d266
3 changed files with 109 additions and 108 deletions

View file

@ -8,6 +8,7 @@ use std::sync::{
use crate::{
animation_manager::AnimationManager,
data::output::Output,
frame_state::FrameState,
input_state::*,
layers::GraphicLayers,
mutex::{Mutex, MutexGuard},
@ -17,114 +18,6 @@ use crate::{
// ----------------------------------------------------------------------------
/// 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.
available_rect: Rect,
/// Starts off as the screen_rect, shrinks as panels are added.
/// The `CentralPanel` retracts from this.
unused_rect: Rect,
/// 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)>,
}
impl Default for FrameState {
fn default() -> Self {
Self {
used_ids: Default::default(),
available_rect: Rect::NAN,
unused_rect: Rect::NAN,
used_by_panels: Rect::NAN,
tooltip_rect: None,
scroll_delta: Vec2::ZERO,
scroll_target: None,
}
}
}
impl FrameState {
fn begin_frame(&mut self, input: &InputState) {
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.
/// This is the "background" area, what egui doesn't cover with panels (but may cover with windows).
/// This is also the area to which windows are constrained.
pub fn available_rect(&self) -> Rect {
debug_assert!(
self.available_rect.is_finite(),
"Called `available_rect()` before `CtxRef::begin_frame()`"
);
self.available_rect
}
/// Shrink `available_rect`.
pub(crate) fn allocate_left_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching left panel. You must not create a panel from within another panel."
);
self.available_rect.min.x = panel_rect.max.x;
self.unused_rect.min.x = panel_rect.max.x;
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
/// Shrink `available_rect`.
pub(crate) fn allocate_top_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching top panel. You must not create a panel from within another panel."
);
self.available_rect.min.y = panel_rect.max.y;
self.unused_rect.min.y = panel_rect.max.y;
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) {
// Note: we do not shrink `available_rect`, because
// we allow windows to cover the CentralPanel.
self.unused_rect = Rect::NOTHING; // Nothing left unused after this
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
}
// ----------------------------------------------------------------------------
/// A wrapper around [`Arc`](std::sync::Arc)`<`[`Context`]`>`.
/// This is how you will normally create and access a [`Context`].
///

107
egui/src/frame_state.rs Normal file
View file

@ -0,0 +1,107 @@
use crate::{paint::ahash, *};
/// 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.
pub(crate) available_rect: Rect,
/// Starts off as the screen_rect, shrinks as panels are added.
/// The `CentralPanel` retracts from this.
pub(crate) unused_rect: Rect,
/// How much space is used by panels.
pub(crate) 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)>,
}
impl Default for FrameState {
fn default() -> Self {
Self {
used_ids: Default::default(),
available_rect: Rect::NAN,
unused_rect: Rect::NAN,
used_by_panels: Rect::NAN,
tooltip_rect: None,
scroll_delta: Vec2::ZERO,
scroll_target: None,
}
}
}
impl FrameState {
pub(crate) fn begin_frame(&mut self, input: &InputState) {
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.
/// This is the "background" area, what egui doesn't cover with panels (but may cover with windows).
/// This is also the area to which windows are constrained.
pub(crate) fn available_rect(&self) -> Rect {
debug_assert!(
self.available_rect.is_finite(),
"Called `available_rect()` before `CtxRef::begin_frame()`"
);
self.available_rect
}
/// Shrink `available_rect`.
pub(crate) fn allocate_left_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching left panel. You must not create a panel from within another panel."
);
self.available_rect.min.x = panel_rect.max.x;
self.unused_rect.min.x = panel_rect.max.x;
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
/// Shrink `available_rect`.
pub(crate) fn allocate_top_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching top panel. You must not create a panel from within another panel."
);
self.available_rect.min.y = panel_rect.max.y;
self.unused_rect.min.y = panel_rect.max.y;
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) {
// Note: we do not shrink `available_rect`, because
// we allow windows to cover the CentralPanel.
self.unused_rect = Rect::NOTHING; // Nothing left unused after this
self.used_by_panels = self.used_by_panels.union(panel_rect);
}
}

View file

@ -103,6 +103,7 @@ pub mod containers;
mod context;
mod data;
pub mod experimental;
mod frame_state;
pub(crate) mod grid;
mod id;
mod input_state;