1use gpui::{AppContext, FontWeight};
2use settings::{EditableSettingControl, Settings};
3use theme::ThemeSettings;
4use ui::{prelude::*, ContextMenu, DropdownMenu, NumericStepper, SettingsContainer, SettingsGroup};
5
6#[derive(IntoElement)]
7pub struct ThemeSettingsControls {}
8
9impl ThemeSettingsControls {
10 pub fn new() -> Self {
11 Self {}
12 }
13}
14
15impl RenderOnce for ThemeSettingsControls {
16 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
17 SettingsContainer::new().child(
18 SettingsGroup::new("Font")
19 .child(UiFontSizeControl)
20 .child(UiFontWeightControl),
21 )
22 }
23}
24
25#[derive(IntoElement)]
26struct UiFontSizeControl;
27
28impl EditableSettingControl for UiFontSizeControl {
29 type Value = Pixels;
30 type Settings = ThemeSettings;
31
32 fn name(&self) -> SharedString {
33 "UI Font Size".into()
34 }
35
36 fn read(cx: &AppContext) -> Self::Value {
37 let settings = ThemeSettings::get_global(cx);
38 settings.ui_font_size
39 }
40
41 fn apply(settings: &mut <Self::Settings as Settings>::FileContent, value: Self::Value) {
42 settings.ui_font_size = Some(value.into());
43 }
44}
45
46impl RenderOnce for UiFontSizeControl {
47 fn render(self, cx: &mut WindowContext) -> impl IntoElement {
48 let value = Self::read(cx);
49
50 h_flex()
51 .gap_2()
52 .child(Icon::new(IconName::FontSize))
53 .child(NumericStepper::new(
54 value.to_string(),
55 move |_, cx| {
56 Self::write(value - px(1.), cx);
57 },
58 move |_, cx| {
59 Self::write(value + px(1.), cx);
60 },
61 ))
62 }
63}
64
65#[derive(IntoElement)]
66struct UiFontWeightControl;
67
68impl EditableSettingControl for UiFontWeightControl {
69 type Value = FontWeight;
70 type Settings = ThemeSettings;
71
72 fn name(&self) -> SharedString {
73 "UI Font Weight".into()
74 }
75
76 fn read(cx: &AppContext) -> Self::Value {
77 let settings = ThemeSettings::get_global(cx);
78 settings.ui_font.weight
79 }
80
81 fn apply(settings: &mut <Self::Settings as Settings>::FileContent, value: Self::Value) {
82 settings.ui_font_weight = Some(value.0);
83 }
84}
85
86impl RenderOnce for UiFontWeightControl {
87 fn render(self, cx: &mut WindowContext) -> impl IntoElement {
88 let value = Self::read(cx);
89
90 h_flex()
91 .gap_2()
92 .child(Icon::new(IconName::FontWeight))
93 .child(DropdownMenu::new(
94 "ui-font-weight",
95 value.0.to_string(),
96 ContextMenu::build(cx, |mut menu, _cx| {
97 for weight in FontWeight::ALL {
98 menu = menu.custom_entry(
99 move |_cx| Label::new(weight.0.to_string()).into_any_element(),
100 {
101 move |cx| {
102 Self::write(weight, cx);
103 }
104 },
105 )
106 }
107
108 menu
109 }),
110 ))
111 }
112}