1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 07:03:14 -04:00

Remove Option<Option<X>> and simplify ViewportBuilder

This commit is contained in:
Emil Ernerfeldt
2023-11-15 18:22:30 +01:00
parent d21458d166
commit e36ef75f68
6 changed files with 64 additions and 63 deletions

View File

@@ -1,4 +1,4 @@
use std::{sync::Arc, time::Instant};
use std::time::Instant;
use winit::event_loop::EventLoopWindowTarget;
@@ -92,17 +92,19 @@ pub fn window_builder<E>(
.with_maximized(*maximized)
.with_resizable(*resizable)
.with_transparent(*transparent)
.with_window_icon(icon_data.clone().map(|d| {
Arc::new(egui::ColorImage::from_rgba_premultiplied(
[d.width as usize, d.height as usize],
&d.rgba,
))
}))
.with_active(*active)
// Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
// We must also keep the window hidden until AccessKit is initialized.
.with_visible(false);
if let Some(icon_data) = icon_data {
viewport_builder =
viewport_builder.with_window_icon(egui::ColorImage::from_rgba_premultiplied(
[icon_data.width as usize, icon_data.height as usize],
&icon_data.rgba,
));
}
#[cfg(target_os = "macos")]
if *fullsize_content {
viewport_builder = viewport_builder
@@ -120,10 +122,10 @@ pub fn window_builder<E>(
}
if let Some(min_size) = *min_window_size {
viewport_builder = viewport_builder.with_min_inner_size(Some(min_size));
viewport_builder = viewport_builder.with_min_inner_size(min_size);
}
if let Some(max_size) = *max_window_size {
viewport_builder = viewport_builder.with_max_inner_size(Some(max_size));
viewport_builder = viewport_builder.with_max_inner_size(max_size);
}
viewport_builder = viewport_builder.with_drag_and_drop(*drag_and_drop_support);
@@ -141,13 +143,13 @@ pub fn window_builder<E>(
window_settings.inner_size_points()
} else {
if let Some(pos) = *initial_window_pos {
viewport_builder = viewport_builder.with_position(Some(pos));
viewport_builder = viewport_builder.with_position(pos);
}
if let Some(initial_window_size) = *initial_window_size {
let initial_window_size =
initial_window_size.at_most(largest_monitor_point_size(event_loop));
viewport_builder = viewport_builder.with_inner_size(Some(initial_window_size));
viewport_builder = viewport_builder.with_inner_size(initial_window_size);
}
*initial_window_size
@@ -161,7 +163,7 @@ pub fn window_builder<E>(
if monitor_size.width > 0.0 && monitor_size.height > 0.0 {
let x = (monitor_size.width - inner_size.x) / 2.0;
let y = (monitor_size.height - inner_size.y) / 2.0;
viewport_builder = viewport_builder.with_position(Some(egui::Pos2::new(x, y)));
viewport_builder = viewport_builder.with_position([x, y]);
}
}
}

View File

@@ -1035,10 +1035,14 @@ pub fn process_viewport_commands(
window.set_outer_position(LogicalPosition::new(pos.x, pos.y));
}
ViewportCommand::MinInnerSize(s) => {
window.set_min_inner_size(s.map(|s| LogicalSize::new(s.x, s.y)));
window.set_min_inner_size(
(s.is_finite() && s != Vec2::ZERO).then_some(LogicalSize::new(s.x, s.y)),
);
}
ViewportCommand::MaxInnerSize(s) => {
window.set_max_inner_size(s.map(|s| LogicalSize::new(s.x, s.y)));
window.set_max_inner_size(
(s.is_finite() && s != Vec2::INFINITY).then_some(LogicalSize::new(s.x, s.y)),
);
}
ViewportCommand::ResizeIncrements(s) => {
window.set_resize_increments(s.map(|s| LogicalSize::new(s.x, s.y)));
@@ -1168,31 +1172,31 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::
})
.with_active(builder.active.unwrap_or(true));
if let Some(Some(inner_size)) = builder.inner_size {
if let Some(inner_size) = builder.inner_size {
window_builder = window_builder
.with_inner_size(winit::dpi::LogicalSize::new(inner_size.x, inner_size.y));
}
if let Some(Some(min_inner_size)) = builder.min_inner_size {
if let Some(min_inner_size) = builder.min_inner_size {
window_builder = window_builder.with_min_inner_size(winit::dpi::LogicalSize::new(
min_inner_size.x,
min_inner_size.y,
));
}
if let Some(Some(max_inner_size)) = builder.max_inner_size {
if let Some(max_inner_size) = builder.max_inner_size {
window_builder = window_builder.with_max_inner_size(winit::dpi::LogicalSize::new(
max_inner_size.x,
max_inner_size.y,
));
}
if let Some(Some(position)) = builder.position {
if let Some(position) = builder.position {
window_builder =
window_builder.with_position(winit::dpi::LogicalPosition::new(position.x, position.y));
}
if let Some(Some(icon)) = builder.icon.clone() {
if let Some(icon) = builder.icon.clone() {
window_builder = window_builder.with_window_icon(Some(
winit::window::Icon::from_rgba(
icon.as_raw().to_owned(),

View File

@@ -60,12 +60,12 @@ impl WindowSettings {
self.outer_position_pixels
};
if let Some(pos) = pos_px {
viewport_builder = viewport_builder.with_position(Some(pos));
viewport_builder = viewport_builder.with_position(pos);
}
if let Some(inner_size_points) = self.inner_size_points {
viewport_builder = viewport_builder
.with_inner_size(Some(inner_size_points))
.with_inner_size(inner_size_points)
.with_fullscreen(self.fullscreen);
}

View File

@@ -112,21 +112,22 @@ pub struct ViewportBuilder {
/// This is wayland only. See [`Self::with_name`].
pub name: Option<(String, String)>,
pub position: Option<Option<Pos2>>,
pub inner_size: Option<Option<Vec2>>,
pub position: Option<Pos2>,
pub inner_size: Option<Vec2>,
pub min_inner_size: Option<Vec2>,
pub max_inner_size: Option<Vec2>,
pub fullscreen: Option<bool>,
pub maximized: Option<bool>,
pub resizable: Option<bool>,
pub transparent: Option<bool>,
pub decorations: Option<bool>,
pub icon: Option<Option<Arc<ColorImage>>>,
pub icon: Option<Arc<ColorImage>>,
pub active: Option<bool>,
pub visible: Option<bool>,
pub title_hidden: Option<bool>,
pub titlebar_transparent: Option<bool>,
pub fullsize_content_view: Option<bool>,
pub min_inner_size: Option<Option<Vec2>>,
pub max_inner_size: Option<Option<Vec2>>,
pub drag_and_drop: Option<bool>,
pub close_button: Option<bool>,
@@ -209,8 +210,8 @@ impl ViewportBuilder {
/// The icon needs to be wrapped in Arc because will be cloned every frame
#[inline]
pub fn with_window_icon(mut self, icon: Option<Arc<ColorImage>>) -> Self {
self.icon = Some(icon);
pub fn with_window_icon(mut self, icon: impl Into<Arc<ColorImage>>) -> Self {
self.icon = Some(icon.into());
self
}
@@ -274,8 +275,8 @@ impl ViewportBuilder {
/// Should be bigger then 0
/// Look at winit for more details
#[inline]
pub fn with_inner_size(mut self, value: Option<Vec2>) -> Self {
self.inner_size = Some(value);
pub fn with_inner_size(mut self, size: impl Into<Vec2>) -> Self {
self.inner_size = Some(size.into());
self
}
@@ -287,8 +288,8 @@ impl ViewportBuilder {
/// Should be bigger then 0
/// Look at winit for more details
#[inline]
pub fn with_min_inner_size(mut self, value: Option<Vec2>) -> Self {
self.min_inner_size = Some(value);
pub fn with_min_inner_size(mut self, size: impl Into<Vec2>) -> Self {
self.min_inner_size = Some(size.into());
self
}
@@ -300,8 +301,8 @@ impl ViewportBuilder {
/// Should be bigger then 0
/// Look at winit for more details
#[inline]
pub fn with_max_inner_size(mut self, value: Option<Vec2>) -> Self {
self.max_inner_size = Some(value);
pub fn with_max_inner_size(mut self, size: impl Into<Vec2>) -> Self {
self.max_inner_size = Some(size.into());
self
}
@@ -335,8 +336,8 @@ impl ViewportBuilder {
/// This will probably not work as expected!
#[inline]
pub fn with_position(mut self, value: Option<Pos2>) -> Self {
self.position = Some(value);
pub fn with_position(mut self, pos: impl Into<Pos2>) -> Self {
self.position = Some(pos.into());
self
}
@@ -378,18 +379,14 @@ impl ViewportBuilder {
if let Some(new_position) = new.position {
if Some(new_position) != self.position {
self.position = Some(new_position);
if let Some(position) = new_position {
commands.push(ViewportCommand::OuterPosition(position));
}
commands.push(ViewportCommand::OuterPosition(new_position));
}
}
if let Some(new_inner_size) = new.inner_size {
if Some(new_inner_size) != self.inner_size {
self.inner_size = Some(new_inner_size);
if let Some(inner_size) = new_inner_size {
commands.push(ViewportCommand::InnerSize(inner_size));
}
commands.push(ViewportCommand::InnerSize(new_inner_size));
}
}
@@ -442,23 +439,15 @@ impl ViewportBuilder {
}
}
if let Some(new_icon) = new.icon.clone() {
let eq = match &new_icon {
Some(icon) => {
if let Some(self_icon) = &self.icon {
matches!(self_icon, Some(self_icon) if Arc::ptr_eq(icon, self_icon))
} else {
false
}
}
None => self.icon == Some(None),
if let Some(new_icon) = &new.icon {
let is_new = match &self.icon {
Some(existing) => !Arc::ptr_eq(new_icon, existing),
None => true,
};
if !eq {
commands.push(ViewportCommand::WindowIcon(
new_icon.as_ref().map(|i| i.as_ref().clone()),
));
self.icon = Some(new_icon);
if is_new {
commands.push(ViewportCommand::WindowIcon(Some(new_icon.clone())));
self.icon = Some(new_icon.clone());
}
}
@@ -587,6 +576,8 @@ pub enum ResizeDirection {
/// You can send a [`ViewportCommand`] to the viewport with [`Context::viewport_command`].
///
/// All coordinates are in logical points.
///
/// This is essentially a way to diff [`ViewportBuilder`].
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ViewportCommand {
@@ -612,10 +603,10 @@ pub enum ViewportCommand {
InnerSize(Vec2),
/// Should be bigger then 0
MinInnerSize(Option<Vec2>),
MinInnerSize(Vec2),
/// Should be bigger then 0
MaxInnerSize(Option<Vec2>),
MaxInnerSize(Vec2),
/// Should be bigger then 0
ResizeIncrements(Option<Vec2>),
@@ -644,7 +635,7 @@ pub enum ViewportCommand {
Decorations(bool),
WindowLevel(WindowLevel),
WindowIcon(Option<ColorImage>),
WindowIcon(Option<Arc<ColorImage>>),
IMEPosition(Pos2),
IMEAllowed(bool),

View File

@@ -52,7 +52,9 @@ impl eframe::App for MyApp {
if self.show_immediate_viewport {
ctx.show_viewport_immediate(
egui::ViewportId::from_hash_of("immediate_viewport"),
egui::ViewportBuilder::default().with_title("Immediate Viewport"),
egui::ViewportBuilder::default()
.with_title("Immediate Viewport")
.with_inner_size([200.0, 100.0]),
|ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Hello from immediate viewport");
@@ -70,7 +72,9 @@ impl eframe::App for MyApp {
let show_deferred_viewport = self.show_deferred_viewport.clone();
ctx.show_viewport_immediate(
egui::ViewportId::from_hash_of("deferred_viewport"),
egui::ViewportBuilder::default().with_title("Deferred Viewport"),
egui::ViewportBuilder::default()
.with_title("Deferred Viewport")
.with_inner_size([200.0, 100.0]),
|ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Hello from deferred viewport");

View File

@@ -67,7 +67,7 @@ impl ViewportState {
let viewport = ViewportBuilder::default()
.with_title(&title)
.with_inner_size(Some(egui::vec2(450.0, 400.0)));
.with_inner_size([450.0, 400.0]);
if immediate {
let mut vp_state = vp_state.write();