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