From 7374ed9d00e21474ddd60f1b004b912d1ce893da Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 8 May 2021 10:14:56 +0200 Subject: [PATCH] epi/eframe: move options out of `trait App` into new `NativeOptions` --- eframe/CHANGELOG.md | 1 + eframe/examples/hello_world.rs | 3 +- eframe/src/lib.rs | 7 +++-- egui_demo_app/src/main.rs | 7 ++++- egui_demo_lib/src/wrap_app.rs | 4 --- egui_glium/src/backend.rs | 23 +++++++++------- egui_glium/src/lib.rs | 2 ++ epi/src/lib.rs | 50 +++++++++++++++++++--------------- 8 files changed, 57 insertions(+), 40 deletions(-) diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md index bcc4eea1c7a..d13edfec71d 100644 --- a/eframe/CHANGELOG.md +++ b/eframe/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to the `eframe` crate. ## Unreleased +* Moved options out of `trait App` into new `NativeOptions`. ## 0.11.0 - 2021-04-05 diff --git a/eframe/examples/hello_world.rs b/eframe/examples/hello_world.rs index aaabfd54e87..4437f1a33ba 100644 --- a/eframe/examples/hello_world.rs +++ b/eframe/examples/hello_world.rs @@ -41,5 +41,6 @@ impl epi::App for MyApp { } fn main() { - eframe::run_native(Box::new(MyApp::default())); + let options = eframe::NativeOptions::default(); + eframe::run_native(Box::new(MyApp::default()), options); } diff --git a/eframe/src/lib.rs b/eframe/src/lib.rs index 44e7223987b..4d98501a12c 100644 --- a/eframe/src/lib.rs +++ b/eframe/src/lib.rs @@ -20,6 +20,9 @@ pub use {egui, epi}; +#[cfg(not(target_arch = "wasm32"))] +pub use epi::NativeOptions; + // ---------------------------------------------------------------------------- // When compiling for web @@ -56,6 +59,6 @@ pub fn start_web(canvas_id: &str, app: Box) -> Result<(), wasm_bin /// Call from `fn main` like this: `eframe::run_native(Box::new(MyEguiApp::default()))` #[cfg(not(target_arch = "wasm32"))] -pub fn run_native(app: Box) -> ! { - egui_glium::run(app) +pub fn run_native(app: Box, native_options: epi::NativeOptions) -> ! { + egui_glium::run(app, native_options) } diff --git a/egui_demo_app/src/main.rs b/egui_demo_app/src/main.rs index a8cf0bac15b..f7bad3dcbc5 100644 --- a/egui_demo_app/src/main.rs +++ b/egui_demo_app/src/main.rs @@ -8,5 +8,10 @@ // When compiling natively: fn main() { let app = egui_demo_lib::WrapApp::default(); - eframe::run_native(Box::new(app)); + let options = eframe::NativeOptions { + // Let's show off that we support transparent windows + transparent: true, + ..Default::default() + }; + eframe::run_native(Box::new(app), options); } diff --git a/egui_demo_lib/src/wrap_app.rs b/egui_demo_lib/src/wrap_app.rs index 3461a5887ef..731ef337dec 100644 --- a/egui_demo_lib/src/wrap_app.rs +++ b/egui_demo_lib/src/wrap_app.rs @@ -54,10 +54,6 @@ impl epi::App for WrapApp { self.backend_panel.max_size_points_active } - // Let's show off that we support transparent windows (on native): - fn transparent(&self) -> bool { - true - } fn clear_color(&self) -> egui::Rgba { egui::Rgba::TRANSPARENT // we set a `CentralPanel` fill color in `demo_windows.rs` } diff --git a/egui_glium/src/backend.rs b/egui_glium/src/backend.rs index 886b5b55c04..fd8fa5cd059 100644 --- a/egui_glium/src/backend.rs +++ b/egui_glium/src/backend.rs @@ -76,20 +76,22 @@ fn window_builder_drag_and_drop( fn create_display( app: &dyn epi::App, + native_options: &epi::NativeOptions, window_settings: Option, window_icon: Option, event_loop: &glutin::event_loop::EventLoop, ) -> glium::Display { let mut window_builder = glutin::window::WindowBuilder::new() - .with_decorations(app.decorated()) - .with_resizable(app.is_resizable()) + .with_decorations(native_options.decorated) + .with_resizable(native_options.resizable) .with_title(app.name()) .with_window_icon(window_icon) - .with_transparent(app.transparent()); + .with_transparent(native_options.transparent); - window_builder = window_builder_drag_and_drop(window_builder, app.drag_and_drop_support()); + window_builder = + window_builder_drag_and_drop(window_builder, native_options.drag_and_drop_support); - let initial_size_points = app.initial_window_size(); + let initial_size_points = native_options.initial_window_size; if let Some(window_settings) = &window_settings { window_builder = window_settings.initialize_size(window_builder); @@ -154,13 +156,14 @@ fn integration_info( } } -fn load_icon(icon_data: Option) -> Option { - let icon_data = icon_data?; +fn load_icon(icon_data: epi::IconData) -> Option { glutin::window::Icon::from_rgba(icon_data.rgba, icon_data.width, icon_data.height).ok() } +// ---------------------------------------------------------------------------- + /// Run an egui app -pub fn run(mut app: Box) -> ! { +pub fn run(mut app: Box, nativve_options: epi::NativeOptions) -> ! { let mut storage = create_storage(app.name()); if let Some(storage) = &mut storage { @@ -169,8 +172,8 @@ pub fn run(mut app: Box) -> ! { let window_settings = deserialize_window_settings(&storage); let event_loop = glutin::event_loop::EventLoop::with_user_event(); - let icon = load_icon(app.icon_data()); - let display = create_display(&*app, window_settings, icon, &event_loop); + let icon = nativve_options.icon_data.clone().and_then(load_icon); + let display = create_display(&*app, &nativve_options, window_settings, icon, &event_loop); let repaint_signal = std::sync::Arc::new(GliumRepaintSignal(std::sync::Mutex::new( event_loop.create_proxy(), diff --git a/egui_glium/src/lib.rs b/egui_glium/src/lib.rs index d8f310e7c4e..9cc8105ef0a 100644 --- a/egui_glium/src/lib.rs +++ b/egui_glium/src/lib.rs @@ -25,6 +25,8 @@ pub mod window_settings; pub use backend::*; pub use painter::Painter; +pub use epi::NativeOptions; + use { copypasta::ClipboardProvider, egui::*, diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 93aa99fe9c5..6ec8f31084b 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -108,21 +108,11 @@ pub trait App { /// The name of your App. fn name(&self) -> &str; - /// The initial size of the native window in points (logical pixels). - fn initial_window_size(&self) -> Option { - None - } - /// Time between automatic calls to `save()` fn auto_save_interval(&self) -> std::time::Duration { std::time::Duration::from_secs(30) } - /// Returns true if this app window should be resizable. - fn is_resizable(&self) -> bool { - true - } - /// The size limit of the web app canvas fn max_size_points(&self) -> egui::Vec2 { // Some browsers get slow with huge WebGL canvases, so we limit the size: @@ -137,33 +127,49 @@ pub trait App { // `transparent()` option they get immediate results. egui::Color32::from_rgba_unmultiplied(12, 12, 12, 180).into() } +} +/// Options controlling the behavior of a native window +#[derive(Clone)] +pub struct NativeOptions { /// The application icon, e.g. in the Windows task bar etc. - fn icon_data(&self) -> Option { - None - } + pub icon_data: Option, + + /// The initial size of the native window in points (logical pixels). + pub initial_window_size: Option, + + /// Should the app window be resizable? + pub resizable: bool, /// On desktop: add window decorations (i.e. a frame around your app)? /// If false it will be difficult to move and resize the app. - fn decorated(&self) -> bool { - true - } + pub decorated: bool, /// On desktop: make the window transparent. - /// You control the transparency with [`Self::clear_color()`]. + /// You control the transparency with [`App::clear_color()`]. /// You should avoid having a [`egui::CentralPanel`], or make sure its frame is also transparent. - fn transparent(&self) -> bool { - false - } + pub transparent: bool, /// On Windows: enable drag and drop support. /// Set to false to avoid issues with crates such as cpal which uses that use multi-threaded COM API - fn drag_and_drop_support(&self) -> bool { - true + pub drag_and_drop_support: bool, +} + +impl Default for NativeOptions { + fn default() -> Self { + Self { + icon_data: None, + initial_window_size: None, + resizable: true, + decorated: true, + transparent: false, + drag_and_drop_support: true, + } } } /// Image data for the icon. +#[derive(Clone)] pub struct IconData { /// RGBA pixels. pub rgba: Vec,