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:
@@ -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 {
|
||||||
|
|||||||
@@ -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()),
|
||||||
|
|||||||
Reference in New Issue
Block a user