diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 075d69d781..4dad415445 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -1,6 +1,6 @@ use crate::persistence::model::DockData; -use crate::DraggedDock; use crate::{status_bar::StatusItemView, Workspace}; +use crate::{DraggedDock, Event}; use gpui::{ deferred, div, px, Action, AnchorCorner, AnyView, AppContext, Axis, ClickEvent, Entity, EntityId, EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton, @@ -149,7 +149,8 @@ pub struct Dock { active_panel_index: usize, focus_handle: FocusHandle, pub(crate) serialized_dock: Option, - _focus_subscription: Subscription, + resizeable: bool, + _subscriptions: [Subscription; 2], } impl FocusableView for Dock { @@ -195,21 +196,28 @@ pub struct PanelButtons { impl Dock { pub fn new(position: DockPosition, cx: &mut ViewContext) -> View { let focus_handle = cx.focus_handle(); - + let workspace = cx.view().clone(); let dock = cx.new_view(|cx: &mut ViewContext| { let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| { if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) { active_entry.panel.focus_handle(cx).focus(cx) } }); + let zoom_subscription = cx.subscribe(&workspace, |dock, workspace, e: &Event, cx| { + if matches!(e, Event::ZoomChanged) { + let is_zoomed = workspace.read(cx).zoomed.is_some(); + dock.resizeable = !is_zoomed; + } + }); Self { position, panel_entries: Default::default(), active_panel_index: 0, is_open: false, focus_handle: focus_handle.clone(), - _focus_subscription: focus_subscription, + _subscriptions: [focus_subscription, zoom_subscription], serialized_dock: None, + resizeable: true, } }); @@ -229,6 +237,7 @@ impl Dock { workspace.zoomed = None; workspace.zoomed_position = None; } + cx.emit(Event::ZoomChanged); workspace.dismiss_zoomed_items_to_reveal(Some(position), cx); workspace.update_active_view_for_followers(cx) } @@ -241,6 +250,7 @@ impl Dock { if panel.is_zoomed(cx) { workspace.zoomed = Some(panel.to_any().downgrade()); workspace.zoomed_position = Some(position); + cx.emit(Event::ZoomChanged); return; } } @@ -248,6 +258,7 @@ impl Dock { if workspace.zoomed_position == Some(position) { workspace.zoomed = None; workspace.zoomed_position = None; + cx.emit(Event::ZoomChanged); } }) .detach(); @@ -380,6 +391,7 @@ impl Dock { .update(cx, |workspace, cx| { workspace.zoomed = Some(panel.downgrade().into()); workspace.zoomed_position = Some(panel.read(cx).position(cx)); + cx.emit(Event::ZoomChanged); }) .ok(); } @@ -390,6 +402,7 @@ impl Dock { if workspace.zoomed_position == Some(this.position) { workspace.zoomed = None; workspace.zoomed_position = None; + cx.emit(Event::ZoomChanged); } cx.notify(); }) @@ -553,47 +566,49 @@ impl Render for Dock { let size = entry.panel.size(cx); let position = self.position; - let handle = div() - .id("resize-handle") - .on_drag(DraggedDock(position), |dock, cx| { - cx.stop_propagation(); - cx.new_view(|_| dock.clone()) - }) - .on_click(cx.listener(|v, e: &ClickEvent, cx| { - if e.down.button == MouseButton::Left && e.down.click_count == 2 { - v.resize_active_panel(None, cx); + let create_resize_handle = || { + let handle = div() + .id("resize-handle") + .on_drag(DraggedDock(position), |dock, cx| { cx.stop_propagation(); - } - })) - .occlude(); - let handle = match self.position() { - DockPosition::Left => deferred( - handle - .absolute() - .right(-RESIZE_HANDLE_SIZE / 2.) - .top(px(0.)) - .h_full() - .w(RESIZE_HANDLE_SIZE) - .cursor_col_resize(), - ), - DockPosition::Bottom => deferred( - handle - .absolute() - .top(-RESIZE_HANDLE_SIZE / 2.) - .left(px(0.)) - .w_full() - .h(RESIZE_HANDLE_SIZE) - .cursor_row_resize(), - ), - DockPosition::Right => deferred( - handle - .absolute() - .top(px(0.)) - .left(-RESIZE_HANDLE_SIZE / 2.) - .h_full() - .w(RESIZE_HANDLE_SIZE) - .cursor_col_resize(), - ), + cx.new_view(|_| dock.clone()) + }) + .on_click(cx.listener(|v, e: &ClickEvent, cx| { + if e.down.button == MouseButton::Left && e.down.click_count == 2 { + v.resize_active_panel(None, cx); + cx.stop_propagation(); + } + })) + .occlude(); + match self.position() { + DockPosition::Left => deferred( + handle + .absolute() + .right(-RESIZE_HANDLE_SIZE / 2.) + .top(px(0.)) + .h_full() + .w(RESIZE_HANDLE_SIZE) + .cursor_col_resize(), + ), + DockPosition::Bottom => deferred( + handle + .absolute() + .top(-RESIZE_HANDLE_SIZE / 2.) + .left(px(0.)) + .w_full() + .h(RESIZE_HANDLE_SIZE) + .cursor_row_resize(), + ), + DockPosition::Right => deferred( + handle + .absolute() + .top(px(0.)) + .left(-RESIZE_HANDLE_SIZE / 2.) + .h_full() + .w(RESIZE_HANDLE_SIZE) + .cursor_col_resize(), + ), + } }; div() @@ -625,7 +640,7 @@ impl Render for Dock { .cached(StyleRefinement::default().v_flex().size_full()), ), ) - .child(handle) + .when(self.resizeable, |this| this.child(create_resize_handle())) } else { div() .key_context(dispatch_context) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 937e9e2fa2..bfaa0c74ba 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -75,9 +75,9 @@ use theme::{ActiveTheme, SystemAppearance, ThemeSettings}; pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView}; pub use ui; use ui::{ - div, Context as _, Div, Element, ElementContext, InteractiveElement as _, IntoElement, Label, - ParentElement as _, Pixels, SharedString, Styled as _, ViewContext, VisualContext as _, - WindowContext, + div, Context as _, Div, Element, ElementContext, FluentBuilder as _, InteractiveElement as _, + IntoElement, Label, ParentElement as _, Pixels, SharedString, Styled as _, ViewContext, + VisualContext as _, WindowContext, }; use util::ResultExt; use uuid::Uuid; @@ -520,6 +520,7 @@ pub enum Event { ContactRequestedJoin(u64), WorkspaceCreated(WeakView), SpawnTask(SpawnInTerminal), + ZoomChanged, } pub enum OpenVisible { @@ -1913,6 +1914,7 @@ impl Workspace { if self.zoomed_position != dock_to_reveal { self.zoomed = None; self.zoomed_position = None; + cx.emit(Event::ZoomChanged); } cx.notify(); @@ -2341,6 +2343,7 @@ impl Workspace { self.zoomed = None; } self.zoomed_position = None; + cx.emit(Event::ZoomChanged); self.update_active_view_for_followers(cx); cx.notify(); @@ -2390,6 +2393,7 @@ impl Workspace { if pane.read(cx).has_focus(cx) { self.zoomed = Some(pane.downgrade().into()); self.zoomed_position = None; + cx.emit(Event::ZoomChanged); } cx.notify(); } @@ -2398,6 +2402,7 @@ impl Workspace { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); if self.zoomed_position.is_none() { self.zoomed = None; + cx.emit(Event::ZoomChanged); } cx.notify(); } @@ -3918,9 +3923,9 @@ impl Render for Workspace { .absolute() .size_full() }) - .on_drag_move( - cx.listener(|workspace, e: &DragMoveEvent, cx| { - match e.drag(cx).0 { + .when(self.zoomed.is_none(), |this| { + this.on_drag_move(cx.listener( + |workspace, e: &DragMoveEvent, cx| match e.drag(cx).0 { DockPosition::Left => { let size = workspace.bounds.left() + e.event.position.x; workspace.left_dock.update(cx, |left_dock, cx| { @@ -3939,9 +3944,9 @@ impl Render for Workspace { bottom_dock.resize_active_panel(Some(size), cx); }); } - } - }), - ) + }, + )) + }) .child( div() .flex()