1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 15:13:12 -04:00
Files
egui/examples/multiple_viewports/src/main.rs
Emil Ernerfeldt 8d98763fe1 Replace #[allow attributes with expect (#7796)
We do have `clippy::allow_attributes` turned on, but it doesn't seem to
work properly
2025-12-19 20:55:50 +01:00

115 lines
4.4 KiB
Rust

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
#![expect(rustdoc::missing_crate_level_docs)] // it's an example
use std::sync::{
Arc,
atomic::{AtomicBool, Ordering},
};
use eframe::egui;
fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
eframe::run_native(
"Multiple viewports",
options,
Box::new(|_cc| Ok(Box::<MyApp>::default())),
)
}
#[derive(Default)]
struct MyApp {
/// Immediate viewports are show immediately, so passing state to/from them is easy.
/// The downside is that their painting is linked with the parent viewport:
/// if either needs repainting, they are both repainted.
show_immediate_viewport: bool,
/// Deferred viewports run independent of the parent viewport, which can save
/// CPU if only some of the viewports require repainting.
/// However, this requires passing state with `Arc` and locks.
show_deferred_viewport: Arc<AtomicBool>,
}
impl eframe::App for MyApp {
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show_inside(ui, |ui| {
ui.label("Hello from the root viewport");
ui.checkbox(
&mut self.show_immediate_viewport,
"Show immediate child viewport",
);
{
let mut show_deferred_viewport =
self.show_deferred_viewport.load(Ordering::Relaxed);
ui.checkbox(&mut show_deferred_viewport, "Show deferred child viewport");
self.show_deferred_viewport
.store(show_deferred_viewport, Ordering::Relaxed);
}
ui.add_space(16.0);
{
let mut embedded = ui.embed_viewports();
ui.checkbox(&mut embedded, "Embed all viewports");
ui.set_embed_viewports(embedded);
}
});
if self.show_immediate_viewport {
ui.ctx().show_viewport_immediate(
egui::ViewportId::from_hash_of("immediate_viewport"),
egui::ViewportBuilder::default()
.with_title("Immediate Viewport")
.with_inner_size([200.0, 100.0]),
|ui, class| {
if class == egui::ViewportClass::EmbeddedWindow {
ui.label(
"This viewport is embedded in the parent window, and cannot be moved outside of it.",
);
} else {
egui::CentralPanel::default().show_inside(ui, |ui| {
ui.label("Hello from immediate viewport");
if ui.input(|i| i.viewport().close_requested()) {
// Tell parent viewport that we should not show next frame:
self.show_immediate_viewport = false;
}
});
}
},
);
}
if self.show_deferred_viewport.load(Ordering::Relaxed) {
let show_deferred_viewport = Arc::clone(&self.show_deferred_viewport);
ui.ctx().show_viewport_deferred(
egui::ViewportId::from_hash_of("deferred_viewport"),
egui::ViewportBuilder::default()
.with_title("Deferred Viewport")
.with_inner_size([200.0, 100.0]),
move |ui, class| {
if class == egui::ViewportClass::EmbeddedWindow {
ui.label(
"This viewport is embedded in the parent window, and cannot be moved outside of it.",
);
} else {
egui::CentralPanel::default().show_inside(ui, |ui| {
ui.label("Hello from deferred viewport");
if ui.input(|i| i.viewport().close_requested()) {
// Tell parent to close us.
show_deferred_viewport.store(false, Ordering::Relaxed);
}
});
}
},
);
}
}
}