1use crate::{
2 calc::Calc,
3 unit::{self, *},
4 Style, StyleUpdater,
5};
6use derive_rich::Rich;
7
8#[derive(Rich, Clone, Debug, PartialEq, Default)]
22pub struct Size {
23 #[rich(write, write(option))]
24 pub width: Option<Length>,
25 #[rich(write, write(option))]
26 pub min_width: Option<Length>,
27 #[rich(write, write(option))]
28 pub max_width: Option<Length>,
29 #[rich(write, write(option))]
30 pub height: Option<Length>,
31 #[rich(write, write(option))]
32 pub min_height: Option<Length>,
33 #[rich(write, write(option))]
34 pub max_height: Option<Length>,
35}
36
37impl StyleUpdater for Size {
38 fn update_style(self, style: Style) -> Style {
39 style
40 .try_insert("width", self.width)
41 .try_insert("min-width", self.min_width)
42 .try_insert("max-width", self.max_width)
43 .try_insert("height", self.height)
44 .try_insert("min-height", self.min_height)
45 .try_insert("max-height", self.max_height)
46 }
47}
48
49impl From<Length> for Size {
50 fn from(source: Length) -> Self {
51 Self::default().all(source)
52 }
53}
54
55impl From<unit::Length> for Size {
56 fn from(source: unit::Length) -> Self {
57 Self::default().all(source)
58 }
59}
60
61impl From<Percent> for Size {
62 fn from(source: Percent) -> Self {
63 Self::default().all(source)
64 }
65}
66
67impl From<f32> for Size {
68 fn from(source: f32) -> Self {
69 Self::default().all(source)
70 }
71}
72
73impl<W, H> From<(W, H)> for Size
74where
75 W: Into<Length>,
76 H: Into<Length>,
77{
78 fn from((w, h): (W, H)) -> Self {
79 Self::default().width(w).height(h)
80 }
81}
82
83impl Unit for Length {
84 fn zero() -> Self {
85 0.0.into()
86 }
87
88 fn half() -> Self {
89 0.5.into()
90 }
91
92 fn full() -> Self {
93 1.0.into()
94 }
95}
96
97impl Size {
98 pub fn full(self) -> Self {
99 self.width(Length::full()).height(Length::full())
100 }
101
102 pub fn half(self) -> Self {
103 self.width(Length::half()).height(Length::half())
104 }
105
106 pub fn zero(self) -> Self {
107 self.width(Length::zero()).height(Length::zero())
108 }
109
110 pub fn min_content(self) -> Self {
111 self.width(Length::MinContent).height(Length::MinContent)
112 }
113
114 pub fn max_content(self) -> Self {
115 self.width(Length::MaxContent).height(Length::MaxContent)
116 }
117
118 pub fn auto(self) -> Self {
119 self.width(Length::Auto).height(Length::Auto)
120 }
121
122 pub fn resize(self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
123 self.width(width).height(height)
124 }
125
126 pub fn all(self, val: impl Into<Length>) -> Self {
127 let val = val.into();
128 self.all_widths(val.clone()).all_heights(val)
129 }
130
131 pub fn all_widths(self, width: impl Into<Length>) -> Self {
132 let width = width.into();
133 self.width(width.clone())
134 .min_width(width.clone())
135 .max_width(width)
136 }
137
138 pub fn all_heights(self, val: impl Into<Length>) -> Self {
139 let val = val.into();
140 self.height(val.clone())
141 .min_height(val.clone())
142 .max_height(val)
143 }
144}
145
146#[derive(Clone, Debug, PartialEq, Display, From)]
148pub enum Length {
149 #[display(fmt = "auto")]
150 Auto,
151 #[display(fmt = "min-content")]
152 MinContent,
153 #[display(fmt = "max-content")]
154 MaxContent,
155 #[from]
156 Length(unit::Length),
157 #[from(forward)]
158 Percent(Percent),
159}
160
161impl From<Calc> for Length {
162 fn from(source: Calc) -> Self {
163 Length::Length(source.into())
164 }
165}