1use std::ops::Deref;
2
3use gpui3::{
4 rems, AbsoluteLength, AnyElement, BorrowAppContext, Bounds, LayoutId, Pixels, WindowContext,
5};
6
7use crate::prelude::*;
8
9/// Returns the user settings.
10pub fn user_settings(cx: &WindowContext) -> FakeSettings {
11 cx.global::<FakeSettings>().clone()
12}
13
14pub fn user_settings_mut<'cx>(cx: &'cx mut WindowContext) -> &'cx mut FakeSettings {
15 cx.global_mut::<FakeSettings>()
16}
17
18#[derive(Clone)]
19pub enum SettingValue<T> {
20 UserDefined(T),
21 Default(T),
22}
23
24impl<T> Deref for SettingValue<T> {
25 type Target = T;
26
27 fn deref(&self) -> &Self::Target {
28 match self {
29 Self::UserDefined(value) => value,
30 Self::Default(value) => value,
31 }
32 }
33}
34
35#[derive(Clone)]
36pub struct TitlebarSettings {
37 pub show_project_owner: SettingValue<bool>,
38 pub show_git_status: SettingValue<bool>,
39 pub show_git_controls: SettingValue<bool>,
40}
41
42impl Default for TitlebarSettings {
43 fn default() -> Self {
44 Self {
45 show_project_owner: SettingValue::Default(true),
46 show_git_status: SettingValue::Default(true),
47 show_git_controls: SettingValue::Default(true),
48 }
49 }
50}
51
52// These should be merged into settings
53#[derive(Clone)]
54pub struct FakeSettings {
55 pub default_panel_size: SettingValue<AbsoluteLength>,
56 pub list_disclosure_style: SettingValue<DisclosureControlStyle>,
57 pub list_indent_depth: SettingValue<AbsoluteLength>,
58 pub titlebar: TitlebarSettings,
59 pub ui_scale: SettingValue<f32>,
60}
61
62impl Default for FakeSettings {
63 fn default() -> Self {
64 Self {
65 titlebar: TitlebarSettings::default(),
66 list_disclosure_style: SettingValue::Default(DisclosureControlStyle::ChevronOnHover),
67 list_indent_depth: SettingValue::Default(rems(0.3).into()),
68 default_panel_size: SettingValue::Default(rems(16.).into()),
69 ui_scale: SettingValue::Default(1.),
70 }
71 }
72}
73
74impl FakeSettings {}
75
76pub fn with_settings<E, F>(
77 settings: FakeSettings,
78 cx: &mut ViewContext<E::ViewState>,
79 build_child: F,
80) -> WithSettings<E>
81where
82 E: Element,
83 F: FnOnce(&mut ViewContext<E::ViewState>) -> E,
84{
85 let child = cx.with_global(settings.clone(), |cx| build_child(cx));
86 WithSettings { settings, child }
87}
88
89pub struct WithSettings<E> {
90 pub(crate) settings: FakeSettings,
91 pub(crate) child: E,
92}
93
94impl<E> IntoAnyElement<E::ViewState> for WithSettings<E>
95where
96 E: Element,
97{
98 fn into_any(self) -> AnyElement<E::ViewState> {
99 AnyElement::new(self)
100 }
101}
102
103impl<E: Element> Element for WithSettings<E> {
104 type ViewState = E::ViewState;
105 type ElementState = E::ElementState;
106
107 fn id(&self) -> Option<gpui3::ElementId> {
108 None
109 }
110
111 fn initialize(
112 &mut self,
113 view_state: &mut Self::ViewState,
114 element_state: Option<Self::ElementState>,
115 cx: &mut ViewContext<Self::ViewState>,
116 ) -> Self::ElementState {
117 cx.with_global(self.settings.clone(), |cx| {
118 self.child.initialize(view_state, element_state, cx)
119 })
120 }
121
122 fn layout(
123 &mut self,
124 view_state: &mut E::ViewState,
125 element_state: &mut Self::ElementState,
126 cx: &mut ViewContext<E::ViewState>,
127 ) -> LayoutId
128 where
129 Self: Sized,
130 {
131 cx.with_global(self.settings.clone(), |cx| {
132 self.child.layout(view_state, element_state, cx)
133 })
134 }
135
136 fn paint(
137 &mut self,
138 bounds: Bounds<Pixels>,
139 view_state: &mut Self::ViewState,
140 frame_state: &mut Self::ElementState,
141 cx: &mut ViewContext<Self::ViewState>,
142 ) where
143 Self: Sized,
144 {
145 cx.with_global(self.settings.clone(), |cx| {
146 self.child.paint(bounds, view_state, frame_state, cx);
147 });
148 }
149}