@@ -7,7 +7,7 @@ use text::Point;
use theme::ActiveTheme;
use ui::{h_stack, modal, v_stack, Label, LabelColor};
use util::paths::FILE_ROW_COLUMN_DELIMITER;
-use workspace::ModalRegistry;
+use workspace::{ModalRegistry, Modal, ModalEvent};
actions!(Toggle);
@@ -33,7 +33,7 @@ pub enum Event {
}
impl EventEmitter for GoToLine {
- type Event = ModalEvent;
+ type Event = Event;
}
impl GoToLine {
@@ -100,7 +100,7 @@ impl GoToLine {
cx.emit(Event::Dismissed);
}
- fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
+ fn confirm(&mut self, _: &menu::Confirm, _cx: &mut ViewContext<Self>) {
// // if let Some(point) = self.point_from_query(cx) {
// // self.active_editor.update(cx, |active_editor, cx| {
// // let snapshot = active_editor.snapshot(cx).display_snapshot;
@@ -119,6 +119,14 @@ impl GoToLine {
}
}
+impl Modal for GoToLine {
+ fn to_modal_event(&self, e: &Self::Event) -> Option<ModalEvent> {
+ match e {
+ Event::Dismissed => Some(ModalEvent::Dismissed),
+ }
+ }
+}
+
impl Render for GoToLine {
type Element = Div<Self>;
@@ -1,7 +1,7 @@
use crate::Workspace;
use gpui::{
- div, px, AnyView, AppContext, Component, Div, ParentElement, Render, StatelessInteractive,
- Styled, View, ViewContext, EventEmitter,
+ div, px, AnyView, AppContext, Component, Div, EventEmitter, ParentElement, Render,
+ StatelessInteractive, Styled, Subscription, View, ViewContext, WeakView,
};
use std::{any::TypeId, sync::Arc};
use ui::v_stack;
@@ -10,11 +10,10 @@ pub struct ModalRegistry {
registered_modals: Vec<(TypeId, Box<dyn Fn(Div<Workspace>) -> Div<Workspace>>)>,
}
-pub trait Modal {}
-
-#[derive(Clone)]
pub struct ModalLayer {
+ workspace: WeakView<Workspace>,
open_modal: Option<AnyView>,
+ subscription: Option<Subscription>,
}
pub fn init_modal_registry(cx: &mut AppContext) {
@@ -23,23 +22,19 @@ pub fn init_modal_registry(cx: &mut AppContext) {
});
}
-struct ToggleModal {
- name: String,
-}
-
-pub enum ModalEvents {
- Dismissed
+pub enum ModalEvent {
+ Dismissed,
}
-trait Modal: EventEmitter + Render {
- fn to_modal_events(&Self::Event) -> Option<ModalEvents>;
+pub trait Modal: EventEmitter + Render {
+ fn to_modal_event(&self, _: &Self::Event) -> Option<ModalEvent>;
}
impl ModalRegistry {
pub fn register_modal<A: 'static, V, B>(&mut self, action: A, build_view: B)
where
V: Modal,
- B: Fn(&Workspace, &mut ViewContext<Workspace>) -> Option<View<V>> + 'static,
+ B: Fn(&mut Workspace, &mut ViewContext<Workspace>) -> Option<View<V>> + 'static,
{
let build_view = Arc::new(build_view);
@@ -48,35 +43,47 @@ impl ModalRegistry {
Box::new(move |mut div| {
let build_view = build_view.clone();
- div.on_action(
- move |workspace: &mut Workspace, event: &A, cx: &mut ViewContext<Workspace>| {
- let Some(new_modal) = (build_view)(workspace, cx) else {
- return;
+ div.on_action(move |workspace, event: &A, cx| {
+ let Some(new_modal) =
+ (build_view)(workspace, cx) else {
+ return
};
- workspace.modal_layer.update(cx, |modal_layer, _| {
- modal_layer.open_modal = Some(new_modal.into());
- });
- cx.subscribe(new_modal, |e, modal, cx| {
- match modal.to_modal_events(e) {
- Some(Dismissed) =>
- dismissed -> whatever
- }
- })
-
- cx.notify();
- },
- )
+ workspace.modal_layer.update(cx, |modal_layer, cx| {
+ modal_layer.show_modal(new_modal, cx);
+ })
+ })
}),
));
}
}
impl ModalLayer {
- pub fn new() -> Self {
- Self { open_modal: None }
+ pub fn new(workspace: WeakView<Workspace>) -> Self {
+ Self {
+ workspace,
+ open_modal: None,
+ subscription: None,
+ }
+ }
+
+ pub fn show_modal<V: Modal>(&mut self, new_modal: View<V>, cx: &mut ViewContext<Self>) {
+ self.subscription = Some(cx.subscribe(&new_modal, |this, modal, e, cx| {
+ match modal.read(cx).to_modal_event(e) {
+ Some(ModalEvent::Dismissed) => this.hide_modal(cx),
+ None => {}
+ }
+ }));
+ self.open_modal = Some(new_modal.into());
+ cx.notify();
+ }
+
+ pub fn hide_modal(&mut self, cx: &mut ViewContext<Self>) {
+ self.open_modal.take();
+ self.subscription.take();
+ cx.notify();
}
- pub fn render(&self, workspace: &Workspace, cx: &ViewContext<Workspace>) -> Div<Workspace> {
+ pub fn render(&self, cx: &ViewContext<Workspace>) -> Div<Workspace> {
let mut parent = div().relative().size_full();
for (_, action) in cx.global::<ModalRegistry>().registered_modals.iter() {
@@ -46,8 +46,7 @@ use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings,
use itertools::Itertools;
use language2::LanguageRegistry;
use lazy_static::lazy_static;
-pub use modal_layer::ModalRegistry;
-use modal_layer::{init_modal_registry, ModalLayer};
+pub use modal_layer::*;
use node_runtime::NodeRuntime;
use notifications::{simple_message_notification::MessageNotification, NotificationHandle};
pub use pane::*;
@@ -697,7 +696,8 @@ impl Workspace {
status_bar
});
- let modal_layer = cx.build_view(|cx| ModalLayer::new());
+ let workspace_handle = cx.view().downgrade();
+ let modal_layer = cx.build_view(|cx| ModalLayer::new(workspace_handle));
// todo!()
// cx.update_default_global::<DragAndDrop<Workspace>, _, _>(|drag_and_drop, _| {
@@ -3709,7 +3709,7 @@ impl Render for Workspace {
.child(
self.modal_layer
.read(cx)
- .render(self, cx)
+ .render(cx)
.relative()
.flex_1()
.w_full()