mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
Create struct ImmediateViewport to simplify argument lists
This commit is contained in:
@@ -455,8 +455,8 @@ mod glow_integration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use egui::{
|
use egui::{
|
||||||
epaint::ahash::HashMap, NumExt as _, ViewportIdMap, ViewportIdPair, ViewportIdSet,
|
epaint::ahash::HashMap, ImmediateViewport, NumExt as _, ViewportIdMap, ViewportIdPair,
|
||||||
ViewportOutput, ViewportUiCallback,
|
ViewportIdSet, ViewportOutput, ViewportUiCallback,
|
||||||
};
|
};
|
||||||
use egui_winit::{create_winit_window_builder, process_viewport_commands, EventResponse};
|
use egui_winit::{create_winit_window_builder, process_viewport_commands, EventResponse};
|
||||||
|
|
||||||
@@ -1362,7 +1362,7 @@ mod glow_integration {
|
|||||||
let event_loop: *const EventLoopWindowTarget<UserEvent> = event_loop;
|
let event_loop: *const EventLoopWindowTarget<UserEvent> = event_loop;
|
||||||
|
|
||||||
egui::Context::set_immediate_viewport_renderer(
|
egui::Context::set_immediate_viewport_renderer(
|
||||||
move |egui_ctx, viewport_builder, ids, viewport_ui_cb| {
|
move |egui_ctx, immediate_viewport| {
|
||||||
if let (Some(glutin), Some(painter)) = (glutin.upgrade(), painter.upgrade())
|
if let (Some(glutin), Some(painter)) = (glutin.upgrade(), painter.upgrade())
|
||||||
{
|
{
|
||||||
// SAFETY: the event loop lives longer than
|
// SAFETY: the event loop lives longer than
|
||||||
@@ -1373,12 +1373,10 @@ mod glow_integration {
|
|||||||
render_immediate_viewport(
|
render_immediate_viewport(
|
||||||
event_loop,
|
event_loop,
|
||||||
egui_ctx,
|
egui_ctx,
|
||||||
viewport_builder,
|
|
||||||
ids,
|
|
||||||
viewport_ui_cb,
|
|
||||||
&glutin,
|
&glutin,
|
||||||
&painter,
|
&painter,
|
||||||
beginning,
|
beginning,
|
||||||
|
immediate_viewport,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
log::warn!("render_sync_callback called after window closed");
|
log::warn!("render_sync_callback called after window closed");
|
||||||
@@ -1400,28 +1398,30 @@ mod glow_integration {
|
|||||||
|
|
||||||
/// This is called (via a callback) by user code to render immediate viewports,
|
/// This is called (via a callback) by user code to render immediate viewports,
|
||||||
/// i.e. viewport that are directly nested inside a parent viewport.
|
/// i.e. viewport that are directly nested inside a parent viewport.
|
||||||
#[inline(always)]
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
fn render_immediate_viewport(
|
fn render_immediate_viewport(
|
||||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||||
egui_ctx: &egui::Context,
|
egui_ctx: &egui::Context,
|
||||||
mut viewport_builder: ViewportBuilder,
|
|
||||||
ids: ViewportIdPair,
|
|
||||||
viewport_ui_cb: Box<dyn FnOnce(&egui::Context) + '_>,
|
|
||||||
glutin: &RefCell<GlutinWindowContext>,
|
glutin: &RefCell<GlutinWindowContext>,
|
||||||
painter: &RefCell<egui_glow::Painter>,
|
painter: &RefCell<egui_glow::Painter>,
|
||||||
beginning: Instant,
|
beginning: Instant,
|
||||||
|
immediate_viewport: ImmediateViewport<'_>,
|
||||||
) {
|
) {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
||||||
|
let ImmediateViewport {
|
||||||
|
ids,
|
||||||
|
mut builder,
|
||||||
|
viewport_ui_cb,
|
||||||
|
} = immediate_viewport;
|
||||||
|
|
||||||
if !glutin.borrow().viewports.contains_key(&ids.this) {
|
if !glutin.borrow().viewports.contains_key(&ids.this) {
|
||||||
// A new viewport - create a window for it!
|
// A new viewport - create a window for it!
|
||||||
|
|
||||||
let mut glutin = glutin.borrow_mut();
|
let mut glutin = glutin.borrow_mut();
|
||||||
|
|
||||||
// Inherit parent icon if none
|
// Inherit parent icon if none
|
||||||
if viewport_builder.icon.is_none() && glutin.builders.get(&ids.this).is_none() {
|
if builder.icon.is_none() && glutin.builders.get(&ids.this).is_none() {
|
||||||
viewport_builder.icon = glutin
|
builder.icon = glutin
|
||||||
.builders
|
.builders
|
||||||
.get(&ids.parent)
|
.get(&ids.parent)
|
||||||
.and_then(|b| b.icon.clone());
|
.and_then(|b| b.icon.clone());
|
||||||
@@ -1432,7 +1432,7 @@ mod glow_integration {
|
|||||||
.entry(ids.this)
|
.entry(ids.this)
|
||||||
.or_insert(Viewport::new(ids));
|
.or_insert(Viewport::new(ids));
|
||||||
|
|
||||||
glutin.builders.entry(ids.this).or_insert(viewport_builder);
|
glutin.builders.entry(ids.this).or_insert(builder);
|
||||||
|
|
||||||
glutin
|
glutin
|
||||||
.init_viewport(ids.this, event_loop)
|
.init_viewport(ids.this, event_loop)
|
||||||
@@ -1820,8 +1820,8 @@ mod wgpu_integration {
|
|||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use egui::{
|
use egui::{
|
||||||
FullOutput, ViewportIdMap, ViewportIdPair, ViewportIdSet, ViewportOutput,
|
FullOutput, ImmediateViewport, ViewportIdMap, ViewportIdPair, ViewportIdSet,
|
||||||
ViewportUiCallback,
|
ViewportOutput, ViewportUiCallback,
|
||||||
};
|
};
|
||||||
use egui_winit::{create_winit_window_builder, process_viewport_commands};
|
use egui_winit::{create_winit_window_builder, process_viewport_commands};
|
||||||
|
|
||||||
@@ -2075,7 +2075,7 @@ mod wgpu_integration {
|
|||||||
let event_loop: *const EventLoopWindowTarget<UserEvent> = event_loop;
|
let event_loop: *const EventLoopWindowTarget<UserEvent> = event_loop;
|
||||||
|
|
||||||
egui::Context::set_immediate_viewport_renderer(
|
egui::Context::set_immediate_viewport_renderer(
|
||||||
move |egui_ctx, viewport_builder, ids, viewport_ui_cb| {
|
move |egui_ctx, immediate_viewport| {
|
||||||
if let Some(shared) = shared.upgrade() {
|
if let Some(shared) = shared.upgrade() {
|
||||||
// SAFETY: the event loop lives longer than
|
// SAFETY: the event loop lives longer than
|
||||||
// the Rc:s we just upgraded above.
|
// the Rc:s we just upgraded above.
|
||||||
@@ -2085,11 +2085,9 @@ mod wgpu_integration {
|
|||||||
render_immediate_viewport(
|
render_immediate_viewport(
|
||||||
event_loop,
|
event_loop,
|
||||||
egui_ctx,
|
egui_ctx,
|
||||||
viewport_builder,
|
|
||||||
ids,
|
|
||||||
viewport_ui_cb,
|
|
||||||
beginning,
|
beginning,
|
||||||
&shared,
|
&shared,
|
||||||
|
immediate_viewport,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
log::warn!("render_sync_callback called after window closed");
|
log::warn!("render_sync_callback called after window closed");
|
||||||
@@ -2125,19 +2123,21 @@ mod wgpu_integration {
|
|||||||
Ok((window, window_builder))
|
Ok((window, window_builder))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
fn render_immediate_viewport(
|
fn render_immediate_viewport(
|
||||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||||
egui_ctx: &egui::Context,
|
egui_ctx: &egui::Context,
|
||||||
mut viewport_builder: ViewportBuilder,
|
|
||||||
ids: ViewportIdPair,
|
|
||||||
viewport_ui_cb: Box<dyn FnOnce(&egui::Context) + '_>,
|
|
||||||
beginning: Instant,
|
beginning: Instant,
|
||||||
shared: &RefCell<SharedState>,
|
shared: &RefCell<SharedState>,
|
||||||
|
immediate_viewport: ImmediateViewport<'_>,
|
||||||
) {
|
) {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
||||||
|
let ImmediateViewport {
|
||||||
|
ids,
|
||||||
|
mut builder,
|
||||||
|
viewport_ui_cb,
|
||||||
|
} = immediate_viewport;
|
||||||
|
|
||||||
let input = {
|
let input = {
|
||||||
let mut shared = shared.borrow_mut();
|
let mut shared = shared.borrow_mut();
|
||||||
let SharedState {
|
let SharedState {
|
||||||
@@ -2148,15 +2148,15 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
// Creating a new native window if is needed
|
// Creating a new native window if is needed
|
||||||
if !viewports.contains_key(&ids.this) {
|
if !viewports.contains_key(&ids.this) {
|
||||||
if viewport_builder.icon.is_none() {
|
if builder.icon.is_none() {
|
||||||
viewport_builder.icon = viewports
|
builder.icon = viewports
|
||||||
.get(&ids.parent)
|
.get(&ids.parent)
|
||||||
.and_then(|vp| vp.builder.icon.clone());
|
.and_then(|vp| vp.builder.icon.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewport = viewports.entry(ids.this).or_insert(Viewport {
|
let viewport = viewports.entry(ids.this).or_insert(Viewport {
|
||||||
ids,
|
ids,
|
||||||
builder: viewport_builder,
|
builder,
|
||||||
viewport_ui_cb: None,
|
viewport_ui_cb: None,
|
||||||
window: None,
|
window: None,
|
||||||
egui_winit: None,
|
egui_winit: None,
|
||||||
@@ -2586,16 +2586,16 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
// Add new viewports, and update existing ones:
|
// Add new viewports, and update existing ones:
|
||||||
for ViewportOutput {
|
for ViewportOutput {
|
||||||
builder: mut new_builder,
|
|
||||||
ids,
|
ids,
|
||||||
|
mut builder,
|
||||||
viewport_ui_cb,
|
viewport_ui_cb,
|
||||||
} in out_viewports
|
} in out_viewports
|
||||||
{
|
{
|
||||||
active_viewports_ids.insert(ids.this);
|
active_viewports_ids.insert(ids.this);
|
||||||
|
|
||||||
if new_builder.icon.is_none() {
|
if builder.icon.is_none() {
|
||||||
// Inherit icon from parent
|
// Inherit icon from parent
|
||||||
new_builder.icon = viewports
|
builder.icon = viewports
|
||||||
.get_mut(&ids.parent)
|
.get_mut(&ids.parent)
|
||||||
.and_then(|vp| vp.builder.icon.clone());
|
.and_then(|vp| vp.builder.icon.clone());
|
||||||
}
|
}
|
||||||
@@ -2605,7 +2605,7 @@ mod wgpu_integration {
|
|||||||
// New viewport:
|
// New viewport:
|
||||||
entry.insert(Viewport {
|
entry.insert(Viewport {
|
||||||
ids,
|
ids,
|
||||||
builder: new_builder,
|
builder,
|
||||||
viewport_ui_cb,
|
viewport_ui_cb,
|
||||||
window: None,
|
window: None,
|
||||||
egui_winit: None,
|
egui_winit: None,
|
||||||
@@ -2619,7 +2619,7 @@ mod wgpu_integration {
|
|||||||
viewport.ids.parent = ids.parent;
|
viewport.ids.parent = ids.parent;
|
||||||
viewport.viewport_ui_cb = viewport_ui_cb;
|
viewport.viewport_ui_cb = viewport_ui_cb;
|
||||||
|
|
||||||
let (commands, recreate) = viewport.builder.patch(&new_builder);
|
let (commands, recreate) = viewport.builder.patch(&builder);
|
||||||
|
|
||||||
if recreate {
|
if recreate {
|
||||||
if let Some(viewport) = viewports.get_mut(&ids.this) {
|
if let Some(viewport) = viewports.get_mut(&ids.this) {
|
||||||
|
|||||||
@@ -2517,8 +2517,7 @@ impl Context {
|
|||||||
/// Look in `crates/eframe/native/run.rs` and search for `set_immediate_viewport_renderer` to see for what is used.
|
/// Look in `crates/eframe/native/run.rs` and search for `set_immediate_viewport_renderer` to see for what is used.
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
pub fn set_immediate_viewport_renderer(
|
pub fn set_immediate_viewport_renderer(
|
||||||
callback: impl for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>)
|
callback: impl for<'a> Fn(&Context, ImmediateViewport<'a>) + 'static,
|
||||||
+ 'static,
|
|
||||||
) {
|
) {
|
||||||
let callback = Box::new(callback);
|
let callback = Box::new(callback);
|
||||||
IMMEDIATE_VIEWPORT_RENDERER.with(|render_sync| {
|
IMMEDIATE_VIEWPORT_RENDERER.with(|render_sync| {
|
||||||
@@ -2628,7 +2627,7 @@ impl Context {
|
|||||||
/// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a [`crate::Window`].
|
/// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a [`crate::Window`].
|
||||||
pub fn show_viewport_immediate<T>(
|
pub fn show_viewport_immediate<T>(
|
||||||
&self,
|
&self,
|
||||||
viewport_builder: &ViewportBuilder,
|
builder: ViewportBuilder,
|
||||||
viewport_ui_cb: impl FnOnce(&Context) -> T,
|
viewport_ui_cb: impl FnOnce(&Context) -> T,
|
||||||
) -> T {
|
) -> T {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
@@ -2647,9 +2646,9 @@ impl Context {
|
|||||||
let ids = self.write(|ctx| {
|
let ids = self.write(|ctx| {
|
||||||
let parent = ctx.viewport_id();
|
let parent = ctx.viewport_id();
|
||||||
|
|
||||||
if let Some(window) = ctx.viewports.get_mut(&viewport_builder.id) {
|
if let Some(window) = ctx.viewports.get_mut(&builder.id) {
|
||||||
// Existing
|
// Existing
|
||||||
window.builder = viewport_builder.clone();
|
window.builder = builder.clone();
|
||||||
window.ids.parent = parent;
|
window.ids.parent = parent;
|
||||||
window.used = true;
|
window.used = true;
|
||||||
window.viewport_ui_cb = None;
|
window.viewport_ui_cb = None;
|
||||||
@@ -2657,13 +2656,13 @@ impl Context {
|
|||||||
} else {
|
} else {
|
||||||
// New
|
// New
|
||||||
let ids = ViewportIdPair {
|
let ids = ViewportIdPair {
|
||||||
this: viewport_builder.id,
|
this: builder.id,
|
||||||
parent,
|
parent,
|
||||||
};
|
};
|
||||||
ctx.viewports.insert(
|
ctx.viewports.insert(
|
||||||
viewport_builder.id,
|
builder.id,
|
||||||
ViewportState {
|
ViewportState {
|
||||||
builder: viewport_builder.clone(),
|
builder: builder.clone(),
|
||||||
ids,
|
ids,
|
||||||
used: true,
|
used: true,
|
||||||
viewport_ui_cb: None,
|
viewport_ui_cb: None,
|
||||||
@@ -2677,12 +2676,13 @@ impl Context {
|
|||||||
{
|
{
|
||||||
let out = &mut out;
|
let out = &mut out;
|
||||||
|
|
||||||
immediate_viewport_renderer(
|
let viewport = ImmediateViewport {
|
||||||
self,
|
|
||||||
viewport_builder.clone(),
|
|
||||||
ids,
|
ids,
|
||||||
Box::new(move |context| *out = Some(viewport_ui_cb(context))),
|
builder,
|
||||||
);
|
viewport_ui_cb: Box::new(move |context| *out = Some(viewport_ui_cb(context))),
|
||||||
|
};
|
||||||
|
|
||||||
|
immediate_viewport_renderer(self, viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.expect(
|
out.expect(
|
||||||
|
|||||||
@@ -89,8 +89,7 @@ impl ViewportIdPair {
|
|||||||
pub type ViewportUiCallback = dyn Fn(&Context) + Sync + Send;
|
pub type ViewportUiCallback = dyn Fn(&Context) + Sync + Send;
|
||||||
|
|
||||||
/// Render the given viewport, calling the given ui callback.
|
/// Render the given viewport, calling the given ui callback.
|
||||||
pub type ImmediateViewportRendererCallback =
|
pub type ImmediateViewportRendererCallback = dyn for<'a> Fn(&Context, ImmediateViewport<'a>);
|
||||||
dyn for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>);
|
|
||||||
|
|
||||||
/// Control the building of a new egui viewport (i.e. native window).
|
/// Control the building of a new egui viewport (i.e. native window).
|
||||||
///
|
///
|
||||||
@@ -734,3 +733,14 @@ impl ViewportOutput {
|
|||||||
self.ids.this
|
self.ids.this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Viewport for immediate rendering.
|
||||||
|
pub struct ImmediateViewport<'a> {
|
||||||
|
/// Id of us and our parent.
|
||||||
|
pub ids: ViewportIdPair,
|
||||||
|
|
||||||
|
pub builder: ViewportBuilder,
|
||||||
|
|
||||||
|
/// The user-code that shows the GUI.
|
||||||
|
pub viewport_ui_cb: Box<dyn FnOnce(&Context) + 'a>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl ViewportState {
|
|||||||
|
|
||||||
if immediate {
|
if immediate {
|
||||||
let mut vp_state = vp_state.write();
|
let mut vp_state = vp_state.write();
|
||||||
ctx.show_viewport_immediate(&vp_builder, move |ctx| {
|
ctx.show_viewport_immediate(vp_builder, move |ctx| {
|
||||||
show_as_popup(ctx, &title, vp_id.into(), |ui: &mut egui::Ui| {
|
show_as_popup(ctx, &title, vp_id.into(), |ui: &mut egui::Ui| {
|
||||||
generic_child_ui(ui, &mut vp_state);
|
generic_child_ui(ui, &mut vp_state);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user