Allow Picker
to be headless (#9099)
At the moment, `Picker` always has an editor at the top, that allows the user to search list elements by text. Sometimes, the UI doesn't need such an editor. Like in the [tab switcher](https://github.com/zed-industries/zed/issues/7653) that will confirm selection on the modifier keys release, so there will be no searching capabilities. This PR adds support for a "headless picker" that doesn't display an editor. It only has an invisible element to hold input focus for preventing it from jumping back to the workspace. At the moment, none of the picker implementations is made headless. It's for the future implementations. But I'd like to make it a separate PR to keep it focused on this particular feature. Release Notes: - N/A Related Issues: - Part of #7653 --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
parent
ad97c357a5
commit
7512c9949c
2 changed files with 120 additions and 36 deletions
59
crates/picker/src/head.rs
Normal file
59
crates/picker/src/head.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use editor::{Editor, EditorEvent};
|
||||
use gpui::{prelude::*, AppContext, FocusHandle, FocusableView, View};
|
||||
use ui::prelude::*;
|
||||
|
||||
/// The head of a [`Picker`](crate::Picker).
|
||||
pub(crate) enum Head {
|
||||
/// Picker has an editor that allows the user to filter the list.
|
||||
Editor(View<Editor>),
|
||||
|
||||
/// Picker has no head, it's just a list of items.
|
||||
Empty(View<EmptyHead>),
|
||||
}
|
||||
|
||||
impl Head {
|
||||
pub fn editor<V: 'static>(
|
||||
placeholder_text: Arc<str>,
|
||||
cx: &mut ViewContext<V>,
|
||||
edit_handler: impl FnMut(&mut V, View<Editor>, &EditorEvent, &mut ViewContext<'_, V>) + 'static,
|
||||
) -> Self {
|
||||
let editor = cx.new_view(|cx| {
|
||||
let mut editor = Editor::single_line(cx);
|
||||
editor.set_placeholder_text(placeholder_text, cx);
|
||||
editor
|
||||
});
|
||||
cx.subscribe(&editor, edit_handler).detach();
|
||||
Self::Editor(editor)
|
||||
}
|
||||
|
||||
pub fn empty(cx: &mut WindowContext) -> Self {
|
||||
Self::Empty(cx.new_view(|cx| EmptyHead::new(cx)))
|
||||
}
|
||||
}
|
||||
|
||||
/// An invisible element that can hold focus.
|
||||
pub(crate) struct EmptyHead {
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
||||
impl EmptyHead {
|
||||
fn new(cx: &mut ViewContext<Self>) -> Self {
|
||||
Self {
|
||||
focus_handle: cx.focus_handle(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for EmptyHead {
|
||||
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
div().track_focus(&self.focus_handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl FocusableView for EmptyHead {
|
||||
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue