workspace: Fix panel resize handles leaking through zoomed panels (#9909)
Fixes #9501 Release Notes: - Fixed panel resize handle "leaking through" into a zoomed panel or pane.
This commit is contained in:
parent
f5823f9942
commit
cb7c53bc52
2 changed files with 74 additions and 54 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::persistence::model::DockData;
|
use crate::persistence::model::DockData;
|
||||||
use crate::DraggedDock;
|
|
||||||
use crate::{status_bar::StatusItemView, Workspace};
|
use crate::{status_bar::StatusItemView, Workspace};
|
||||||
|
use crate::{DraggedDock, Event};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
deferred, div, px, Action, AnchorCorner, AnyView, AppContext, Axis, ClickEvent, Entity,
|
deferred, div, px, Action, AnchorCorner, AnyView, AppContext, Axis, ClickEvent, Entity,
|
||||||
EntityId, EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton,
|
EntityId, EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton,
|
||||||
|
@ -149,7 +149,8 @@ pub struct Dock {
|
||||||
active_panel_index: usize,
|
active_panel_index: usize,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
pub(crate) serialized_dock: Option<DockData>,
|
pub(crate) serialized_dock: Option<DockData>,
|
||||||
_focus_subscription: Subscription,
|
resizeable: bool,
|
||||||
|
_subscriptions: [Subscription; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for Dock {
|
impl FocusableView for Dock {
|
||||||
|
@ -195,21 +196,28 @@ pub struct PanelButtons {
|
||||||
impl Dock {
|
impl Dock {
|
||||||
pub fn new(position: DockPosition, cx: &mut ViewContext<Workspace>) -> View<Self> {
|
pub fn new(position: DockPosition, cx: &mut ViewContext<Workspace>) -> View<Self> {
|
||||||
let focus_handle = cx.focus_handle();
|
let focus_handle = cx.focus_handle();
|
||||||
|
let workspace = cx.view().clone();
|
||||||
let dock = cx.new_view(|cx: &mut ViewContext<Self>| {
|
let dock = cx.new_view(|cx: &mut ViewContext<Self>| {
|
||||||
let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
|
let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
|
||||||
if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
|
if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
|
||||||
active_entry.panel.focus_handle(cx).focus(cx)
|
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 {
|
Self {
|
||||||
position,
|
position,
|
||||||
panel_entries: Default::default(),
|
panel_entries: Default::default(),
|
||||||
active_panel_index: 0,
|
active_panel_index: 0,
|
||||||
is_open: false,
|
is_open: false,
|
||||||
focus_handle: focus_handle.clone(),
|
focus_handle: focus_handle.clone(),
|
||||||
_focus_subscription: focus_subscription,
|
_subscriptions: [focus_subscription, zoom_subscription],
|
||||||
serialized_dock: None,
|
serialized_dock: None,
|
||||||
|
resizeable: true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -229,6 +237,7 @@ impl Dock {
|
||||||
workspace.zoomed = None;
|
workspace.zoomed = None;
|
||||||
workspace.zoomed_position = None;
|
workspace.zoomed_position = None;
|
||||||
}
|
}
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
workspace.dismiss_zoomed_items_to_reveal(Some(position), cx);
|
workspace.dismiss_zoomed_items_to_reveal(Some(position), cx);
|
||||||
workspace.update_active_view_for_followers(cx)
|
workspace.update_active_view_for_followers(cx)
|
||||||
}
|
}
|
||||||
|
@ -241,6 +250,7 @@ impl Dock {
|
||||||
if panel.is_zoomed(cx) {
|
if panel.is_zoomed(cx) {
|
||||||
workspace.zoomed = Some(panel.to_any().downgrade());
|
workspace.zoomed = Some(panel.to_any().downgrade());
|
||||||
workspace.zoomed_position = Some(position);
|
workspace.zoomed_position = Some(position);
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,6 +258,7 @@ impl Dock {
|
||||||
if workspace.zoomed_position == Some(position) {
|
if workspace.zoomed_position == Some(position) {
|
||||||
workspace.zoomed = None;
|
workspace.zoomed = None;
|
||||||
workspace.zoomed_position = None;
|
workspace.zoomed_position = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
@ -380,6 +391,7 @@ impl Dock {
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
workspace.zoomed = Some(panel.downgrade().into());
|
workspace.zoomed = Some(panel.downgrade().into());
|
||||||
workspace.zoomed_position = Some(panel.read(cx).position(cx));
|
workspace.zoomed_position = Some(panel.read(cx).position(cx));
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
@ -390,6 +402,7 @@ impl Dock {
|
||||||
if workspace.zoomed_position == Some(this.position) {
|
if workspace.zoomed_position == Some(this.position) {
|
||||||
workspace.zoomed = None;
|
workspace.zoomed = None;
|
||||||
workspace.zoomed_position = None;
|
workspace.zoomed_position = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
|
@ -553,6 +566,7 @@ impl Render for Dock {
|
||||||
let size = entry.panel.size(cx);
|
let size = entry.panel.size(cx);
|
||||||
|
|
||||||
let position = self.position;
|
let position = self.position;
|
||||||
|
let create_resize_handle = || {
|
||||||
let handle = div()
|
let handle = div()
|
||||||
.id("resize-handle")
|
.id("resize-handle")
|
||||||
.on_drag(DraggedDock(position), |dock, cx| {
|
.on_drag(DraggedDock(position), |dock, cx| {
|
||||||
|
@ -566,7 +580,7 @@ impl Render for Dock {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.occlude();
|
.occlude();
|
||||||
let handle = match self.position() {
|
match self.position() {
|
||||||
DockPosition::Left => deferred(
|
DockPosition::Left => deferred(
|
||||||
handle
|
handle
|
||||||
.absolute()
|
.absolute()
|
||||||
|
@ -594,6 +608,7 @@ impl Render for Dock {
|
||||||
.w(RESIZE_HANDLE_SIZE)
|
.w(RESIZE_HANDLE_SIZE)
|
||||||
.cursor_col_resize(),
|
.cursor_col_resize(),
|
||||||
),
|
),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
div()
|
div()
|
||||||
|
@ -625,7 +640,7 @@ impl Render for Dock {
|
||||||
.cached(StyleRefinement::default().v_flex().size_full()),
|
.cached(StyleRefinement::default().v_flex().size_full()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(handle)
|
.when(self.resizeable, |this| this.child(create_resize_handle()))
|
||||||
} else {
|
} else {
|
||||||
div()
|
div()
|
||||||
.key_context(dispatch_context)
|
.key_context(dispatch_context)
|
||||||
|
|
|
@ -75,9 +75,9 @@ use theme::{ActiveTheme, SystemAppearance, ThemeSettings};
|
||||||
pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
|
pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
|
||||||
pub use ui;
|
pub use ui;
|
||||||
use ui::{
|
use ui::{
|
||||||
div, Context as _, Div, Element, ElementContext, InteractiveElement as _, IntoElement, Label,
|
div, Context as _, Div, Element, ElementContext, FluentBuilder as _, InteractiveElement as _,
|
||||||
ParentElement as _, Pixels, SharedString, Styled as _, ViewContext, VisualContext as _,
|
IntoElement, Label, ParentElement as _, Pixels, SharedString, Styled as _, ViewContext,
|
||||||
WindowContext,
|
VisualContext as _, WindowContext,
|
||||||
};
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -520,6 +520,7 @@ pub enum Event {
|
||||||
ContactRequestedJoin(u64),
|
ContactRequestedJoin(u64),
|
||||||
WorkspaceCreated(WeakView<Workspace>),
|
WorkspaceCreated(WeakView<Workspace>),
|
||||||
SpawnTask(SpawnInTerminal),
|
SpawnTask(SpawnInTerminal),
|
||||||
|
ZoomChanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum OpenVisible {
|
pub enum OpenVisible {
|
||||||
|
@ -1913,6 +1914,7 @@ impl Workspace {
|
||||||
if self.zoomed_position != dock_to_reveal {
|
if self.zoomed_position != dock_to_reveal {
|
||||||
self.zoomed = None;
|
self.zoomed = None;
|
||||||
self.zoomed_position = None;
|
self.zoomed_position = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -2341,6 +2343,7 @@ impl Workspace {
|
||||||
self.zoomed = None;
|
self.zoomed = None;
|
||||||
}
|
}
|
||||||
self.zoomed_position = None;
|
self.zoomed_position = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
self.update_active_view_for_followers(cx);
|
self.update_active_view_for_followers(cx);
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -2390,6 +2393,7 @@ impl Workspace {
|
||||||
if pane.read(cx).has_focus(cx) {
|
if pane.read(cx).has_focus(cx) {
|
||||||
self.zoomed = Some(pane.downgrade().into());
|
self.zoomed = Some(pane.downgrade().into());
|
||||||
self.zoomed_position = None;
|
self.zoomed_position = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -2398,6 +2402,7 @@ impl Workspace {
|
||||||
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
||||||
if self.zoomed_position.is_none() {
|
if self.zoomed_position.is_none() {
|
||||||
self.zoomed = None;
|
self.zoomed = None;
|
||||||
|
cx.emit(Event::ZoomChanged);
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -3918,9 +3923,9 @@ impl Render for Workspace {
|
||||||
.absolute()
|
.absolute()
|
||||||
.size_full()
|
.size_full()
|
||||||
})
|
})
|
||||||
.on_drag_move(
|
.when(self.zoomed.is_none(), |this| {
|
||||||
cx.listener(|workspace, e: &DragMoveEvent<DraggedDock>, cx| {
|
this.on_drag_move(cx.listener(
|
||||||
match e.drag(cx).0 {
|
|workspace, e: &DragMoveEvent<DraggedDock>, cx| match e.drag(cx).0 {
|
||||||
DockPosition::Left => {
|
DockPosition::Left => {
|
||||||
let size = workspace.bounds.left() + e.event.position.x;
|
let size = workspace.bounds.left() + e.event.position.x;
|
||||||
workspace.left_dock.update(cx, |left_dock, cx| {
|
workspace.left_dock.update(cx, |left_dock, cx| {
|
||||||
|
@ -3939,9 +3944,9 @@ impl Render for Workspace {
|
||||||
bottom_dock.resize_active_panel(Some(size), cx);
|
bottom_dock.resize_active_panel(Some(size), cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}),
|
))
|
||||||
)
|
})
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue