Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Max Brunsfeld 2023-11-07 13:03:36 -08:00
parent 10c94cc8b7
commit 80e6427eec

View file

@ -41,96 +41,109 @@ impl<V: PickerDelegate> Picker<V> {
phantom: std::marker::PhantomData, phantom: std::marker::PhantomData,
} }
} }
fn bind_actions<T: StatelessInteractive<V>>(
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<V: 'static + PickerDelegate> Picker<V> { impl<V: 'static + PickerDelegate> Picker<V> {
pub fn render(self, view: &mut V, _cx: &mut ViewContext<V>) -> impl Component<V> { pub fn render(self, view: &mut V, _cx: &mut ViewContext<V>) -> impl Component<V> {
let id = self.id.clone(); let id = self.id.clone();
let scroll_handle = UniformListScrollHandle::new(); let scroll_handle = UniformListScrollHandle::new();
div() Self::bind_actions(
.size_full() div()
.id(self.id.clone()) .id(self.id.clone())
.track_focus(&self.focus_handle) .size_full()
.context("picker") .track_focus(&self.focus_handle)
.on_action({ .context("picker")
let id = id.clone(); .child(
let scroll_handle = scroll_handle.clone(); uniform_list(
move |view: &mut V, _: &menu::SelectNext, cx| { "candidates",
let count = view.match_count(id.clone()); view.match_count(self.id.clone()),
if count > 0 { move |view: &mut V, visible_range, cx| {
let index = view.selected_index(id.clone()); let selected_ix = view.selected_index(self.id.clone());
let ix = cmp::min(index + 1, count - 1); visible_range
view.set_selected_index(ix, id.clone(), cx); .map(|ix| {
scroll_handle.scroll_to_item(ix); view.render_match(ix, ix == selected_ix, self.id.clone(), cx)
} })
} .collect()
}) },
.on_action({ )
let id = id.clone(); .track_scroll(scroll_handle.clone())
let scroll_handle = scroll_handle.clone(); .size_full(),
move |view, _: &menu::SelectPrev, cx| { ),
let count = view.match_count(id.clone()); id,
if count > 0 { &scroll_handle,
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(),
)
} }
} }