1use gpui::{px, rems, Pixels, Rems, WindowContext};
2use settings::Settings;
3use theme::{ThemeSettings, UiDensity};
4
5use crate::{rems_from_px, BASE_REM_SIZE_IN_PX};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub enum Spacing {
9 /// No spacing
10 None,
11 /// Usually a one pixel spacing. Grows to 2px in comfortable density.
12 /// @16px/rem: `1px`|`1px`|`2px`
13 XXSmall,
14 /// Extra small spacing - @16px/rem: `1px`|`2px`|`4px`
15 ///
16 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
17 XSmall,
18 /// Small spacing - @16px/rem: `2px`|`4px`|`6px`
19 ///
20 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
21 Small,
22 /// Medium spacing - @16px/rem: `3px`|`6px`|`8px`
23 ///
24 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
25 Medium,
26 /// Large spacing - @16px/rem: `4px`|`8px`|`10px`
27 ///
28 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
29 Large,
30 /// Extra Large spacing - @16px/rem: `8px`|`12px`|`16px`
31 ///
32 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
33 XLarge,
34 /// 2X Large spacing - @16px/rem: `12px`|`16px`|`20px`
35 ///
36 /// Relative to the user's `ui_font_size` and [UiDensity] setting.
37 XXLarge,
38}
39
40impl Spacing {
41 pub fn spacing_ratio(self, cx: &WindowContext) -> f32 {
42 match ThemeSettings::get_global(cx).ui_density {
43 UiDensity::Compact => match self {
44 Spacing::None => 0.,
45 Spacing::XXSmall => 1. / BASE_REM_SIZE_IN_PX,
46 Spacing::XSmall => 1. / BASE_REM_SIZE_IN_PX,
47 Spacing::Small => 2. / BASE_REM_SIZE_IN_PX,
48 Spacing::Medium => 3. / BASE_REM_SIZE_IN_PX,
49 Spacing::Large => 4. / BASE_REM_SIZE_IN_PX,
50 Spacing::XLarge => 8. / BASE_REM_SIZE_IN_PX,
51 Spacing::XXLarge => 12. / BASE_REM_SIZE_IN_PX,
52 },
53 UiDensity::Default => match self {
54 Spacing::None => 0.,
55 Spacing::XXSmall => 1. / BASE_REM_SIZE_IN_PX,
56 Spacing::XSmall => 2. / BASE_REM_SIZE_IN_PX,
57 Spacing::Small => 4. / BASE_REM_SIZE_IN_PX,
58 Spacing::Medium => 6. / BASE_REM_SIZE_IN_PX,
59 Spacing::Large => 8. / BASE_REM_SIZE_IN_PX,
60 Spacing::XLarge => 12. / BASE_REM_SIZE_IN_PX,
61 Spacing::XXLarge => 16. / BASE_REM_SIZE_IN_PX,
62 },
63 UiDensity::Comfortable => match self {
64 Spacing::None => 0.,
65 Spacing::XXSmall => 2. / BASE_REM_SIZE_IN_PX,
66 Spacing::XSmall => 3. / BASE_REM_SIZE_IN_PX,
67 Spacing::Small => 6. / BASE_REM_SIZE_IN_PX,
68 Spacing::Medium => 8. / BASE_REM_SIZE_IN_PX,
69 Spacing::Large => 10. / BASE_REM_SIZE_IN_PX,
70 Spacing::XLarge => 16. / BASE_REM_SIZE_IN_PX,
71 Spacing::XXLarge => 20. / BASE_REM_SIZE_IN_PX,
72 },
73 }
74 }
75
76 pub fn rems(self, cx: &WindowContext) -> Rems {
77 rems(self.spacing_ratio(cx))
78 }
79
80 pub fn px(self, cx: &WindowContext) -> Pixels {
81 let ui_font_size_f32: f32 = ThemeSettings::get_global(cx).ui_font_size.into();
82
83 px(ui_font_size_f32 * self.spacing_ratio(cx))
84 }
85}
86
87pub fn user_spacing_style(cx: &WindowContext) -> UiDensity {
88 ThemeSettings::get_global(cx).ui_density
89}
90
91pub fn custom_spacing(cx: &WindowContext, size: f32) -> Rems {
92 rems_from_px(size * user_spacing_style(cx).spacing_ratio())
93}