gpui_component/
geometry.rs1use std::fmt::{self, Display, Formatter};
2
3use gpui::{AbsoluteLength, Axis, Length, Pixels};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10pub enum Placement {
11 #[serde(rename = "top")]
12 Top,
13 #[serde(rename = "bottom")]
14 Bottom,
15 #[serde(rename = "left")]
16 Left,
17 #[serde(rename = "right")]
18 Right,
19}
20
21impl Display for Placement {
22 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 match self {
24 Placement::Top => write!(f, "Top"),
25 Placement::Bottom => write!(f, "Bottom"),
26 Placement::Left => write!(f, "Left"),
27 Placement::Right => write!(f, "Right"),
28 }
29 }
30}
31
32impl Placement {
33 #[inline]
34 pub fn is_horizontal(&self) -> bool {
35 match self {
36 Placement::Left | Placement::Right => true,
37 _ => false,
38 }
39 }
40
41 #[inline]
42 pub fn is_vertical(&self) -> bool {
43 match self {
44 Placement::Top | Placement::Bottom => true,
45 _ => false,
46 }
47 }
48
49 #[inline]
50 pub fn axis(&self) -> Axis {
51 match self {
52 Placement::Top | Placement::Bottom => Axis::Vertical,
53 Placement::Left | Placement::Right => Axis::Horizontal,
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
62pub enum Side {
63 #[serde(rename = "left")]
64 Left,
65 #[serde(rename = "right")]
66 Right,
67}
68
69impl Side {
70 #[inline]
72 pub fn is_left(&self) -> bool {
73 matches!(self, Self::Left)
74 }
75
76 #[inline]
78 pub fn is_right(&self) -> bool {
79 matches!(self, Self::Right)
80 }
81}
82
83pub trait AxisExt {
85 fn is_horizontal(self) -> bool;
86 fn is_vertical(self) -> bool;
87}
88
89impl AxisExt for Axis {
90 #[inline]
91 fn is_horizontal(self) -> bool {
92 self == Axis::Horizontal
93 }
94
95 #[inline]
96 fn is_vertical(self) -> bool {
97 self == Axis::Vertical
98 }
99}
100
101pub trait PixelsExt {
103 fn as_f32(&self) -> f32;
104 fn as_f64(self) -> f64;
105}
106impl PixelsExt for Pixels {
107 fn as_f32(&self) -> f32 {
108 f32::from(self)
109 }
110
111 fn as_f64(self) -> f64 {
112 f64::from(self)
113 }
114}
115
116pub trait LengthExt {
118 fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option<Pixels>;
122}
123
124impl LengthExt for Length {
125 fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option<Pixels> {
126 match self {
127 Length::Auto => None,
128 Length::Definite(len) => Some(len.to_pixels(base_size, rem_size)),
129 }
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::Placement;
136 #[test]
137 fn test_placement() {
138 assert!(Placement::Left.is_horizontal());
139 assert!(Placement::Right.is_horizontal());
140 assert!(!Placement::Top.is_horizontal());
141 assert!(!Placement::Bottom.is_horizontal());
142
143 assert!(Placement::Top.is_vertical());
144 assert!(Placement::Bottom.is_vertical());
145 assert!(!Placement::Left.is_vertical());
146 assert!(!Placement::Right.is_vertical());
147
148 assert_eq!(Placement::Top.axis(), gpui::Axis::Vertical);
149 assert_eq!(Placement::Bottom.axis(), gpui::Axis::Vertical);
150 assert_eq!(Placement::Left.axis(), gpui::Axis::Horizontal);
151 assert_eq!(Placement::Right.axis(), gpui::Axis::Horizontal);
152
153 assert_eq!(Placement::Top.to_string(), "Top");
154 assert_eq!(Placement::Bottom.to_string(), "Bottom");
155 assert_eq!(Placement::Left.to_string(), "Left");
156 assert_eq!(Placement::Right.to_string(), "Right");
157
158 assert_eq!(serde_json::to_string(&Placement::Top).unwrap(), r#""top""#);
159 assert_eq!(
160 serde_json::to_string(&Placement::Bottom).unwrap(),
161 r#""bottom""#
162 );
163 assert_eq!(
164 serde_json::to_string(&Placement::Left).unwrap(),
165 r#""left""#
166 );
167 assert_eq!(
168 serde_json::to_string(&Placement::Right).unwrap(),
169 r#""right""#
170 );
171
172 assert_eq!(
173 serde_json::from_str::<Placement>(r#""top""#).unwrap(),
174 Placement::Top
175 );
176 assert_eq!(
177 serde_json::from_str::<Placement>(r#""bottom""#).unwrap(),
178 Placement::Bottom
179 );
180 assert_eq!(
181 serde_json::from_str::<Placement>(r#""left""#).unwrap(),
182 Placement::Left
183 );
184 assert_eq!(
185 serde_json::from_str::<Placement>(r#""right""#).unwrap(),
186 Placement::Right
187 );
188 }
189
190 #[test]
191 fn test_side() {
192 use super::Side;
193 let left = Side::Left;
194 let right = Side::Right;
195
196 assert!(left.is_left());
197 assert!(!left.is_right());
198
199 assert!(right.is_right());
200 assert!(!right.is_left());
201
202 assert_eq!(serde_json::to_string(&left).unwrap(), r#""left""#);
204 assert_eq!(serde_json::to_string(&right).unwrap(), r#""right""#);
205 assert_eq!(
206 serde_json::from_str::<Side>(r#""left""#).unwrap(),
207 Side::Left
208 );
209 assert_eq!(
210 serde_json::from_str::<Side>(r#""right""#).unwrap(),
211 Side::Right
212 );
213 }
214}