mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
switch winit size to logical to be dpi independent (#947)
* switch winit size to logical * make scale factor available from bevy_window
This commit is contained in:
parent
4cd3dd70b7
commit
6b004f7d16
4 changed files with 67 additions and 32 deletions
|
@ -46,6 +46,7 @@ pub struct Window {
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
pub canvas: Option<String>,
|
||||
command_queue: Vec<WindowCommand>,
|
||||
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
|
||||
|
|
|
@ -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<f32>,
|
||||
) -> 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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -185,28 +185,27 @@ pub fn winit_runner(mut app: App) {
|
|||
|
||||
match event {
|
||||
event::Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
event,
|
||||
window_id: winit_window_id,
|
||||
..
|
||||
} => {
|
||||
} => match event {
|
||||
WindowEvent::Resized(size) => {
|
||||
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
|
||||
let mut windows = app.resources.get_mut::<Windows>().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::<Events<WindowResized>>().unwrap();
|
||||
let mut resize_events =
|
||||
app.resources.get_mut::<Events<WindowResized>>().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::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::<WinitWindows>().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::<f32>(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::<Events<TouchInput>>().unwrap();
|
||||
|
||||
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
|
||||
let windows = app.resources.get_mut::<Windows>().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::<WinitWindows>().unwrap();
|
||||
let mut windows = app.resources.get_mut::<Windows>().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::<Events<CreateWindow>>().unwrap();
|
||||
let mut window_created_events = resources.get_mut::<Events<WindowCreated>>().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 });
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue