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 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 engine/src/windowing/dpi.rs (limited to 'engine/src/windowing/dpi.rs') 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) +} -- cgit v1.2.3-18-g5258