Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use egui::ViewportBuilder in eframe::NativeOptions #3572

Merged
merged 22 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
"--workspace",
"--message-format=json",
"--all-targets",
"--all-features",
],
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"cargo",
"check",
"cranky",
"--quiet",
"--target-dir=target_ra",
"--workspace",
"--message-format=json",
"--all-targets",
"--all-features",
],
}
162 changes: 22 additions & 140 deletions crates/eframe/src/epi/mod.rs → crates/eframe/src/epi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@

#![warn(missing_docs)] // Let's keep `epi` well-documented.

#[cfg(not(target_arch = "wasm32"))]
mod icon_data;

#[cfg(not(target_arch = "wasm32"))]
pub use icon_data::IconData;

#[cfg(target_arch = "wasm32")]
use std::any::Any;

Expand Down Expand Up @@ -250,74 +244,23 @@ pub enum HardwareAcceleration {

/// Options controlling the behavior of a native window.
///
/// Only a single native window is currently supported.
/// Addintional windows can be opened using (egui viewports)[`egui::viewport`].
///
/// Set the window title and size using [`Self::viewport`].
///
/// ### Application id
/// [`egui::ViewportBuilder::with_app_id`] is used for determining the folder to persist the app to.
///
/// On native the path is picked using [`crate::storage_dir`].
///
/// If you don't set an app id, the title argument to [`crate::run_native`]
/// will be used as app id instead.
#[cfg(not(target_arch = "wasm32"))]
pub struct NativeOptions {
/// Sets whether or not the window will always be on top of other windows at initialization.
pub always_on_top: bool,

/// Show window in maximized mode
pub maximized: 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.
pub decorated: bool,

/// Start in (borderless) fullscreen?
/// Controls the native window of the root viewport.
///
/// Default: `false`.
pub fullscreen: bool,

/// 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
#[cfg(target_os = "macos")]
pub fullsize_content: bool,

/// 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
pub drag_and_drop_support: bool,

/// The application icon, e.g. in the Windows task bar or the alt-tab menu.
///
/// The default icon is a white `e` on a black background (for "egui" or "eframe").
/// If you prefer the OS default, set this to `None`.
pub icon_data: Option<IconData>,

/// 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).
pub initial_window_size: Option<egui::Vec2>,

/// The minimum inner window size in points (logical pixels).
pub min_window_size: Option<egui::Vec2>,

/// The maximum inner window size in points (logical pixels).
pub max_window_size: Option<egui::Vec2>,

/// Should the app window be resizable?
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,

/// 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,

/// Whether grant focus when window initially opened. True by default.
pub active: bool,
/// This is where you set things like window title and size.
pub viewport: egui::ViewportBuilder,

/// Turn on vertical syncing, limiting the FPS to the display refresh rate.
///
Expand Down Expand Up @@ -419,47 +362,6 @@ pub struct NativeOptions {
#[cfg(feature = "wgpu")]
pub wgpu_options: egui_wgpu::WgpuConfiguration,

/// The application id, used for determining the folder to persist the app to.
///
/// On native the path is picked using [`crate::storage_dir`].
///
/// If you don't set [`Self::app_id`], the title argument to [`crate::run_native`]
/// will be used as app id instead.
///
/// ### On Wayland
/// On Wayland this sets the Application ID for the window.
///
/// The application ID is used in several places of the compositor, e.g. for
/// grouping windows of the same application. It is also important for
/// connecting the configuration of a `.desktop` file with the window, by
/// using the application ID as file name. This allows e.g. a proper icon
/// handling under Wayland.
///
/// See [Waylands XDG shell documentation][xdg-shell] for more information
/// on this Wayland-specific option.
///
/// [xdg-shell]: https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_app_id
///
/// # Example
/// ``` no_run
/// fn main() -> eframe::Result<()> {
///
/// let mut options = eframe::NativeOptions::default();
/// // Set the application ID for Wayland only on Linux
/// #[cfg(target_os = "linux")]
/// {
/// options.app_id = Some("egui-example".to_string());
/// }
///
/// eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.heading("My egui Application");
/// });
/// })
/// }
/// ```
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,
Expand All @@ -469,7 +371,7 @@ pub struct NativeOptions {
impl Clone for NativeOptions {
fn clone(&self) -> Self {
Self {
icon_data: self.icon_data.clone(),
viewport: self.viewport.clone(),

#[cfg(any(feature = "glow", feature = "wgpu"))]
event_loop_builder: None, // Skip any builder callbacks if cloning
Expand All @@ -480,8 +382,6 @@ impl Clone for NativeOptions {
#[cfg(feature = "wgpu")]
wgpu_options: self.wgpu_options.clone(),

app_id: self.app_id.clone(),

..*self
}
}
Expand All @@ -491,29 +391,13 @@ impl Clone for NativeOptions {
impl Default for NativeOptions {
fn default() -> Self {
Self {
always_on_top: false,
maximized: false,
decorated: true,
fullscreen: false,

#[cfg(target_os = "macos")]
fullsize_content: false,

// We set a default "egui" or "eframe" icon, which is usually more distinctive than the default OS icon.
icon_data: Some(
IconData::try_from_png_bytes(&include_bytes!("../../data/icon.png")[..]).unwrap(),
),

drag_and_drop_support: true,
initial_window_pos: None,
initial_window_size: None,
min_window_size: None,
max_window_size: None,
resizable: true,
transparent: false,
mouse_passthrough: false,

active: true,
viewport: egui::ViewportBuilder {
icon: Some(std::sync::Arc::new(
crate::icon_data::from_png_bytes(&include_bytes!("../data/icon.png")[..])
.unwrap(),
)),
..Default::default()
},

vsync: true,
multisampling: 0,
Expand Down Expand Up @@ -542,8 +426,6 @@ impl Default for NativeOptions {
#[cfg(feature = "wgpu")]
wgpu_options: egui_wgpu::WgpuConfiguration::default(),

app_id: None,

persist_window: true,
}
}
Expand Down
76 changes: 0 additions & 76 deletions crates/eframe/src/epi/icon_data.rs

This file was deleted.

62 changes: 62 additions & 0 deletions crates/eframe/src/icon_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//! Helpers for loading [`egui::IconData`].

use egui::IconData;

/// Helpers for working with [`IconData`].
pub trait IconDataExt {
/// Convert into [`image::RgbaImage`]
///
/// # Errors
/// If `width*height != 4 * rgba.len()`, or if the image is too big.
fn to_image(&self) -> Result<image::RgbaImage, String>;

/// Encode as PNG.
///
/// # Errors
/// The image is invalid, or the PNG encoder failed.
fn to_png_bytes(&self) -> Result<Vec<u8>, String>;
}

/// Load the contents of .png file.
///
/// # Errors
/// If this is not a valid png.
pub fn from_png_bytes(png_bytes: &[u8]) -> Result<IconData, image::ImageError> {
crate::profile_function!();
let image = image::load_from_memory(png_bytes)?;
Ok(from_image(image))
}

fn from_image(image: image::DynamicImage) -> IconData {
let image = image.into_rgba8();
IconData {
width: image.width(),
height: image.height(),
rgba: image.into_raw(),
}
}

impl IconDataExt for IconData {
fn to_image(&self) -> Result<image::RgbaImage, String> {
crate::profile_function!();
let Self {
rgba,
width,
height,
} = self.clone();
image::RgbaImage::from_raw(width, height, rgba).ok_or_else(|| "Invalid IconData".to_owned())
}

fn to_png_bytes(&self) -> Result<Vec<u8>, String> {
crate::profile_function!();
let image = self.to_image()?;
let mut png_bytes: Vec<u8> = Vec::new();
image
.write_to(
&mut std::io::Cursor::new(&mut png_bytes),
image::ImageOutputFormat::Png,
)
.map_err(|err| err.to_string())?;
Ok(png_bytes)
}
}
Loading
Loading