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

Clean up example code

This commit is contained in:
Emil Ernerfeldt
2023-11-06 18:35:27 +01:00
parent c29727f82c
commit 0ae7eebfd4
2 changed files with 126 additions and 95 deletions

View File

@@ -11,12 +11,14 @@ use epaint::{ColorImage, Pos2, Vec2};
use crate::{Context, Id}; use crate::{Context, Id};
// ----------------------------------------------------------------------------
/// A unique identifier of a viewport. /// A unique identifier of a viewport.
/// ///
/// Generated by [`Context`]. /// Generated by [`Context`].
/// ///
/// This is returned by [`Context::viewport_id`] and [`Context::parent_viewport_id`]. /// This is returned by [`Context::viewport_id`] and [`Context::parent_viewport_id`].
#[derive(Hash, Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct ViewportId(pub Id); pub struct ViewportId(pub Id);
impl Default for ViewportId { impl Default for ViewportId {
@@ -40,6 +42,15 @@ impl ViewportId {
} }
} }
impl From<ViewportId> for Id {
#[inline]
fn from(id: ViewportId) -> Self {
id.0
}
}
// ----------------------------------------------------------------------------
/// This will deref to [`Self::this`]. /// This will deref to [`Self::this`].
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub struct ViewportIdPair { pub struct ViewportIdPair {

View File

@@ -3,26 +3,63 @@ use std::sync::Arc;
use eframe::egui; use eframe::egui;
use egui::{mutex::RwLock, Id, InnerResponse, ViewportBuilder, ViewportId}; use egui::{mutex::RwLock, Id, InnerResponse, ViewportBuilder, ViewportId};
#[derive(Default)] pub struct ViewportState {
pub count: usize,
pub title: String,
}
impl ViewportState {
pub fn new(title: impl Into<String>) -> Self {
Self {
count: 0,
title: title.into(),
}
}
}
pub struct App { pub struct App {
show_async_viewport: bool, show_async_viewport: bool,
show_sync_viewport: bool, show_sync_viewport: bool,
async_viewport_state: Arc<RwLock<usize>>, top_async_state: Arc<RwLock<ViewportState>>,
sync_viewport_state: usize, top_sync_state: ViewportState,
async_async_viewport_state: Arc<RwLock<usize>>, async_async_state: Arc<RwLock<ViewportState>>,
async_sync_viewport_state: Arc<RwLock<usize>>, async_sync_state: Arc<RwLock<ViewportState>>,
sync_async_viewport_state: Arc<RwLock<usize>>, sync_async_state: Arc<RwLock<ViewportState>>,
sync_sync_viewport_state: usize, sync_sync_state: ViewportState,
}
impl Default for App {
fn default() -> Self {
Self {
show_async_viewport: false,
show_sync_viewport: false,
top_async_state: Arc::new(RwLock::new(ViewportState::new("Top Async Viewport"))),
top_sync_state: ViewportState::new("Top Sync Viewport"),
async_async_state: Arc::new(RwLock::new(ViewportState::new(
"AA: Async Viewport in Async Viewport",
))),
async_sync_state: Arc::new(RwLock::new(ViewportState::new(
"AS: Sync Viewport in Async Viewport",
))),
sync_async_state: Arc::new(RwLock::new(ViewportState::new(
"SA: Async Viewport in Sync Viewport",
))),
sync_sync_state: ViewportState::new("SS: Sync Viewport in Sync Viewport"),
}
}
} }
impl eframe::App for App { impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Main viewport"); ui.heading("Main viewport");
generic_ui(ui, "main_viewport"); generic_ui(ui, Id::new("main_viewport"));
{ {
let mut force_embedding = ctx.force_embedding(); let mut force_embedding = ctx.force_embedding();
ui.checkbox(&mut force_embedding, "Force embedding of new viewprts"); ui.checkbox(&mut force_embedding, "Force embedding of new viewprts");
@@ -35,27 +72,27 @@ impl eframe::App for App {
// Showing Async Viewport // Showing Async Viewport
if self.show_async_viewport { if self.show_async_viewport {
let async_state = self.async_async_viewport_state.clone(); let async_async_state = self.async_async_state.clone();
let sync_state = self.async_sync_viewport_state.clone(); let async_sync_state = self.async_sync_state.clone();
show_async_viewport( show_async_viewport(
ctx, ctx,
"Async Viewport", ViewportId::from_hash_of("async_viewport"),
self.async_viewport_state.clone(), self.top_async_state.clone(),
vec![ vec![
AsyncViewport::new("AA: Async Viewport in Async Viewport", move |ctx| { AsyncViewport::new("AA: Async Viewport in Async Viewport", move |ctx| {
show_async_viewport( show_async_viewport(
ctx, ctx,
"AA: Async Viewport in Async Viewport", ViewportId::from_hash_of("AA_vp"),
async_state.clone(), async_async_state.clone(),
vec![], vec![],
); );
}), }),
AsyncViewport::new("AS: Sync Viewport in Async Viewport", move |ctx| { AsyncViewport::new("AS: Sync Viewport in Async Viewport", move |ctx| {
let mut state = sync_state.write(); let mut state = async_sync_state.write();
show_sync_viewport( show_sync_viewport(
ctx, ctx,
"AS: Sync Viewport in Async Viewport", ViewportId::from_hash_of("AS_vp"),
&mut state, &mut state,
vec![], vec![],
); );
@@ -66,26 +103,26 @@ impl eframe::App for App {
// Showing Sync Viewport // Showing Sync Viewport
if self.show_sync_viewport { if self.show_sync_viewport {
let async_state = self.sync_async_viewport_state.clone(); let sync_async_state = self.sync_async_state.clone();
let sync_state = &mut self.sync_sync_viewport_state; let sync_sync_state = &mut self.sync_sync_state;
show_sync_viewport( show_sync_viewport(
ctx, ctx,
"Sync Viewport", ViewportId::from_hash_of("sync_viewport"),
&mut self.sync_viewport_state, &mut self.top_sync_state,
vec![ vec![
SyncViewport::new("SA: Async Viewport in Sync Viewport", move |ctx| { SyncViewport::new("SA: Async Viewport in Sync Viewport", move |ctx| {
show_async_viewport( show_async_viewport(
ctx, ctx,
"SA: Async Viewport in Sync Viewport", ViewportId::from_hash_of("SA_vp"),
async_state.clone(), sync_async_state.clone(),
vec![], vec![],
); );
}), }),
SyncViewport::new("SS: Sync Viewport in Sync Viewport", move |ctx| { SyncViewport::new("SS: Sync Viewport in Sync Viewport", move |ctx| {
show_sync_viewport( show_sync_viewport(
ctx, ctx,
"SS: Sync Viewport in Sync Viewport", ViewportId::from_hash_of("SS_vp"),
sync_state, sync_sync_state,
vec![], vec![],
); );
}), }),
@@ -103,28 +140,28 @@ struct State {
#[derive(Clone)] #[derive(Clone)]
struct AsyncViewport { struct AsyncViewport {
name: String, name: &'static str,
init: Arc<Box<dyn Fn(&egui::Context) + Sync + Send>>, init: Arc<Box<dyn Fn(&egui::Context) + Sync + Send>>,
} }
impl AsyncViewport { impl AsyncViewport {
fn new(name: impl Into<String>, init: impl Fn(&egui::Context) + Sync + Send + 'static) -> Self { fn new(name: &'static str, init: impl Fn(&egui::Context) + Sync + Send + 'static) -> Self {
Self { Self {
name: name.into(), name,
init: Arc::new(Box::new(init)), init: Arc::new(Box::new(init)),
} }
} }
} }
struct SyncViewport<'a> { struct SyncViewport<'a> {
name: String, name: &'static str,
init: Box<dyn FnMut(&egui::Context) + 'a>, init: Box<dyn FnMut(&egui::Context) + 'a>,
} }
impl<'a> SyncViewport<'a> { impl<'a> SyncViewport<'a> {
fn new(name: impl Into<String>, init: impl FnMut(&egui::Context) + 'a) -> Self { fn new(name: &'static str, init: impl FnMut(&egui::Context) + 'a) -> Self {
Self { Self {
name: name.into(), name,
init: Box::new(init), init: Box::new(init),
} }
} }
@@ -132,102 +169,87 @@ impl<'a> SyncViewport<'a> {
fn show_async_viewport( fn show_async_viewport(
ctx: &egui::Context, ctx: &egui::Context,
name: impl Into<String>, vp_id: ViewportId,
count: Arc<RwLock<usize>>, vp_state: Arc<RwLock<ViewportState>>,
viewports: Vec<AsyncViewport>, viewports: Vec<AsyncViewport>,
) { ) {
let name: String = name.into(); let id = Id::from(vp_id);
let title = vp_state.read().title.clone();
ctx.create_viewport_async( ctx.create_viewport_async(
ViewportBuilder::new(ViewportId::from_hash_of(&name)) ViewportBuilder::new(vp_id)
.with_title(name.as_str()) .with_title(&title)
.with_inner_size(Some(egui::vec2(450.0, 350.0))), .with_inner_size(Some(egui::vec2(450.0, 350.0))),
move |ctx| { move |ctx| {
let mut count = count.write(); let mut vp_state = vp_state.write();
let viewports = viewports.clone(); let viewports = viewports.clone();
let n = name.clone();
let name = n.clone();
let content = move |ui: &mut egui::Ui| { let content = move |ui: &mut egui::Ui| {
generic_ui(ui, name.clone()); generic_ui(ui, id);
let ctx = ui.ctx().clone(); if !viewports.is_empty() {
let mut state = ctx.memory_mut(|mem| { let mut state =
mem.data ctx.memory_mut(|mem| mem.data.get_temp_mut_or_default::<State>(id).clone());
.get_temp_mut_or_default::<State>(name.clone().into())
.clone()
});
state.active.resize(viewports.len(), false); state.active.resize(viewports.len(), false);
for (i, viewport) in viewports.iter().enumerate() { for (i, viewport) in viewports.iter().enumerate() {
ui.checkbox(&mut state.active[i], &viewport.name); ui.checkbox(&mut state.active[i], viewport.name);
} if state.active[i] {
(viewport.init)(ctx);
ui.add(egui::DragValue::new(&mut *count).prefix("Count: ")); }
for (i, viewport) in viewports.iter().enumerate() {
if state.active[i] {
(viewport.init)(&ctx);
} }
ctx.memory_mut(move |mem| {
*mem.data.get_temp_mut_or_default::<State>(id) = state;
});
} }
ctx.memory_mut(move |mem| { ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
*mem.data.get_temp_mut_or_default::<State>(name.into()) = state;
});
}; };
show_as_popup(ctx, &n, content); show_as_popup(ctx, &title, id, content);
}, },
); );
} }
fn show_sync_viewport( fn show_sync_viewport(
ctx: &egui::Context, ctx: &egui::Context,
name: impl Into<String>, vp_id: ViewportId,
count: &mut usize, vp_state: &mut ViewportState,
mut viewports: Vec<SyncViewport<'_>>, mut viewports: Vec<SyncViewport<'_>>,
) { ) {
let name: String = name.into(); let id = Id::from(vp_id);
ctx.create_viewport_sync( ctx.create_viewport_sync(
ViewportBuilder::new(ViewportId::from_hash_of(&name)) ViewportBuilder::new(vp_id)
.with_title(name.as_str()) .with_title(vp_state.title.clone())
.with_inner_size(Some(egui::vec2(450.0, 350.0))), .with_inner_size(Some(egui::vec2(450.0, 350.0))),
move |ctx| { move |ctx| {
let n = name.clone();
let content = |ui: &mut egui::Ui| { let content = |ui: &mut egui::Ui| {
generic_ui(ui, name.clone()); generic_ui(ui, id);
let ctx = ui.ctx().clone(); if !viewports.is_empty() {
let mut state = ctx.memory_mut(|mem| { let mut state =
mem.data ctx.memory_mut(|mem| mem.data.get_temp_mut_or_default::<State>(id).clone());
.get_temp_mut_or_default::<State>(name.clone().into())
.clone()
});
state.active.resize(viewports.len(), false); state.active.resize(viewports.len(), false);
for (i, viewport) in viewports.iter().enumerate() { for (i, viewport) in viewports.iter_mut().enumerate() {
ui.checkbox(&mut state.active[i], &viewport.name); ui.checkbox(&mut state.active[i], viewport.name);
} if state.active[i] {
(viewport.init)(ctx);
ui.add(egui::DragValue::new(count).prefix("Count: ")); }
for (i, viewport) in viewports.iter_mut().enumerate() {
if state.active[i] {
(viewport.init)(&ctx);
} }
ctx.memory_mut(move |mem| {
*mem.data.get_temp_mut_or_default::<State>(id) = state;
});
} }
ctx.memory_mut(move |mem| { ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
*mem.data.get_temp_mut_or_default::<State>(name.into()) = state;
});
}; };
show_as_popup(ctx, &n, content); show_as_popup(ctx, &vp_state.title, id, content);
}, },
); );
} }
@@ -303,17 +325,15 @@ fn drop_target<R>(
} }
/// This will make the content as a popup if cannot has his own native window /// This will make the content as a popup if cannot has his own native window
fn show_as_popup(ctx: &egui::Context, name: &str, content: impl FnOnce(&mut egui::Ui)) { fn show_as_popup(ctx: &egui::Context, title: &str, id: Id, content: impl FnOnce(&mut egui::Ui)) {
if ctx.viewport_id() == ctx.parent_viewport_id() { if ctx.viewport_id() == ctx.parent_viewport_id() {
egui::Window::new(name).show(ctx, content); egui::Window::new(title).id(id).show(ctx, content);
} else { } else {
egui::CentralPanel::default().show(ctx, content); egui::CentralPanel::default().show(ctx, content);
} }
} }
fn generic_ui(ui: &mut egui::Ui, container_id: impl Into<Id>) { fn generic_ui(ui: &mut egui::Ui, container_id: Id) {
let container_id = container_id.into();
let ctx = ui.ctx().clone(); let ctx = ui.ctx().clone();
ui.label(format!( ui.label(format!(
"Frame nr: {} (this increases when this viewport is being rendered)", "Frame nr: {} (this increases when this viewport is being rendered)",
@@ -502,7 +522,7 @@ fn main() {
#[cfg(feature = "wgpu")] #[cfg(feature = "wgpu")]
renderer: eframe::Renderer::Wgpu, renderer: eframe::Renderer::Wgpu,
initial_window_size: Some(egui::Vec2::new(450.0, 320.0)), initial_window_size: Some(egui::Vec2::new(450.0, 360.0)),
..Default::default() ..Default::default()
}, },
Box::new(|_| Box::<App>::default()), Box::new(|_| Box::<App>::default()),