@@ -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<DockData>,
- _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<Workspace>) -> View<Self> {
let focus_handle = cx.focus_handle();
-
+ let workspace = cx.view().clone();
let dock = cx.new_view(|cx: &mut ViewContext<Self>| {
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)
@@ -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<Workspace>),
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<DraggedDock>, cx| {
- match e.drag(cx).0 {
+ .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 = 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()