From 360b83e8f708ca5468342280f94b637c8544f303 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 8 Nov 2021 23:25:24 +0100 Subject: [PATCH] Do two passes if the option is enabled --- egui/src/context.rs | 67 ++++++++++++++++++++++++----------------- egui/src/frame_state.rs | 14 +++++---- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/egui/src/context.rs b/egui/src/context.rs index e1a4b3e3d..d4835c826 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -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) { + 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(); diff --git a/egui/src/frame_state.rs b/egui/src/frame_state.rs index c2f03aebb..45d0f51e3 100644 --- a/egui/src/frame_state.rs +++ b/egui/src/frame_state.rs @@ -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, @@ -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,