Make Modals dismissable in theory
This commit is contained in:
parent
097efdebc5
commit
6a802e2fda
4 changed files with 57 additions and 42 deletions
|
@ -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,4 +1,4 @@
|
|||
use gpui::{actions, ctor};
|
||||
use gpui::actions;
|
||||
|
||||
// todo!(remove this)
|
||||
// https://github.com/rust-lang/rust/issues/47384
|
||||
|
|
|
@ -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 ModalEvent {
|
||||
Dismissed,
|
||||
}
|
||||
|
||||
pub enum ModalEvents {
|
||||
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 render(&self, workspace: &Workspace, cx: &ViewContext<Workspace>) -> Div<Workspace> {
|
||||
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, 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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue