1use crate::{calc::Calc, unit::*, Style, StyleUpdater};
2use derive_rich::Rich;
3
4#[derive(Rich, Clone, Debug, PartialEq, Default)]
13pub struct Position {
14 #[rich(write(rename = position), write(option, rename = try_position), value_fns = {
15 static_ = PositionType::Static,
16 absolute = PositionType::Absolute,
17 fixed = PositionType::Fixed,
18 relative = PositionType::Relative,
19 sticky = PositionType::Sticky,
20 initial = PositionType::Initial,
21 inherit = PositionType::Inherit,
22 })]
23 pub position: Option<PositionType>,
24 #[rich(write, write(option))]
25 pub left: Option<PostionLength>,
26 #[rich(write, write(option))]
27 pub top: Option<PostionLength>,
28 #[rich(write, write(option))]
29 pub right: Option<PostionLength>,
30 #[rich(write, write(option))]
31 pub bottom: Option<PostionLength>,
32 #[rich(write, write(option))]
33 pub z_index: Option<i32>,
34 #[rich(write, write(option))]
35 pub clip: Option<Clip>,
36}
37
38impl Position {
39 pub fn move_top(self) -> Self {
40 self.top(px(0))
41 }
42
43 pub fn move_right(self) -> Self {
44 self.right(px(0))
45 }
46
47 pub fn move_bottom(self) -> Self {
48 self.bottom(px(0))
49 }
50
51 pub fn move_left(self) -> Self {
52 self.left(px(0))
53 }
54
55 pub fn move_top_stretch(self) -> Self {
56 self.move_top().move_left().move_right()
57 }
58
59 pub fn move_right_stretch(self) -> Self {
60 self.move_right().move_top().move_bottom()
61 }
62
63 pub fn move_bottom_stretch(self) -> Self {
64 self.move_bottom().move_left().move_right()
65 }
66
67 pub fn move_left_stretch(self) -> Self {
68 self.move_left().move_top().move_bottom()
69 }
70
71 pub fn move_top_right(self) -> Self {
72 self.move_top().move_right()
73 }
74
75 pub fn move_top_left(self) -> Self {
76 self.move_top().move_left()
77 }
78
79 pub fn move_bottom_right(self) -> Self {
80 self.move_bottom().move_right()
81 }
82
83 pub fn move_bottom_left(self) -> Self {
84 self.move_bottom().move_left()
85 }
86
87 pub fn cover(self) -> Self {
88 self.move_top_right().move_bottom_left()
89 }
90}
91
92impl StyleUpdater for Position {
93 fn update_style(self, style: Style) -> Style {
94 style
95 .try_insert("position", self.position.as_ref())
96 .try_insert("left", self.left.as_ref())
97 .try_insert("top", self.top.as_ref())
98 .try_insert("right", self.right.as_ref())
99 .try_insert("bottom", self.bottom.as_ref())
100 .try_insert("z-index", self.z_index.as_ref())
101 .try_insert("clip", self.clip.as_ref())
102 }
103}
104
105impl<T> From<T> for Position
106where
107 T: Into<PositionType>,
108{
109 fn from(source: T) -> Self {
110 Self {
111 position: Some(source.into()),
112 ..Position::default()
113 }
114 }
115}
116
117#[derive(Clone, Debug, PartialEq, Display, From)]
118pub enum PostionLength {
119 #[display(fmt = "initial")]
120 Initial,
121 #[display(fmt = "inherit")]
122 Inherit,
123 #[display(fmt = "auto")]
124 Auto,
125 #[from]
126 Length(Length),
127 #[from(forward)]
128 Percent(Percent),
129}
130
131impl From<Calc> for PostionLength {
132 fn from(source: Calc) -> Self {
133 PostionLength::Length(source.into())
134 }
135}
136
137#[derive(Clone, Debug, PartialEq, Display, From)]
138pub enum Clip {
139 #[display(fmt = "auto")]
140 Auto,
141 #[display(fmt = "rect({}, {}, {}, {})", top, right, bottom, left)]
142 ShapeRect {
143 top: ClipRectLength,
144 right: ClipRectLength,
145 bottom: ClipRectLength,
146 left: ClipRectLength,
147 },
148 #[display(fmt = "initial")]
149 Initial,
150 #[display(fmt = "inherit")]
151 Inherit,
152}
153
154impl Clip {
155 pub fn rect(
156 top: impl Into<ClipRectLength>,
157 right: impl Into<ClipRectLength>,
158 bottom: impl Into<ClipRectLength>,
159 left: impl Into<ClipRectLength>,
160 ) -> Self {
161 Self::ShapeRect {
162 top: top.into(),
163 right: right.into(),
164 bottom: bottom.into(),
165 left: left.into(),
166 }
167 }
168}
169
170#[derive(Clone, Debug, PartialEq, Display, From)]
171pub enum ClipRectLength {
172 #[display(fmt = "initial")]
173 Initial,
174 #[display(fmt = "inherit")]
175 Inherit,
176 #[display(fmt = "auto")]
177 Auto,
178 #[from]
179 Length(Length),
180 #[from(forward)]
181 Percent(Percent),
182}
183
184impl From<Calc> for ClipRectLength {
185 fn from(source: Calc) -> Self {
186 ClipRectLength::Length(source.into())
187 }
188}
189
190#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
191pub enum PositionType {
192 #[display(fmt = "static")]
193 Static,
194 #[display(fmt = "absolute")]
195 Absolute,
196 #[display(fmt = "fixed")]
197 Fixed,
198 #[display(fmt = "relative")]
199 Relative,
200 #[display(fmt = "sticky")]
201 Sticky,
202 #[display(fmt = "initial")]
203 Initial,
204 #[display(fmt = "inherit")]
205 Inherit,
206}