This commit is contained in:
Emil Ernerfeldt 2021-12-28 20:54:26 +01:00
parent 19264c8043
commit 238581c65e
4 changed files with 79 additions and 2 deletions

View file

@ -19,6 +19,15 @@ use epaint::{stats::*, text::Fonts, *};
// ----------------------------------------------------------------------------
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PassState {
SinglePass,
SizePass,
LayoutPass,
}
// ----------------------------------------------------------------------------
/// A wrapper around [`Arc`](std::sync::Arc)`<`[`Context`]`>`.
/// This is how you will normally create and access a [`Context`].
///
@ -103,7 +112,7 @@ impl CtxRef {
pub fn run(
&mut self,
new_raw_input: RawInput,
mut run_ui: impl FnMut(&CtxRef),
run_ui: impl Fn(&CtxRef),
) -> (Output, Vec<ClippedShape>) {
self.memory().begin_frame(&self.input, &new_raw_input);
@ -126,6 +135,48 @@ impl CtxRef {
},
);
if self.memory().options.multi_pass {
self.frame_state.lock().begin_pass(&self.input);
self.mutate(|context| {
context.pass_state = Some(PassState::SizePass);
});
run_ui(self);
self.drain_paint_lists();
self.mutate(|context| {
context.input.on_events(new_raw_input);
context.pass_state = Some(PassState::LayoutPass);
});
self.frame_state.lock().begin_pass(&self.input);
run_ui(self);
} else {
self.mutate(|context| {
context.input.on_events(new_raw_input);
context.pass_state = Some(PassState::SinglePass);
});
}
self.mutate(|context| {
if let Some(new_pixels_per_point) = context.memory.lock().new_pixels_per_point.take() {
context.input.pixels_per_point = new_pixels_per_point;
}
context.input.begin_frame(&new_raw_input);
context.update_fonts(context.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,
},
);
if self.memory().options.multi_pass {
self.frame_state.lock().begin_pass(&self.input);
run_ui(self);
@ -142,6 +193,10 @@ impl CtxRef {
run_ui(self);
}
self.mutate(|context| {
context.pass_state = None;
});
self.end_frame()
}
@ -392,6 +447,8 @@ pub struct Context {
/// While positive, keep requesting repaints. Decrement at the end of each frame.
repaint_requests: AtomicU32,
pub(crate) pass_state: Option<PassState>,
}
impl Clone for Context {
@ -407,6 +464,7 @@ impl Clone for Context {
output: self.output.clone(),
paint_stats: self.paint_stats.clone(),
repaint_requests: self.repaint_requests.load(SeqCst).into(),
pass_state: None,
}
}
}

View file

@ -230,6 +230,18 @@ impl Layout {
}
}
/// change layout to one suitable for size pass
pub(crate) fn for_size_pass(self) -> Self {
Self {
main_dir: self.main_dir,
main_wrap: self.main_wrap,
main_align: Align::Min,
main_justify: false,
cross_align: Align::Min,
cross_justify: false,
}
}
#[inline(always)]
pub fn with_main_wrap(self, main_wrap: bool) -> Self {
Self { main_wrap, ..self }

View file

@ -396,6 +396,8 @@ pub mod text {
};
}
pub(crate) use context::PassState;
pub use {
containers::*,
context::{Context, CtxRef},

View file

@ -92,10 +92,15 @@ impl Ui {
pub fn child_ui_with_id_source(
&mut self,
max_rect: Rect,
layout: Layout,
mut layout: Layout,
id_source: impl Hash,
) -> Self {
crate::egui_assert!(!max_rect.any_nan());
if self.ctx().pass_state == Some(PassState::SizePass) {
layout = layout.for_size_pass();
}
let next_auto_id_source = Id::new(self.next_auto_id_source).with("child").value();
self.next_auto_id_source = self.next_auto_id_source.wrapping_add(1);
let menu_state = self.get_menu_state();