From 6b004f7d16795c413ca64ff8e3973dbb453da66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Tue, 1 Dec 2020 03:24:49 +0100 Subject: [PATCH] switch winit size to logical to be dpi independent (#947) * switch winit size to logical * make scale factor available from bevy_window --- crates/bevy_window/src/window.rs | 12 +++++ crates/bevy_winit/src/converters.rs | 7 ++- crates/bevy_winit/src/lib.rs | 74 ++++++++++++++++---------- crates/bevy_winit/src/winit_windows.rs | 6 ++- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 387f320cbfe9d..9ce9917948417 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -46,6 +46,7 @@ pub struct Window { #[cfg(target_arch = "wasm32")] pub canvas: Option, command_queue: Vec, + scale_factor: f64, } #[derive(Debug)] @@ -110,6 +111,7 @@ impl Window { #[cfg(target_arch = "wasm32")] canvas: window_descriptor.canvas.clone(), command_queue: Vec::new(), + scale_factor: 1.0, } } @@ -141,6 +143,16 @@ impl Window { self.height = height; } + #[doc(hidden)] + pub fn update_scale_factor_from_backend(&mut self, scale_factor: f64) { + self.scale_factor = scale_factor; + } + + #[inline] + pub fn scale_factor(&self) -> f64 { + self.scale_factor + } + #[inline] pub fn title(&self) -> &str { &self.title diff --git a/crates/bevy_winit/src/converters.rs b/crates/bevy_winit/src/converters.rs index 060096de401c1..19d6ed903be5d 100644 --- a/crates/bevy_winit/src/converters.rs +++ b/crates/bevy_winit/src/converters.rs @@ -30,7 +30,10 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut } } -pub fn convert_touch_input(touch_input: winit::event::Touch) -> TouchInput { +pub fn convert_touch_input( + touch_input: winit::event::Touch, + location: winit::dpi::LogicalPosition, +) -> TouchInput { TouchInput { phase: match touch_input.phase { winit::event::TouchPhase::Started => TouchPhase::Started, @@ -38,7 +41,7 @@ pub fn convert_touch_input(touch_input: winit::event::Touch) -> TouchInput { winit::event::TouchPhase::Ended => TouchPhase::Ended, winit::event::TouchPhase::Cancelled => TouchPhase::Cancelled, }, - position: Vec2::new(touch_input.location.x as f32, touch_input.location.y as f32), + position: Vec2::new(location.x as f32, location.y as f32), force: touch_input.force.map(|f| match f { winit::event::Force::Calibrated { force, diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index d740e08700d96..ec8120701ad24 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -73,7 +73,7 @@ fn change_window(_: &mut World, resources: &mut Resources) { } bevy_window::WindowCommand::SetResolution { width, height } => { let window = winit_windows.get_window(id).unwrap(); - window.set_inner_size(winit::dpi::PhysicalSize::new(width, height)); + window.set_inner_size(winit::dpi::LogicalSize::new(width, height)); } bevy_window::WindowCommand::SetVsync { .. } => (), bevy_window::WindowCommand::SetResizable { resizable } => { @@ -97,7 +97,7 @@ fn change_window(_: &mut World, resources: &mut Resources) { bevy_window::WindowCommand::SetCursorPosition { x, y } => { let window = winit_windows.get_window(id).unwrap(); window - .set_cursor_position(winit::dpi::PhysicalPosition::new(x, y)) + .set_cursor_position(winit::dpi::LogicalPosition::new(x, y)) .unwrap_or_else(|e| error!("Unable to set cursor position: {}", e)); } } @@ -184,29 +184,28 @@ pub fn winit_runner(mut app: App) { } match event { - event::Event::WindowEvent { - event: WindowEvent::Resized(size), - window_id: winit_window_id, - .. - } => { - let winit_windows = app.resources.get_mut::().unwrap(); - let mut windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let window = windows.get_mut(window_id).unwrap(); - window.update_resolution_from_backend(size.width, size.height); - - let mut resize_events = app.resources.get_mut::>().unwrap(); - resize_events.send(WindowResized { - id: window_id, - height: window.height() as usize, - width: window.width() as usize, - }); - } event::Event::WindowEvent { event, window_id: winit_window_id, .. } => match event { + WindowEvent::Resized(size) => { + let winit_windows = app.resources.get_mut::().unwrap(); + let mut windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + let winit_window = winit_windows.get_window(window_id).unwrap(); + let window = windows.get_mut(window_id).unwrap(); + let size = size.to_logical(winit_window.scale_factor()); + window.update_resolution_from_backend(size.width, size.height); + + let mut resize_events = + app.resources.get_mut::>().unwrap(); + resize_events.send(WindowResized { + id: window_id, + height: window.height() as usize, + width: window.width() as usize, + }); + } WindowEvent::CloseRequested => { let mut window_close_requested_events = app .resources @@ -227,12 +226,13 @@ pub fn winit_runner(mut app: App) { let winit_windows = app.resources.get_mut::().unwrap(); let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); let window = winit_windows.get_window(window_id).unwrap(); - let inner_size = window.inner_size(); + let position = position.to_logical(window.scale_factor()); + let inner_size = window.inner_size().to_logical::(window.scale_factor()); // move origin to bottom left - let y_position = inner_size.height as f32 - position.y as f32; + let y_position = inner_size.height - position.y; cursor_moved_events.send(CursorMoved { id: window_id, - position: Vec2::new(position.x as f32, y_position as f32), + position: Vec2::new(position.x, y_position), }); } WindowEvent::MouseInput { state, button, .. } => { @@ -263,16 +263,22 @@ pub fn winit_runner(mut app: App) { }); } }, - WindowEvent::Touch(mut touch) => { + WindowEvent::Touch(touch) => { let mut touch_input_events = app.resources.get_mut::>().unwrap(); + + let winit_windows = app.resources.get_mut::().unwrap(); let windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + let winit_window = winit_windows.get_window(window_id).unwrap(); + let mut location = touch.location.to_logical(winit_window.scale_factor()); + // FIXME?: On Android window start is top while on PC/Linux/OSX on bottom if cfg!(target_os = "android") { let window_height = windows.get_primary().unwrap().height(); - touch.location.y = window_height as f64 - touch.location.y; + location.y = window_height as f32 - location.y; } - touch_input_events.send(converters::convert_touch_input(touch)); + touch_input_events.send(converters::convert_touch_input(touch, location)); } WindowEvent::ReceivedCharacter(c) => { let mut char_input_events = app @@ -288,6 +294,18 @@ pub fn winit_runner(mut app: App) { char: c, }) } + WindowEvent::ScaleFactorChanged { + scale_factor, + new_inner_size, + } => { + let winit_windows = app.resources.get_mut::().unwrap(); + let mut windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + let window = windows.get_mut(window_id).unwrap(); + let size = new_inner_size.to_logical(scale_factor); + window.update_scale_factor_from_backend(scale_factor); + window.update_resolution_from_backend(size.width, size.height); + } _ => {} }, event::Event::DeviceEvent { ref event, .. } => { @@ -327,8 +345,8 @@ fn handle_create_window_events( let create_window_events = resources.get::>().unwrap(); let mut window_created_events = resources.get_mut::>().unwrap(); for create_window_event in create_window_event_reader.iter(&create_window_events) { - let window = Window::new(create_window_event.id, &create_window_event.descriptor); - winit_windows.create_window(event_loop, &window); + let mut window = Window::new(create_window_event.id, &create_window_event.descriptor); + winit_windows.create_window(event_loop, &mut window); let window_id = window.id(); windows.add(window); window_created_events.send(WindowCreated { id: window_id }); diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index ec86a1a800dee..01cbde57fefd2 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -12,7 +12,7 @@ impl WinitWindows { pub fn create_window( &mut self, event_loop: &winit::event_loop::EventLoopWindowTarget<()>, - window: &Window, + window: &mut Window, ) { #[cfg(target_os = "windows")] let mut winit_window_builder = { @@ -38,7 +38,7 @@ impl WinitWindows { }), )), _ => winit_window_builder - .with_inner_size(winit::dpi::PhysicalSize::new( + .with_inner_size(winit::dpi::LogicalSize::new( window.width(), window.height(), )) @@ -100,6 +100,8 @@ impl WinitWindows { } } + window.update_scale_factor_from_backend(winit_window.scale_factor()); + self.windows.insert(winit_window.id(), winit_window); }