head.rs

 1use std::sync::Arc;
 2
 3use editor::{Editor, EditorEvent};
 4use gpui::{prelude::*, AppContext, FocusHandle, FocusableView, View};
 5use ui::prelude::*;
 6
 7/// The head of a [`Picker`](crate::Picker).
 8pub(crate) enum Head {
 9    /// Picker has an editor that allows the user to filter the list.
10    Editor(View<Editor>),
11
12    /// Picker has no head, it's just a list of items.
13    Empty(View<EmptyHead>),
14}
15
16impl Head {
17    pub fn editor<V: 'static>(
18        placeholder_text: Arc<str>,
19        edit_handler: impl FnMut(&mut V, View<Editor>, &EditorEvent, &mut ViewContext<'_, V>) + 'static,
20        cx: &mut ViewContext<V>,
21    ) -> Self {
22        let editor = cx.new_view(|cx| {
23            let mut editor = Editor::single_line(cx);
24            editor.set_placeholder_text(placeholder_text, cx);
25            editor
26        });
27        cx.subscribe(&editor, edit_handler).detach();
28        Self::Editor(editor)
29    }
30
31    pub fn empty(cx: &mut WindowContext) -> Self {
32        Self::Empty(cx.new_view(|cx| EmptyHead::new(cx)))
33    }
34}
35
36/// An invisible element that can hold focus.
37pub(crate) struct EmptyHead {
38    focus_handle: FocusHandle,
39}
40
41impl EmptyHead {
42    fn new(cx: &mut ViewContext<Self>) -> Self {
43        Self {
44            focus_handle: cx.focus_handle(),
45        }
46    }
47}
48
49impl Render for EmptyHead {
50    fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
51        div().track_focus(&self.focus_handle)
52    }
53}
54
55impl FocusableView for EmptyHead {
56    fn focus_handle(&self, _: &AppContext) -> FocusHandle {
57        self.focus_handle.clone()
58    }
59}