Detailed changes
@@ -1,44 +1,66 @@
-use gpui::{elements::*, Entity, ModelHandle, View, ViewContext, ViewHandle, WeakViewHandle};
+use crate::TerminalView;
+use gpui::{
+ elements::*, AppContext, Entity, ModelHandle, Subscription, View, ViewContext, ViewHandle,
+ WeakViewHandle,
+};
use project::Project;
use settings::{Settings, WorkingDirectory};
use util::ResultExt;
-use workspace::{dock::Panel, DraggedItem, Pane, Workspace};
+use workspace::{dock::Panel, pane, DraggedItem, Pane, Workspace};
-use crate::TerminalView;
+pub enum Event {
+ Close,
+}
pub struct TerminalPanel {
project: ModelHandle<Project>,
pane: ViewHandle<Pane>,
workspace: WeakViewHandle<Workspace>,
+ _subscription: Subscription,
}
impl TerminalPanel {
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
+ let pane = cx.add_view(|cx| {
+ let window_id = cx.window_id();
+ let mut pane = Pane::new(
+ workspace.weak_handle(),
+ workspace.app_state().background_actions,
+ cx,
+ );
+ pane.on_can_drop(move |drag_and_drop, cx| {
+ drag_and_drop
+ .currently_dragged::<DraggedItem>(window_id)
+ .map_or(false, |(_, item)| {
+ item.handle.act_as::<TerminalView>(cx).is_some()
+ })
+ });
+ pane
+ });
+ let subscription = cx.subscribe(&pane, Self::handle_pane_event);
Self {
project: workspace.project().clone(),
- pane: cx.add_view(|cx| {
- let window_id = cx.window_id();
- let mut pane = Pane::new(
- workspace.weak_handle(),
- workspace.app_state().background_actions,
- cx,
- );
- pane.on_can_drop(move |drag_and_drop, cx| {
- drag_and_drop
- .currently_dragged::<DraggedItem>(window_id)
- .map_or(false, |(_, item)| {
- item.handle.act_as::<TerminalView>(cx).is_some()
- })
- });
- pane
- }),
+ pane,
workspace: workspace.weak_handle(),
+ _subscription: subscription,
+ }
+ }
+
+ fn handle_pane_event(
+ &mut self,
+ _pane: ViewHandle<Pane>,
+ event: &pane::Event,
+ cx: &mut ViewContext<Self>,
+ ) {
+ match event {
+ pane::Event::Remove => cx.emit(Event::Close),
+ _ => {}
}
}
}
impl Entity for TerminalPanel {
- type Event = ();
+ type Event = Event;
}
impl View for TerminalPanel {
@@ -82,4 +104,8 @@ impl View for TerminalPanel {
}
}
-impl Panel for TerminalPanel {}
+impl Panel for TerminalPanel {
+ fn should_close_on_event(&self, event: &Event, _: &AppContext) -> bool {
+ matches!(event, Event::Close)
+ }
+}
@@ -8,7 +8,10 @@ use settings::Settings;
use std::rc::Rc;
pub trait Panel: View {
- fn should_activate_item_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+ fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+ false
+ }
+ fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
false
}
fn should_show_badge(&self, _: &AppContext) -> bool {
@@ -53,6 +56,10 @@ impl From<&dyn PanelHandle> for AnyViewHandle {
}
}
+pub enum Event {
+ Close,
+}
+
pub struct Dock {
position: DockPosition,
items: Vec<Item>,
@@ -138,7 +145,7 @@ impl Dock {
let subscriptions = [
cx.observe(&view, |_, _, cx| cx.notify()),
cx.subscribe(&view, |this, view, event, cx| {
- if view.read(cx).should_activate_item_on_event(event, cx) {
+ if view.read(cx).should_activate_on_event(event, cx) {
if let Some(ix) = this
.items
.iter()
@@ -146,6 +153,8 @@ impl Dock {
{
this.activate_item(ix, cx);
}
+ } else if view.read(cx).should_close_on_event(event, cx) {
+ cx.emit(Event::Close);
}
}),
];
@@ -183,7 +192,7 @@ impl Dock {
}
impl Entity for Dock {
- type Event = ();
+ type Event = Event;
}
impl View for Dock {
@@ -461,7 +461,7 @@ pub struct Workspace {
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
database_id: WorkspaceId,
app_state: Arc<AppState>,
- _window_subscriptions: [Subscription; 3],
+ _subscriptions: Vec<Subscription>,
_apply_leader_updates: Task<Result<()>>,
_observe_current_user: Task<Result<()>>,
}
@@ -592,7 +592,7 @@ impl Workspace {
active_call = Some((call, subscriptions));
}
- let subscriptions = [
+ let subscriptions = vec![
cx.observe_fullscreen(|_, _, cx| cx.notify()),
cx.observe_window_activation(Self::on_window_activation_changed),
cx.observe_window_bounds(move |_, mut bounds, display, cx| {
@@ -612,6 +612,9 @@ impl Workspace {
.spawn(DB.set_window_bounds(workspace_id, bounds, display))
.detach_and_log_err(cx);
}),
+ Self::register_dock(&left_dock, cx),
+ Self::register_dock(&bottom_dock, cx),
+ Self::register_dock(&right_dock, cx),
];
let mut this = Workspace {
@@ -640,7 +643,7 @@ impl Workspace {
_observe_current_user,
_apply_leader_updates,
leader_updates_tx,
- _window_subscriptions: subscriptions,
+ _subscriptions: subscriptions,
};
this.project_remote_id_changed(project.read(cx).remote_id(), cx);
cx.defer(|this, cx| this.update_window_title(cx));
@@ -1316,6 +1319,26 @@ impl Workspace {
}
}
+ fn register_dock(dock: &ViewHandle<Dock>, cx: &mut ViewContext<Self>) -> Subscription {
+ cx.subscribe(dock, Self::handle_dock_event)
+ }
+
+ fn handle_dock_event(
+ &mut self,
+ dock: ViewHandle<Dock>,
+ event: &dock::Event,
+ cx: &mut ViewContext<Self>,
+ ) {
+ match event {
+ dock::Event::Close => {
+ dock.update(cx, |dock, cx| dock.set_open(false, cx));
+ self.serialize_workspace(cx);
+ cx.focus_self();
+ cx.notify();
+ }
+ }
+ }
+
pub fn toggle_dock(&mut self, dock_side: DockPosition, cx: &mut ViewContext<Self>) {
let dock = match dock_side {
DockPosition::Left => &mut self.left_dock,