Skip to content

Commit d4b1d1b

Browse files
committed
Move from register_modals to register_workspace_action
1 parent e6d6806 commit d4b1d1b

File tree

4 files changed

+84
-97
lines changed

4 files changed

+84
-97
lines changed

crates/command_palette2/src/command_palette.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,23 @@ actions!(Toggle);
2121

2222
pub fn init(cx: &mut AppContext) {
2323
cx.set_global(HitCounts::default());
24-
25-
cx.observe_new_views(
26-
|workspace: &mut Workspace, _: &mut ViewContext<Workspace>| {
27-
workspace.modal_layer().register_modal(Toggle, |cx| {
28-
let Some(previous_focus_handle) = cx.focused() else {
29-
return None;
30-
};
31-
32-
Some(cx.build_view(|cx| CommandPalette::new(previous_focus_handle, cx)))
33-
});
34-
},
35-
)
36-
.detach();
24+
cx.observe_new_views(CommandPalette::register).detach();
3725
}
3826

3927
pub struct CommandPalette {
4028
picker: View<Picker<CommandPaletteDelegate>>,
4129
}
4230

4331
impl CommandPalette {
32+
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
33+
workspace.register_action(|workspace, _: &Toggle, cx| {
34+
let Some(previous_focus_handle) = cx.focused() else {
35+
return;
36+
};
37+
workspace.toggle_modal(cx, move |cx| CommandPalette::new(previous_focus_handle, cx));
38+
});
39+
}
40+
4441
fn new(previous_focus_handle: FocusHandle, cx: &mut ViewContext<Self>) -> Self {
4542
let filter = cx.try_global::<CommandPaletteFilter>();
4643

crates/go_to_line2/src/go_to_line.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,7 @@ use workspace::{Modal, ModalEvent, Workspace};
1313
actions!(Toggle);
1414

1515
pub fn init(cx: &mut AppContext) {
16-
cx.observe_new_views(
17-
|workspace: &mut Workspace, cx: &mut ViewContext<Workspace>| {
18-
let handle = cx.view().downgrade();
19-
20-
workspace.modal_layer().register_modal(Toggle, move |cx| {
21-
let workspace = handle.upgrade()?;
22-
let editor = workspace
23-
.read(cx)
24-
.active_item(cx)
25-
.and_then(|active_item| active_item.downcast::<Editor>())?;
26-
27-
Some(cx.build_view(|cx| GoToLine::new(editor, cx)))
28-
});
29-
},
30-
)
31-
.detach();
16+
cx.observe_new_views(GoToLine::register).detach();
3217
}
3318

3419
pub struct GoToLine {
@@ -47,6 +32,19 @@ impl Modal for GoToLine {
4732
}
4833

4934
impl GoToLine {
35+
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
36+
workspace.register_action(|workspace, _: &Toggle, cx| {
37+
let Some(editor) = workspace
38+
.active_item(cx)
39+
.and_then(|active_item| active_item.downcast::<Editor>())
40+
else {
41+
return;
42+
};
43+
44+
workspace.toggle_modal(cx, move |cx| GoToLine::new(editor, cx));
45+
});
46+
}
47+
5048
pub fn new(active_editor: View<Editor>, cx: &mut ViewContext<Self>) -> Self {
5149
let line_editor = cx.build_view(|cx| Editor::single_line(cx));
5250
let line_editor_change = cx.subscribe(&line_editor, Self::on_line_editor_event);

crates/workspace2/src/modal_layer.rs

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::Workspace;
22
use gpui::{
33
div, px, AnyView, Component, Div, EventEmitter, FocusHandle, ParentElement, Render,
44
StatefulInteractivity, StatelessInteractive, Styled, Subscription, View, ViewContext,
5-
WindowContext,
5+
VisualContext, WindowContext,
66
};
77
use std::{any::TypeId, sync::Arc};
88
use ui::v_stack;
@@ -16,14 +16,6 @@ pub struct ActiveModal {
1616

1717
pub struct ModalLayer {
1818
active_modal: Option<ActiveModal>,
19-
registered_modals: Vec<(
20-
TypeId,
21-
Box<
22-
dyn Fn(
23-
Div<Workspace, StatefulInteractivity<Workspace>>,
24-
) -> Div<Workspace, StatefulInteractivity<Workspace>>,
25-
>,
26-
)>,
2719
}
2820

2921
pub trait Modal: Render + EventEmitter<ModalEvent> {
@@ -36,35 +28,13 @@ pub enum ModalEvent {
3628

3729
impl ModalLayer {
3830
pub fn new() -> Self {
39-
Self {
40-
active_modal: None,
41-
registered_modals: Vec::new(),
42-
}
31+
Self { active_modal: None }
4332
}
4433

45-
pub fn register_modal<A: 'static, V, B>(&mut self, action: A, build_view: B)
34+
pub fn toggle_modal<V, B>(&mut self, cx: &mut ViewContext<Workspace>, build_view: B)
4635
where
4736
V: Modal,
48-
B: Fn(&mut WindowContext) -> Option<View<V>> + 'static,
49-
{
50-
let build_view = Arc::new(build_view);
51-
52-
self.registered_modals.push((
53-
TypeId::of::<A>(),
54-
Box::new(move |mut div| {
55-
let build_view = build_view.clone();
56-
57-
div.on_action(move |workspace, event: &A, cx| {
58-
workspace.modal_layer().toggle_modal(build_view.clone(), cx)
59-
})
60-
}),
61-
));
62-
}
63-
64-
pub fn toggle_modal<V, B>(&mut self, build_view: Arc<B>, cx: &mut ViewContext<Workspace>)
65-
where
66-
V: Modal,
67-
B: Fn(&mut WindowContext) -> Option<View<V>> + 'static,
37+
B: FnOnce(&mut ViewContext<V>) -> V,
6838
{
6939
let previous_focus = cx.focused();
7040

@@ -74,28 +44,23 @@ impl ModalLayer {
7444
return;
7545
}
7646
}
77-
let Some(new_modal) = (build_view)(cx) else {
78-
return;
79-
};
80-
self.show_modal(previous_focus, new_modal, cx);
47+
let new_modal = cx.build_view(build_view);
48+
self.show_modal(new_modal, cx);
8149
}
8250

83-
pub fn show_modal<V>(
84-
&mut self,
85-
previous_focus: Option<FocusHandle>,
86-
new_modal: View<V>,
87-
cx: &mut ViewContext<Workspace>,
88-
) where
51+
pub fn show_modal<V>(&mut self, new_modal: View<V>, cx: &mut ViewContext<Workspace>)
52+
where
8953
V: Modal,
9054
{
9155
self.active_modal = Some(ActiveModal {
9256
modal: new_modal.clone().into(),
93-
subscription: cx.subscribe(&new_modal, |this, modal, e, cx| match e {
94-
ModalEvent::Dismissed => this.modal_layer().hide_modal(cx),
57+
subscription: cx.subscribe(&new_modal, |workspace, modal, e, cx| match e {
58+
ModalEvent::Dismissed => workspace.modal_layer.hide_modal(cx),
9559
}),
96-
previous_focus_handle: previous_focus,
60+
previous_focus_handle: cx.focused(),
9761
focus_handle: cx.focus_handle(),
9862
});
63+
new_modal.update(cx, |modal, cx| modal.focus(cx));
9964
cx.notify();
10065
}
10166

@@ -115,12 +80,7 @@ impl ModalLayer {
11580
&self,
11681
cx: &ViewContext<Workspace>,
11782
) -> Div<Workspace, StatefulInteractivity<Workspace>> {
118-
let mut parent = div().id("modal layer").relative().size_full();
119-
120-
for (_, action) in self.registered_modals.iter() {
121-
parent = (action)(parent);
122-
}
123-
83+
let parent = div().id("boop");
12484
parent.when_some(self.active_modal.as_ref(), |parent, open_modal| {
12585
let container1 = div()
12686
.absolute()
@@ -137,8 +97,8 @@ impl ModalLayer {
13797
.relative()
13898
.top_20()
13999
.track_focus(&open_modal.focus_handle)
140-
.on_mouse_down_out(|workspace: &mut Workspace, _, cx| {
141-
workspace.modal_layer().hide_modal(cx);
100+
.on_mouse_down_out(|workspace: &mut Workspace, event, cx| {
101+
workspace.modal_layer.hide_modal(cx);
142102
});
143103

144104
parent.child(container1.child(container2.child(open_modal.modal.clone())))

crates/workspace2/src/workspace2.rs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@ use futures::{
3636
Future, FutureExt, StreamExt,
3737
};
3838
use gpui::{
39-
actions, div, point, rems, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext,
40-
AsyncWindowContext, Bounds, Component, DispatchContext, Div, Entity, EntityId, EventEmitter,
41-
FocusHandle, GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size,
42-
StatefulInteractive, StatefulInteractivity, Styled, Subscription, Task, View, ViewContext,
43-
VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions,
39+
actions, div, point, rems, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
40+
AsyncAppContext, AsyncWindowContext, Bounds, Component, DispatchContext, Div, Entity, EntityId,
41+
EventEmitter, FocusHandle, GlobalPixels, Model, ModelContext, ParentElement, Point, Render,
42+
Size, StatefulInteractive, StatefulInteractivity, StatelessInteractive, Styled, Subscription,
43+
Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle,
44+
WindowOptions,
4445
};
4546
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
4647
use itertools::Itertools;
@@ -530,6 +531,13 @@ pub enum Event {
530531
pub struct Workspace {
531532
weak_self: WeakView<Self>,
532533
focus_handle: FocusHandle,
534+
workspace_actions: Vec<
535+
Box<
536+
dyn Fn(
537+
Div<Workspace, StatefulInteractivity<Workspace>>,
538+
) -> Div<Workspace, StatefulInteractivity<Workspace>>,
539+
>,
540+
>,
533541
zoomed: Option<AnyWeakView>,
534542
zoomed_position: Option<DockPosition>,
535543
center: PaneGroup,
@@ -775,13 +783,10 @@ impl Workspace {
775783
leader_updates_tx,
776784
subscriptions,
777785
pane_history_timestamp,
786+
workspace_actions: Default::default(),
778787
}
779788
}
780789

781-
pub fn modal_layer(&mut self) -> &mut ModalLayer {
782-
&mut self.modal_layer
783-
}
784-
785790
fn new_local(
786791
abs_paths: Vec<PathBuf>,
787792
app_state: Arc<AppState>,
@@ -3495,6 +3500,34 @@ impl Workspace {
34953500
// )
34963501
// }
34973502
// }
3503+
pub fn register_action<A: Action>(
3504+
&mut self,
3505+
callback: impl Fn(&mut Self, &A, &mut ViewContext<Self>) + 'static,
3506+
) {
3507+
let callback = Arc::new(callback);
3508+
3509+
self.workspace_actions.push(Box::new(move |div| {
3510+
let callback = callback.clone();
3511+
div.on_action(move |workspace, event, cx| (callback.clone())(workspace, event, cx))
3512+
}));
3513+
}
3514+
3515+
fn add_workspace_actions_listeners(
3516+
&self,
3517+
mut div: Div<Workspace, StatefulInteractivity<Workspace>>,
3518+
) -> Div<Workspace, StatefulInteractivity<Workspace>> {
3519+
for action in self.workspace_actions.iter() {
3520+
div = (action)(div)
3521+
}
3522+
div
3523+
}
3524+
3525+
pub fn toggle_modal<V: Modal, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
3526+
where
3527+
B: FnOnce(&mut ViewContext<V>) -> V,
3528+
{
3529+
self.modal_layer.toggle_modal(cx, build)
3530+
}
34983531
}
34993532

35003533
fn window_bounds_env_override(cx: &AsyncAppContext) -> Option<WindowBounds> {
@@ -3706,14 +3739,13 @@ fn notify_if_database_failed(workspace: WindowHandle<Workspace>, cx: &mut AsyncA
37063739
impl EventEmitter<Event> for Workspace {}
37073740

37083741
impl Render for Workspace {
3709-
type Element = Div<Self, StatefulInteractivity<Self>>;
3742+
type Element = Div<Self>;
37103743

37113744
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
37123745
let mut context = DispatchContext::default();
37133746
context.insert("Workspace");
37143747
cx.with_key_dispatch_context(context, |cx| {
37153748
div()
3716-
.id("workspace")
37173749
.relative()
37183750
.size_full()
37193751
.flex()
@@ -3727,8 +3759,7 @@ impl Render for Workspace {
37273759
.child(self.render_titlebar(cx))
37283760
.child(
37293761
// todo! should this be a component a view?
3730-
self.modal_layer
3731-
.wrapper_element(cx)
3762+
self.add_workspace_actions_listeners(div().id("workspace"))
37323763
.relative()
37333764
.flex_1()
37343765
.w_full()
@@ -3737,6 +3768,7 @@ impl Render for Workspace {
37373768
.border_t()
37383769
.border_b()
37393770
.border_color(cx.theme().colors().border)
3771+
.child(self.modal_layer.wrapper_element(cx))
37403772
// .children(
37413773
// Some(
37423774
// Panel::new("project-panel-outer", cx)

0 commit comments

Comments
 (0)