mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-04 07:29:32 +00:00
Move from register_modals to register_workspace_action
This commit is contained in:
parent
e6d6806693
commit
d4b1d1b528
4 changed files with 84 additions and 97 deletions
|
@ -21,19 +21,7 @@ actions!(Toggle);
|
|||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
cx.set_global(HitCounts::default());
|
||||
|
||||
cx.observe_new_views(
|
||||
|workspace: &mut Workspace, _: &mut ViewContext<Workspace>| {
|
||||
workspace.modal_layer().register_modal(Toggle, |cx| {
|
||||
let Some(previous_focus_handle) = cx.focused() else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(cx.build_view(|cx| CommandPalette::new(previous_focus_handle, cx)))
|
||||
});
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
cx.observe_new_views(CommandPalette::register).detach();
|
||||
}
|
||||
|
||||
pub struct CommandPalette {
|
||||
|
@ -41,6 +29,15 @@ pub struct CommandPalette {
|
|||
}
|
||||
|
||||
impl CommandPalette {
|
||||
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
|
||||
workspace.register_action(|workspace, _: &Toggle, cx| {
|
||||
let Some(previous_focus_handle) = cx.focused() else {
|
||||
return;
|
||||
};
|
||||
workspace.toggle_modal(cx, move |cx| CommandPalette::new(previous_focus_handle, cx));
|
||||
});
|
||||
}
|
||||
|
||||
fn new(previous_focus_handle: FocusHandle, cx: &mut ViewContext<Self>) -> Self {
|
||||
let filter = cx.try_global::<CommandPaletteFilter>();
|
||||
|
||||
|
|
|
@ -13,22 +13,7 @@ use workspace::{Modal, ModalEvent, Workspace};
|
|||
actions!(Toggle);
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
cx.observe_new_views(
|
||||
|workspace: &mut Workspace, cx: &mut ViewContext<Workspace>| {
|
||||
let handle = cx.view().downgrade();
|
||||
|
||||
workspace.modal_layer().register_modal(Toggle, move |cx| {
|
||||
let workspace = handle.upgrade()?;
|
||||
let editor = workspace
|
||||
.read(cx)
|
||||
.active_item(cx)
|
||||
.and_then(|active_item| active_item.downcast::<Editor>())?;
|
||||
|
||||
Some(cx.build_view(|cx| GoToLine::new(editor, cx)))
|
||||
});
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
cx.observe_new_views(GoToLine::register).detach();
|
||||
}
|
||||
|
||||
pub struct GoToLine {
|
||||
|
@ -47,6 +32,19 @@ impl Modal for GoToLine {
|
|||
}
|
||||
|
||||
impl GoToLine {
|
||||
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
|
||||
workspace.register_action(|workspace, _: &Toggle, cx| {
|
||||
let Some(editor) = workspace
|
||||
.active_item(cx)
|
||||
.and_then(|active_item| active_item.downcast::<Editor>())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
workspace.toggle_modal(cx, move |cx| GoToLine::new(editor, cx));
|
||||
});
|
||||
}
|
||||
|
||||
pub fn new(active_editor: View<Editor>, cx: &mut ViewContext<Self>) -> Self {
|
||||
let line_editor = cx.build_view(|cx| Editor::single_line(cx));
|
||||
let line_editor_change = cx.subscribe(&line_editor, Self::on_line_editor_event);
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::Workspace;
|
|||
use gpui::{
|
||||
div, px, AnyView, Component, Div, EventEmitter, FocusHandle, ParentElement, Render,
|
||||
StatefulInteractivity, StatelessInteractive, Styled, Subscription, View, ViewContext,
|
||||
WindowContext,
|
||||
VisualContext, WindowContext,
|
||||
};
|
||||
use std::{any::TypeId, sync::Arc};
|
||||
use ui::v_stack;
|
||||
|
@ -16,14 +16,6 @@ pub struct ActiveModal {
|
|||
|
||||
pub struct ModalLayer {
|
||||
active_modal: Option<ActiveModal>,
|
||||
registered_modals: Vec<(
|
||||
TypeId,
|
||||
Box<
|
||||
dyn Fn(
|
||||
Div<Workspace, StatefulInteractivity<Workspace>>,
|
||||
) -> Div<Workspace, StatefulInteractivity<Workspace>>,
|
||||
>,
|
||||
)>,
|
||||
}
|
||||
|
||||
pub trait Modal: Render + EventEmitter<ModalEvent> {
|
||||
|
@ -36,35 +28,13 @@ pub enum ModalEvent {
|
|||
|
||||
impl ModalLayer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_modal: None,
|
||||
registered_modals: Vec::new(),
|
||||
}
|
||||
Self { active_modal: None }
|
||||
}
|
||||
|
||||
pub fn register_modal<A: 'static, V, B>(&mut self, action: A, build_view: B)
|
||||
pub fn toggle_modal<V, B>(&mut self, cx: &mut ViewContext<Workspace>, build_view: B)
|
||||
where
|
||||
V: Modal,
|
||||
B: Fn(&mut WindowContext) -> Option<View<V>> + 'static,
|
||||
{
|
||||
let build_view = Arc::new(build_view);
|
||||
|
||||
self.registered_modals.push((
|
||||
TypeId::of::<A>(),
|
||||
Box::new(move |mut div| {
|
||||
let build_view = build_view.clone();
|
||||
|
||||
div.on_action(move |workspace, event: &A, cx| {
|
||||
workspace.modal_layer().toggle_modal(build_view.clone(), cx)
|
||||
})
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
pub fn toggle_modal<V, B>(&mut self, build_view: Arc<B>, cx: &mut ViewContext<Workspace>)
|
||||
where
|
||||
V: Modal,
|
||||
B: Fn(&mut WindowContext) -> Option<View<V>> + 'static,
|
||||
B: FnOnce(&mut ViewContext<V>) -> V,
|
||||
{
|
||||
let previous_focus = cx.focused();
|
||||
|
||||
|
@ -74,28 +44,23 @@ impl ModalLayer {
|
|||
return;
|
||||
}
|
||||
}
|
||||
let Some(new_modal) = (build_view)(cx) else {
|
||||
return;
|
||||
};
|
||||
self.show_modal(previous_focus, new_modal, cx);
|
||||
let new_modal = cx.build_view(build_view);
|
||||
self.show_modal(new_modal, cx);
|
||||
}
|
||||
|
||||
pub fn show_modal<V>(
|
||||
&mut self,
|
||||
previous_focus: Option<FocusHandle>,
|
||||
new_modal: View<V>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) where
|
||||
pub fn show_modal<V>(&mut self, new_modal: View<V>, cx: &mut ViewContext<Workspace>)
|
||||
where
|
||||
V: Modal,
|
||||
{
|
||||
self.active_modal = Some(ActiveModal {
|
||||
modal: new_modal.clone().into(),
|
||||
subscription: cx.subscribe(&new_modal, |this, modal, e, cx| match e {
|
||||
ModalEvent::Dismissed => this.modal_layer().hide_modal(cx),
|
||||
subscription: cx.subscribe(&new_modal, |workspace, modal, e, cx| match e {
|
||||
ModalEvent::Dismissed => workspace.modal_layer.hide_modal(cx),
|
||||
}),
|
||||
previous_focus_handle: previous_focus,
|
||||
previous_focus_handle: cx.focused(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
});
|
||||
new_modal.update(cx, |modal, cx| modal.focus(cx));
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -115,12 +80,7 @@ impl ModalLayer {
|
|||
&self,
|
||||
cx: &ViewContext<Workspace>,
|
||||
) -> Div<Workspace, StatefulInteractivity<Workspace>> {
|
||||
let mut parent = div().id("modal layer").relative().size_full();
|
||||
|
||||
for (_, action) in self.registered_modals.iter() {
|
||||
parent = (action)(parent);
|
||||
}
|
||||
|
||||
let parent = div().id("boop");
|
||||
parent.when_some(self.active_modal.as_ref(), |parent, open_modal| {
|
||||
let container1 = div()
|
||||
.absolute()
|
||||
|
@ -137,8 +97,8 @@ impl ModalLayer {
|
|||
.relative()
|
||||
.top_20()
|
||||
.track_focus(&open_modal.focus_handle)
|
||||
.on_mouse_down_out(|workspace: &mut Workspace, _, cx| {
|
||||
workspace.modal_layer().hide_modal(cx);
|
||||
.on_mouse_down_out(|workspace: &mut Workspace, event, cx| {
|
||||
workspace.modal_layer.hide_modal(cx);
|
||||
});
|
||||
|
||||
parent.child(container1.child(container2.child(open_modal.modal.clone())))
|
||||
|
|
|
@ -36,11 +36,12 @@ use futures::{
|
|||
Future, FutureExt, StreamExt,
|
||||
};
|
||||
use gpui::{
|
||||
actions, div, point, rems, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext,
|
||||
AsyncWindowContext, Bounds, Component, DispatchContext, Div, Entity, EntityId, EventEmitter,
|
||||
FocusHandle, GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size,
|
||||
StatefulInteractive, StatefulInteractivity, Styled, Subscription, Task, View, ViewContext,
|
||||
VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions,
|
||||
actions, div, point, rems, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
|
||||
AsyncAppContext, AsyncWindowContext, Bounds, Component, DispatchContext, Div, Entity, EntityId,
|
||||
EventEmitter, FocusHandle, GlobalPixels, Model, ModelContext, ParentElement, Point, Render,
|
||||
Size, StatefulInteractive, StatefulInteractivity, StatelessInteractive, Styled, Subscription,
|
||||
Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle,
|
||||
WindowOptions,
|
||||
};
|
||||
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
|
||||
use itertools::Itertools;
|
||||
|
@ -530,6 +531,13 @@ pub enum Event {
|
|||
pub struct Workspace {
|
||||
weak_self: WeakView<Self>,
|
||||
focus_handle: FocusHandle,
|
||||
workspace_actions: Vec<
|
||||
Box<
|
||||
dyn Fn(
|
||||
Div<Workspace, StatefulInteractivity<Workspace>>,
|
||||
) -> Div<Workspace, StatefulInteractivity<Workspace>>,
|
||||
>,
|
||||
>,
|
||||
zoomed: Option<AnyWeakView>,
|
||||
zoomed_position: Option<DockPosition>,
|
||||
center: PaneGroup,
|
||||
|
@ -775,13 +783,10 @@ impl Workspace {
|
|||
leader_updates_tx,
|
||||
subscriptions,
|
||||
pane_history_timestamp,
|
||||
workspace_actions: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modal_layer(&mut self) -> &mut ModalLayer {
|
||||
&mut self.modal_layer
|
||||
}
|
||||
|
||||
fn new_local(
|
||||
abs_paths: Vec<PathBuf>,
|
||||
app_state: Arc<AppState>,
|
||||
|
@ -3495,6 +3500,34 @@ impl Workspace {
|
|||
// )
|
||||
// }
|
||||
// }
|
||||
pub fn register_action<A: Action>(
|
||||
&mut self,
|
||||
callback: impl Fn(&mut Self, &A, &mut ViewContext<Self>) + 'static,
|
||||
) {
|
||||
let callback = Arc::new(callback);
|
||||
|
||||
self.workspace_actions.push(Box::new(move |div| {
|
||||
let callback = callback.clone();
|
||||
div.on_action(move |workspace, event, cx| (callback.clone())(workspace, event, cx))
|
||||
}));
|
||||
}
|
||||
|
||||
fn add_workspace_actions_listeners(
|
||||
&self,
|
||||
mut div: Div<Workspace, StatefulInteractivity<Workspace>>,
|
||||
) -> Div<Workspace, StatefulInteractivity<Workspace>> {
|
||||
for action in self.workspace_actions.iter() {
|
||||
div = (action)(div)
|
||||
}
|
||||
div
|
||||
}
|
||||
|
||||
pub fn toggle_modal<V: Modal, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
|
||||
where
|
||||
B: FnOnce(&mut ViewContext<V>) -> V,
|
||||
{
|
||||
self.modal_layer.toggle_modal(cx, build)
|
||||
}
|
||||
}
|
||||
|
||||
fn window_bounds_env_override(cx: &AsyncAppContext) -> Option<WindowBounds> {
|
||||
|
@ -3706,14 +3739,13 @@ fn notify_if_database_failed(workspace: WindowHandle<Workspace>, cx: &mut AsyncA
|
|||
impl EventEmitter<Event> for Workspace {}
|
||||
|
||||
impl Render for Workspace {
|
||||
type Element = Div<Self, StatefulInteractivity<Self>>;
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
let mut context = DispatchContext::default();
|
||||
context.insert("Workspace");
|
||||
cx.with_key_dispatch_context(context, |cx| {
|
||||
div()
|
||||
.id("workspace")
|
||||
.relative()
|
||||
.size_full()
|
||||
.flex()
|
||||
|
@ -3727,8 +3759,7 @@ impl Render for Workspace {
|
|||
.child(self.render_titlebar(cx))
|
||||
.child(
|
||||
// todo! should this be a component a view?
|
||||
self.modal_layer
|
||||
.wrapper_element(cx)
|
||||
self.add_workspace_actions_listeners(div().id("workspace"))
|
||||
.relative()
|
||||
.flex_1()
|
||||
.w_full()
|
||||
|
@ -3737,6 +3768,7 @@ impl Render for Workspace {
|
|||
.border_t()
|
||||
.border_b()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.child(self.modal_layer.wrapper_element(cx))
|
||||
// .children(
|
||||
// Some(
|
||||
// Panel::new("project-panel-outer", cx)
|
||||
|
|
Loading…
Reference in a new issue