1mod appearance_settings_controls;
2
3use std::any::TypeId;
4
5use command_palette_hooks::CommandPaletteFilter;
6use editor::EditorSettingsControls;
7use feature_flags::{FeatureFlag, FeatureFlagViewExt};
8use gpui::{actions, AppContext, EventEmitter, FocusHandle, FocusableView, View};
9use ui::prelude::*;
10use workspace::item::{Item, ItemEvent};
11use workspace::Workspace;
12
13use crate::appearance_settings_controls::AppearanceSettingsControls;
14
15pub struct SettingsUiFeatureFlag;
16
17impl FeatureFlag for SettingsUiFeatureFlag {
18 const NAME: &'static str = "settings-ui";
19}
20
21actions!(zed, [OpenSettingsEditor]);
22
23pub fn init(cx: &mut AppContext) {
24 cx.observe_new_views(|workspace: &mut Workspace, cx| {
25 workspace.register_action(|workspace, _: &OpenSettingsEditor, cx| {
26 let existing = workspace
27 .active_pane()
28 .read(cx)
29 .items()
30 .find_map(|item| item.downcast::<SettingsPage>());
31
32 if let Some(existing) = existing {
33 workspace.activate_item(&existing, true, true, cx);
34 } else {
35 let settings_page = SettingsPage::new(workspace, cx);
36 workspace.add_item_to_active_pane(Box::new(settings_page), None, true, cx)
37 }
38 });
39
40 let settings_ui_actions = [TypeId::of::<OpenSettingsEditor>()];
41
42 CommandPaletteFilter::update_global(cx, |filter, _cx| {
43 filter.hide_action_types(&settings_ui_actions);
44 });
45
46 cx.observe_flag::<SettingsUiFeatureFlag, _>(move |is_enabled, _view, cx| {
47 if is_enabled {
48 CommandPaletteFilter::update_global(cx, |filter, _cx| {
49 filter.show_action_types(settings_ui_actions.iter());
50 });
51 } else {
52 CommandPaletteFilter::update_global(cx, |filter, _cx| {
53 filter.hide_action_types(&settings_ui_actions);
54 });
55 }
56 })
57 .detach();
58 })
59 .detach();
60}
61
62pub struct SettingsPage {
63 focus_handle: FocusHandle,
64}
65
66impl SettingsPage {
67 pub fn new(_workspace: &Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
68 cx.new_view(|cx| Self {
69 focus_handle: cx.focus_handle(),
70 })
71 }
72}
73
74impl EventEmitter<ItemEvent> for SettingsPage {}
75
76impl FocusableView for SettingsPage {
77 fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
78 self.focus_handle.clone()
79 }
80}
81
82impl Item for SettingsPage {
83 type Event = ItemEvent;
84
85 fn tab_icon(&self, _cx: &WindowContext) -> Option<Icon> {
86 Some(Icon::new(IconName::Settings))
87 }
88
89 fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
90 Some("Settings".into())
91 }
92
93 fn show_toolbar(&self) -> bool {
94 false
95 }
96
97 fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
98 f(*event)
99 }
100}
101
102impl Render for SettingsPage {
103 fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
104 v_flex()
105 .p_4()
106 .size_full()
107 .gap_4()
108 .child(Label::new("Settings").size(LabelSize::Large))
109 .child(
110 v_flex().gap_1().child(Label::new("Appearance")).child(
111 v_flex()
112 .elevation_2(cx)
113 .child(AppearanceSettingsControls::new()),
114 ),
115 )
116 .child(
117 v_flex().gap_1().child(Label::new("Editor")).child(
118 v_flex()
119 .elevation_2(cx)
120 .child(EditorSettingsControls::new()),
121 ),
122 )
123 }
124}