crates/settings_ui/src/settings_ui.rs 🔗
@@ -1069,6 +1069,36 @@ impl SettingsWindow {
.on_click(cx.listener(
move |this, evt: &gpui::ClickEvent, window, cx| {
this.navbar_entry = ix;
+
+ if !this.navbar_entries[ix].is_root {
+ let mut selected_page_ix = ix;
+
+ while !this.navbar_entries[selected_page_ix]
+ .is_root
+ {
+ selected_page_ix -= 1;
+ }
+
+ let section_header = ix - selected_page_ix;
+
+ if let Some(section_index) = this
+ .page_items()
+ .enumerate()
+ .filter(|item| {
+ matches!(
+ item.1,
+ SettingsPageItem::SectionHeader(_)
+ )
+ })
+ .take(section_header)
+ .last()
+ .map(|pair| pair.0)
+ {
+ this.scroll_handle
+ .scroll_to_item(section_index);
+ }
+ }
+
if evt.is_keyboard() {
// todo(settings_ui): Focus the actual item and scroll to it
this.focus_first_content_item(window, cx);
@@ -1163,7 +1193,26 @@ impl SettingsWindow {
.size_full()
.gap_4()
.overflow_y_scroll()
- .track_scroll(&self.scroll_handle);
+ .track_scroll(&self.scroll_handle)
+ .on_scroll_wheel(cx.listener(move |this, _, _, _| {
+ let scroll_index = this.scroll_handle.logical_scroll_top().0;
+
+ let mut page_index = this.navbar_entry;
+
+ while !this.navbar_entries[page_index].is_root {
+ page_index -= 1;
+ }
+
+ if this.navbar_entries[page_index].expanded {
+ let section_index = this
+ .page_items()
+ .take(scroll_index + 1)
+ .filter(|item| matches!(item, SettingsPageItem::SectionHeader(_)))
+ .count();
+
+ this.navbar_entry = section_index + page_index;
+ }
+ }));
let items: Vec<_> = items.collect();
let items_len = items.len();