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}