Get actions + focus working on picker, now that it's a view

Max Brunsfeld and Marshall created

Co-authored-by: Marshall <marshall@zed.dev>

Change summary

crates/editor2/src/editor.rs            |  2 +-
crates/picker2/src/picker2.rs           | 15 +++++++++++----
crates/storybook2/src/stories/picker.rs | 15 ++++++---------
3 files changed, 18 insertions(+), 14 deletions(-)

Detailed changes

crates/editor2/src/editor.rs 🔗

@@ -9186,7 +9186,7 @@ impl Editor {
     //         supports
     //     }
 
-    fn focus(&self, cx: &mut WindowContext) {
+    pub fn focus(&self, cx: &mut WindowContext) {
         cx.focus(&self.focus_handle)
     }
 }

crates/picker2/src/picker2.rs 🔗

@@ -1,7 +1,8 @@
 use editor::Editor;
 use gpui::{
-    div, uniform_list, Component, Div, ParentElement, Render, StatelessInteractive, Styled,
-    UniformListScrollHandle, View, ViewContext, VisualContext,
+    div, uniform_list, Component, Div, FocusEnabled, ParentElement, Render, StatefulInteractivity,
+    StatelessInteractive, Styled, UniformListScrollHandle, View, ViewContext, VisualContext,
+    WindowContext,
 };
 use std::cmp;
 
@@ -41,6 +42,10 @@ impl<D: PickerDelegate> Picker<D> {
         }
     }
 
+    pub fn focus(&self, cx: &mut WindowContext) {
+        self.editor.update(cx, |editor, cx| editor.focus(cx));
+    }
+
     fn select_next(&mut self, _: &menu::SelectNext, cx: &mut ViewContext<Self>) {
         let count = self.delegate.match_count();
         if count > 0 {
@@ -91,12 +96,14 @@ impl<D: PickerDelegate> Picker<D> {
 }
 
 impl<D: PickerDelegate> Render for Picker<D> {
-    type Element = Div<Self>;
+    type Element = Div<Self, StatefulInteractivity<Self>, FocusEnabled<Self>>;
 
     fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         div()
-            .size_full()
             .context("picker")
+            .id("picker-container")
+            .focusable()
+            .size_full()
             .on_action(Self::select_next)
             .on_action(Self::select_prev)
             .on_action(Self::select_first)

crates/storybook2/src/stories/picker.rs 🔗

@@ -1,13 +1,12 @@
 use gpui::{
-    div, Component, Div, FocusHandle, KeyBinding, ParentElement, Render, SharedString,
-    StatelessInteractive, Styled, View, VisualContext, WindowContext,
+    div, Component, Div, KeyBinding, ParentElement, Render, SharedString, StatelessInteractive,
+    Styled, View, VisualContext, WindowContext,
 };
 use picker::{Picker, PickerDelegate};
 use theme2::ActiveTheme;
 
 pub struct PickerStory {
     picker: View<Picker<Delegate>>,
-    focus_handle: FocusHandle,
 }
 
 struct Delegate {
@@ -86,13 +85,9 @@ impl PickerStory {
                 KeyBinding::new("ctrl-c", menu::Cancel, Some("picker")),
             ]);
 
-            let focus_handle = cx.focus_handle();
-            cx.focus(&focus_handle);
-
             PickerStory {
-                focus_handle,
                 picker: cx.build_view(|cx| {
-                    Picker::new(
+                    let picker = Picker::new(
                         Delegate {
                             candidates: vec![
                                 "Baguette (France)".into(),
@@ -148,7 +143,9 @@ impl PickerStory {
                             selected_ix: 0,
                         },
                         cx,
-                    )
+                    );
+                    picker.focus(cx);
+                    picker
                 }),
             }
         })