mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Replace eframe::Frame commands and WindowInfo with egui (#3564)
* Part of https://github.com/emilk/egui/issues/3556 ## In short You now almost never need to use `eframe::Frame` - instead use `ui.input(|i| i.viewport())` for information about the current viewport (native window), and use `ctx.send_viewport_cmd` to modify it. ## In detail This PR removes most commands from `eframe::Frame`, and replaces them with `ViewportCommand`. So `frame.close()` becomes `ctx.send_viewport_cmd(ViewportCommand::Close)`, etc. `frame.info().window_info` is now also gone, replaced with `ui.input(|i| i.viewport())`. `frame.info().native_pixels_per_point` is replaced with `ui.input(|i| i.raw.native_pixels_per_point)`. `RawInput` now contains one `ViewportInfo` for each viewport. Screenshots are taken with `ctx.send_viewport_cmd(ViewportCommand::Screenshots)` and are returned in `egui::Event` which you can check with: ``` ust ui.input(|i| { for event in &i.raw.events { if let egui::Event::Screenshot { viewport_id, image } = event { // handle it here } } }); ``` ### Motivation You no longer need to pass around the `&eframe::Frame` everywhere. This also opens the door for other integrations to use the same API of `ViewportCommand`s.
This commit is contained in:
@@ -27,6 +27,7 @@ impl Default for Demos {
|
||||
Box::<super::context_menu::ContextMenus>::default(),
|
||||
Box::<super::dancing_strings::DancingStrings>::default(),
|
||||
Box::<super::drag_and_drop::DragAndDropDemo>::default(),
|
||||
Box::<super::extra_viewport::ExtraViewport>::default(),
|
||||
Box::<super::font_book::FontBook>::default(),
|
||||
Box::<super::MiscDemoWindow>::default(),
|
||||
Box::<super::multi_touch::MultiTouch>::default(),
|
||||
@@ -61,9 +62,11 @@ impl Demos {
|
||||
pub fn checkboxes(&mut self, ui: &mut Ui) {
|
||||
let Self { demos, open } = self;
|
||||
for demo in demos {
|
||||
let mut is_open = open.contains(demo.name());
|
||||
ui.toggle_value(&mut is_open, demo.name());
|
||||
set_open(open, demo.name(), is_open);
|
||||
if demo.is_enabled(ui.ctx()) {
|
||||
let mut is_open = open.contains(demo.name());
|
||||
ui.toggle_value(&mut is_open, demo.name());
|
||||
set_open(open, demo.name(), is_open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
72
crates/egui_demo_lib/src/demo/extra_viewport.rs
Normal file
72
crates/egui_demo_lib/src/demo/extra_viewport.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
#[derive(Default)]
|
||||
pub struct ExtraViewport {}
|
||||
|
||||
impl super::Demo for ExtraViewport {
|
||||
fn is_enabled(&self, ctx: &egui::Context) -> bool {
|
||||
!ctx.embed_viewports()
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"🗖 Extra Viewport"
|
||||
}
|
||||
|
||||
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
|
||||
if !*open {
|
||||
return;
|
||||
}
|
||||
|
||||
let id = egui::Id::new(self.name());
|
||||
|
||||
ctx.show_viewport_immediate(
|
||||
egui::ViewportId(id),
|
||||
egui::ViewportBuilder::default()
|
||||
.with_title(self.name())
|
||||
.with_inner_size([400.0, 512.0]),
|
||||
|ctx, class| {
|
||||
if class == egui::ViewportClass::Embedded {
|
||||
// Not a real viewport
|
||||
egui::Window::new(self.name())
|
||||
.id(id)
|
||||
.open(open)
|
||||
.show(ctx, |ui| {
|
||||
ui.label("This egui integration does not support multiple viewports");
|
||||
});
|
||||
} else {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.push_id(id, |ui| {
|
||||
viewport_content(ui, ctx, open);
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn viewport_content(ui: &mut egui::Ui, ctx: &egui::Context, open: &mut bool) {
|
||||
ui.label("egui and eframe supports having multiple native windows like this, which egui calls 'viewports'.");
|
||||
|
||||
ui.label(format!(
|
||||
"This viewport has id: {:?}, child of viewport {:?}",
|
||||
ctx.viewport_id(),
|
||||
ctx.parent_viewport_id()
|
||||
));
|
||||
|
||||
ui.label("Here you can see all the open viewports:");
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
let viewports = ui.input(|i| i.raw.viewports.clone());
|
||||
for (id, viewport) in viewports {
|
||||
ui.group(|ui| {
|
||||
ui.label(format!("viewport {id:?}"));
|
||||
ui.push_id(id, |ui| {
|
||||
viewport.ui(ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if ui.input(|i| i.viewport().close_requested) {
|
||||
*open = false;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ pub mod context_menu;
|
||||
pub mod dancing_strings;
|
||||
pub mod demo_app_windows;
|
||||
pub mod drag_and_drop;
|
||||
pub mod extra_viewport;
|
||||
pub mod font_book;
|
||||
pub mod highlighting;
|
||||
pub mod layout_test;
|
||||
@@ -46,6 +47,11 @@ pub trait View {
|
||||
|
||||
/// Something to view
|
||||
pub trait Demo {
|
||||
/// Is the demo enabled for this integraton?
|
||||
fn is_enabled(&self, _ctx: &egui::Context) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// `&'static` so we can also use it as a key to store open/close state.
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user