1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 22:30:03 -04:00

A lot of changes:

Now the Viewport render function is passed to the backend
I was needed to update the demo because now Window::show() needs a Fn before was a FnOnce
I changed from FnOnce to Fn because we want the window to be rendered separately from the main window
That means now the variabiles that we are moving to window need to be Rc or Arc!
This is making harder to use `Window`!
I'am waiting for more ideas!
In eframe now any Window has a property render that stores the current window render function, if has not function App::update will be called insted!
New problems in any other window excluding the main window we have no mouse input, i don't know why!
Now every window has embedded to false by default, for testing purposes!
This commit is contained in:
Konkitoman
2023-07-23 19:38:02 +03:00
parent fdca2b9220
commit 3a1d9f2e21
32 changed files with 971 additions and 645 deletions

View File

@@ -191,7 +191,7 @@ impl<'open> Window<'open> {
collapsible: true,
default_open: true,
with_title_bar: true,
embedded: true,
embedded: false,
}
}
@@ -417,19 +417,11 @@ impl<'open> Window<'open> {
/// Returns `None` if the window is not open (if [`Window::open`] was called with `&mut false`).
/// Returns `Some(InnerResponse { inner: None })` if the window is collapsed.
#[inline]
pub fn show<R>(
self,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<InnerResponse<Option<R>>> {
pub fn show(self, ctx: &Context, add_contents: impl Fn(&mut Ui) + Send + Sync + 'static) {
self.show_dyn(ctx, Box::new(add_contents))
}
fn show_dyn<'c, R>(
self,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> Option<InnerResponse<Option<R>>> {
fn show_dyn(self, ctx: &Context, add_contents: Box<dyn Fn(&mut Ui) + Send + Sync + 'static>) {
let Window {
title,
open,
@@ -444,31 +436,34 @@ impl<'open> Window<'open> {
mut window_builder,
} = self;
let is_explicitly_closed = matches!(open, Some(false));
let is_open = !is_explicitly_closed || ctx.memory(|mem| mem.everything_is_visible());
if !embedded {
if !is_open {
return;
}
if let Some(size) = ctx.data(|data| data.get_temp::<Vec2>(area.id.with("size"))) {
let size = size.round() + ctx.style().spacing.window_margin.sum();
window_builder =
window_builder.with_inner_size((size.x as u32 + 1, size.y as u32 + 1));
}
ctx.create_viewport(window_builder, move |_window_id| {
ctx.create_viewport(window_builder, move |ctx| {
let mut frame = frame.unwrap_or(Frame::window(&ctx.style())).rounding(0.0);
CentralPanel::default()
.frame(frame)
.show(ctx, |ui| Some(add_contents(ui)))
.show(ctx, |ui| Some(add_contents(ui)));
})
} else {
if ctx.current_viewport() != ctx.current_rendering_viewport() {
return None;
return;
}
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
let is_explicitly_closed = matches!(open, Some(false));
let is_open = !is_explicitly_closed || ctx.memory(|mem| mem.everything_is_visible());
area.show_open_close_animation(ctx, &frame, is_open);
if !is_open {
return None;
return;
}
let area_id = area.id;
@@ -623,7 +618,7 @@ impl<'open> Window<'open> {
inner: content_inner,
response: full_response,
};
Some(inner_response)
// Some(inner_response)
}
}
}

View File

@@ -160,7 +160,16 @@ struct ContextImpl {
repaint: Repaint,
viewports: HashMap<String, (ViewportBuilder, u64, u64, bool)>,
viewports: HashMap<
String,
(
ViewportBuilder,
u64,
u64,
bool,
Arc<Box<dyn Fn(&Context) + Sync + Send>>,
),
>,
viewport_counter: u64,
current_rendering_viewport: u64,
viewport_stack: Vec<u64>,
@@ -1274,19 +1283,30 @@ impl Context {
let repaint_after = self.write(|ctx| ctx.repaint.end_frame());
let shapes = self.drain_paint_lists();
// This is used for,
// If there are no viewport that contains the current viewpor that viewport needs to be destroyed!
let avalibile_viewports = self.read(|ctx| {
let mut avalibile_viewports = vec![0];
for (_, (_, id, _, _, _)) in ctx.viewports.iter() {
avalibile_viewports.push(*id);
}
avalibile_viewports
});
let mut viewports = Vec::new();
self.write(|ctx| {
ctx.viewports.retain(|_, (builder, id, parent, used)| {
let out = *used;
if ctx.current_rendering_viewport == *parent
|| ctx.current_rendering_viewport == *id
{
*used = false;
} else {
}
viewports.push((*id, builder.clone()));
out
})
ctx.viewports
.retain(|_, (builder, id, parent, used, render)| {
let out = *used;
if ctx.current_rendering_viewport == *parent {
*used = false;
}
viewports.push((*id, builder.clone(), render.clone()));
(out || ctx.current_rendering_viewport != *parent)
&& avalibile_viewports.contains(parent)
})
});
FullOutput {
@@ -1921,16 +1941,17 @@ impl Context {
self.write(|ctx| ctx.is_desktop = value)
}
pub fn create_viewport<T>(
pub fn create_viewport(
&self,
window_builder: ViewportBuilder,
func: impl FnOnce(u64) -> T,
) -> Option<T> {
func: impl Fn(&Context) + Send + Sync + 'static,
) {
let id = self.write(|ctx| {
if ctx.is_desktop {
if let Some(window) = ctx.viewports.get_mut(&window_builder.title) {
window.2 = *ctx.viewport_stack.last().unwrap_or(&0);
window.3 = true;
window.4 = Arc::new(Box::new(func));
window.1
} else {
let id = ctx.viewport_counter + 1;
@@ -1942,6 +1963,7 @@ impl Context {
id,
*ctx.viewport_stack.last().unwrap_or(&0),
true,
Arc::new(Box::new(func)),
),
);
id
@@ -1954,11 +1976,9 @@ impl Context {
ctx.viewport_stack.push(id);
ctx.viewport_stack.last().cloned().unwrap_or(0) == ctx.current_rendering_viewport
});
let out = if should_render { Some(func(id)) } else { None };
self.write(|ctx| {
ctx.viewport_stack.pop();
});
out
}
}

View File

@@ -1,11 +1,14 @@
//! All the data egui returns to the backend at the end of each frame.
use std::sync::Arc;
use crate::Context;
use crate::{window::ViewportBuilder, WidgetType};
/// What egui emits each frame from [`crate::Context::run`].
///
/// The backend should use this.
#[derive(Clone, Default, PartialEq)]
#[derive(Clone, Default)]
pub struct FullOutput {
/// Non-rendering related output.
pub platform_output: PlatformOutput,
@@ -31,7 +34,11 @@ pub struct FullOutput {
/// You can use [`crate::Context::tessellate`] to turn this into triangles.
pub shapes: Vec<epaint::ClippedShape>,
pub viewports: Vec<(u64, ViewportBuilder)>,
pub viewports: Vec<(
u64,
ViewportBuilder,
Arc<Box<dyn Fn(&Context) + Sync + Send>>,
)>,
}
impl FullOutput {