diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 74bdcd19bd..2040ff484f 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -41,96 +41,109 @@ impl Picker { phantom: std::marker::PhantomData, } } + + fn bind_actions>( + div: T, + id: ElementId, + scroll_handle: &UniformListScrollHandle, + ) -> T { + div.on_action({ + let id = id.clone(); + let scroll_handle = scroll_handle.clone(); + move |view: &mut V, _: &menu::SelectNext, cx| { + let count = view.match_count(id.clone()); + if count > 0 { + let index = view.selected_index(id.clone()); + let ix = cmp::min(index + 1, count - 1); + view.set_selected_index(ix, id.clone(), cx); + scroll_handle.scroll_to_item(ix); + } + } + }) + .on_action({ + let id = id.clone(); + let scroll_handle = scroll_handle.clone(); + move |view, _: &menu::SelectPrev, cx| { + let count = view.match_count(id.clone()); + if count > 0 { + let index = view.selected_index(id.clone()); + let ix = index.saturating_sub(1); + view.set_selected_index(ix, id.clone(), cx); + scroll_handle.scroll_to_item(ix); + } + } + }) + .on_action({ + let id = id.clone(); + let scroll_handle = scroll_handle.clone(); + move |view: &mut V, _: &menu::SelectFirst, cx| { + let count = view.match_count(id.clone()); + if count > 0 { + view.set_selected_index(0, id.clone(), cx); + scroll_handle.scroll_to_item(0); + } + } + }) + .on_action({ + let id = id.clone(); + let scroll_handle = scroll_handle.clone(); + move |view: &mut V, _: &menu::SelectLast, cx| { + let count = view.match_count(id.clone()); + if count > 0 { + view.set_selected_index(count - 1, id.clone(), cx); + scroll_handle.scroll_to_item(count - 1); + } + } + }) + .on_action({ + let id = id.clone(); + move |view: &mut V, _: &menu::Cancel, cx| { + view.dismissed(id.clone(), cx); + } + }) + .on_action({ + let id = id.clone(); + move |view: &mut V, _: &menu::Confirm, cx| { + view.confirm(false, id.clone(), cx); + } + }) + .on_action({ + let id = id.clone(); + move |view: &mut V, _: &menu::SecondaryConfirm, cx| { + view.confirm(true, id.clone(), cx); + } + }) + } } impl Picker { pub fn render(self, view: &mut V, _cx: &mut ViewContext) -> impl Component { let id = self.id.clone(); let scroll_handle = UniformListScrollHandle::new(); - div() - .size_full() - .id(self.id.clone()) - .track_focus(&self.focus_handle) - .context("picker") - .on_action({ - let id = id.clone(); - let scroll_handle = scroll_handle.clone(); - move |view: &mut V, _: &menu::SelectNext, cx| { - let count = view.match_count(id.clone()); - if count > 0 { - let index = view.selected_index(id.clone()); - let ix = cmp::min(index + 1, count - 1); - view.set_selected_index(ix, id.clone(), cx); - scroll_handle.scroll_to_item(ix); - } - } - }) - .on_action({ - let id = id.clone(); - let scroll_handle = scroll_handle.clone(); - move |view, _: &menu::SelectPrev, cx| { - let count = view.match_count(id.clone()); - if count > 0 { - let index = view.selected_index(id.clone()); - let ix = index.saturating_sub(1); - view.set_selected_index(ix, id.clone(), cx); - scroll_handle.scroll_to_item(ix); - } - } - }) - .on_action({ - let id = id.clone(); - let scroll_handle = scroll_handle.clone(); - move |view: &mut V, _: &menu::SelectFirst, cx| { - let count = view.match_count(id.clone()); - if count > 0 { - view.set_selected_index(0, id.clone(), cx); - scroll_handle.scroll_to_item(0); - } - } - }) - .on_action({ - let id = id.clone(); - let scroll_handle = scroll_handle.clone(); - move |view: &mut V, _: &menu::SelectLast, cx| { - let count = view.match_count(id.clone()); - if count > 0 { - view.set_selected_index(count - 1, id.clone(), cx); - scroll_handle.scroll_to_item(count - 1); - } - } - }) - .on_action({ - let id = id.clone(); - move |view: &mut V, _: &menu::Cancel, cx| { - view.dismissed(id.clone(), cx); - } - }) - .on_action({ - let id = id.clone(); - move |view: &mut V, _: &menu::Confirm, cx| { - view.confirm(false, id.clone(), cx); - } - }) - .on_action({ - let id = id.clone(); - move |view: &mut V, _: &menu::SecondaryConfirm, cx| { - view.confirm(true, id.clone(), cx); - } - }) - .child( - uniform_list( - "candidates", - view.match_count(self.id.clone()), - move |view: &mut V, visible_range, cx| { - let selected_ix = view.selected_index(self.id.clone()); - visible_range - .map(|ix| view.render_match(ix, ix == selected_ix, self.id.clone(), cx)) - .collect() - }, - ) - .track_scroll(scroll_handle.clone()) - .size_full(), - ) + Self::bind_actions( + div() + .id(self.id.clone()) + .size_full() + .track_focus(&self.focus_handle) + .context("picker") + .child( + uniform_list( + "candidates", + view.match_count(self.id.clone()), + move |view: &mut V, visible_range, cx| { + let selected_ix = view.selected_index(self.id.clone()); + visible_range + .map(|ix| { + view.render_match(ix, ix == selected_ix, self.id.clone(), cx) + }) + .collect() + }, + ) + .track_scroll(scroll_handle.clone()) + .size_full(), + ), + id, + &scroll_handle, + ) } }