diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index bac900451..62055c728 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -124,12 +124,10 @@ pub fn window_builder( } if let Some(min_size) = *min_window_size { - window_builder = - window_builder.with_min_inner_size(Some((min_size.x as u32, min_size.y as u32))); + window_builder = window_builder.with_min_inner_size(Some(min_size.to_pos2())); } if let Some(max_size) = *max_window_size { - window_builder = - window_builder.with_max_inner_size(Some((max_size.x as u32, max_size.y as u32))); + window_builder = window_builder.with_max_inner_size(Some(max_size.to_pos2())); } window_builder = window_builder.with_drag_and_drop(*drag_and_drop_support); @@ -147,16 +145,13 @@ pub fn window_builder( window_settings.inner_size_points() } else { if let Some(pos) = *initial_window_pos { - window_builder = window_builder.with_position(Some((pos.x as i32, pos.y as i32))); + window_builder = window_builder.with_position(Some(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)); - window_builder = window_builder.with_inner_size(Some(( - initial_window_size.x as u32, - initial_window_size.y as u32, - ))); + window_builder = window_builder.with_inner_size(Some(initial_window_size.to_pos2())); } *initial_window_size @@ -165,12 +160,12 @@ pub fn window_builder( #[cfg(not(target_os = "ios"))] if *centered { if let Some(monitor) = event_loop.available_monitors().next() { - let monitor_size = monitor.size().to_logical::(monitor.scale_factor()); + let monitor_size = monitor.size().to_logical::(monitor.scale_factor()); let inner_size = inner_size_points.unwrap_or(egui::Vec2 { x: 800.0, y: 600.0 }); if monitor_size.width > 0.0 && monitor_size.height > 0.0 { - let x = (monitor_size.width - inner_size.x as f64) / 2.0; - let y = (monitor_size.height - inner_size.y as f64) / 2.0; - window_builder = window_builder.with_position(Some((x as i32, y as i32))); + let x = (monitor_size.width - inner_size.x) / 2.0; + let y = (monitor_size.height - inner_size.y) / 2.0; + window_builder = window_builder.with_position(Some(egui::Pos2::new(x, y))); } } } diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 73d7ebeb5..adb8e6379 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -188,7 +188,7 @@ impl State { None }; - self.egui_input.viewport_inner_pos = if getting_info { + self.egui_input.inner_pos = if getting_info { window .inner_position() .map(|pos| Pos2::new(pos.x as f32, pos.y as f32)) @@ -197,7 +197,7 @@ impl State { None }; - self.egui_input.viewport_outer_pos = if getting_info { + self.egui_input.outer_pos = if getting_info { window .outer_position() .map(|pos| Pos2::new(pos.x as f32, pos.y as f32)) @@ -206,14 +206,14 @@ impl State { None }; - self.egui_input.viewport_inner_size = if getting_info { + self.egui_input.inner_size = if getting_info { let size = window.inner_size(); Some(Pos2::new(size.width as f32, size.height as f32)) } else { None }; - self.egui_input.viewport_outer_size = if getting_info { + self.egui_input.outer_size = if getting_info { let size = window.outer_size(); Some(Pos2::new(size.width as f32, size.height as f32)) } else { @@ -950,7 +950,6 @@ pub fn process_viewport_commands( focused: Option, window: &Arc>, ) { - use winit::dpi::PhysicalSize; use winit::window::ResizeDirection; let win = window.read(); @@ -965,10 +964,10 @@ pub fn process_viewport_commands( } } } - egui::ViewportCommand::InnerSize(width, height) => { - let width = width.max(1); - let height = height.max(1); - win.set_inner_size(PhysicalSize::new(width, height)); + egui::ViewportCommand::InnerSize(size) => { + let width = size.x.max(1.0); + let height = size.y.max(1.0); + win.set_inner_size(LogicalSize::new(width, height)); } egui::ViewportCommand::Resize(top, bottom, right, left) => { // TODO posibile return the error to `egui::Context` @@ -986,17 +985,17 @@ pub fn process_viewport_commands( ViewportCommand::Title(title) => win.set_title(&title), ViewportCommand::Transparent(v) => win.set_transparent(v), ViewportCommand::Visible(v) => win.set_visible(v), - ViewportCommand::OuterPosition(x, y) => { - win.set_outer_position(LogicalPosition::new(x, y)); + ViewportCommand::OuterPosition(pos) => { + win.set_outer_position(LogicalPosition::new(pos.x, pos.y)); } ViewportCommand::MinInnerSize(s) => { - win.set_min_inner_size(s.map(|s| LogicalSize::new(s.0, s.1))); + win.set_min_inner_size(s.map(|s| LogicalSize::new(s.x, s.y))); } ViewportCommand::MaxInnerSize(s) => { - win.set_max_inner_size(s.map(|s| LogicalSize::new(s.0, s.1))); + win.set_max_inner_size(s.map(|s| LogicalSize::new(s.x, s.y))); } ViewportCommand::ResizeIncrements(s) => { - win.set_resize_increments(s.map(|s| LogicalSize::new(s.0, s.1))); + win.set_resize_increments(s.map(|s| LogicalSize::new(s.x, s.y))); } ViewportCommand::Resizable(v) => win.set_resizable(v), ViewportCommand::EnableButtons { @@ -1035,7 +1034,9 @@ pub fn process_viewport_commands( .expect("Invalid ICON data!") })); } - ViewportCommand::IMEPosition(x, y) => win.set_ime_position(LogicalPosition::new(x, y)), + ViewportCommand::IMEPosition(pos) => { + win.set_ime_position(LogicalPosition::new(pos.x, pos.y)); + } ViewportCommand::IMEAllowed(v) => win.set_ime_allowed(v), ViewportCommand::IMEPurpose(o) => win.set_ime_purpose(match o { 1 => winit::window::ImePurpose::Password, @@ -1057,8 +1058,8 @@ pub fn process_viewport_commands( } })), ViewportCommand::ContentProtected(v) => win.set_content_protected(v), - ViewportCommand::CursorPosition(x, y) => { - if let Err(err) = win.set_cursor_position(LogicalPosition::new(x, y)) { + ViewportCommand::CursorPosition(pos) => { + if let Err(err) = win.set_cursor_position(LogicalPosition::new(pos.x, pos.y)) { log::error!("{err}"); } } @@ -1097,9 +1098,9 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window:: let mut window_builder = winit::window::WindowBuilder::new() .with_title(builder.title.clone()) .with_transparent(builder.transparent.map_or(false, |e| e)) - .with_decorations(builder.decorations.map_or(false, |e| e)) - .with_resizable(builder.resizable.map_or(false, |e| e)) - .with_visible(builder.visible.map_or(false, |e| e)) + .with_decorations(builder.decorations.map_or(true, |e| e)) + .with_resizable(builder.resizable.map_or(true, |e| e)) + .with_visible(builder.visible.map_or(true, |e| e)) .with_maximized(builder.minimized.map_or(false, |e| e)) .with_maximized(builder.maximized.map_or(false, |e| e)) .with_fullscreen( @@ -1122,25 +1123,29 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window:: .unwrap_or(WindowButtons::empty()), ) .with_active(builder.active.map_or(false, |e| e)); + if let Some(Some(inner_size)) = builder.inner_size { window_builder = window_builder - .with_inner_size(winit::dpi::PhysicalSize::new(inner_size.0, inner_size.1)); + .with_inner_size(winit::dpi::LogicalSize::new(inner_size.x, inner_size.y)); } + if let Some(Some(min_inner_size)) = builder.min_inner_size { - window_builder = window_builder.with_min_inner_size(winit::dpi::PhysicalSize::new( - min_inner_size.0, - min_inner_size.1, + 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 { - window_builder = window_builder.with_max_inner_size(winit::dpi::PhysicalSize::new( - max_inner_size.0, - max_inner_size.1, + 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 { window_builder = - window_builder.with_position(winit::dpi::PhysicalPosition::new(position.0, position.1)); + window_builder.with_position(winit::dpi::LogicalPosition::new(position.x, position.y)); } if let Some(Some(icon)) = builder.icon.clone() { @@ -1181,7 +1186,7 @@ pub fn changes_between_builders( if Some(position) != last.position { last.position = Some(position); if let Some(position) = position { - commands.push(ViewportCommand::OuterPosition(position.0, position.1)); + commands.push(ViewportCommand::OuterPosition(position)); } } } @@ -1190,7 +1195,7 @@ pub fn changes_between_builders( if Some(inner_size) != last.inner_size { last.inner_size = Some(inner_size); if let Some(inner_size) = inner_size { - commands.push(ViewportCommand::InnerSize(inner_size.0, inner_size.1)); + commands.push(ViewportCommand::InnerSize(inner_size)); } } } diff --git a/crates/egui-winit/src/window_settings.rs b/crates/egui-winit/src/window_settings.rs index 94de38c48..98a0abb97 100644 --- a/crates/egui-winit/src/window_settings.rs +++ b/crates/egui-winit/src/window_settings.rs @@ -57,15 +57,12 @@ impl WindowSettings { self.outer_position_pixels }; if let Some(pos) = pos_px { - window = window.with_position(Some((pos.x as i32, pos.y as i32))); + window = window.with_position(Some(pos)); } if let Some(inner_size_points) = self.inner_size_points { window - .with_inner_size(Some(( - inner_size_points.x as u32, - inner_size_points.y as u32, - ))) + .with_inner_size(Some(inner_size_points.to_pos2())) .with_fullscreen(self.fullscreen) } else { window diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index d5dea546d..b50bca014 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -1618,19 +1618,19 @@ impl Context { } pub fn viewport_inner_pos(&self) -> Pos2 { - self.input(|i| i.viewport_inner_pos) + self.input(|i| i.inner_pos) } pub fn viewport_outer_pos(&self) -> Pos2 { - self.input(|i| i.viewport_outer_pos) + self.input(|i| i.outer_pos) } pub fn viewport_inner_size(&self) -> Pos2 { - self.input(|i| i.viewport_inner_size) + self.input(|i| i.inner_size) } pub fn viewport_outer_size(&self) -> Pos2 { - self.input(|i| i.viewport_outer_size) + self.input(|i| i.outer_size) } /// How much space is still available after panels has been added. @@ -2261,7 +2261,11 @@ impl Context { } /// With this you can send a command to a viewport - pub fn viewport_command(&self, id: ViewportId, command: ViewportCommand) { + pub fn viewport_command(&self, command: ViewportCommand) { + self.viewport_command_for(self.get_viewport_id(), command); + } + + pub fn viewport_command_for(&self, id: ViewportId, command: ViewportCommand) { self.write(|ctx| ctx.viewport_commands.push((id, command))); } diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index 9837c86bc..2c4a55e28 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -23,10 +23,21 @@ pub struct RawInput { /// `None` will be treated as "same as last frame", with the default being a very big area. pub screen_rect: Option, - pub viewport_inner_pos: Option, - pub viewport_outer_pos: Option, - pub viewport_inner_size: Option, - pub viewport_outer_size: Option, + /// Viewport inner position, only the drowable area + /// If is not working as expected is a winit bug! + pub inner_pos: Option, + + /// Viewport outer position, drowable area + decorations + /// If is not working as expected is a winit bug! + pub outer_pos: Option, + + /// Viewport inner size, only drowable area + /// If is not working as expected is a winit bug! + pub inner_size: Option, + + /// Viewport outer size, drowable area + decorations + /// If is not working as expected is a winit bug! + pub outer_size: Option, /// Also known as device pixel ratio, > 1 for high resolution screens. /// If text looks blurry you probably forgot to set this. @@ -78,10 +89,10 @@ impl Default for RawInput { fn default() -> Self { Self { screen_rect: None, - viewport_inner_pos: None, - viewport_outer_pos: None, - viewport_inner_size: None, - viewport_outer_size: None, + inner_pos: None, + outer_pos: None, + inner_size: None, + outer_size: None, pixels_per_point: None, max_texture_side: None, time: None, @@ -103,10 +114,10 @@ impl RawInput { pub fn take(&mut self) -> RawInput { RawInput { screen_rect: self.screen_rect.take(), - viewport_inner_pos: self.viewport_inner_pos.take(), - viewport_outer_pos: self.viewport_outer_pos.take(), - viewport_inner_size: self.viewport_inner_size.take(), - viewport_outer_size: self.viewport_outer_size.take(), + inner_pos: self.inner_pos.take(), + outer_pos: self.outer_pos.take(), + inner_size: self.inner_size.take(), + outer_size: self.outer_size.take(), pixels_per_point: self.pixels_per_point.take(), max_texture_side: self.max_texture_side.take(), time: self.time.take(), @@ -123,10 +134,10 @@ impl RawInput { pub fn append(&mut self, newer: Self) { let Self { screen_rect, - viewport_inner_pos, - viewport_outer_pos, - viewport_inner_size, - viewport_outer_size, + inner_pos: viewport_inner_pos, + outer_pos: viewport_outer_pos, + inner_size: viewport_inner_size, + outer_size: viewport_outer_size, pixels_per_point, max_texture_side, time, @@ -139,10 +150,10 @@ impl RawInput { } = newer; self.screen_rect = screen_rect.or(self.screen_rect); - self.viewport_inner_pos = viewport_inner_pos.or(self.viewport_inner_pos); - self.viewport_outer_pos = viewport_outer_pos.or(self.viewport_outer_pos); - self.viewport_inner_size = viewport_inner_size.or(self.viewport_inner_size); - self.viewport_outer_size = viewport_outer_size.or(self.viewport_outer_size); + self.inner_pos = viewport_inner_pos.or(self.inner_pos); + self.outer_pos = viewport_outer_pos.or(self.outer_pos); + self.inner_size = viewport_inner_size.or(self.inner_size); + self.outer_size = viewport_outer_size.or(self.outer_size); self.pixels_per_point = pixels_per_point.or(self.pixels_per_point); self.max_texture_side = max_texture_side.or(self.max_texture_side); self.time = time; // use latest time @@ -958,10 +969,10 @@ impl RawInput { pub fn ui(&self, ui: &mut crate::Ui) { let Self { screen_rect, - viewport_inner_pos, - viewport_outer_pos, - viewport_inner_size, - viewport_outer_size, + inner_pos: viewport_inner_pos, + outer_pos: viewport_outer_pos, + inner_size: viewport_inner_size, + outer_size: viewport_outer_size, pixels_per_point, max_texture_side, time, diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index 606864bcb..70b140b58 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -54,10 +54,21 @@ pub struct InputState { /// Position and size of the egui area. pub screen_rect: Rect, - pub viewport_inner_pos: Pos2, - pub viewport_outer_pos: Pos2, - pub viewport_inner_size: Pos2, - pub viewport_outer_size: Pos2, + /// Viewport inner position, only the drowable area + /// If is not working as expected is a winit bug! + pub inner_pos: Pos2, + + /// Viewport outer position, drowable area + decorations + /// If is not working as expected is a winit bug! + pub outer_pos: Pos2, + + /// Viewport inner size, only drowable area + /// If is not working as expected is a winit bug! + pub inner_size: Pos2, + + /// Viewport outer size, drowable area + decorations + /// If is not working as expected is a winit bug! + pub outer_size: Pos2, /// Also known as device pixel ratio, > 1 for high resolution screens. pub pixels_per_point: f32, @@ -143,10 +154,10 @@ impl Default for InputState { modifiers: Default::default(), keys_down: Default::default(), events: Default::default(), - viewport_inner_pos: Pos2::ZERO, - viewport_outer_pos: Pos2::ZERO, - viewport_inner_size: pos2(10_000.0, 10_000.0), - viewport_outer_size: pos2(10_000.0, 10_000.0), + inner_pos: Pos2::ZERO, + outer_pos: Pos2::ZERO, + inner_size: pos2(10_000.0, 10_000.0), + outer_size: pos2(10_000.0, 10_000.0), } } } @@ -170,10 +181,10 @@ impl InputState { }; let screen_rect = new.screen_rect.unwrap_or(self.screen_rect); - let viewport_inner_pos = new.viewport_inner_pos.unwrap_or(self.viewport_inner_pos); - let viewport_outer_pos = new.viewport_outer_pos.unwrap_or(self.viewport_outer_pos); - let viewport_inner_size = new.viewport_inner_size.unwrap_or(self.viewport_inner_size); - let viewport_outer_size = new.viewport_outer_size.unwrap_or(self.viewport_outer_size); + let viewport_inner_pos = new.inner_pos.unwrap_or(self.inner_pos); + let viewport_outer_pos = new.outer_pos.unwrap_or(self.outer_pos); + let viewport_inner_size = new.inner_size.unwrap_or(self.inner_size); + let viewport_outer_size = new.outer_size.unwrap_or(self.outer_size); self.create_touch_states_for_new_devices(&new.events); for touch_state in self.touch_states.values_mut() { @@ -229,10 +240,10 @@ impl InputState { scroll_delta, zoom_factor_delta, screen_rect, - viewport_inner_pos, - viewport_outer_pos, - viewport_inner_size, - viewport_outer_size, + inner_pos: viewport_inner_pos, + outer_pos: viewport_outer_pos, + inner_size: viewport_inner_size, + outer_size: viewport_outer_size, pixels_per_point: new.pixels_per_point.unwrap_or(self.pixels_per_point), max_texture_side: new.max_texture_side.unwrap_or(self.max_texture_side), time, @@ -990,10 +1001,10 @@ impl InputState { scroll_delta, zoom_factor_delta, screen_rect, - viewport_inner_pos, - viewport_outer_pos, - viewport_inner_size, - viewport_outer_size, + inner_pos: viewport_inner_pos, + outer_pos: viewport_outer_pos, + inner_size: viewport_inner_size, + outer_size: viewport_outer_size, pixels_per_point, max_texture_side, time, diff --git a/crates/egui/src/viewport.rs b/crates/egui/src/viewport.rs index 7c0fad904..81632826e 100644 --- a/crates/egui/src/viewport.rs +++ b/crates/egui/src/viewport.rs @@ -1,5 +1,7 @@ use std::{fmt::Display, sync::Arc}; +use epaint::Pos2; + use crate::{Context, Id}; /// This is used to send a command to a specific viewport @@ -24,13 +26,13 @@ pub type ViewportRender = dyn Fn(&Context) + Sync + Send; /// The filds in this struct should not be change directly, but is not problem tho! /// Every thing is wrapped in Option<> indicates that thing should not be changed! -#[derive(Hash, PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone)] pub struct ViewportBuilder { pub id: Id, pub title: String, pub name: Option<(String, String)>, - pub position: Option>, - pub inner_size: Option>, + pub position: Option>, + pub inner_size: Option>, pub fullscreen: Option, pub maximized: Option, pub minimized: Option, @@ -43,8 +45,8 @@ pub struct ViewportBuilder { pub title_hidden: Option, pub titlebar_transparent: Option, pub fullsize_content_view: Option, - pub min_inner_size: Option>, - pub max_inner_size: Option>, + pub min_inner_size: Option>, + pub max_inner_size: Option>, pub drag_and_drop: Option, pub close_button: Option, @@ -61,7 +63,7 @@ impl ViewportBuilder { title: "Dummy egui viewport".into(), name: None, position: None, - inner_size: Some(Some((300, 200))), + inner_size: Some(Some(Pos2::new(300.0, 200.0))), fullscreen: None, maximized: None, resizable: Some(true), @@ -181,17 +183,20 @@ impl ViewportBuilder { self } - pub fn with_inner_size(mut self, value: Option<(u32, u32)>) -> Self { + /// Should be bigger then 0 + pub fn with_inner_size(mut self, value: Option) -> Self { self.inner_size = Some(value); self } - pub fn with_min_inner_size(mut self, value: Option<(u32, u32)>) -> Self { + /// Should be bigger then 0 + pub fn with_min_inner_size(mut self, value: Option) -> Self { self.min_inner_size = Some(value); self } - pub fn with_max_inner_size(mut self, value: Option<(u32, u32)>) -> Self { + /// Should be bigger then 0 + pub fn with_max_inner_size(mut self, value: Option) -> Self { self.max_inner_size = Some(value); self } @@ -211,12 +216,13 @@ impl ViewportBuilder { self } + /// This currently only work on windows to be disabled! pub fn with_drag_and_drop(mut self, value: bool) -> Self { self.drag_and_drop = Some(value); self } - pub fn with_position(mut self, value: Option<(i32, i32)>) -> Self { + pub fn with_position(mut self, value: Option) -> Self { self.position = Some(value); self } @@ -242,11 +248,17 @@ pub enum ViewportCommand { Transparent(bool), Visible(bool), Drag, - OuterPosition(i32, i32), - InnerSize(u32, u32), - MinInnerSize(Option<(u32, u32)>), - MaxInnerSize(Option<(u32, u32)>), - ResizeIncrements(Option<(u32, u32)>), + OuterPosition(Pos2), + + /// Should be bigger then 0 + InnerSize(Pos2), + + /// Should be bigger then 0 + MinInnerSize(Option), + + /// Should be bigger then 0 + MaxInnerSize(Option), + ResizeIncrements(Option), /// Top, Bottom, Right, Left Resize(bool, bool, bool, bool), @@ -264,7 +276,7 @@ pub enum ViewportCommand { /// 0 = Normal, 1 = AlwaysOnBottom, 2 = AlwaysOnTop WindowLevel(u8), WindowIcon(Option<(Vec, u32, u32)>), - IMEPosition(u32, u32), + IMEPosition(Pos2), IMEAllowed(bool), /// 0 = Normal, 1 = Password, 2 = Terminal @@ -278,7 +290,7 @@ pub enum ViewportCommand { ContentProtected(bool), - CursorPosition(i32, i32), + CursorPosition(Pos2), /// 0 = None, 1 = Confined, 2 = Locked CursorGrab(u8),