Poke at getting the project panel showing up

Mikayla created

Change summary

crates/project_panel2/src/project_panel.rs |  66 ++++---
crates/settings2/src/keymap_file.rs        |   6 
crates/workspace2/src/dock.rs              |  14 +
crates/workspace2/src/modal_layer.rs       |  24 --
crates/workspace2/src/workspace2.rs        | 204 ++++++++++++-----------
5 files changed, 157 insertions(+), 157 deletions(-)

Detailed changes

crates/project_panel2/src/project_panel.rs 🔗

@@ -9,10 +9,10 @@ use file_associations::FileAssociations;
 use anyhow::{anyhow, Result};
 use gpui::{
     actions, div, px, svg, uniform_list, Action, AppContext, AssetSource, AsyncAppContext,
-    AsyncWindowContext, ClipboardItem, Div, Element, Entity, EventEmitter, FocusHandle, Model,
-    ParentElement as _, Pixels, Point, PromptLevel, Render, StatefulInteractive,
-    StatefulInteractivity, Styled, Task, UniformListScrollHandle, View, ViewContext,
-    VisualContext as _, WeakView, WindowContext,
+    AsyncWindowContext, ClipboardItem, Div, Element, Entity, EventEmitter, FocusEnabled,
+    FocusHandle, Model, ParentElement as _, Pixels, Point, PromptLevel, Render,
+    StatefulInteractive, StatefulInteractivity, Styled, Task, UniformListScrollHandle, View,
+    ViewContext, VisualContext as _, WeakView, WindowContext,
 };
 use menu::{Confirm, SelectNext, SelectPrev};
 use project::{
@@ -131,6 +131,7 @@ pub fn init_settings(cx: &mut AppContext) {
 pub fn init(assets: impl AssetSource, cx: &mut AppContext) {
     init_settings(cx);
     file_associations::init(assets, cx);
+
     // cx.add_action(ProjectPanel::expand_selected_entry);
     // cx.add_action(ProjectPanel::collapse_selected_entry);
     // cx.add_action(ProjectPanel::collapse_all_entries);
@@ -1437,7 +1438,7 @@ impl ProjectPanel {
 }
 
 impl Render for ProjectPanel {
-    type Element = Div<Self, StatefulInteractivity<Self>>;
+    type Element = Div<Self, StatefulInteractivity<Self>, FocusEnabled<Self>>;
 
     fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
         enum ProjectPanel {}
@@ -1447,31 +1448,36 @@ impl Render for ProjectPanel {
         let has_worktree = self.visible_entries.len() != 0;
 
         if has_worktree {
-            div().id("project-panel").child(
-                uniform_list(
-                    "entries",
-                    self.visible_entries
-                        .iter()
-                        .map(|(_, worktree_entries)| worktree_entries.len())
-                        .sum(),
-                    |this: &mut Self, range, cx| {
-                        let mut items = SmallVec::new();
-                        this.for_each_visible_entry(range, cx, |id, details, cx| {
-                            items.push(Self::render_entry(
-                                id,
-                                details,
-                                &this.filename_editor,
-                                // &mut dragged_entry_destination,
-                                cx,
-                            ));
-                        });
-                        items
-                    },
+            div()
+                .id("project-panel")
+                .track_focus(&self.focus_handle)
+                .child(
+                    uniform_list(
+                        "entries",
+                        self.visible_entries
+                            .iter()
+                            .map(|(_, worktree_entries)| worktree_entries.len())
+                            .sum(),
+                        |this: &mut Self, range, cx| {
+                            let mut items = SmallVec::new();
+                            this.for_each_visible_entry(range, cx, |id, details, cx| {
+                                items.push(Self::render_entry(
+                                    id,
+                                    details,
+                                    &this.filename_editor,
+                                    // &mut dragged_entry_destination,
+                                    cx,
+                                ));
+                            });
+                            items
+                        },
+                    )
+                    .track_scroll(self.list.clone()),
                 )
-                .track_scroll(self.list.clone()),
-            )
         } else {
-            v_stack().id("empty-project_panel")
+            v_stack()
+                .id("empty-project_panel")
+                .track_focus(&self.focus_handle)
         }
     }
 }
@@ -1537,6 +1543,10 @@ impl workspace::dock::Panel for ProjectPanel {
         "Project Panel"
     }
 
+    fn focus_handle(&self, _cx: &WindowContext) -> FocusHandle {
+        self.focus_handle.clone()
+    }
+
     // fn is_focus_event(event: &Self::Event) -> bool {
     //     matches!(event, Event::Focus)
     // }

crates/settings2/src/keymap_file.rs 🔗

@@ -9,7 +9,7 @@ use schemars::{
 };
 use serde::Deserialize;
 use serde_json::Value;
-use util::{asset_str, ResultExt};
+use util::asset_str;
 
 #[derive(Debug, Deserialize, Default, Clone, JsonSchema)]
 #[serde(transparent)]
@@ -86,7 +86,9 @@ impl KeymapFile {
                             "invalid binding value for keystroke {keystroke}, context {context:?}"
                         )
                     })
-                    .log_err()
+                    // todo!()
+                    .ok()
+                    // .log_err()
                     .map(|action| KeyBinding::load(&keystroke, action, context.as_deref()))
                 })
                 .collect::<Result<Vec<_>>>()?;

crates/workspace2/src/dock.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{status_bar::StatusItemView, Axis, Workspace};
 use gpui::{
-    div, Action, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, ParentElement, Render,
-    Subscription, View, ViewContext, WeakView, WindowContext,
+    div, Action, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, FocusHandle,
+    ParentElement, Render, Subscription, View, ViewContext, WeakView, WindowContext,
 };
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
@@ -34,6 +34,7 @@ pub trait Panel: Render + EventEmitter<PanelEvent> {
     fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
     fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
     fn has_focus(&self, cx: &WindowContext) -> bool;
+    fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
 }
 
 pub trait PanelHandle: Send + Sync {
@@ -51,6 +52,7 @@ pub trait PanelHandle: Send + Sync {
     fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>);
     fn icon_label(&self, cx: &WindowContext) -> Option<String>;
     fn has_focus(&self, cx: &WindowContext) -> bool;
+    fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
     fn to_any(&self) -> AnyView;
 }
 
@@ -117,6 +119,10 @@ where
     fn to_any(&self) -> AnyView {
         self.clone().into()
     }
+
+    fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
+        self.read(cx).focus_handle(cx).clone()
+    }
 }
 
 impl From<&dyn PanelHandle> for AnyView {
@@ -728,5 +734,9 @@ pub mod test {
         fn has_focus(&self, _cx: &WindowContext) -> bool {
             self.has_focus
         }
+
+        fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
+            unimplemented!()
+        }
     }
 }

crates/workspace2/src/modal_layer.rs 🔗

@@ -89,27 +89,3 @@ impl ModalLayer {
         })
     }
 }
-
-// impl Render for ModalLayer {
-//     type Element = Div<Self>;
-
-//     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-//         let mut div = div();
-//         for (type_id, build_view) in cx.global::<ModalRegistry>().registered_modals {
-//             div = div.useful_on_action(
-//                 type_id,
-//                 Box::new(|this, _: dyn Any, phase, cx: &mut ViewContext<Self>| {
-//                     if phase == DispatchPhase::Capture {
-//                         return;
-//                     }
-//                     self.workspace.update(cx, |workspace, cx| {
-//                         self.open_modal = Some(build_view(workspace, cx));
-//                     });
-//                     cx.notify();
-//                 }),
-//             )
-//         }
-
-//         div
-//     }
-// }

crates/workspace2/src/workspace2.rs 🔗

@@ -39,8 +39,8 @@ use gpui::{
     actions, div, point, rems, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext,
     AsyncWindowContext, Bounds, Component, Div, Entity, EntityId, EventEmitter, FocusHandle,
     GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size, StatefulInteractive,
-    Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds,
-    WindowContext, WindowHandle, WindowOptions,
+    StatelessInteractive, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
+    WindowBounds, WindowContext, WindowHandle, WindowOptions,
 };
 use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
 use itertools::Itertools;
@@ -247,102 +247,6 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
     //             }
     //         }
     //     });
-    //     cx.add_async_action(Workspace::open);
-
-    //     cx.add_async_action(Workspace::follow_next_collaborator);
-    //     cx.add_async_action(Workspace::close);
-    //     cx.add_async_action(Workspace::close_inactive_items_and_panes);
-    //     cx.add_async_action(Workspace::close_all_items_and_panes);
-    //     cx.add_global_action(Workspace::close_global);
-    //     cx.add_global_action(restart);
-    //     cx.add_async_action(Workspace::save_all);
-    //     cx.add_action(Workspace::add_folder_to_project);
-    //     cx.add_action(
-    //         |workspace: &mut Workspace, _: &Unfollow, cx: &mut ViewContext<Workspace>| {
-    //             let pane = workspace.active_pane().clone();
-    //             workspace.unfollow(&pane, cx);
-    //         },
-    //     );
-    //     cx.add_action(
-    //         |workspace: &mut Workspace, action: &Save, cx: &mut ViewContext<Workspace>| {
-    //             workspace
-    //                 .save_active_item(action.save_intent.unwrap_or(SaveIntent::Save), cx)
-    //                 .detach_and_log_err(cx);
-    //         },
-    //     );
-    //     cx.add_action(
-    //         |workspace: &mut Workspace, _: &SaveAs, cx: &mut ViewContext<Workspace>| {
-    //             workspace
-    //                 .save_active_item(SaveIntent::SaveAs, cx)
-    //                 .detach_and_log_err(cx);
-    //         },
-    //     );
-    //     cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| {
-    //         workspace.activate_previous_pane(cx)
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &ActivateNextPane, cx| {
-    //         workspace.activate_next_pane(cx)
-    //     });
-
-    //     cx.add_action(
-    //         |workspace: &mut Workspace, action: &ActivatePaneInDirection, cx| {
-    //             workspace.activate_pane_in_direction(action.0, cx)
-    //         },
-    //     );
-
-    //     cx.add_action(
-    //         |workspace: &mut Workspace, action: &SwapPaneInDirection, cx| {
-    //             workspace.swap_pane_in_direction(action.0, cx)
-    //         },
-    //     );
-
-    //     cx.add_action(|workspace: &mut Workspace, _: &ToggleLeftDock, cx| {
-    //         workspace.toggle_dock(DockPosition::Left, cx);
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
-    //         workspace.toggle_dock(DockPosition::Right, cx);
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &ToggleBottomDock, cx| {
-    //         workspace.toggle_dock(DockPosition::Bottom, cx);
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &CloseAllDocks, cx| {
-    //         workspace.close_all_docks(cx);
-    //     });
-    //     cx.add_action(Workspace::activate_pane_at_index);
-    //     cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
-    //         workspace.reopen_closed_item(cx).detach();
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| {
-    //         workspace
-    //             .go_back(workspace.active_pane().downgrade(), cx)
-    //             .detach();
-    //     });
-    //     cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| {
-    //         workspace
-    //             .go_forward(workspace.active_pane().downgrade(), cx)
-    //             .detach();
-    //     });
-
-    //     cx.add_action(|_: &mut Workspace, _: &install_cli::Install, cx| {
-    //         cx.spawn(|workspace, mut cx| async move {
-    //             let err = install_cli::install_cli(&cx)
-    //                 .await
-    //                 .context("Failed to create CLI symlink");
-
-    //             workspace.update(&mut cx, |workspace, cx| {
-    //                 if matches!(err, Err(_)) {
-    //                     err.notify_err(workspace, cx);
-    //                 } else {
-    //                     workspace.show_notification(1, cx, |cx| {
-    //                         cx.build_view(|_| {
-    //                             MessageNotification::new("Successfully installed the `zed` binary")
-    //                         })
-    //                     });
-    //                 }
-    //             })
-    //         })
-    //         .detach();
-    //     });
 }
 
 type ProjectItemBuilders =
@@ -1653,7 +1557,8 @@ impl Workspace {
                         focus_center = true;
                     }
                 } else {
-                    // cx.focus(active_panel.as_any());
+                    let focus_handle = &active_panel.focus_handle(cx);
+                    cx.focus(focus_handle);
                     reveal_dock = true;
                 }
             }
@@ -3350,6 +3255,103 @@ impl Workspace {
         })
     }
 
+    fn actions(div: Div<Self>) -> Div<Self> {
+        div
+            //     cx.add_async_action(Workspace::open);
+            //     cx.add_async_action(Workspace::follow_next_collaborator);
+            //     cx.add_async_action(Workspace::close);
+            //     cx.add_async_action(Workspace::close_inactive_items_and_panes);
+            //     cx.add_async_action(Workspace::close_all_items_and_panes);
+            //     cx.add_global_action(Workspace::close_global);
+            //     cx.add_global_action(restart);
+            //     cx.add_async_action(Workspace::save_all);
+            //     cx.add_action(Workspace::add_folder_to_project);
+            //     cx.add_action(
+            //         |workspace: &mut Workspace, _: &Unfollow, cx: &mut ViewContext<Workspace>| {
+            //             let pane = workspace.active_pane().clone();
+            //             workspace.unfollow(&pane, cx);
+            //         },
+            //     );
+            //     cx.add_action(
+            //         |workspace: &mut Workspace, action: &Save, cx: &mut ViewContext<Workspace>| {
+            //             workspace
+            //                 .save_active_item(action.save_intent.unwrap_or(SaveIntent::Save), cx)
+            //                 .detach_and_log_err(cx);
+            //         },
+            //     );
+            //     cx.add_action(
+            //         |workspace: &mut Workspace, _: &SaveAs, cx: &mut ViewContext<Workspace>| {
+            //             workspace
+            //                 .save_active_item(SaveIntent::SaveAs, cx)
+            //                 .detach_and_log_err(cx);
+            //         },
+            //     );
+            //     cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| {
+            //         workspace.activate_previous_pane(cx)
+            //     });
+            //     cx.add_action(|workspace: &mut Workspace, _: &ActivateNextPane, cx| {
+            //         workspace.activate_next_pane(cx)
+            //     });
+            //     cx.add_action(
+            //         |workspace: &mut Workspace, action: &ActivatePaneInDirection, cx| {
+            //             workspace.activate_pane_in_direction(action.0, cx)
+            //         },
+            //     );
+            //     cx.add_action(
+            //         |workspace: &mut Workspace, action: &SwapPaneInDirection, cx| {
+            //             workspace.swap_pane_in_direction(action.0, cx)
+            //         },
+            //     );
+            .on_action(|this, e: &ToggleLeftDock, cx| {
+                println!("TOGGLING DOCK");
+                this.toggle_dock(DockPosition::Left, cx);
+            })
+        //     cx.add_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
+        //         workspace.toggle_dock(DockPosition::Right, cx);
+        //     });
+        //     cx.add_action(|workspace: &mut Workspace, _: &ToggleBottomDock, cx| {
+        //         workspace.toggle_dock(DockPosition::Bottom, cx);
+        //     });
+        //     cx.add_action(|workspace: &mut Workspace, _: &CloseAllDocks, cx| {
+        //         workspace.close_all_docks(cx);
+        //     });
+        //     cx.add_action(Workspace::activate_pane_at_index);
+        //     cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
+        //         workspace.reopen_closed_item(cx).detach();
+        //     });
+        //     cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| {
+        //         workspace
+        //             .go_back(workspace.active_pane().downgrade(), cx)
+        //             .detach();
+        //     });
+        //     cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| {
+        //         workspace
+        //             .go_forward(workspace.active_pane().downgrade(), cx)
+        //             .detach();
+        //     });
+
+        //     cx.add_action(|_: &mut Workspace, _: &install_cli::Install, cx| {
+        //         cx.spawn(|workspace, mut cx| async move {
+        //             let err = install_cli::install_cli(&cx)
+        //                 .await
+        //                 .context("Failed to create CLI symlink");
+
+        //             workspace.update(&mut cx, |workspace, cx| {
+        //                 if matches!(err, Err(_)) {
+        //                     err.notify_err(workspace, cx);
+        //                 } else {
+        //                     workspace.show_notification(1, cx, |cx| {
+        //                         cx.build_view(|_| {
+        //                             MessageNotification::new("Successfully installed the `zed` binary")
+        //                         })
+        //                     });
+        //                 }
+        //             })
+        //         })
+        //         .detach();
+        //     });
+    }
+
     // todo!()
     //     #[cfg(any(test, feature = "test-support"))]
     //     pub fn test_new(project: ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
@@ -3628,7 +3630,7 @@ impl Render for Workspace {
             .text_color(cx.theme().colors().text)
             .bg(cx.theme().colors().background)
             .child(self.render_titlebar(cx))
-            .child(
+            .child(Workspace::actions(
                 // todo! should this be a component a view?
                 self.modal_layer
                     .wrapper_element(cx)
@@ -3717,7 +3719,7 @@ impl Render for Workspace {
                        //     )
                        //     .filter(|_| self.is_assistant_panel_open()),
                        // ),
-            )
+            ))
             .child(self.status_bar.clone())
             // .when(self.debug.show_toast, |this| {
             //     this.child(Toast::new(ToastOrigin::Bottom).child(Label::new("A toast")))