// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 use crate::BorderRadius; use crate::Coord; /// This type is used as a tagging type for use with [`euclid::Scale`] to convert /// between physical and logical pixels. pub struct PhysicalPx; /// This type is used as a tagging type for use with [`euclid::Scale`] to convert /// between physical and logical pixels. pub struct LogicalPx; pub type LogicalLength = euclid::Length; pub type LogicalRect = euclid::Rect; pub type LogicalPoint = euclid::Point2D; pub type LogicalSize = euclid::Size2D; pub type LogicalVector = euclid::Vector2D; pub type LogicalBorderRadius = BorderRadius; pub type PhysicalBorderRadius = BorderRadius; pub type ItemTransform = euclid::Transform2D; pub type ScaleFactor = euclid::Scale; pub trait SizeLengths { type LengthType; fn width_length(&self) -> Self::LengthType; fn height_length(&self) -> Self::LengthType; } impl SizeLengths for euclid::Size2D { type LengthType = euclid::Length; fn width_length(&self) -> Self::LengthType { euclid::Length::new(self.width) } fn height_length(&self) -> Self::LengthType { euclid::Length::new(self.height) } } pub trait PointLengths { type LengthType; fn x_length(&self) -> Self::LengthType; fn y_length(&self) -> Self::LengthType; } impl PointLengths for euclid::Point2D { type LengthType = euclid::Length; fn x_length(&self) -> Self::LengthType { euclid::Length::new(self.x) } fn y_length(&self) -> Self::LengthType { euclid::Length::new(self.y) } } impl PointLengths for euclid::Vector2D { type LengthType = euclid::Length; fn x_length(&self) -> Self::LengthType { euclid::Length::new(self.x) } fn y_length(&self) -> Self::LengthType { euclid::Length::new(self.y) } } pub trait RectLengths { type SizeType; type LengthType; fn size_length(&self) -> Self::SizeType; fn width_length(&self) -> Self::LengthType; fn height_length(&self) -> Self::LengthType; /// The typed horizontal range, unlike euclid's unitless [`euclid::Rect::x_range`]. fn x_length_range(&self) -> core::ops::Range; } impl, U> RectLengths for euclid::Rect { type LengthType = euclid::Length; type SizeType = euclid::Size2D; fn size_length(&self) -> Self::SizeType { euclid::Size2D::new(self.size.width, self.size.height) } fn width_length(&self) -> Self::LengthType { self.size_length().width_length() } fn height_length(&self) -> Self::LengthType { self.size_length().height_length() } fn x_length_range(&self) -> core::ops::Range { self.origin.x_length()..self.origin.x_length() + self.width_length() } } /// Convert from the api size to the internal size /// (This doesn't use the `From` trait because it would expose the conversion to euclid in the public API) pub fn logical_size_from_api(size: crate::api::LogicalSize) -> LogicalSize { size.to_euclid() } pub fn logical_point_from_api(position: crate::api::LogicalPosition) -> LogicalPoint { position.to_euclid() } pub fn logical_position_to_api(pos: LogicalPoint) -> crate::api::LogicalPosition { crate::api::LogicalPosition::from_euclid(pos) } pub fn logical_size_to_api(size: LogicalSize) -> crate::api::LogicalSize { crate::api::LogicalSize::from_euclid(size) } /// Four distances from the edges of a rectangle represented in the coordinate space of logical pixels. #[derive(Debug, Default, Copy, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[repr(C)] pub struct LogicalEdges { /// The top distance in logical pixels. pub top: f32, /// The bottom distance in logical pixels. pub bottom: f32, /// The left distance in logical pixels. pub left: f32, /// The right distance in logical pixels. pub right: f32, } impl LogicalEdges { /// Construct a new logical edges struct from the given border values, that are assumed to be /// in the logical coordinate space. pub const fn new(top: f32, bottom: f32, left: f32, right: f32) -> Self { Self { top, bottom, left, right } } /// Converts the top edge to logical pixels. #[inline] pub const fn top(&self) -> LogicalLength { LogicalLength::new(self.top as crate::Coord) } /// Converts the bottom edge to logical pixels. #[inline] pub const fn bottom(&self) -> LogicalLength { LogicalLength::new(self.bottom as crate::Coord) } /// Converts the left edge to logical pixels. #[inline] pub const fn left(&self) -> LogicalLength { LogicalLength::new(self.left as crate::Coord) } /// Converts the right edge to logical pixels. #[inline] pub const fn right(&self) -> LogicalLength { LogicalLength::new(self.right as crate::Coord) } } /// Four distances from the edges of a rectangle represented in the coordinate space of physical pixels. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PhysicalEdges { /// The top edge in physical pixels. pub top: i32, /// The bottom edge in physical pixels. pub bottom: i32, /// The left edge in physical pixels. pub left: i32, /// The right edge in physical pixels. pub right: i32, } impl PhysicalEdges { /// Construct a new physical edges struct from the given border values, that are assumed to be /// in the physical coordinate space. pub const fn new(top: i32, bottom: i32, left: i32, right: i32) -> Self { Self { top, bottom, left, right } } /// Convert a given logical edges to a physical edges by dividing the lengths by the /// specified scale factor. #[inline] pub const fn to_logical(&self, scale_factor: f32) -> LogicalEdges { LogicalEdges::new( self.top_to_logical(scale_factor).0 as f32, self.bottom_to_logical(scale_factor).0 as f32, self.left_to_logical(scale_factor).0 as f32, self.right_to_logical(scale_factor).0 as f32, ) } /// Convert the top logical edge to a physical edge by dividing the length by the /// specified scale factor. #[inline] pub const fn top_to_logical(&self, scale_factor: f32) -> LogicalLength { LogicalLength::new((self.top as f32 / scale_factor) as crate::Coord) } /// Convert the bottom logical edge to a physical edge by dividing the length by the /// specified scale factor. #[inline] pub const fn bottom_to_logical(&self, scale_factor: f32) -> LogicalLength { LogicalLength::new((self.bottom as f32 / scale_factor) as crate::Coord) } #[inline] /// Convert the left logical edge to a physical edge by dividing the length by the /// specified scale factor. pub const fn left_to_logical(&self, scale_factor: f32) -> LogicalLength { LogicalLength::new((self.left as f32 / scale_factor) as crate::Coord) } /// Convert the right logical edge to a physical edge by dividing the length by the /// specified scale factor. #[inline] pub const fn right_to_logical(&self, scale_factor: f32) -> LogicalLength { LogicalLength::new((self.right as f32 / scale_factor) as crate::Coord) } }