Detailed changes
@@ -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)
// }
@@ -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<_>>>()?;
@@ -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!()
+ }
}
}
@@ -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
-// }
-// }
@@ -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")))