Improve nav bar navigation

Anthony created

Change summary

crates/settings_ui/src/settings_ui.rs | 51 ++++++++++++++++++++++++++++
1 file changed, 50 insertions(+), 1 deletion(-)

Detailed changes

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();