1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 21:00:03 -04:00

Do two passes if the option is enabled

This commit is contained in:
Emil Ernerfeldt
2021-11-08 23:25:24 +01:00
parent e0a8e8f36a
commit 360b83e8f7
2 changed files with 47 additions and 34 deletions

View File

@@ -102,14 +102,49 @@ impl CtxRef {
#[must_use]
pub fn run(
&mut self,
new_input: RawInput,
run_ui: impl FnOnce(&CtxRef),
new_raw_input: RawInput,
mut run_ui: impl FnMut(&CtxRef),
) -> (Output, Vec<ClippedShape>) {
self.memory().begin_frame(&self.input, &new_raw_input);
let mut self_: Context = (*self.0).clone();
self_.begin_frame_mut(new_input);
if let Some(new_pixels_per_point) = self_.memory.lock().new_pixels_per_point.take() {
self_.input.pixels_per_point = new_pixels_per_point;
}
self_.input.begin_frame(&new_raw_input);
self_.update_fonts(self_.input.pixels_per_point());
*self = Self(Arc::new(self_));
run_ui(self);
// Ensure we register the background area so panels and background ui can catch clicks:
let screen_rect = self.input.screen_rect();
self.memory().areas.set_state(
LayerId::background(),
containers::area::State {
pos: screen_rect.min,
size: screen_rect.size(),
interactable: true,
},
);
if self.memory().options.multi_pass {
self.frame_state.lock().begin_pass(&self.input);
run_ui(self);
self.drain_paint_lists();
let mut self_: Context = (*self.0).clone();
self_.input.on_events(new_raw_input);
*self = Self(Arc::new(self_));
self.frame_state.lock().begin_pass(&self.input);
run_ui(self);
} else {
let mut self_: Context = (*self.0).clone();
self_.input.on_events(new_raw_input);
*self = Self(Arc::new(self_));
self.frame_state.lock().begin_pass(&self.input);
run_ui(self);
}
self.end_frame()
}
@@ -566,30 +601,6 @@ impl Context {
// ---------------------------------------------------------------------
fn begin_frame_mut(&mut self, new_raw_input: RawInput) {
self.memory().begin_frame(&self.input, &new_raw_input);
if let Some(new_pixels_per_point) = self.memory.lock().new_pixels_per_point.take() {
self.input.pixels_per_point = new_pixels_per_point;
}
self.input.begin_frame(&new_raw_input);
self.input.on_events(new_raw_input);
self.frame_state.lock().begin_frame(&self.input);
self.update_fonts(self.input.pixels_per_point());
// Ensure we register the background area so panels and background ui can catch clicks:
let screen_rect = self.input.screen_rect();
self.memory().areas.set_state(
LayerId::background(),
containers::area::State {
pos: screen_rect.min,
size: screen_rect.size(),
interactable: true,
},
);
}
/// Load fonts unless already loaded.
fn update_fonts(&mut self, pixels_per_point: f32) {
let new_font_definitions = self.memory().new_font_definitions.take();

View File

@@ -1,10 +1,12 @@
use crate::*;
/// State that is collected during a frame and then cleared.
/// Short-term (single frame) memory.
// TODO: rename `FrameState` -> `PassState` ?
/// State that is collected during a pass and then cleared.
///
/// One frame consists of either one or two passes.
#[derive(Clone)]
pub(crate) struct FrameState {
/// All `Id`s that were used this frame.
/// All `Id`s that were used this pass.
/// Used to debug `Id` clashes of widgets.
pub(crate) used_ids: IdMap<Rect>,
@@ -20,9 +22,9 @@ pub(crate) struct FrameState {
/// How much space is used by panels.
pub(crate) used_by_panels: Rect,
/// If a tooltip has been shown this frame, where was it?
/// If a tooltip has been shown this pass, where was it?
/// This is used to prevent multiple tooltips to cover each other.
/// Initialized to `None` at the start of each frame.
/// Initialized to `None` at the start of each pass.
pub(crate) tooltip_rect: Option<(Id, Rect, usize)>,
/// Cleared by the first `ScrollArea` that makes use of it.
@@ -46,7 +48,7 @@ impl Default for FrameState {
}
impl FrameState {
pub(crate) fn begin_frame(&mut self, input: &InputState) {
pub(crate) fn begin_pass(&mut self, input: &InputState) {
let Self {
used_ids,
available_rect,