yakui_core/geometry/
dim.rs

1use glam::Vec2;
2
3/// Describes a length consisting of one or more measurements added together.
4///
5/// This struct is inspired by CSS's unit system, which is a very flexible way
6/// to talk about the size of widgets in a layout.
7///
8/// The equivalent CSS for a given `Dim` is:
9///
10/// ```css
11/// calc(dim.pixels + 100 * dim.percent)
12/// ```
13///
14/// where `dim.pixels` is the `px` unit in CSS and `dim.percent` is the `%` unit
15/// in CSS.
16#[derive(Debug, Clone, Copy, Default, PartialEq)]
17pub struct Dim {
18    /// The portion of the value in logical pixels. Works like the `px` unit in
19    /// CSS.
20    pub pixels: f32,
21
22    /// A value scaled based on the parent object's measurement on the axis.
23    /// `1.0` corresponds to 100% of the parent width, while `0.0` corresponds
24    /// to 0%.
25    pub percent: f32,
26}
27
28impl Dim {
29    /// A `Dim` corresponding to a length of zero.
30    pub const ZERO: Self = Self {
31        pixels: 0.0,
32        percent: 0.0,
33    };
34
35    /// Returns a `Dim` with the given length in pixels.
36    pub const fn pixels(pixels: f32) -> Self {
37        Self {
38            pixels,
39            ..Self::ZERO
40        }
41    }
42
43    /// Returns a `Dim` with the given length as a percentage of the parent
44    /// container.
45    pub const fn percent(percent: f32) -> Self {
46        Self {
47            percent,
48            ..Self::ZERO
49        }
50    }
51
52    /// Resolves the `Dim` to a single value in pixels using information about
53    /// the surrounding context.
54    pub fn resolve(&self, parent_length: f32) -> f32 {
55        self.pixels + parent_length * self.percent
56    }
57}
58
59/// A size or position in 2D based on one or more measurements added together.
60///
61/// See [`Dim`] for more information on the units available and their meaning.
62#[derive(Debug, Clone, Copy, Default, PartialEq)]
63pub struct Dim2 {
64    /// The dimension on the X axis.
65    pub x: Dim,
66
67    /// The dimension on the Y axis.
68    pub y: Dim,
69}
70
71impl Dim2 {
72    /// A `Dim2` corresponding to zero on both axes.
73    pub const ZERO: Self = Dim2 {
74        x: Dim::ZERO,
75        y: Dim::ZERO,
76    };
77
78    /// Create a new `Dim2` from two [`Dim`] values.
79    pub const fn new(x: Dim, y: Dim) -> Self {
80        Self { x, y }
81    }
82
83    /// Create a new `Dim2` with pixel values for each axis.
84    pub const fn pixels(x: f32, y: f32) -> Self {
85        Self {
86            x: Dim::pixels(x),
87            y: Dim::pixels(y),
88        }
89    }
90
91    /// Resolves the `Dim2` to a measurement in pixels using information about
92    /// the surrounding context.
93    pub fn resolve(&self, parent_size: Vec2) -> Vec2 {
94        let x = self.x.resolve(parent_size.x);
95        let y = self.y.resolve(parent_size.y);
96
97        Vec2::new(x, y)
98    }
99}