2022-04-30 08:44:35 +00:00
//! Platform-agnostic interface for writing apps using [`egui`] (epi = egui programming interface).
2020-07-23 16:54:16 +00:00
//!
2021-09-03 19:04:43 +00:00
//! `epi` provides interfaces for window management and serialization.
2020-12-31 13:31:11 +00:00
//!
2021-01-02 10:59:20 +00:00
//! Start by looking at the [`App`] trait, and implement [`App::update`].
2020-12-29 13:15:46 +00:00
2021-09-08 22:16:06 +00:00
#![ warn(missing_docs) ] // Let's keep `epi` well-documented.
2020-12-29 13:15:46 +00:00
2022-09-09 06:22:46 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
use std ::any ::Any ;
2022-08-23 12:43:22 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
pub use crate ::native ::run ::RequestRepaintEvent ;
2022-10-31 16:57:32 +00:00
2022-08-23 12:43:22 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
pub use winit ::event_loop ::EventLoopBuilder ;
/// Hook into the building of an event loop before it is run
///
/// You can configure any platform specific details required on top of the default configuration
/// done by `EFrame`.
#[ cfg(not(target_arch = " wasm32 " )) ]
pub type EventLoopBuilderHook = Box < dyn FnOnce ( & mut EventLoopBuilder < RequestRepaintEvent > ) > ;
2022-04-30 08:44:35 +00:00
/// This is how your app is created.
2022-03-16 14:39:48 +00:00
///
/// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc.
2022-03-18 13:23:07 +00:00
pub type AppCreator = Box < dyn FnOnce ( & CreationContext < '_ > ) -> Box < dyn App > > ;
2022-03-16 14:39:48 +00:00
/// Data that is passed to [`AppCreator`] that can be used to setup and initialize your app.
pub struct CreationContext < ' s > {
/// The egui Context.
///
/// You can use this to customize the look of egui, e.g to call [`egui::Context::set_fonts`],
/// [`egui::Context::set_visuals`] etc.
pub egui_ctx : egui ::Context ,
/// Information about the surrounding environment.
pub integration_info : IntegrationInfo ,
/// You can use the storage to restore app state(requires the "persistence" feature).
pub storage : Option < & ' s dyn Storage > ,
/// The [`glow::Context`] allows you to initialize OpenGL resources (e.g. shaders) that
/// you might want to use later from a [`egui::PaintCallback`].
2022-08-08 10:15:31 +00:00
///
/// Only available when compiling with the `glow` feature and using [`Renderer::Glow`].
2022-05-12 07:02:28 +00:00
#[ cfg(feature = " glow " ) ]
2022-05-22 15:43:30 +00:00
pub gl : Option < std ::sync ::Arc < glow ::Context > > ,
2022-05-28 15:52:36 +00:00
2022-08-08 10:15:31 +00:00
/// The underlying WGPU render state.
///
/// Only available when compiling with the `wgpu` feature and using [`Renderer::Wgpu`].
///
/// Can be used to manage GPU resources for custom rendering with WGPU using [`egui::PaintCallback`]s.
2022-05-28 15:52:36 +00:00
#[ cfg(feature = " wgpu " ) ]
2022-08-08 10:15:31 +00:00
pub wgpu_render_state : Option < egui_wgpu ::RenderState > ,
2022-03-16 14:39:48 +00:00
}
2020-12-29 13:15:46 +00:00
// ----------------------------------------------------------------------------
2020-09-11 06:56:47 +00:00
2022-08-20 13:18:02 +00:00
/// Implement this trait to write apps that can be compiled for both web/wasm and desktop/native using [`eframe`](https://github.com/emilk/egui/tree/master/crates/eframe).
2020-07-23 16:54:16 +00:00
pub trait App {
2020-12-31 13:31:11 +00:00
/// Called each time the UI needs repainting, which may be many times per second.
2021-10-23 03:58:10 +00:00
///
2021-05-26 20:06:10 +00:00
/// Put your widgets into a [`egui::SidePanel`], [`egui::TopBottomPanel`], [`egui::CentralPanel`], [`egui::Window`] or [`egui::Area`].
2021-10-23 03:58:10 +00:00
///
2022-03-25 20:19:31 +00:00
/// The [`egui::Context`] can be cloned and saved if you like.
2021-12-26 20:21:28 +00:00
///
2022-03-16 14:39:48 +00:00
/// To force a repaint, call [`egui::Context::request_repaint`] at any time (e.g. from another thread).
2022-03-25 20:19:31 +00:00
fn update ( & mut self , ctx : & egui ::Context , frame : & mut Frame ) ;
2020-12-18 21:34:48 +00:00
2022-09-20 11:58:55 +00:00
/// Get a handle to the app.
2022-09-09 06:22:46 +00:00
///
2022-09-20 11:58:55 +00:00
/// Can be used from web to interact or other external context.
///
/// You need to implement this if you want to be able to access the application from JS using [`AppRunner::app_mut`].
///
2022-10-30 19:55:07 +00:00
/// This is needed because downcasting `Box<dyn App>` -> `Box<dyn Any>` to get &`ConcreteApp` is not simple in current rust.
2022-09-09 06:22:46 +00:00
///
2022-09-13 07:32:05 +00:00
/// Just copy-paste this as your implementation:
/// ```ignore
/// #[cfg(target_arch = "wasm32")]
2022-09-20 11:58:55 +00:00
/// fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
/// Some(&mut *self)
2022-09-13 07:32:05 +00:00
/// }
/// ```
2022-09-09 06:22:46 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
2022-09-20 11:58:55 +00:00
fn as_any_mut ( & mut self ) -> Option < & mut dyn Any > {
None
}
2022-09-09 06:22:46 +00:00
2020-12-19 19:50:00 +00:00
/// Called on shutdown, and perhaps at regular intervals. Allows you to save state.
2021-02-28 17:53:45 +00:00
///
2021-09-29 06:45:13 +00:00
/// Only called when the "persistence" feature is enabled.
///
2022-03-16 14:39:48 +00:00
/// On web the state is stored to "Local Storage".
2021-03-31 17:51:19 +00:00
/// On native the path is picked using [`directories_next::ProjectDirs::data_dir`](https://docs.rs/directories-next/2.0.0/directories_next/struct.ProjectDirs.html#method.data_dir) which is:
/// * Linux: `/home/UserName/.local/share/APPNAME`
/// * macOS: `/Users/UserName/Library/Application Support/APPNAME`
/// * Windows: `C:\Users\UserName\AppData\Roaming\APPNAME`
///
2022-03-16 14:39:48 +00:00
/// where `APPNAME` is what is given to `eframe::run_native`.
2020-12-19 19:50:00 +00:00
fn save ( & mut self , _storage : & mut dyn Storage ) { }
2022-08-20 14:08:59 +00:00
/// Called when the user attempts to close the desktop window and/or quit the application.
///
/// By returning `false` the closing will be aborted. To continue the closing return `true`.
2022-01-17 17:45:09 +00:00
///
/// A scenario where this method will be run is after pressing the close button on a native
/// window, which allows you to ask the user whether they want to do something before exiting.
2022-04-13 14:13:24 +00:00
/// See the example at <https://github.com/emilk/egui/blob/master/examples/confirm_exit/> for practical usage.
2022-01-17 17:45:09 +00:00
///
/// It will _not_ be called on the web or when the window is forcefully closed.
2022-08-20 14:08:59 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
#[ doc(alias = " exit " ) ]
#[ doc(alias = " quit " ) ]
fn on_close_event ( & mut self ) -> bool {
2022-01-17 17:45:09 +00:00
true
}
2022-03-16 14:39:48 +00:00
/// Called once on shutdown, after [`Self::save`].
///
2022-08-20 14:08:59 +00:00
/// If you need to abort an exit use [`Self::on_close_event`].
2022-05-12 07:02:28 +00:00
///
/// To get a [`glow`] context you need to compile with the `glow` feature flag,
/// and run eframe with the glow backend.
#[ cfg(feature = " glow " ) ]
fn on_exit ( & mut self , _gl : Option < & glow ::Context > ) { }
/// Called once on shutdown, after [`Self::save`].
///
2022-08-20 14:08:59 +00:00
/// If you need to abort an exit use [`Self::on_close_event`].
2022-05-12 07:02:28 +00:00
#[ cfg(not(feature = " glow " )) ]
fn on_exit ( & mut self ) { }
2020-12-31 13:31:11 +00:00
// ---------
// Settings:
2021-06-12 20:10:40 +00:00
/// Time between automatic calls to [`Self::save`]
2020-12-19 19:50:00 +00:00
fn auto_save_interval ( & self ) -> std ::time ::Duration {
std ::time ::Duration ::from_secs ( 30 )
}
2021-06-12 20:10:40 +00:00
/// The size limit of the web app canvas.
2022-01-08 10:15:05 +00:00
///
2022-03-19 12:47:30 +00:00
/// By default the max size is [`egui::Vec2::INFINITY`], i.e. unlimited.
2022-01-08 10:15:05 +00:00
///
2022-03-19 12:47:30 +00:00
/// A large canvas can lead to bad frame rates on some older browsers on some platforms
/// (see <https://bugzilla.mozilla.org/show_bug.cgi?id=1010527#c0>).
2021-02-12 16:57:53 +00:00
fn max_size_points ( & self ) -> egui ::Vec2 {
2022-03-19 12:47:30 +00:00
egui ::Vec2 ::INFINITY
2021-02-12 16:57:53 +00:00
}
2020-12-31 13:31:11 +00:00
/// Background color for the app, e.g. what is sent to `gl.clearColor`.
/// This is the background of your windows if you don't set a central panel.
2022-04-30 13:41:43 +00:00
fn clear_color ( & self , _visuals : & egui ::Visuals ) -> egui ::Rgba {
2020-12-31 13:31:11 +00:00
// NOTE: a bright gray makes the shadows of the windows look weird.
2021-03-31 18:53:13 +00:00
// We use a bit of transparency so that if the user switches on the
// `transparent()` option they get immediate results.
egui ::Color32 ::from_rgba_unmultiplied ( 12 , 12 , 12 , 180 ) . into ( )
2022-04-30 13:41:43 +00:00
// _visuals.window_fill() would also be a natural choice
2020-12-31 13:31:11 +00:00
}
2021-09-29 06:45:13 +00:00
2022-02-05 17:14:16 +00:00
/// Controls whether or not the native window position and size will be
2021-09-29 06:45:13 +00:00
/// persisted (only if the "persistence" feature is enabled).
fn persist_native_window ( & self ) -> bool {
true
}
2022-02-05 17:14:16 +00:00
/// Controls whether or not the egui memory (window positions etc) will be
2021-09-29 06:45:13 +00:00
/// persisted (only if the "persistence" feature is enabled).
fn persist_egui_memory ( & self ) -> bool {
true
}
2022-01-25 00:08:10 +00:00
/// If `true` a warm-up call to [`Self::update`] will be issued where
/// `ctx.memory().everything_is_visible()` will be set to `true`.
///
/// This can help pre-caching resources loaded by different parts of the UI, preventing stutter later on.
///
/// In this warm-up call, all painted shapes will be ignored.
///
/// The default is `false`, and it is unlikely you will want to change this.
fn warm_up_enabled ( & self ) -> bool {
false
}
2022-05-29 18:33:04 +00:00
/// Called each time after the rendering the UI.
///
/// Can be used to access pixel data with `get_pixels`
fn post_rendering ( & mut self , _window_size_px : [ u32 ; 2 ] , _frame : & Frame ) { }
2021-05-08 08:14:56 +00:00
}
2021-02-26 14:59:30 +00:00
2022-05-29 18:37:19 +00:00
/// Selects the level of hardware graphics acceleration.
2022-06-09 15:41:59 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-05-29 18:37:19 +00:00
#[ derive(Clone, Copy, Debug, PartialEq, Eq, Hash) ]
pub enum HardwareAcceleration {
/// Require graphics acceleration.
Required ,
/// Prefer graphics acceleration, but fall back to software.
Preferred ,
/// Do NOT use graphics acceleration.
///
/// On some platforms (MacOS) this is ignored and treated the same as [`Self::Preferred`].
Off ,
}
2021-12-28 16:33:49 +00:00
/// Options controlling the behavior of a native window.
///
/// Only a single native window is currently supported.
2022-06-09 15:41:59 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2021-05-08 08:14:56 +00:00
pub struct NativeOptions {
2022-09-17 09:20:40 +00:00
/// Sets whether or not the window will always be on top of other windows at initialization.
2021-05-08 08:19:47 +00:00
pub always_on_top : bool ,
2021-08-25 16:20:53 +00:00
/// Show window in maximized mode
pub maximized : bool ,
2021-05-08 08:19:47 +00:00
/// On desktop: add window decorations (i.e. a frame around your app)?
/// If false it will be difficult to move and resize the app.
pub decorated : bool ,
2022-07-29 12:21:23 +00:00
/// Start in (borderless) fullscreen?
///
/// Default: `false`.
pub fullscreen : bool ,
2022-09-16 12:31:21 +00:00
/// On Mac: the window doesn't have a titlebar, but floating window buttons.
///
/// See [winit's documentation][with_fullsize_content_view] for information on Mac-specific options.
///
/// [with_fullsize_content_view]: https://docs.rs/winit/latest/x86_64-apple-darwin/winit/platform/macos/trait.WindowBuilderExtMacOS.html#tymethod.with_fullsize_content_view
2022-10-21 06:55:56 +00:00
#[ cfg(target_os = " macos " ) ]
2022-09-16 12:31:21 +00:00
pub fullsize_content : bool ,
2022-03-07 09:33:59 +00:00
/// On Windows: enable drag and drop support. Drag and drop can
/// not be disabled on other platforms.
///
/// See [winit's documentation][drag_and_drop] for information on why you
/// might want to disable this on windows.
///
/// [drag_and_drop]: https://docs.rs/winit/latest/x86_64-pc-windows-msvc/winit/platform/windows/trait.WindowBuilderExtWindows.html#tymethod.with_drag_and_drop
2021-05-08 08:19:47 +00:00
pub drag_and_drop_support : bool ,
2021-02-26 14:59:30 +00:00
/// The application icon, e.g. in the Windows task bar etc.
2022-07-30 16:39:38 +00:00
///
/// This doesn't work on Mac and on Wayland.
/// See <https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_window_icon> for more.
2021-05-08 08:14:56 +00:00
pub icon_data : Option < IconData > ,
2022-02-05 18:12:03 +00:00
/// The initial (inner) position of the native window in points (logical pixels).
pub initial_window_pos : Option < egui ::Pos2 > ,
/// The initial inner size of the native window in points (logical pixels).
2021-05-08 08:14:56 +00:00
pub initial_window_size : Option < egui ::Vec2 > ,
2022-02-05 18:12:03 +00:00
/// The minimum inner window size
2022-02-02 15:47:27 +00:00
pub min_window_size : Option < egui ::Vec2 > ,
2022-02-05 18:12:03 +00:00
/// The maximum inner window size
2022-02-02 15:47:27 +00:00
pub max_window_size : Option < egui ::Vec2 > ,
2021-05-08 08:14:56 +00:00
/// Should the app window be resizable?
pub resizable : bool ,
2021-03-31 18:53:13 +00:00
/// On desktop: make the window transparent.
2021-05-08 08:14:56 +00:00
/// You control the transparency with [`App::clear_color()`].
2021-03-31 18:53:13 +00:00
/// You should avoid having a [`egui::CentralPanel`], or make sure its frame is also transparent.
2021-05-08 08:14:56 +00:00
pub transparent : bool ,
2022-03-23 10:13:57 +00:00
2022-10-02 06:45:37 +00:00
/// On desktop: mouse clicks pass through the window, used for non-interactable overlays
/// Generally you would use this in conjunction with always_on_top
pub mouse_passthrough : bool ,
2022-03-23 10:13:57 +00:00
/// Turn on vertical syncing, limiting the FPS to the display refresh rate.
///
/// The default is `true`.
pub vsync : bool ,
/// Set the level of the multisampling anti-aliasing (MSAA).
///
/// Must be a power-of-two. Higher = more smooth 3D.
///
/// A value of `0` turns it off (default).
///
/// `egui` already performs anti-aliasing via "feathering"
/// (controlled by [`egui::epaint::TessellationOptions`]),
/// but if you are embedding 3D in egui you may want to turn on multisampling.
pub multisampling : u16 ,
/// Sets the number of bits in the depth buffer.
///
/// `egui` doesn't need the depth buffer, so the default value is 0.
2022-09-06 12:37:07 +00:00
///
/// On `wgpu` backends, due to limited depth texture format options, this
/// will be interpreted as a boolean (non-zero = true) for whether or not
/// specifically a `Depth32Float` buffer is used.
2022-03-23 10:13:57 +00:00
pub depth_buffer : u8 ,
/// Sets the number of bits in the stencil buffer.
///
/// `egui` doesn't need the stencil buffer, so the default value is 0.
pub stencil_buffer : u8 ,
2022-05-12 07:02:28 +00:00
2022-09-06 12:37:07 +00:00
/// Specify whether or not hardware acceleration is preferred, required, or not.
2022-05-29 18:37:19 +00:00
///
/// Default: [`HardwareAcceleration::Preferred`].
pub hardware_acceleration : HardwareAcceleration ,
2022-05-28 15:53:05 +00:00
2022-05-12 07:02:28 +00:00
/// What rendering backend to use.
pub renderer : Renderer ,
2022-06-09 15:41:59 +00:00
2022-08-20 09:11:07 +00:00
/// Only used if the `dark-light` feature is enabled:
2022-06-09 15:41:59 +00:00
///
/// Try to detect and follow the system preferred setting for dark vs light mode.
///
/// By default, this is `true` on Mac and Windows, but `false` on Linux
/// due to <https://github.com/frewsxcv/rust-dark-light/issues/17>.
///
/// See also [`Self::default_theme`].
pub follow_system_theme : bool ,
/// Which theme to use in case [`Self::follow_system_theme`] is `false`
/// or the `dark-light` feature is disabled.
///
2022-08-20 09:11:07 +00:00
/// Default: [`Theme::Dark`].
2022-06-09 15:41:59 +00:00
pub default_theme : Theme ,
Continue execution after closing native eframe window (#1889)
This adds `NativeOptions::run_and_return` with default value `true`.
If `true`, execution will continue after the eframe window is closed. This is a new behavior introduced in this PR.
If `false`, the app will close once the eframe window is closed. The is the old behavior.
This is `true` by default, and the `false` option is only there so we can revert if we find any bugs.
When `true`, [`winit::platform::run_return::EventLoopExtRunReturn::run_return`](https://docs.rs/winit/latest/winit/platform/run_return/trait.EventLoopExtRunReturn.html#tymethod.run_return) is used. The winit docs warns of its usage, recommending `EventLoop::run`, but 🤷
When `false`, [`winit::event_loop::EventLoop::run`](https://docs.rs/winit/latest/winit/event_loop/struct.EventLoop.html#method.run) is used.
This is a really useful feature. You can now use `eframe` to quickly open up a window and show some data or options, and then continue your program after the `eframe` window is closed
My previous attempt at this caused some problems, but my new attempt seems to be working much better, at least on my Mac.
2022-08-05 06:20:31 +00:00
/// This controls what happens when you close the main eframe window.
///
/// If `true`, execution will continue after the eframe window is closed.
/// If `false`, the app will close once the eframe window is closed.
///
/// This is `true` by default, and the `false` option is only there
/// so we can revert if we find any bugs.
///
/// This feature was introduced in <https://github.com/emilk/egui/pull/1889>.
///
/// When `true`, [`winit::platform::run_return::EventLoopExtRunReturn::run_return`] is used.
/// When `false`, [`winit::event_loop::EventLoop::run`] is used.
pub run_and_return : bool ,
2022-08-23 12:43:22 +00:00
/// Hook into the building of an event loop before it is run.
///
/// Specify a callback here in case you need to make platform specific changes to the
/// event loop before it is run.
///
/// Note: A [`NativeOptions`] clone will not include any `event_loop_builder` hook.
pub event_loop_builder : Option < EventLoopBuilderHook > ,
2022-09-06 08:08:16 +00:00
#[ cfg(feature = " glow " ) ]
/// Needed for cross compiling for VirtualBox VMSVGA driver with OpenGL ES 2.0 and OpenGL 2.1 which doesn't support SRGB texture.
/// See <https://github.com/emilk/egui/pull/1993>.
///
/// For OpenGL ES 2.0: set this to [`egui_glow::ShaderVersion::Es100`] to solve blank texture problem (by using the "fallback shader").
pub shader_version : Option < egui_glow ::ShaderVersion > ,
2022-09-17 09:20:40 +00:00
/// On desktop: make the window position to be centered at initialization.
///
/// Platform specific:
///
/// Wayland desktop currently not supported.
pub centered : bool ,
2022-10-31 16:57:32 +00:00
/// Configures wgpu instance/device/adapter/surface creation and renderloop.
#[ cfg(feature = " wgpu " ) ]
pub wgpu_options : egui_wgpu ::WgpuConfiguration ,
2022-08-23 12:43:22 +00:00
}
#[ cfg(not(target_arch = " wasm32 " )) ]
impl Clone for NativeOptions {
fn clone ( & self ) -> Self {
Self {
icon_data : self . icon_data . clone ( ) ,
event_loop_builder : None , // Skip any builder callbacks if cloning
2022-10-31 16:57:32 +00:00
#[ cfg(feature = " wgpu " ) ]
wgpu_options : self . wgpu_options . clone ( ) ,
2022-08-23 12:43:22 +00:00
.. * self
}
}
2021-05-08 08:14:56 +00:00
}
2022-06-09 15:41:59 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2021-05-08 08:14:56 +00:00
impl Default for NativeOptions {
fn default ( ) -> Self {
Self {
2021-05-08 08:19:47 +00:00
always_on_top : false ,
2021-08-25 16:20:53 +00:00
maximized : false ,
2021-05-08 08:19:47 +00:00
decorated : true ,
2022-07-29 12:21:23 +00:00
fullscreen : false ,
2022-10-21 06:55:56 +00:00
#[ cfg(target_os = " macos " ) ]
2022-09-16 12:31:21 +00:00
fullsize_content : false ,
2022-03-07 09:33:59 +00:00
drag_and_drop_support : true ,
2021-05-08 08:14:56 +00:00
icon_data : None ,
2022-02-05 18:12:03 +00:00
initial_window_pos : None ,
2021-05-08 08:14:56 +00:00
initial_window_size : None ,
2022-02-02 15:47:27 +00:00
min_window_size : None ,
max_window_size : None ,
2021-05-08 08:14:56 +00:00
resizable : true ,
transparent : false ,
2022-10-02 06:45:37 +00:00
mouse_passthrough : false ,
2022-03-23 10:13:57 +00:00
vsync : true ,
multisampling : 0 ,
depth_buffer : 0 ,
stencil_buffer : 0 ,
2022-05-29 18:37:19 +00:00
hardware_acceleration : HardwareAcceleration ::Preferred ,
2022-05-12 07:02:28 +00:00
renderer : Renderer ::default ( ) ,
2022-06-09 15:41:59 +00:00
follow_system_theme : cfg ! ( target_os = " macos " ) | | cfg! ( target_os = " windows " ) ,
default_theme : Theme ::Dark ,
Continue execution after closing native eframe window (#1889)
This adds `NativeOptions::run_and_return` with default value `true`.
If `true`, execution will continue after the eframe window is closed. This is a new behavior introduced in this PR.
If `false`, the app will close once the eframe window is closed. The is the old behavior.
This is `true` by default, and the `false` option is only there so we can revert if we find any bugs.
When `true`, [`winit::platform::run_return::EventLoopExtRunReturn::run_return`](https://docs.rs/winit/latest/winit/platform/run_return/trait.EventLoopExtRunReturn.html#tymethod.run_return) is used. The winit docs warns of its usage, recommending `EventLoop::run`, but 🤷
When `false`, [`winit::event_loop::EventLoop::run`](https://docs.rs/winit/latest/winit/event_loop/struct.EventLoop.html#method.run) is used.
This is a really useful feature. You can now use `eframe` to quickly open up a window and show some data or options, and then continue your program after the `eframe` window is closed
My previous attempt at this caused some problems, but my new attempt seems to be working much better, at least on my Mac.
2022-08-05 06:20:31 +00:00
run_and_return : true ,
2022-08-23 12:43:22 +00:00
event_loop_builder : None ,
2022-09-06 08:08:16 +00:00
#[ cfg(feature = " glow " ) ]
shader_version : None ,
2022-09-17 09:20:40 +00:00
centered : false ,
2022-10-31 16:57:32 +00:00
#[ cfg(feature = " wgpu " ) ]
wgpu_options : egui_wgpu ::WgpuConfiguration ::default ( ) ,
2022-06-09 15:41:59 +00:00
}
}
}
#[ cfg(not(target_arch = " wasm32 " )) ]
impl NativeOptions {
/// The theme used by the system.
#[ cfg(feature = " dark-light " ) ]
pub fn system_theme ( & self ) -> Option < Theme > {
if self . follow_system_theme {
crate ::profile_scope! ( " dark_light::detect " ) ;
match dark_light ::detect ( ) {
dark_light ::Mode ::Dark = > Some ( Theme ::Dark ) ,
dark_light ::Mode ::Light = > Some ( Theme ::Light ) ,
}
} else {
None
}
}
/// The theme used by the system.
#[ cfg(not(feature = " dark-light " )) ]
pub fn system_theme ( & self ) -> Option < Theme > {
None
}
}
// ----------------------------------------------------------------------------
/// Options when using `eframe` in a web page.
#[ cfg(target_arch = " wasm32 " ) ]
pub struct WebOptions {
/// Try to detect and follow the system preferred setting for dark vs light mode.
///
/// See also [`Self::default_theme`].
///
2022-11-05 08:20:53 +00:00
/// Default: `true`.
2022-06-09 15:41:59 +00:00
pub follow_system_theme : bool ,
/// Which theme to use in case [`Self::follow_system_theme`] is `false`
/// or system theme detection fails.
///
/// Default: `Theme::Dark`.
pub default_theme : Theme ,
2022-07-08 08:40:44 +00:00
/// Which version of WebGl context to select
///
/// Default: [`WebGlContextOption::BestFirst`].
2022-10-05 18:14:18 +00:00
#[ cfg(feature = " glow " ) ]
2022-07-08 08:40:44 +00:00
pub webgl_context_option : WebGlContextOption ,
2022-10-31 16:57:32 +00:00
/// Configures wgpu instance/device/adapter/surface creation and renderloop.
#[ cfg(feature = " wgpu " ) ]
pub wgpu_options : egui_wgpu ::WgpuConfiguration ,
2022-06-09 15:41:59 +00:00
}
#[ cfg(target_arch = " wasm32 " ) ]
impl Default for WebOptions {
fn default ( ) -> Self {
Self {
follow_system_theme : true ,
default_theme : Theme ::Dark ,
2022-10-31 16:57:32 +00:00
2022-10-05 18:14:18 +00:00
#[ cfg(feature = " glow " ) ]
2022-07-08 08:40:44 +00:00
webgl_context_option : WebGlContextOption ::BestFirst ,
2022-10-31 16:57:32 +00:00
#[ cfg(feature = " wgpu " ) ]
wgpu_options : egui_wgpu ::WgpuConfiguration {
// WebGPU is not stable enough yet, use WebGL emulation
backends : wgpu ::Backends ::GL ,
device_descriptor : wgpu ::DeviceDescriptor {
label : Some ( " egui wgpu device " ) ,
features : wgpu ::Features ::default ( ) ,
limits : wgpu ::Limits {
// When using a depth buffer, we have to be able to create a texture
// large enough for the entire surface, and we want to support 4k+ displays.
max_texture_dimension_2d : 8192 ,
.. wgpu ::Limits ::downlevel_webgl2_defaults ( )
} ,
} ,
.. Default ::default ( )
} ,
2022-06-09 15:41:59 +00:00
}
}
}
// ----------------------------------------------------------------------------
/// Dark or Light theme.
#[ derive(Clone, Copy, Debug, PartialEq, Eq, Hash) ]
#[ cfg_attr(feature = " serde " , derive(serde::Deserialize, serde::Serialize)) ]
pub enum Theme {
/// Dark mode: light text on a dark background.
Dark ,
2022-08-02 15:26:33 +00:00
2022-06-09 15:41:59 +00:00
/// Light mode: dark text on a light background.
Light ,
}
impl Theme {
/// Get the egui visuals corresponding to this theme.
///
/// Use with [`egui::Context::set_visuals`].
pub fn egui_visuals ( self ) -> egui ::Visuals {
match self {
Self ::Dark = > egui ::Visuals ::dark ( ) ,
Self ::Light = > egui ::Visuals ::light ( ) ,
2022-05-12 07:02:28 +00:00
}
}
}
// ----------------------------------------------------------------------------
2022-07-24 15:13:12 +00:00
/// WebGL Context options
2022-07-08 08:40:44 +00:00
#[ derive(Clone, Copy, Debug, PartialEq, Eq, Hash) ]
#[ cfg_attr(feature = " serde " , derive(serde::Deserialize, serde::Serialize)) ]
pub enum WebGlContextOption {
/// Force Use WebGL1.
WebGl1 ,
2022-08-02 15:26:33 +00:00
2022-07-08 08:40:44 +00:00
/// Force use WebGL2.
WebGl2 ,
2022-08-02 15:26:33 +00:00
2022-07-08 08:40:44 +00:00
/// Use WebGl2 first.
BestFirst ,
2022-08-02 15:26:33 +00:00
2022-07-08 08:40:44 +00:00
/// Use WebGl1 first
CompatibilityFirst ,
}
// ----------------------------------------------------------------------------
2022-05-12 07:02:28 +00:00
/// What rendering backend to use.
///
/// You need to enable the "glow" and "wgpu" features to have a choice.
#[ derive(Clone, Copy, Debug, PartialEq, Eq) ]
#[ cfg_attr(feature = " serde " , derive(serde::Deserialize, serde::Serialize)) ]
#[ cfg_attr(feature = " serde " , serde(rename_all = " snake_case " )) ]
pub enum Renderer {
/// Use [`egui_glow`] renderer for [`glow`](https://github.com/grovesNL/glow).
#[ cfg(feature = " glow " ) ]
Glow ,
/// Use [`egui_wgpu`] renderer for [`wgpu`](https://github.com/gfx-rs/wgpu).
#[ cfg(feature = " wgpu " ) ]
Wgpu ,
}
impl Default for Renderer {
fn default ( ) -> Self {
#[ cfg(feature = " glow " ) ]
return Self ::Glow ;
#[ cfg(not(feature = " glow " )) ]
#[ cfg(feature = " wgpu " ) ]
return Self ::Wgpu ;
#[ cfg(not(feature = " glow " )) ]
#[ cfg(not(feature = " wgpu " )) ]
compile_error! ( " eframe: you must enable at least one of the rendering backend features: 'glow' or 'wgpu' " ) ;
}
}
impl std ::fmt ::Display for Renderer {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
match self {
#[ cfg(feature = " glow " ) ]
Self ::Glow = > " glow " . fmt ( f ) ,
#[ cfg(feature = " wgpu " ) ]
Self ::Wgpu = > " wgpu " . fmt ( f ) ,
}
}
}
impl std ::str ::FromStr for Renderer {
type Err = String ;
fn from_str ( name : & str ) -> Result < Self , String > {
match name . to_lowercase ( ) . as_str ( ) {
#[ cfg(feature = " glow " ) ]
" glow " = > Ok ( Self ::Glow ) ,
#[ cfg(feature = " wgpu " ) ]
" wgpu " = > Ok ( Self ::Wgpu ) ,
_ = > Err ( format! ( " eframe renderer {name:?} is not available. Make sure that the corresponding eframe feature is enabled. " ) )
2021-05-08 08:14:56 +00:00
}
2021-04-19 20:49:28 +00:00
}
2021-02-26 14:59:30 +00:00
}
2022-05-12 07:02:28 +00:00
// ----------------------------------------------------------------------------
2022-04-30 08:44:35 +00:00
/// Image data for an application icon.
2021-05-08 08:14:56 +00:00
#[ derive(Clone) ]
2021-02-26 14:59:30 +00:00
pub struct IconData {
2021-12-26 20:21:28 +00:00
/// RGBA pixels, unmultiplied.
2021-02-26 14:59:30 +00:00
pub rgba : Vec < u8 > ,
/// Image width. This should be a multiple of 4.
pub width : u32 ,
/// Image height. This should be a multiple of 4.
pub height : u32 ,
2020-07-23 16:54:16 +00:00
}
2020-12-31 13:31:11 +00:00
/// Represents the surroundings of your app.
///
/// It provides methods to inspect the surroundings (are we on the web?),
2021-09-03 19:04:43 +00:00
/// allocate textures, and change settings (e.g. window size).
2022-03-25 20:19:31 +00:00
pub struct Frame {
/// Information about the integration.
2022-07-29 12:37:23 +00:00
pub ( crate ) info : IntegrationInfo ,
2021-12-26 20:21:28 +00:00
2022-03-25 20:19:31 +00:00
/// Where the app can issue commands back to the integration.
2022-07-29 12:37:23 +00:00
pub ( crate ) output : backend ::AppOutput ,
2021-12-26 20:21:28 +00:00
2022-03-25 20:19:31 +00:00
/// A place where you can store custom data in a way that persists when you restart the app.
2022-07-29 12:37:23 +00:00
pub ( crate ) storage : Option < Box < dyn Storage > > ,
2022-03-27 13:20:45 +00:00
/// A reference to the underlying [`glow`] (OpenGL) context.
2022-05-12 07:02:28 +00:00
#[ cfg(feature = " glow " ) ]
2022-07-29 12:37:23 +00:00
pub ( crate ) gl : Option < std ::sync ::Arc < glow ::Context > > ,
2022-05-28 15:52:36 +00:00
2022-08-08 10:15:31 +00:00
/// Can be used to manage GPU resources for custom rendering with WGPU using [`egui::PaintCallback`]s.
2022-05-28 15:52:36 +00:00
#[ cfg(feature = " wgpu " ) ]
2022-08-08 10:15:31 +00:00
pub ( crate ) wgpu_render_state : Option < egui_wgpu ::RenderState > ,
2022-03-25 20:19:31 +00:00
}
2020-12-31 13:31:11 +00:00
2022-03-25 20:19:31 +00:00
impl Frame {
2020-12-31 13:31:11 +00:00
/// True if you are in a web environment.
2022-07-29 12:37:23 +00:00
///
/// Equivalent to `cfg!(target_arch = "wasm32")`
#[ allow(clippy::unused_self) ]
2020-12-31 13:31:11 +00:00
pub fn is_web ( & self ) -> bool {
2022-07-29 12:37:23 +00:00
cfg! ( target_arch = " wasm32 " )
2020-12-31 13:31:11 +00:00
}
2020-10-24 17:23:16 +00:00
/// Information about the integration.
2021-12-26 20:21:28 +00:00
pub fn info ( & self ) -> IntegrationInfo {
2022-03-25 20:19:31 +00:00
self . info . clone ( )
}
/// A place where you can store custom data in a way that persists when you restart the app.
pub fn storage ( & self ) -> Option < & dyn Storage > {
self . storage . as_deref ( )
}
/// A place where you can store custom data in a way that persists when you restart the app.
pub fn storage_mut ( & mut self ) -> Option < & mut ( dyn Storage + 'static ) > {
self . storage . as_deref_mut ( )
2020-12-31 13:31:11 +00:00
}
2022-03-27 13:20:45 +00:00
/// A reference to the underlying [`glow`] (OpenGL) context.
///
/// This can be used, for instance, to:
/// * Render things to offscreen buffers.
/// * Read the pixel buffer from the previous frame (`glow::Context::read_pixels`).
/// * Render things behind the egui windows.
///
/// Note that all egui painting is deferred to after the call to [`App::update`]
/// ([`egui`] only collects [`egui::Shape`]s and then eframe paints them all in one go later on).
2022-05-12 07:02:28 +00:00
///
/// To get a [`glow`] context you need to compile with the `glow` feature flag,
2022-08-08 10:15:31 +00:00
/// and run eframe using [`Renderer::Glow`].
2022-05-12 07:02:28 +00:00
#[ cfg(feature = " glow " ) ]
2022-05-22 15:43:30 +00:00
pub fn gl ( & self ) -> Option < & std ::sync ::Arc < glow ::Context > > {
2022-05-12 07:02:28 +00:00
self . gl . as_ref ( )
2022-03-27 13:20:45 +00:00
}
2022-08-08 10:15:31 +00:00
/// The underlying WGPU render state.
///
/// Only available when compiling with the `wgpu` feature and using [`Renderer::Wgpu`].
///
/// Can be used to manage GPU resources for custom rendering with WGPU using [`egui::PaintCallback`]s.
#[ cfg(feature = " wgpu " ) ]
pub fn wgpu_render_state ( & self ) -> Option < & egui_wgpu ::RenderState > {
self . wgpu_render_state . as_ref ( )
}
2022-08-20 14:08:59 +00:00
/// Tell `eframe` to close the desktop window.
///
/// The window will not close immediately, but at the end of the this frame.
///
/// Calling this will likely result in the app quitting, unless
/// you have more code after the call to [`crate::run_native`].
#[ cfg(not(target_arch = " wasm32 " )) ]
#[ doc(alias = " exit " ) ]
#[ doc(alias = " quit " ) ]
pub fn close ( & mut self ) {
self . output . close = true ;
}
/// Tell `eframe` to close the desktop window.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-08-20 14:08:59 +00:00
#[ deprecated = " Renamed `close` " ]
2022-03-25 20:19:31 +00:00
pub fn quit ( & mut self ) {
2022-08-20 14:08:59 +00:00
self . close ( ) ;
2020-12-31 13:31:11 +00:00
}
/// Set the desired inner size of the window (in egui points).
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-03-25 20:19:31 +00:00
pub fn set_window_size ( & mut self , size : egui ::Vec2 ) {
self . output . window_size = Some ( size ) ;
2020-12-31 13:31:11 +00:00
}
2021-10-22 22:03:17 +00:00
/// Set the desired title of the window.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-03-25 20:19:31 +00:00
pub fn set_window_title ( & mut self , title : & str ) {
self . output . window_title = Some ( title . to_owned ( ) ) ;
2021-10-22 22:03:17 +00:00
}
2021-09-07 19:42:14 +00:00
/// Set whether to show window decorations (i.e. a frame around you app).
2022-07-29 12:21:23 +00:00
///
2021-09-07 19:42:14 +00:00
/// If false it will be difficult to move and resize the app.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-03-25 20:19:31 +00:00
pub fn set_decorations ( & mut self , decorated : bool ) {
self . output . decorated = Some ( decorated ) ;
2021-09-07 19:42:14 +00:00
}
2022-07-29 12:21:23 +00:00
/// Turn borderless fullscreen on/off (native only).
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-07-29 12:21:23 +00:00
pub fn set_fullscreen ( & mut self , fullscreen : bool ) {
self . output . fullscreen = Some ( fullscreen ) ;
}
2022-07-29 12:37:23 +00:00
/// set the position of the outer window.
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-04-16 20:27:22 +00:00
pub fn set_window_pos ( & mut self , pos : egui ::Pos2 ) {
self . output . window_pos = Some ( pos ) ;
}
2021-09-28 15:34:58 +00:00
/// When called, the native window will follow the
/// movement of the cursor while the primary mouse button is down.
///
2021-12-26 20:21:28 +00:00
/// Does not work on the web.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-03-25 20:19:31 +00:00
pub fn drag_window ( & mut self ) {
self . output . drag_window = true ;
2021-09-28 15:34:58 +00:00
}
2022-07-21 18:16:56 +00:00
/// Set the visibility of the window.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-07-21 18:16:56 +00:00
pub fn set_visible ( & mut self , visible : bool ) {
self . output . visible = Some ( visible ) ;
}
2022-09-17 09:20:40 +00:00
/// On desktop: Set the window always on top.
///
/// (Wayland desktop currently not supported)
#[ cfg(not(target_arch = " wasm32 " )) ]
pub fn set_always_on_top ( & mut self , always_on_top : bool ) {
self . output . always_on_top = Some ( always_on_top ) ;
}
/// On desktop: Set the window to be centered.
///
/// (Wayland desktop currently not supported)
#[ cfg(not(target_arch = " wasm32 " )) ]
pub fn set_centered ( & mut self ) {
if let Some ( monitor_size ) = self . info . window_info . monitor_size {
let inner_size = self . info . window_info . size ;
if monitor_size . x > 1.0 & & monitor_size . y > 1.0 {
let x = ( monitor_size . x - inner_size . x ) / 2.0 ;
let y = ( monitor_size . y - inner_size . y ) / 2.0 ;
self . set_window_pos ( egui ::Pos2 { x , y } ) ;
}
}
}
2021-12-26 20:21:28 +00:00
/// for integrations only: call once per frame
2022-07-29 12:37:23 +00:00
pub ( crate ) fn take_app_output ( & mut self ) -> backend ::AppOutput {
2022-03-25 20:19:31 +00:00
std ::mem ::take ( & mut self . output )
2020-12-31 13:31:11 +00:00
}
2020-10-24 17:23:16 +00:00
}
2021-01-17 09:52:01 +00:00
/// Information about the web environment (if applicable).
2020-10-17 21:54:46 +00:00
#[ derive(Clone, Debug) ]
2022-07-29 12:37:23 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
2020-07-23 16:54:16 +00:00
pub struct WebInfo {
2022-10-31 11:58:26 +00:00
/// The browser user agent.
pub user_agent : String ,
2022-02-17 15:46:43 +00:00
/// Information about the URL.
pub location : Location ,
}
2022-05-13 08:15:43 +00:00
/// Information about the application's main window, if available.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-05-13 08:15:43 +00:00
#[ derive(Clone, Debug) ]
pub struct WindowInfo {
/// Coordinates of the window's outer top left corner, relative to the top left corner of the first display.
2022-07-29 12:37:23 +00:00
///
2022-05-13 08:15:43 +00:00
/// Unit: egui points (logical pixels).
2022-07-29 12:37:23 +00:00
///
/// `None` = unknown.
pub position : Option < egui ::Pos2 > ,
2022-05-13 08:15:43 +00:00
2022-07-29 12:21:23 +00:00
/// Are we in fullscreen mode?
pub fullscreen : bool ,
2022-05-13 08:15:43 +00:00
/// Window inner size in egui points (logical pixels).
pub size : egui ::Vec2 ,
2022-09-17 09:20:40 +00:00
/// Current monitor size in egui points (logical pixels)
pub monitor_size : Option < egui ::Vec2 > ,
2022-05-13 08:15:43 +00:00
}
2022-02-17 15:46:43 +00:00
/// Information about the URL.
///
/// Everything has been percent decoded (`%20` -> ` ` etc).
2022-07-29 12:37:23 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
2022-02-17 15:46:43 +00:00
#[ derive(Clone, Debug) ]
pub struct Location {
/// The full URL (`location.href`) without the hash.
///
2022-02-19 19:51:51 +00:00
/// Example: `"http://www.example.com:80/index.html?foo=bar"`.
2022-02-17 15:46:43 +00:00
pub url : String ,
/// `location.protocol`
///
2022-02-19 19:51:51 +00:00
/// Example: `"http:"`.
2022-02-17 15:46:43 +00:00
pub protocol : String ,
/// `location.host`
///
2022-02-19 19:51:51 +00:00
/// Example: `"example.com:80"`.
2022-02-17 15:46:43 +00:00
pub host : String ,
/// `location.hostname`
///
2022-02-19 19:51:51 +00:00
/// Example: `"example.com"`.
2022-02-17 15:46:43 +00:00
pub hostname : String ,
/// `location.port`
///
2022-02-19 19:51:51 +00:00
/// Example: `"80"`.
2022-02-17 15:46:43 +00:00
pub port : String ,
/// The "#fragment" part of "www.example.com/index.html?query#fragment".
///
2021-01-01 16:11:05 +00:00
/// Note that the leading `#` is included in the string.
2021-01-01 20:27:10 +00:00
/// Also known as "hash-link" or "anchor".
2022-02-17 15:46:43 +00:00
pub hash : String ,
/// The "query" part of "www.example.com/index.html?query#fragment".
///
/// Note that the leading `?` is NOT included in the string.
///
2022-05-23 15:25:31 +00:00
/// Use [`Self::query_map`] to get the parsed version of it.
2022-02-17 15:46:43 +00:00
pub query : String ,
/// The parsed "query" part of "www.example.com/index.html?query#fragment".
///
/// "foo=42&bar%20" is parsed as `{"foo": "42", "bar ": ""}`
pub query_map : std ::collections ::BTreeMap < String , String > ,
/// `location.origin`
///
2022-02-19 19:51:51 +00:00
/// Example: `"http://www.example.com:80"`.
2022-02-17 15:46:43 +00:00
pub origin : String ,
2020-07-23 16:54:16 +00:00
}
2020-10-24 17:23:16 +00:00
/// Information about the integration passed to the use app each frame.
2020-10-17 21:54:46 +00:00
#[ derive(Clone, Debug) ]
2020-10-24 17:23:16 +00:00
pub struct IntegrationInfo {
2022-07-29 12:37:23 +00:00
/// Information about the surrounding web environment.
#[ cfg(target_arch = " wasm32 " ) ]
pub web_info : WebInfo ,
2020-07-23 16:54:16 +00:00
2022-06-09 15:41:59 +00:00
/// Does the OS use dark or light mode?
///
2021-06-07 18:56:18 +00:00
/// `None` means "don't know".
2022-06-09 15:41:59 +00:00
pub system_theme : Option < Theme > ,
2021-06-07 18:56:18 +00:00
2020-10-01 20:25:44 +00:00
/// Seconds of cpu usage (in seconds) of UI code on the previous frame.
2020-10-17 10:33:30 +00:00
/// `None` if this is the first frame.
pub cpu_usage : Option < f32 > ,
2020-07-23 16:54:16 +00:00
2020-10-17 21:54:46 +00:00
/// The OS native pixels-per-point
pub native_pixels_per_point : Option < f32 > ,
2022-05-13 08:15:43 +00:00
2022-07-29 12:37:23 +00:00
/// The position and size of the native window.
#[ cfg(not(target_arch = " wasm32 " )) ]
pub window_info : WindowInfo ,
2020-10-17 10:33:30 +00:00
}
2020-09-23 06:57:23 +00:00
2020-12-29 13:15:46 +00:00
// ----------------------------------------------------------------------------
2020-07-23 16:54:16 +00:00
/// A place where you can store custom data in a way that persists when you restart the app.
///
/// On the web this is backed by [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
/// On desktop this is backed by the file system.
2022-04-30 08:44:35 +00:00
///
/// See [`CreationContext::storage`] and [`App::save`].
2020-07-23 16:54:16 +00:00
pub trait Storage {
2020-12-31 13:31:11 +00:00
/// Get the value for the given key.
2020-12-19 13:58:00 +00:00
fn get_string ( & self , key : & str ) -> Option < String > ;
2022-08-02 15:26:33 +00:00
2020-12-31 13:31:11 +00:00
/// Set the value for the given key.
2020-07-23 16:54:16 +00:00
fn set_string ( & mut self , key : & str , value : String ) ;
2020-10-19 18:25:05 +00:00
/// write-to-disk or similar
fn flush ( & mut self ) ;
2020-07-23 16:54:16 +00:00
}
2020-10-19 18:12:14 +00:00
/// Stores nothing.
#[ derive(Clone, Default) ]
2022-04-30 08:44:35 +00:00
pub ( crate ) struct DummyStorage { }
2020-10-19 18:12:14 +00:00
impl Storage for DummyStorage {
2020-12-19 13:58:00 +00:00
fn get_string ( & self , _key : & str ) -> Option < String > {
2020-10-19 18:12:14 +00:00
None
}
2022-08-02 15:26:33 +00:00
2020-10-19 18:12:14 +00:00
fn set_string ( & mut self , _key : & str , _value : String ) { }
2022-08-02 15:26:33 +00:00
2020-10-19 18:25:05 +00:00
fn flush ( & mut self ) { }
2020-10-19 18:12:14 +00:00
}
2021-06-12 20:17:57 +00:00
/// Get and deserialize the [RON](https://github.com/ron-rs/ron) stored at the given key.
2021-04-05 10:09:01 +00:00
#[ cfg(feature = " ron " ) ]
2020-07-23 16:54:16 +00:00
pub fn get_value < T : serde ::de ::DeserializeOwned > ( storage : & dyn Storage , key : & str ) -> Option < T > {
storage
. get_string ( key )
2021-04-05 10:09:01 +00:00
. and_then ( | value | ron ::from_str ( & value ) . ok ( ) )
2020-07-23 16:54:16 +00:00
}
2021-04-15 07:48:06 +00:00
/// Serialize the given value as [RON](https://github.com/ron-rs/ron) and store with the given key.
2021-04-05 10:09:01 +00:00
#[ cfg(feature = " ron " ) ]
2020-07-23 16:54:16 +00:00
pub fn set_value < T : serde ::Serialize > ( storage : & mut dyn Storage , key : & str , value : & T ) {
2022-08-19 10:04:43 +00:00
match ron ::ser ::to_string ( value ) {
Ok ( string ) = > storage . set_string ( key , string ) ,
Err ( err ) = > tracing ::error! ( " eframe failed to encode data using ron: {} " , err ) ,
}
2020-07-23 16:54:16 +00:00
}
2020-12-31 13:31:11 +00:00
/// [`Storage`] key used for app
2020-07-23 16:54:16 +00:00
pub const APP_KEY : & str = " app " ;
2020-12-30 19:56:50 +00:00
// ----------------------------------------------------------------------------
2020-12-31 13:31:11 +00:00
/// You only need to look here if you are writing a backend for `epi`.
2022-07-29 12:37:23 +00:00
pub ( crate ) mod backend {
2020-12-31 13:31:11 +00:00
/// Action that can be taken by the user app.
2022-03-25 20:19:31 +00:00
#[ derive(Clone, Debug, Default) ]
2021-12-26 20:21:28 +00:00
#[ must_use ]
2020-12-31 13:31:11 +00:00
pub struct AppOutput {
2022-08-20 14:08:59 +00:00
/// Set to `true` to close the native window (which often quits the app).
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-08-20 14:08:59 +00:00
pub close : bool ,
2020-12-31 13:31:11 +00:00
/// Set to some size to resize the outer window (e.g. glium window) to this size.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2020-12-31 13:31:11 +00:00
pub window_size : Option < egui ::Vec2 > ,
2021-09-07 19:42:14 +00:00
2021-10-22 22:03:17 +00:00
/// Set to some string to rename the outer window (e.g. glium window) to this title.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2021-10-22 22:03:17 +00:00
pub window_title : Option < String > ,
2021-12-26 20:21:28 +00:00
/// Set to some bool to change window decorations.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2021-09-07 19:42:14 +00:00
pub decorated : Option < bool > ,
2021-09-28 15:34:58 +00:00
2022-07-29 12:21:23 +00:00
/// Set to some bool to change window fullscreen.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ] // TODO: implement fullscreen on web
2022-07-29 12:21:23 +00:00
pub fullscreen : Option < bool > ,
2021-12-26 20:21:28 +00:00
/// Set to true to drag window while primary mouse button is down.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2021-09-28 15:34:58 +00:00
pub drag_window : bool ,
2022-04-16 20:27:22 +00:00
/// Set to some position to move the outer window (e.g. glium window) to this position
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-04-16 20:27:22 +00:00
pub window_pos : Option < egui ::Pos2 > ,
2022-07-21 18:16:56 +00:00
/// Set to some bool to change window visibility.
2022-07-29 12:37:23 +00:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2022-07-21 18:16:56 +00:00
pub visible : Option < bool > ,
2022-09-17 09:20:40 +00:00
/// Set to some bool to tell the window always on top.
#[ cfg(not(target_arch = " wasm32 " )) ]
pub always_on_top : Option < bool > ,
2020-12-31 13:31:11 +00:00
}
2020-12-30 19:56:50 +00:00
}