Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions crates/story/src/stories/settings_story.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub struct SettingsStory {
focus_handle: FocusHandle,
group_variant: GroupBoxVariant,
size: Size,
last_page_index: usize,
}

struct OpenURLSettingField {
Expand Down Expand Up @@ -121,6 +122,7 @@ impl SettingsStory {
focus_handle: cx.focus_handle(),
group_variant: GroupBoxVariant::Outline,
size: Size::default(),
last_page_index: 0,
}
}

Expand Down Expand Up @@ -455,9 +457,20 @@ impl Focusable for SettingsStory {

impl Render for SettingsStory {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let entity = cx.entity();
Settings::new("app-settings")
.with_size(self.size)
.with_group_variant(self.group_variant)
.default_selected_index(gpui_component::setting::SelectIndex {
page_ix: self.last_page_index,
group_ix: None,
})
.on_page_change(move |ix, cx| {
entity.update(cx, |this, cx| {
this.last_page_index = ix;
cx.notify();
});
})
.pages(self.setting_pages(window, cx))
}
}
21 changes: 19 additions & 2 deletions crates/ui/src/setting/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use gpui::{
RenderOnce, StyleRefinement, Styled, Window, div, prelude::FluentBuilder as _, px, relative,
};
use rust_i18n::t;
use std::rc::Rc;

/// The settings structure containing multiple pages for app settings.
///
Expand All @@ -34,6 +35,7 @@ pub struct Settings {
sidebar_style: StyleRefinement,
default_selected_index: SelectIndex,
header_style: StyleRefinement,
on_page_change: Option<Rc<dyn Fn(usize, &mut App) + 'static>>,
}

impl Settings {
Expand All @@ -48,6 +50,7 @@ impl Settings {
sidebar_style: StyleRefinement::default(),
default_selected_index: SelectIndex::default(),
header_style: StyleRefinement::default(),
on_page_change: None,
}
}

Expand Down Expand Up @@ -95,6 +98,15 @@ impl Settings {
self
}

/// Set a callback invoked when the user selects a top-level page in the sidebar.
///
/// The first argument is the zero-based page index. This is useful for persisting
/// the last-visited page so it can be restored via [`Self::default_selected_index`].
pub fn on_page_change(mut self, f: impl Fn(usize, &mut App) + 'static) -> Self {
self.on_page_change = Some(Rc::new(f));
self
}

fn filtered_pages(&self, query: &str, cx: &App) -> Vec<SettingPage> {
self.pages
.iter()
Expand Down Expand Up @@ -153,6 +165,7 @@ impl Settings {
&self,
state: &Entity<SettingsState>,
pages: &Vec<SettingPage>,
on_page_change: Option<Rc<dyn Fn(usize, &mut App) + 'static>>,
_: &mut Window,
cx: &mut App,
) -> impl IntoElement {
Expand Down Expand Up @@ -182,14 +195,18 @@ impl Settings {
.active(is_page_active)
.on_click({
let state = state.clone();
let on_page_change = on_page_change.clone();
move |_, _, cx| {
state.update(cx, |state, cx| {
state.selected_index = SelectIndex {
page_ix,
..Default::default()
};
cx.notify();
})
});
if let Some(f) = &on_page_change {
f(page_ix, cx);
}
}
})
.when(page.groups.len() > 1, |this| {
Expand Down Expand Up @@ -288,7 +305,7 @@ impl RenderOnce for Settings {
.child(
resizable_panel()
.size(self.sidebar_width)
.child(self.render_sidebar(&state, &filtered_pages, window, cx)),
.child(self.render_sidebar(&state, &filtered_pages, self.on_page_change.clone(), window, cx)),
)
.child(resizable_panel().child(self.render_active_page(
&state,
Expand Down
Loading