settings_ui.rs

  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}