mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
Remove Option<Option<X>> and simplify ViewportBuilder
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::{sync::Arc, time::Instant};
|
use std::time::Instant;
|
||||||
|
|
||||||
use winit::event_loop::EventLoopWindowTarget;
|
use winit::event_loop::EventLoopWindowTarget;
|
||||||
|
|
||||||
@@ -92,17 +92,19 @@ pub fn window_builder<E>(
|
|||||||
.with_maximized(*maximized)
|
.with_maximized(*maximized)
|
||||||
.with_resizable(*resizable)
|
.with_resizable(*resizable)
|
||||||
.with_transparent(*transparent)
|
.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)
|
.with_active(*active)
|
||||||
// Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
// 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.
|
// We must also keep the window hidden until AccessKit is initialized.
|
||||||
.with_visible(false);
|
.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")]
|
#[cfg(target_os = "macos")]
|
||||||
if *fullsize_content {
|
if *fullsize_content {
|
||||||
viewport_builder = viewport_builder
|
viewport_builder = viewport_builder
|
||||||
@@ -120,10 +122,10 @@ pub fn window_builder<E>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(min_size) = *min_window_size {
|
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 {
|
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);
|
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()
|
window_settings.inner_size_points()
|
||||||
} else {
|
} else {
|
||||||
if let Some(pos) = *initial_window_pos {
|
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 {
|
if let Some(initial_window_size) = *initial_window_size {
|
||||||
let initial_window_size =
|
let initial_window_size =
|
||||||
initial_window_size.at_most(largest_monitor_point_size(event_loop));
|
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
|
*initial_window_size
|
||||||
@@ -161,7 +163,7 @@ pub fn window_builder<E>(
|
|||||||
if monitor_size.width > 0.0 && monitor_size.height > 0.0 {
|
if monitor_size.width > 0.0 && monitor_size.height > 0.0 {
|
||||||
let x = (monitor_size.width - inner_size.x) / 2.0;
|
let x = (monitor_size.width - inner_size.x) / 2.0;
|
||||||
let y = (monitor_size.height - inner_size.y) / 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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1035,10 +1035,14 @@ pub fn process_viewport_commands(
|
|||||||
window.set_outer_position(LogicalPosition::new(pos.x, pos.y));
|
window.set_outer_position(LogicalPosition::new(pos.x, pos.y));
|
||||||
}
|
}
|
||||||
ViewportCommand::MinInnerSize(s) => {
|
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) => {
|
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) => {
|
ViewportCommand::ResizeIncrements(s) => {
|
||||||
window.set_resize_increments(s.map(|s| LogicalSize::new(s.x, s.y)));
|
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));
|
.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
|
window_builder = window_builder
|
||||||
.with_inner_size(winit::dpi::LogicalSize::new(inner_size.x, inner_size.y));
|
.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(
|
window_builder = window_builder.with_min_inner_size(winit::dpi::LogicalSize::new(
|
||||||
min_inner_size.x,
|
min_inner_size.x,
|
||||||
min_inner_size.y,
|
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(
|
window_builder = window_builder.with_max_inner_size(winit::dpi::LogicalSize::new(
|
||||||
max_inner_size.x,
|
max_inner_size.x,
|
||||||
max_inner_size.y,
|
max_inner_size.y,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Some(position)) = builder.position {
|
if let Some(position) = builder.position {
|
||||||
window_builder =
|
window_builder =
|
||||||
window_builder.with_position(winit::dpi::LogicalPosition::new(position.x, position.y));
|
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(
|
window_builder = window_builder.with_window_icon(Some(
|
||||||
winit::window::Icon::from_rgba(
|
winit::window::Icon::from_rgba(
|
||||||
icon.as_raw().to_owned(),
|
icon.as_raw().to_owned(),
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ impl WindowSettings {
|
|||||||
self.outer_position_pixels
|
self.outer_position_pixels
|
||||||
};
|
};
|
||||||
if let Some(pos) = pos_px {
|
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 {
|
if let Some(inner_size_points) = self.inner_size_points {
|
||||||
viewport_builder = viewport_builder
|
viewport_builder = viewport_builder
|
||||||
.with_inner_size(Some(inner_size_points))
|
.with_inner_size(inner_size_points)
|
||||||
.with_fullscreen(self.fullscreen);
|
.with_fullscreen(self.fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,21 +112,22 @@ pub struct ViewportBuilder {
|
|||||||
/// This is wayland only. See [`Self::with_name`].
|
/// This is wayland only. See [`Self::with_name`].
|
||||||
pub name: Option<(String, String)>,
|
pub name: Option<(String, String)>,
|
||||||
|
|
||||||
pub position: Option<Option<Pos2>>,
|
pub position: Option<Pos2>,
|
||||||
pub inner_size: Option<Option<Vec2>>,
|
pub inner_size: Option<Vec2>,
|
||||||
|
pub min_inner_size: Option<Vec2>,
|
||||||
|
pub max_inner_size: Option<Vec2>,
|
||||||
|
|
||||||
pub fullscreen: Option<bool>,
|
pub fullscreen: Option<bool>,
|
||||||
pub maximized: Option<bool>,
|
pub maximized: Option<bool>,
|
||||||
pub resizable: Option<bool>,
|
pub resizable: Option<bool>,
|
||||||
pub transparent: Option<bool>,
|
pub transparent: Option<bool>,
|
||||||
pub decorations: Option<bool>,
|
pub decorations: Option<bool>,
|
||||||
pub icon: Option<Option<Arc<ColorImage>>>,
|
pub icon: Option<Arc<ColorImage>>,
|
||||||
pub active: Option<bool>,
|
pub active: Option<bool>,
|
||||||
pub visible: Option<bool>,
|
pub visible: Option<bool>,
|
||||||
pub title_hidden: Option<bool>,
|
pub title_hidden: Option<bool>,
|
||||||
pub titlebar_transparent: Option<bool>,
|
pub titlebar_transparent: Option<bool>,
|
||||||
pub fullsize_content_view: 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 drag_and_drop: Option<bool>,
|
||||||
|
|
||||||
pub close_button: 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
|
/// The icon needs to be wrapped in Arc because will be cloned every frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_window_icon(mut self, icon: Option<Arc<ColorImage>>) -> Self {
|
pub fn with_window_icon(mut self, icon: impl Into<Arc<ColorImage>>) -> Self {
|
||||||
self.icon = Some(icon);
|
self.icon = Some(icon.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,8 +275,8 @@ impl ViewportBuilder {
|
|||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
/// Look at winit for more details
|
/// Look at winit for more details
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_inner_size(mut self, value: Option<Vec2>) -> Self {
|
pub fn with_inner_size(mut self, size: impl Into<Vec2>) -> Self {
|
||||||
self.inner_size = Some(value);
|
self.inner_size = Some(size.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,8 +288,8 @@ impl ViewportBuilder {
|
|||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
/// Look at winit for more details
|
/// Look at winit for more details
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_min_inner_size(mut self, value: Option<Vec2>) -> Self {
|
pub fn with_min_inner_size(mut self, size: impl Into<Vec2>) -> Self {
|
||||||
self.min_inner_size = Some(value);
|
self.min_inner_size = Some(size.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,8 +301,8 @@ impl ViewportBuilder {
|
|||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
/// Look at winit for more details
|
/// Look at winit for more details
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_max_inner_size(mut self, value: Option<Vec2>) -> Self {
|
pub fn with_max_inner_size(mut self, size: impl Into<Vec2>) -> Self {
|
||||||
self.max_inner_size = Some(value);
|
self.max_inner_size = Some(size.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,8 +336,8 @@ impl ViewportBuilder {
|
|||||||
|
|
||||||
/// This will probably not work as expected!
|
/// This will probably not work as expected!
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_position(mut self, value: Option<Pos2>) -> Self {
|
pub fn with_position(mut self, pos: impl Into<Pos2>) -> Self {
|
||||||
self.position = Some(value);
|
self.position = Some(pos.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,18 +379,14 @@ impl ViewportBuilder {
|
|||||||
if let Some(new_position) = new.position {
|
if let Some(new_position) = new.position {
|
||||||
if Some(new_position) != self.position {
|
if Some(new_position) != self.position {
|
||||||
self.position = Some(new_position);
|
self.position = Some(new_position);
|
||||||
if let Some(position) = new_position {
|
commands.push(ViewportCommand::OuterPosition(new_position));
|
||||||
commands.push(ViewportCommand::OuterPosition(position));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_inner_size) = new.inner_size {
|
if let Some(new_inner_size) = new.inner_size {
|
||||||
if Some(new_inner_size) != self.inner_size {
|
if Some(new_inner_size) != self.inner_size {
|
||||||
self.inner_size = Some(new_inner_size);
|
self.inner_size = Some(new_inner_size);
|
||||||
if let Some(inner_size) = new_inner_size {
|
commands.push(ViewportCommand::InnerSize(new_inner_size));
|
||||||
commands.push(ViewportCommand::InnerSize(inner_size));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,23 +439,15 @@ impl ViewportBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_icon) = new.icon.clone() {
|
if let Some(new_icon) = &new.icon {
|
||||||
let eq = match &new_icon {
|
let is_new = match &self.icon {
|
||||||
Some(icon) => {
|
Some(existing) => !Arc::ptr_eq(new_icon, existing),
|
||||||
if let Some(self_icon) = &self.icon {
|
None => true,
|
||||||
matches!(self_icon, Some(self_icon) if Arc::ptr_eq(icon, self_icon))
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => self.icon == Some(None),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !eq {
|
if is_new {
|
||||||
commands.push(ViewportCommand::WindowIcon(
|
commands.push(ViewportCommand::WindowIcon(Some(new_icon.clone())));
|
||||||
new_icon.as_ref().map(|i| i.as_ref().clone()),
|
self.icon = Some(new_icon.clone());
|
||||||
));
|
|
||||||
self.icon = Some(new_icon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,6 +576,8 @@ pub enum ResizeDirection {
|
|||||||
/// You can send a [`ViewportCommand`] to the viewport with [`Context::viewport_command`].
|
/// You can send a [`ViewportCommand`] to the viewport with [`Context::viewport_command`].
|
||||||
///
|
///
|
||||||
/// All coordinates are in logical points.
|
/// All coordinates are in logical points.
|
||||||
|
///
|
||||||
|
/// This is essentially a way to diff [`ViewportBuilder`].
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub enum ViewportCommand {
|
pub enum ViewportCommand {
|
||||||
@@ -612,10 +603,10 @@ pub enum ViewportCommand {
|
|||||||
InnerSize(Vec2),
|
InnerSize(Vec2),
|
||||||
|
|
||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
MinInnerSize(Option<Vec2>),
|
MinInnerSize(Vec2),
|
||||||
|
|
||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
MaxInnerSize(Option<Vec2>),
|
MaxInnerSize(Vec2),
|
||||||
|
|
||||||
/// Should be bigger then 0
|
/// Should be bigger then 0
|
||||||
ResizeIncrements(Option<Vec2>),
|
ResizeIncrements(Option<Vec2>),
|
||||||
@@ -644,7 +635,7 @@ pub enum ViewportCommand {
|
|||||||
Decorations(bool),
|
Decorations(bool),
|
||||||
|
|
||||||
WindowLevel(WindowLevel),
|
WindowLevel(WindowLevel),
|
||||||
WindowIcon(Option<ColorImage>),
|
WindowIcon(Option<Arc<ColorImage>>),
|
||||||
|
|
||||||
IMEPosition(Pos2),
|
IMEPosition(Pos2),
|
||||||
IMEAllowed(bool),
|
IMEAllowed(bool),
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ impl eframe::App for MyApp {
|
|||||||
if self.show_immediate_viewport {
|
if self.show_immediate_viewport {
|
||||||
ctx.show_viewport_immediate(
|
ctx.show_viewport_immediate(
|
||||||
egui::ViewportId::from_hash_of("immediate_viewport"),
|
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| {
|
|ctx| {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.label("Hello from immediate viewport");
|
ui.label("Hello from immediate viewport");
|
||||||
@@ -70,7 +72,9 @@ impl eframe::App for MyApp {
|
|||||||
let show_deferred_viewport = self.show_deferred_viewport.clone();
|
let show_deferred_viewport = self.show_deferred_viewport.clone();
|
||||||
ctx.show_viewport_immediate(
|
ctx.show_viewport_immediate(
|
||||||
egui::ViewportId::from_hash_of("deferred_viewport"),
|
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| {
|
|ctx| {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.label("Hello from deferred viewport");
|
ui.label("Hello from deferred viewport");
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl ViewportState {
|
|||||||
|
|
||||||
let viewport = ViewportBuilder::default()
|
let viewport = ViewportBuilder::default()
|
||||||
.with_title(&title)
|
.with_title(&title)
|
||||||
.with_inner_size(Some(egui::vec2(450.0, 400.0)));
|
.with_inner_size([450.0, 400.0]);
|
||||||
|
|
||||||
if immediate {
|
if immediate {
|
||||||
let mut vp_state = vp_state.write();
|
let mut vp_state = vp_state.write();
|
||||||
|
|||||||
Reference in New Issue
Block a user