mirror of
https://github.com/emilk/egui.git
synced 2026-09-03 23:30:04 -04:00
Add external eventloop support (#6750)
<!-- Please read the "Making a PR" section of [`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md) before opening a Pull Request! * Keep your PR:s small and focused. * The PR title is what ends up in the changelog, so make it descriptive! * If applicable, add a screenshot or gif. * If it is a non-trivial addition, consider adding a demo for it to `egui_demo_lib`, or a new example. * Do NOT open PR:s from your `master` branch, as that makes it hard for maintainers to test and add commits to your PR. * Remember to run `cargo fmt` and `cargo clippy`. * Open the PR as a draft until you have self-reviewed it and run `./scripts/check.sh`. * When you have addressed a PR comment, mark it as resolved. Please be patient! I will review your PR, but my time is limited! --> * Closes #2875 * Closes https://github.com/emilk/egui/pull/3340 * [x] I have followed the instructions in the PR template Adds `create_native`. Similiar to `run_native` but it returns an `EframeWinitApplication` which is a `winit::ApplicationHandler`. This can be run on your own event loop. A helper fn `pump_eframe_app` is provided to pump the event loop and get the control flow state back. I have been using this approach for a few months. --------- Co-authored-by: Will Brown <opensource@rebeagle.com>
This commit is contained in:
@@ -182,6 +182,14 @@ pub use web::{WebLogger, WebRunner};
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
mod native;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
pub use native::run::EframeWinitApplication;
|
||||
|
||||
#[cfg(not(any(target_arch = "wasm32", target_os = "ios")))]
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
pub use native::run::EframePumpStatus;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
#[cfg(feature = "persistence")]
|
||||
@@ -242,26 +250,7 @@ pub fn run_native(
|
||||
mut native_options: NativeOptions,
|
||||
app_creator: AppCreator<'_>,
|
||||
) -> Result {
|
||||
#[cfg(not(feature = "__screenshot"))]
|
||||
assert!(
|
||||
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
|
||||
"EFRAME_SCREENSHOT_TO found without compiling with the '__screenshot' feature"
|
||||
);
|
||||
|
||||
if native_options.viewport.title.is_none() {
|
||||
native_options.viewport.title = Some(app_name.to_owned());
|
||||
}
|
||||
|
||||
let renderer = native_options.renderer;
|
||||
|
||||
#[cfg(all(feature = "glow", feature = "wgpu"))]
|
||||
{
|
||||
match renderer {
|
||||
Renderer::Glow => "glow",
|
||||
Renderer::Wgpu => "wgpu",
|
||||
};
|
||||
log::info!("Both the glow and wgpu renderers are available. Using {renderer}.");
|
||||
}
|
||||
let renderer = init_native(app_name, &mut native_options);
|
||||
|
||||
match renderer {
|
||||
#[cfg(feature = "glow")]
|
||||
@@ -278,6 +267,113 @@ pub fn run_native(
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides a proxy for your native eframe application to run on your own event loop.
|
||||
///
|
||||
/// See `run_native` for details about `app_name`.
|
||||
///
|
||||
/// Call from `fn main` like this:
|
||||
/// ``` no_run
|
||||
/// use eframe::{egui, UserEvent};
|
||||
/// use winit::event_loop::{ControlFlow, EventLoop};
|
||||
///
|
||||
/// fn main() -> eframe::Result {
|
||||
/// let native_options = eframe::NativeOptions::default();
|
||||
/// let eventloop = EventLoop::<UserEvent>::with_user_event().build()?;
|
||||
/// eventloop.set_control_flow(ControlFlow::Poll);
|
||||
///
|
||||
/// let mut winit_app = eframe::create_native(
|
||||
/// "MyExtApp",
|
||||
/// native_options,
|
||||
/// Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))),
|
||||
/// &eventloop,
|
||||
/// );
|
||||
///
|
||||
/// eventloop.run_app(&mut winit_app)?;
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Default)]
|
||||
/// struct MyEguiApp {}
|
||||
///
|
||||
/// impl MyEguiApp {
|
||||
/// fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||
/// Self::default()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl eframe::App for MyEguiApp {
|
||||
/// fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||
/// egui::CentralPanel::default().show(ctx, |ui| {
|
||||
/// ui.heading("Hello World!");
|
||||
/// });
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// See the `external_eventloop` example for a more complete example.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
pub fn create_native<'a>(
|
||||
app_name: &str,
|
||||
mut native_options: NativeOptions,
|
||||
app_creator: AppCreator<'a>,
|
||||
event_loop: &winit::event_loop::EventLoop<UserEvent>,
|
||||
) -> EframeWinitApplication<'a> {
|
||||
let renderer = init_native(app_name, &mut native_options);
|
||||
|
||||
match renderer {
|
||||
#[cfg(feature = "glow")]
|
||||
Renderer::Glow => {
|
||||
log::debug!("Using the glow renderer");
|
||||
EframeWinitApplication::new(native::run::create_glow(
|
||||
app_name,
|
||||
native_options,
|
||||
app_creator,
|
||||
event_loop,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(feature = "wgpu")]
|
||||
Renderer::Wgpu => {
|
||||
log::debug!("Using the wgpu renderer");
|
||||
EframeWinitApplication::new(native::run::create_wgpu(
|
||||
app_name,
|
||||
native_options,
|
||||
app_creator,
|
||||
event_loop,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
fn init_native(app_name: &str, native_options: &mut NativeOptions) -> Renderer {
|
||||
#[cfg(not(feature = "__screenshot"))]
|
||||
assert!(
|
||||
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
|
||||
"EFRAME_SCREENSHOT_TO found without compiling with the '__screenshot' feature"
|
||||
);
|
||||
|
||||
if native_options.viewport.title.is_none() {
|
||||
native_options.viewport.title = Some(app_name.to_owned());
|
||||
}
|
||||
|
||||
let renderer = native_options.renderer;
|
||||
|
||||
#[cfg(all(feature = "glow", feature = "wgpu"))]
|
||||
{
|
||||
match native_options.renderer {
|
||||
Renderer::Glow => "glow",
|
||||
Renderer::Wgpu => "wgpu",
|
||||
};
|
||||
log::info!("Both the glow and wgpu renderers are available. Using {renderer}.");
|
||||
}
|
||||
|
||||
renderer
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// The simplest way to get started when writing a native app.
|
||||
|
||||
Reference in New Issue
Block a user