1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 05:10:03 -04:00

Merge branch 'master' of https://github.com/emilk/egui into multiples_viewports

This commit is contained in:
Konkitoman
2023-09-30 09:39:45 +03:00
86 changed files with 2288 additions and 1413 deletions

View File

@@ -14,6 +14,15 @@ pub struct IconData {
pub height: u32,
}
impl std::fmt::Debug for IconData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IconData")
.field("width", &self.width)
.field("height", &self.height)
.finish_non_exhaustive()
}
}
impl IconData {
/// Convert into [`image::RgbaImage`]
///

View File

@@ -9,6 +9,7 @@
#[cfg(not(target_arch = "wasm32"))]
mod icon_data;
use egui::ViewportBuilder;
#[cfg(not(target_arch = "wasm32"))]
pub use icon_data::IconData;
@@ -28,7 +29,7 @@ use static_assertions::assert_not_impl_any;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub use winit::event_loop::EventLoopBuilder;
pub use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
/// Hook into the building of an event loop before it is run
///
@@ -38,6 +39,14 @@ pub use winit::event_loop::EventLoopBuilder;
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub type EventLoopBuilderHook = Box<dyn FnOnce(&mut EventLoopBuilder<UserEvent>)>;
/// Hook into the building of a the native window.
///
/// You can configure any platform specific details required on top of the default configuration
/// done by `eframe`.
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub type WindowBuilderHook = Box<dyn FnOnce(ViewportBuilder) -> ViewportBuilder>;
/// This is how your app is created.
///
/// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc.
@@ -182,13 +191,6 @@ pub trait App {
std::time::Duration::from_secs(30)
}
/// The size limit of the web app canvas.
///
/// By default the max size is [`egui::Vec2::INFINITY`], i.e. unlimited.
fn max_size_points(&self) -> egui::Vec2 {
egui::Vec2::INFINITY
}
/// Background color values 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.
@@ -208,12 +210,6 @@ pub trait App {
// _visuals.window_fill() would also be a natural choice
}
/// Controls whether or not the native window position and size will be
/// persisted (only if the "persistence" feature is enabled).
fn persist_native_window(&self) -> bool {
true
}
/// Controls whether or not the egui memory (window positions etc) will be
/// persisted (only if the "persistence" feature is enabled).
fn persist_egui_memory(&self) -> bool {
@@ -313,6 +309,7 @@ pub struct NativeOptions {
pub resizable: bool,
/// On desktop: make the window transparent.
///
/// You control the transparency with [`App::clear_color()`].
/// You should avoid having a [`egui::CentralPanel`], or make sure its frame is also transparent.
pub transparent: bool,
@@ -397,6 +394,15 @@ pub struct NativeOptions {
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub event_loop_builder: Option<EventLoopBuilderHook>,
/// Hook into the building of a window.
///
/// Specify a callback here in case you need to make platform specific changes to the
/// window appearance.
///
/// Note: A [`NativeOptions`] clone will not include any `window_builder` hook.
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub window_builder: Option<WindowBuilderHook>,
#[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>.
@@ -455,6 +461,10 @@ pub struct NativeOptions {
/// }
/// ```
pub app_id: Option<String>,
/// Controls whether or not the native window position and size will be
/// persisted (only if the "persistence" feature is enabled).
pub persist_window: bool,
}
#[cfg(not(target_arch = "wasm32"))]
@@ -466,6 +476,9 @@ impl Clone for NativeOptions {
#[cfg(any(feature = "glow", feature = "wgpu"))]
event_loop_builder: None, // Skip any builder callbacks if cloning
#[cfg(any(feature = "glow", feature = "wgpu"))]
window_builder: None, // Skip any builder callbacks if cloning
#[cfg(feature = "wgpu")]
wgpu_options: self.wgpu_options.clone(),
@@ -520,6 +533,9 @@ impl Default for NativeOptions {
#[cfg(any(feature = "glow", feature = "wgpu"))]
event_loop_builder: None,
#[cfg(any(feature = "glow", feature = "wgpu"))]
window_builder: None,
#[cfg(feature = "glow")]
shader_version: None,
@@ -529,6 +545,8 @@ impl Default for NativeOptions {
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
app_id: None,
persist_window: true,
}
}
}
@@ -566,6 +584,11 @@ pub struct WebOptions {
/// Configures wgpu instance/device/adapter/surface creation and renderloop.
#[cfg(feature = "wgpu")]
pub wgpu_options: egui_wgpu::WgpuConfiguration,
/// The size limit of the web app canvas.
///
/// By default the max size is [`egui::Vec2::INFINITY`], i.e. unlimited.
pub max_size_points: egui::Vec2,
}
#[cfg(target_arch = "wasm32")]
@@ -581,6 +604,8 @@ impl Default for WebOptions {
#[cfg(feature = "wgpu")]
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
max_size_points: egui::Vec2::INFINITY,
}
}
}
@@ -1164,7 +1189,8 @@ pub fn get_value<T: serde::de::DeserializeOwned>(storage: &dyn Storage, key: &st
.and_then(|value| match ron::from_str(&value) {
Ok(value) => Some(value),
Err(err) => {
log::warn!("Failed to decode RON: {err}");
// This happens on when we break the format, e.g. when updating egui.
log::debug!("Failed to decode RON: {err}");
None
}
})

View File

@@ -280,7 +280,7 @@ pub fn run_simple_native(
update_fun: U,
}
impl<U: FnMut(&egui::Context, &mut Frame)> App for SimpleApp<U> {
impl<U: FnMut(&egui::Context, &mut Frame) + 'static> App for SimpleApp<U> {
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
(self.update_fun)(ctx, frame);
}

View File

@@ -70,7 +70,7 @@ pub fn read_window_info(
pub fn window_builder<E>(
event_loop: &EventLoopWindowTarget<E>,
title: &str,
native_options: &epi::NativeOptions,
native_options: &mut epi::NativeOptions,
window_settings: Option<WindowSettings>,
) -> ViewportBuilder {
let epi::NativeOptions {
@@ -173,7 +173,10 @@ pub fn window_builder<E>(
}
}
window_builder
match std::mem::take(&mut native_options.window_builder) {
Some(hook) => hook(window_builder),
None => window_builder,
}
}
pub fn apply_native_options_to_window(
@@ -326,6 +329,8 @@ pub struct EpiIntegration {
can_drag_window: bool,
window_state: WindowState,
follow_system_theme: bool,
#[cfg(feature = "persistence")]
persist_window: bool,
app_icon_setter: super::app_icon::AppTitleIconSetter,
}
@@ -388,6 +393,8 @@ impl EpiIntegration {
can_drag_window: false,
window_state,
follow_system_theme: native_options.follow_system_theme,
#[cfg(feature = "persistence")]
persist_window: native_options.persist_window,
app_icon_setter,
beginning: Instant::now(),
}
@@ -578,7 +585,7 @@ impl EpiIntegration {
crate::profile_function!();
if let Some(window) = _window {
if _app.persist_native_window() {
if self.persist_window {
crate::profile_scope!("native_window");
epi::set_value(
storage,

View File

@@ -130,6 +130,7 @@ fn save_to_disk(file_path: &PathBuf, kv: &HashMap<String, String>) {
let mut writer = std::io::BufWriter::new(file);
let config = Default::default();
crate::profile_scope!("ron::serialize");
if let Err(err) = ron::ser::to_writer_pretty(&mut writer, &kv, config)
.and_then(|_| writer.flush().map_err(|err| err.into()))
{

View File

@@ -895,7 +895,7 @@ mod glow_integration {
event_loop: &EventLoopWindowTarget<UserEvent>,
storage: Option<&dyn epi::Storage>,
title: &str,
native_options: &NativeOptions,
native_options: &mut NativeOptions,
) -> Result<(GlutinWindowContext, glow::Context)> {
crate::profile_function!();
@@ -945,7 +945,7 @@ mod glow_integration {
event_loop,
storage.as_deref(),
&self.app_name,
&self.native_options,
&mut self.native_options,
)?;
let gl = Arc::new(gl);
@@ -1944,7 +1944,7 @@ mod wgpu_integration {
event_loop: &EventLoopWindowTarget<UserEvent>,
storage: Option<&dyn epi::Storage>,
title: &str,
native_options: &NativeOptions,
native_options: &mut NativeOptions,
) -> std::result::Result<(winit::window::Window, ViewportBuilder), winit::error::OsError>
{
crate::profile_function!();
@@ -2556,7 +2556,7 @@ mod wgpu_integration {
event_loop,
running.integration.read().frame.storage(),
&self.app_name,
&self.native_options,
&mut self.native_options,
)?;
self.set_window(ViewportId::MAIN)?;
}
@@ -2571,7 +2571,7 @@ mod wgpu_integration {
event_loop,
storage.as_deref(),
&self.app_name,
&self.native_options,
&mut self.native_options,
)?;
self.init_run_state(event_loop, storage, window, builder)?;
}

View File

@@ -7,6 +7,7 @@ use crate::{epi, App};
use super::{now_sec, web_painter::WebPainter, NeedRepaint};
pub struct AppRunner {
web_options: crate::WebOptions,
pub(crate) frame: epi::Frame,
egui_ctx: egui::Context,
painter: super::ActiveWebPainter,
@@ -99,6 +100,7 @@ impl AppRunner {
}
let mut runner = Self {
web_options,
frame,
egui_ctx,
painter,
@@ -175,7 +177,7 @@ impl AppRunner {
pub fn logic(&mut self) -> (std::time::Duration, Vec<egui::ClippedPrimitive>) {
let frame_start = now_sec();
super::resize_canvas_to_screen_size(self.canvas_id(), self.app.max_size_points());
super::resize_canvas_to_screen_size(self.canvas_id(), self.web_options.max_size_points);
let canvas_size = super::canvas_size_in_points(self.canvas_id());
let raw_input = self.input.new_frame(canvas_size);