From 9df8a4d197e66accb389edb5a5c54117933f157e Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 28 Jun 2026 00:09:06 +0200 Subject: feat(engine): add windowing DPI utilities --- engine/src/windowing/dpi.rs | 182 +++++++++++++++++++++++++++++++++++++++++ engine/src/windowing/mouse.rs | 3 +- engine/src/windowing/window.rs | 41 ++-------- 3 files changed, 191 insertions(+), 35 deletions(-) create mode 100644 engine/src/windowing/dpi.rs (limited to 'engine/src/windowing') diff --git a/engine/src/windowing/dpi.rs b/engine/src/windowing/dpi.rs new file mode 100644 index 0000000..2bac619 --- /dev/null +++ b/engine/src/windowing/dpi.rs @@ -0,0 +1,182 @@ +macro_rules! gen_struct_from_to_impls { + ($struct: ident, fields=($($field: ident),*)) => { + impl From> for $struct + { + fn from(source: winit::dpi::$struct) -> Self + { + Self { + $($field: source.$field),* + } + } + } + + impl From<$struct> for winit::dpi::$struct + { + fn from(source: $struct) -> Self + { + Self { + $($field: source.$field),* + } + } + } + }; +} + +macro_rules! gen_enum_from_to_impls { + ($enum: ident, variants=($($variant: ident),*)) => { + impl From for $enum + { + fn from(source: winit::dpi::$enum) -> Self + { + match source { + $(winit::dpi::$enum::$variant(pos) => Self::$variant(pos.into())),* + } + } + } + + impl From<$enum> for winit::dpi::$enum + { + fn from(source: $enum) -> Self + { + match source { + $($enum::$variant(pos) => Self::$variant(pos.into())),* + } + } + } + }; +} + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct PhysicalPosition +{ + pub x: Pixel, + pub y: Pixel +} + +impl PhysicalPosition +{ + pub fn to_logical(&self, scale_factor: f64) -> LogicalPosition + where + Pixel: Into + Clone, + LogicalPixel: From + { + let x = self.x.clone().into(); + let y = self.y.clone().into(); + + LogicalPosition { + x: (x / scale_factor).into(), + y: (y / scale_factor).into() + } + } + + pub fn try_convert_from(source: PhysicalPosition) -> Result + where + Pixel: TryFrom + { + Ok(Self { + x: source.x.try_into()?, + y: source.y.try_into()? + }) + } +} + +gen_struct_from_to_impls!(PhysicalPosition, fields=(x, y)); + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct LogicalPosition +{ + pub x: Pixel, + pub y: Pixel +} + +impl LogicalPosition +{ + pub fn try_convert_from(source: LogicalPosition) -> Result + where + Pixel: TryFrom + { + Ok(Self { + x: source.x.try_into()?, + y: source.y.try_into()? + }) + } +} + +gen_struct_from_to_impls!(LogicalPosition, fields=(x, y)); + +#[derive(Debug, Clone, PartialEq)] +pub enum Position +{ + Physical(PhysicalPosition), + Logical(LogicalPosition) +} + +gen_enum_from_to_impls!(Position, variants=(Physical, Logical)); + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct PhysicalSize +{ + pub width: Pixel, + pub height: Pixel +} + +impl PhysicalSize +{ + pub fn to_logical(&self, scale_factor: f64) -> LogicalSize + where + Pixel: Into + Clone, + LogicalPixel: From + { + let width = self.width.clone().into(); + let height = self.height.clone().into(); + + LogicalSize { + width: (width / scale_factor).into(), + height: (height / scale_factor).into() + } + } +} + +impl PhysicalSize +{ + pub fn try_convert_from(source: PhysicalSize) -> Result + where + Pixel: TryFrom + { + Ok(Self { + width: source.width.try_into()?, + height: source.height.try_into()? + }) + } +} + +gen_struct_from_to_impls!(PhysicalSize, fields=(width, height)); + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct LogicalSize +{ + pub width: Pixel, + pub height: Pixel +} + +impl LogicalSize +{ + pub fn try_convert_from(source: LogicalSize) -> Result + where + Pixel: TryFrom + { + Ok(Self { + width: source.width.try_into()?, + height: source.height.try_into()? + }) + } +} + +gen_struct_from_to_impls!(LogicalSize, fields=(width, height)); + +#[derive(Debug, Clone, PartialEq)] +pub enum Size +{ + Physical(PhysicalSize), + Logical(LogicalSize) +} diff --git a/engine/src/windowing/mouse.rs b/engine/src/windowing/mouse.rs index f4969ea..649036a 100644 --- a/engine/src/windowing/mouse.rs +++ b/engine/src/windowing/mouse.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use crate::ecs::Sole; use crate::vector::Vec2; +use crate::windowing::dpi::PhysicalPosition; #[derive(Debug, Default, Clone, Sole)] #[non_exhaustive] @@ -15,7 +16,7 @@ pub struct Mouse /// Coordinates in pixels relative to the top-left corner of the window. May have /// been affected by cursor acceleration - pub position: Vec2, + pub position: PhysicalPosition, } /// Mouse buttons. diff --git a/engine/src/windowing/window.rs b/engine/src/windowing/window.rs index 7be2562..039d98a 100644 --- a/engine/src/windowing/window.rs +++ b/engine/src/windowing/window.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; -use crate::data_types::dimens::Dimens; use crate::ecs::Component; use crate::reflection::Reflection; +use crate::windowing::dpi::PhysicalSize; pub mod platform; @@ -99,7 +99,7 @@ pub struct Window pub title: String, pub cursor_visible: bool, pub cursor_grab_mode: CursorGrabMode, - pub inner_size: Dimens, + pub inner_size: PhysicalSize, wid: Id, scale_factor: f64, } @@ -137,15 +137,15 @@ impl Window winit_window.set_title(&self.title); winit_window.set_cursor_visible(self.cursor_visible); - let curr_inner_size = winit_window.inner_size(); + let curr_inner_size = winit_window.inner_size().clone().into(); let inner_size_request_result = match winit_window - .request_inner_size(winit::dpi::Size::Physical(self.inner_size.into())) + .request_inner_size(winit::dpi::Size::Physical(self.inner_size.clone().into())) { // The comparison of curr_inner_size is in case the user's windowing system // lies about using the requested inner size - None if curr_inner_size == self.inner_size.into() => Ok(()), - None => Err(curr_inner_size.into()), + None if curr_inner_size == self.inner_size => Ok(()), + None => Err(curr_inner_size), Some(inner_size) => Err(inner_size.into()), }; @@ -154,11 +154,6 @@ impl Window } } - pub(crate) fn set_inner_size(&mut self, inner_size: Dimens) - { - self.inner_size = inner_size; - } - pub(crate) fn set_scale_factor(&mut self, scale_factor: f64) { self.scale_factor = scale_factor; @@ -184,30 +179,8 @@ pub enum CursorGrabMode /// A unique identifier for an X11 visual. pub type XVisualID = u32; -impl

From> for Dimens

-{ - fn from(size: winit::dpi::PhysicalSize

) -> Self - { - Self { - width: size.width, - height: size.height, - } - } -} - -impl

From> for winit::dpi::PhysicalSize

-{ - fn from(dimens: Dimens

) -> Self - { - Self { - width: dimens.width, - height: dimens.height, - } - } -} - #[derive(Debug)] pub(crate) struct ApplyResults { - pub inner_size_request: Result<(), Dimens>, + pub inner_size_request: Result<(), PhysicalSize>, } -- cgit v1.2.3-18-g5258