Skip to main content

gpui_base/
geometry.rs

1// crates/component/src/geometry.rs
2use std::fmt::{self, Debug, Display, Formatter};
3
4use gpui::{AbsoluteLength, Axis, Length, Pixels};
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8/// A enum for defining the placement of the element.
9///
10/// See also: [`Side`] if you need to define the left, right side.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
12pub enum Placement {
13    #[serde(rename = "top")]
14    Top,
15    #[serde(rename = "bottom")]
16    Bottom,
17    #[serde(rename = "left")]
18    Left,
19    #[serde(rename = "right")]
20    Right,
21}
22
23impl Display for Placement {
24    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25        match self {
26            Placement::Top => write!(f, "Top"),
27            Placement::Bottom => write!(f, "Bottom"),
28            Placement::Left => write!(f, "Left"),
29            Placement::Right => write!(f, "Right"),
30        }
31    }
32}
33
34impl Placement {
35    #[inline]
36    pub fn is_horizontal(&self) -> bool {
37        match self {
38            Placement::Left | Placement::Right => true,
39            _ => false,
40        }
41    }
42
43    #[inline]
44    pub fn is_vertical(&self) -> bool {
45        match self {
46            Placement::Top | Placement::Bottom => true,
47            _ => false,
48        }
49    }
50
51    #[inline]
52    pub fn axis(&self) -> Axis {
53        match self {
54            Placement::Top | Placement::Bottom => Axis::Vertical,
55            Placement::Left | Placement::Right => Axis::Horizontal,
56        }
57    }
58}
59
60// The local Anchor enum has been removed. Use gpui::Anchor instead.
61
62/// A enum for defining the side of the element.
63///
64/// See also: [`Placement`] if you need to define the 4 edges.
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
66pub enum Side {
67    #[serde(rename = "left")]
68    Left,
69    #[serde(rename = "right")]
70    Right,
71}
72
73impl Side {
74    /// Returns true if the side is left.
75    #[inline]
76    pub fn is_left(&self) -> bool {
77        matches!(self, Self::Left)
78    }
79
80    /// Returns true if the side is right.
81    #[inline]
82    pub fn is_right(&self) -> bool {
83        matches!(self, Self::Right)
84    }
85}
86
87/// A trait to extend the [`Axis`] enum with utility methods.
88pub trait AxisExt {
89    fn is_horizontal(self) -> bool;
90    fn is_vertical(self) -> bool;
91}
92
93impl AxisExt for Axis {
94    #[inline]
95    fn is_horizontal(self) -> bool {
96        self == Axis::Horizontal
97    }
98
99    #[inline]
100    fn is_vertical(self) -> bool {
101        self == Axis::Vertical
102    }
103}
104
105/// A trait to extend the [`Length`] enum with utility methods.
106pub trait LengthExt {
107    /// Converts the [`Length`] to [`Pixels`] based on a given `base_size` and `rem_size`.
108    ///
109    /// If the [`Length`] is [`Length::Auto`], it returns `None`.
110    fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option<Pixels>;
111}
112
113impl LengthExt for Length {
114    fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option<Pixels> {
115        match self {
116            Length::Auto => None,
117            Length::Definite(len) => Some(len.to_pixels(base_size, rem_size)),
118        }
119    }
120}
121
122/// A struct for defining the edges of an element.
123///
124/// A extend version of [`gpui::Edges`] to serialize/deserialize.
125#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, Eq, PartialEq)]
126#[repr(C)]
127pub struct Edges<T: Clone + Debug + Default + PartialEq> {
128    /// The size of the top edge.
129    pub top: T,
130    /// The size of the right edge.
131    pub right: T,
132    /// The size of the bottom edge.
133    pub bottom: T,
134    /// The size of the left edge.
135    pub left: T,
136}
137
138impl<T> Edges<T>
139where
140    T: Clone + Debug + Default + PartialEq,
141{
142    /// Creates a new `Edges` instance with all edges set to the same value.
143    pub fn all(value: T) -> Self {
144        Self {
145            top: value.clone(),
146            right: value.clone(),
147            bottom: value.clone(),
148            left: value,
149        }
150    }
151}