css_style/
size.rs

1use crate::{
2    calc::Calc,
3    unit::{self, *},
4    Style, StyleUpdater,
5};
6use derive_rich::Rich;
7
8/// ```
9/// use css_style::{prelude::*, unit::em};
10///
11/// style()
12///     .and_size(|conf| {
13///         conf.width(em(2.))
14///             .height(em(1.5))
15///             .min_width(em(1.5))
16///             .min_height(em(1.))
17///             .max_width(em(4.))
18///             .max_height(em(3.))
19///     });
20/// ```
21#[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// https://www.w3.org/TR/css-values-4/#lengths
147#[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}