head.rs

 1use std::sync::Arc;
 2
 3use editor::{Editor, EditorEvent};
 4use gpui::{App, Entity, FocusHandle, Focusable, prelude::*};
 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(Entity<Editor>),
11
12    /// Picker has no head, it's just a list of items.
13    Empty(Entity<EmptyHead>),
14}
15
16impl Head {
17    pub fn editor<V: 'static>(
18        placeholder_text: Arc<str>,
19        edit_handler: impl FnMut(&mut V, &Entity<Editor>, &EditorEvent, &mut Window, &mut Context<V>)
20        + 'static,
21        window: &mut Window,
22        cx: &mut Context<V>,
23    ) -> Self {
24        let editor = cx.new(|cx| {
25            let mut editor = Editor::single_line(window, cx);
26            editor.set_placeholder_text(placeholder_text.as_ref(), window, cx);
27            editor
28        });
29        cx.subscribe_in(&editor, window, edit_handler).detach();
30        Self::Editor(editor)
31    }
32
33    pub fn empty<V: 'static>(
34        blur_handler: impl FnMut(&mut V, &mut Window, &mut Context<V>) + 'static,
35        window: &mut Window,
36        cx: &mut Context<V>,
37    ) -> Self {
38        let head = cx.new(EmptyHead::new);
39        cx.on_blur(&head.focus_handle(cx), window, blur_handler)
40            .detach();
41        Self::Empty(head)
42    }
43}
44
45/// An invisible element that can hold focus.
46pub(crate) struct EmptyHead {
47    focus_handle: FocusHandle,
48}
49
50impl EmptyHead {
51    fn new(cx: &mut Context<Self>) -> Self {
52        Self {
53            focus_handle: cx.focus_handle(),
54        }
55    }
56}
57
58impl Render for EmptyHead {
59    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
60        div().track_focus(&self.focus_handle(cx))
61    }
62}
63
64impl Focusable for EmptyHead {
65    fn focus_handle(&self, _: &App) -> FocusHandle {
66        self.focus_handle.clone()
67    }
68}