diff options
Diffstat (limited to 'engine/src/windowing/dpi.rs')
| -rw-r--r-- | engine/src/windowing/dpi.rs | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/engine/src/windowing/dpi.rs b/engine/src/windowing/dpi.rs new file mode 100644 index 0000000..d628709 --- /dev/null +++ b/engine/src/windowing/dpi.rs @@ -0,0 +1,201 @@ +use crate::reflection::Reflection; + +macro_rules! gen_struct_from_to_impls { + ($struct: ident, fields=($($field: ident),*)) => { + impl<Pixel> From<winit::dpi::$struct<Pixel>> for $struct<Pixel> + { + fn from(source: winit::dpi::$struct<Pixel>) -> Self + { + Self { + $($field: source.$field),* + } + } + } + + impl<Pixel> From<$struct<Pixel>> for winit::dpi::$struct<Pixel> + { + fn from(source: $struct<Pixel>) -> Self + { + Self { + $($field: source.$field),* + } + } + } + }; +} + +macro_rules! gen_enum_from_to_impls { + ($enum: ident, variants=($($variant: ident),*)) => { + impl From<winit::dpi::$enum> 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, Reflection)] +#[reflection(impl_with_generics(<u32>, <i32>, <f32>, <f64>))] +pub struct PhysicalPosition<Pixel> +{ + pub x: Pixel, + pub y: Pixel, +} + +impl<Pixel> PhysicalPosition<Pixel> +{ + pub fn to_logical<LogicalPixel>( + &self, + scale_factor: f64, + ) -> LogicalPosition<LogicalPixel> + where + Pixel: Into<f64> + Clone, + LogicalPixel: From<f64>, + { + 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<SourcePixel>( + source: PhysicalPosition<SourcePixel>, + ) -> Result<Self, Pixel::Error> + where + Pixel: TryFrom<SourcePixel>, + { + 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, Reflection)] +#[reflection(impl_with_generics(<f64>))] +pub struct LogicalPosition<Pixel> +{ + pub x: Pixel, + pub y: Pixel, +} + +impl<Pixel> LogicalPosition<Pixel> +{ + pub fn try_convert_from<SourcePixel>( + source: LogicalPosition<SourcePixel>, + ) -> Result<Self, Pixel::Error> + where + Pixel: TryFrom<SourcePixel>, + { + 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, Reflection)] +pub enum Position +{ + Physical(PhysicalPosition<i32>), + Logical(LogicalPosition<f64>), +} + +gen_enum_from_to_impls!(Position, variants = (Physical, Logical)); + +#[derive(Debug, Default, Clone, PartialEq, Reflection)] +#[reflection(impl_with_generics(<u32>))] +pub struct PhysicalSize<Pixel> +{ + pub width: Pixel, + pub height: Pixel, +} + +impl<Pixel> PhysicalSize<Pixel> +{ + pub fn to_logical<LogicalPixel>(&self, scale_factor: f64) -> LogicalSize<LogicalPixel> + where + Pixel: Into<f64> + Clone, + LogicalPixel: From<f64>, + { + let width = self.width.clone().into(); + let height = self.height.clone().into(); + + LogicalSize { + width: (width / scale_factor).into(), + height: (height / scale_factor).into(), + } + } +} + +impl<Pixel> PhysicalSize<Pixel> +{ + pub fn try_convert_from<SourcePixel>( + source: PhysicalSize<SourcePixel>, + ) -> Result<Self, Pixel::Error> + where + Pixel: TryFrom<SourcePixel>, + { + 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, Reflection)] +#[reflection(impl_with_generics(<f64>))] +pub struct LogicalSize<Pixel> +{ + pub width: Pixel, + pub height: Pixel, +} + +impl<Pixel> LogicalSize<Pixel> +{ + pub fn try_convert_from<SourcePixel>( + source: LogicalSize<SourcePixel>, + ) -> Result<Self, Pixel::Error> + where + Pixel: TryFrom<SourcePixel>, + { + 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, Reflection)] +pub enum Size +{ + Physical(PhysicalSize<u32>), + Logical(LogicalSize<f64>), +} + +gen_enum_from_to_impls!(Size, variants = (Physical, Logical)); |
