@@ -2,6 +2,7 @@ use std::path::PathBuf;
use dev_server_projects::DevServer;
use gpui::{ClickEvent, DismissEvent, EventEmitter, FocusHandle, FocusableView, Render, WeakView};
+use project::project_settings::ProjectSettings;
use remote::SshConnectionOptions;
use settings::Settings;
use ui::{
@@ -26,6 +27,7 @@ pub struct DisconnectedOverlay {
workspace: WeakView<Workspace>,
host: Host,
focus_handle: FocusHandle,
+ finished: bool,
}
impl EventEmitter<DismissEvent> for DisconnectedOverlay {}
@@ -35,6 +37,9 @@ impl FocusableView for DisconnectedOverlay {
}
}
impl ModalView for DisconnectedOverlay {
+ fn on_before_dismiss(&mut self, _: &mut ViewContext<Self>) -> workspace::DismissDecision {
+ return workspace::DismissDecision::Dismiss(self.finished);
+ }
fn fade_out_background(&self) -> bool {
true
}
@@ -70,6 +75,7 @@ impl DisconnectedOverlay {
};
workspace.toggle_modal(cx, |cx| DisconnectedOverlay {
+ finished: false,
workspace: handle,
host,
focus_handle: cx.focus_handle(),
@@ -79,6 +85,7 @@ impl DisconnectedOverlay {
}
fn handle_reconnect(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
+ self.finished = true;
cx.emit(DismissEvent);
match &self.host {
@@ -186,6 +193,7 @@ impl DisconnectedOverlay {
}
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
+ self.finished = true;
cx.emit(DismissEvent)
}
}
@@ -202,9 +210,17 @@ impl Render for DisconnectedOverlay {
"Your connection to the remote project has been lost.".to_string()
}
Host::SshRemoteProject(options) => {
+ let autosave = if ProjectSettings::get_global(cx)
+ .session
+ .restore_unsaved_buffers
+ {
+ "\nUnsaved changes are stored locally."
+ } else {
+ ""
+ };
format!(
- "Your connection to {} has been lost",
- options.connection_string()
+ "Your connection to {} has been lost.{}",
+ options.host, autosave
)
}
};
@@ -31,7 +31,7 @@ use futures::{
};
use gpui::{
action_as, actions, canvas, impl_action_as, impl_actions, point, relative, size,
- transparent_black, Action, AnyElement, AnyView, AnyWeakView, AppContext, AsyncAppContext,
+ transparent_black, Action, AnyView, AnyWeakView, AppContext, AsyncAppContext,
AsyncWindowContext, Bounds, CursorStyle, Decorations, DragMoveEvent, Entity as _, EntityId,
EventEmitter, Flatten, FocusHandle, FocusableView, Global, Hsla, KeyContext, Keystroke,
ManagedView, Model, ModelContext, MouseButton, PathPromptOptions, Point, PromptLevel, Render,
@@ -762,8 +762,6 @@ pub struct Workspace {
bounds_save_task_queued: Option<Task<()>>,
on_prompt_for_new_path: Option<PromptForNewPath>,
on_prompt_for_open_path: Option<PromptForOpenPath>,
- render_disconnected_overlay:
- Option<Box<dyn Fn(&mut Self, &mut ViewContext<Self>) -> AnyElement>>,
serializable_items_tx: UnboundedSender<Box<dyn SerializableItemHandle>>,
serialized_ssh_project: Option<SerializedSshProject>,
_items_serializer: Task<Result<()>>,
@@ -1067,7 +1065,6 @@ impl Workspace {
bounds_save_task_queued: None,
on_prompt_for_new_path: None,
on_prompt_for_open_path: None,
- render_disconnected_overlay: None,
serializable_items_tx,
_items_serializer,
session_id: Some(session_id),
@@ -1472,13 +1469,6 @@ impl Workspace {
self.serialized_ssh_project = Some(serialized_ssh_project);
}
- pub fn set_render_disconnected_overlay(
- &mut self,
- render: impl Fn(&mut Self, &mut ViewContext<Self>) -> AnyElement + 'static,
- ) {
- self.render_disconnected_overlay = Some(Box::new(render))
- }
-
pub fn prompt_for_open_path(
&mut self,
path_prompt_options: PathPromptOptions,
@@ -4746,130 +4736,158 @@ impl Render for Workspace {
.children(self.titlebar_item.clone())
.child(
div()
- .id("workspace")
- .bg(colors.background)
+ .size_full()
.relative()
.flex_1()
- .w_full()
.flex()
.flex_col()
- .overflow_hidden()
- .border_t_1()
- .border_b_1()
- .border_color(colors.border)
- .child({
- let this = cx.view().clone();
- canvas(
- move |bounds, cx| this.update(cx, |this, _cx| this.bounds = bounds),
- |_, _, _| {},
- )
- .absolute()
- .size_full()
- })
- .when(self.zoomed.is_none(), |this| {
- this.on_drag_move(cx.listener(
- |workspace, e: &DragMoveEvent<DraggedDock>, cx| match e.drag(cx).0 {
- DockPosition::Left => {
- let size = e.event.position.x - workspace.bounds.left();
- workspace.left_dock.update(cx, |left_dock, cx| {
- left_dock.resize_active_panel(Some(size), cx);
- });
- }
- DockPosition::Right => {
- let size = workspace.bounds.right() - e.event.position.x;
- workspace.right_dock.update(cx, |right_dock, cx| {
- right_dock.resize_active_panel(Some(size), cx);
- });
- }
- DockPosition::Bottom => {
- let size = workspace.bounds.bottom() - e.event.position.y;
- workspace.bottom_dock.update(cx, |bottom_dock, cx| {
- bottom_dock.resize_active_panel(Some(size), cx);
- });
- }
- },
- ))
- })
.child(
div()
+ .id("workspace")
+ .bg(colors.background)
+ .relative()
+ .flex_1()
+ .w_full()
.flex()
- .flex_row()
- .h_full()
- // Left Dock
- .children(self.render_dock(DockPosition::Left, &self.left_dock, cx))
- // Panes
+ .flex_col()
+ .overflow_hidden()
+ .border_t_1()
+ .border_b_1()
+ .border_color(colors.border)
+ .child({
+ let this = cx.view().clone();
+ canvas(
+ move |bounds, cx| {
+ this.update(cx, |this, _cx| this.bounds = bounds)
+ },
+ |_, _, _| {},
+ )
+ .absolute()
+ .size_full()
+ })
+ .when(self.zoomed.is_none(), |this| {
+ this.on_drag_move(cx.listener(
+ |workspace, e: &DragMoveEvent<DraggedDock>, cx| {
+ match e.drag(cx).0 {
+ DockPosition::Left => {
+ let size = e.event.position.x
+ - workspace.bounds.left();
+ workspace.left_dock.update(
+ cx,
+ |left_dock, cx| {
+ left_dock.resize_active_panel(
+ Some(size),
+ cx,
+ );
+ },
+ );
+ }
+ DockPosition::Right => {
+ let size = workspace.bounds.right()
+ - e.event.position.x;
+ workspace.right_dock.update(
+ cx,
+ |right_dock, cx| {
+ right_dock.resize_active_panel(
+ Some(size),
+ cx,
+ );
+ },
+ );
+ }
+ DockPosition::Bottom => {
+ let size = workspace.bounds.bottom()
+ - e.event.position.y;
+ workspace.bottom_dock.update(
+ cx,
+ |bottom_dock, cx| {
+ bottom_dock.resize_active_panel(
+ Some(size),
+ cx,
+ );
+ },
+ );
+ }
+ }
+ },
+ ))
+ })
.child(
div()
.flex()
- .flex_col()
- .flex_1()
- .overflow_hidden()
+ .flex_row()
+ .h_full()
+ // Left Dock
+ .children(self.render_dock(
+ DockPosition::Left,
+ &self.left_dock,
+ cx,
+ ))
+ // Panes
.child(
- h_flex()
+ div()
+ .flex()
+ .flex_col()
.flex_1()
- .when_some(paddings.0, |this, p| {
- this.child(p.border_r_1())
- })
- .child(self.center.render(
- &self.project,
- &self.follower_states,
- self.active_call(),
- &self.active_pane,
- self.zoomed.as_ref(),
- &self.app_state,
+ .overflow_hidden()
+ .child(
+ h_flex()
+ .flex_1()
+ .when_some(paddings.0, |this, p| {
+ this.child(p.border_r_1())
+ })
+ .child(self.center.render(
+ &self.project,
+ &self.follower_states,
+ self.active_call(),
+ &self.active_pane,
+ self.zoomed.as_ref(),
+ &self.app_state,
+ cx,
+ ))
+ .when_some(paddings.1, |this, p| {
+ this.child(p.border_l_1())
+ }),
+ )
+ .children(self.render_dock(
+ DockPosition::Bottom,
+ &self.bottom_dock,
cx,
- ))
- .when_some(paddings.1, |this, p| {
- this.child(p.border_l_1())
- }),
+ )),
)
+ // Right Dock
.children(self.render_dock(
- DockPosition::Bottom,
- &self.bottom_dock,
+ DockPosition::Right,
+ &self.right_dock,
cx,
)),
)
- // Right Dock
- .children(self.render_dock(
- DockPosition::Right,
- &self.right_dock,
- cx,
- )),
+ .children(self.zoomed.as_ref().and_then(|view| {
+ let zoomed_view = view.upgrade()?;
+ let div = div()
+ .occlude()
+ .absolute()
+ .overflow_hidden()
+ .border_color(colors.border)
+ .bg(colors.background)
+ .child(zoomed_view)
+ .inset_0()
+ .shadow_lg();
+
+ Some(match self.zoomed_position {
+ Some(DockPosition::Left) => div.right_2().border_r_1(),
+ Some(DockPosition::Right) => div.left_2().border_l_1(),
+ Some(DockPosition::Bottom) => div.top_2().border_t_1(),
+ None => {
+ div.top_2().bottom_2().left_2().right_2().border_1()
+ }
+ })
+ }))
+ .children(self.render_notifications(cx)),
)
- .children(self.zoomed.as_ref().and_then(|view| {
- let zoomed_view = view.upgrade()?;
- let div = div()
- .occlude()
- .absolute()
- .overflow_hidden()
- .border_color(colors.border)
- .bg(colors.background)
- .child(zoomed_view)
- .inset_0()
- .shadow_lg();
-
- Some(match self.zoomed_position {
- Some(DockPosition::Left) => div.right_2().border_r_1(),
- Some(DockPosition::Right) => div.left_2().border_l_1(),
- Some(DockPosition::Bottom) => div.top_2().border_t_1(),
- None => div.top_2().bottom_2().left_2().right_2().border_1(),
- })
- }))
- .child(self.modal_layer.clone())
- .children(self.render_notifications(cx)),
- )
- .child(self.status_bar.clone())
- .children(if self.project.read(cx).is_disconnected(cx) {
- if let Some(render) = self.render_disconnected_overlay.take() {
- let result = render(self, cx);
- self.render_disconnected_overlay = Some(render);
- Some(result)
- } else {
- None
- }
- } else {
- None
- }),
+ .child(self.status_bar.clone())
+ .child(self.modal_layer.clone()),
+ ),
cx,
)
}