mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 02:46:43 +00:00
Fix usability issues with new panel system. (#2544)
This PR updates the dock key bindings according to the following model: There are three bits: Visible: Opened / closed. Focus: Panel focused / center focused. Zoom: Zoomed / Not zoomed. Each of these variables is 'sticky' in that they won't effect each other unless they need to. 'Zooming' a panel conceptually merges the visible and focus bits. cmd-shift-j/b/r have all been removed. cmd-j/b/r have been updated to mean 'toggle visibility of a certain dock', firing them should *always* reveal the panel to you (where you last left it), or hide it, without moving focus (unless the focused element is invisible). This means that, when the terminal panel is zoomed, cmd-j has the same effect as ctrl-` ctrl-` and cmd-shift-e now toggle a panel's focus, without updating the zoom state of a panel. Toggling the focus of a zoomed panel causes it to automatically hide itself, without losing the zoom bit. When focused or made visible, panels which cannot be zoomed automatically unzoom everything else so as to preserve user intent of 'show me this panel' and 'everything stays where it is if I don't take an action' Release Notes: - cmd-shift-j/b/r have been removed. (preview only) - cmd-j/b/r unconditionally show or hide their associated dock, respecting zoom settings. (preview only) - ctrl-` and cmd-shift-e now retain zoom state. (preview only) - Fixed a bug where terminal dock tab would always be in the active state (preview only) - Fixed a bug where terminals would not always open in the terminal panel - Changed the look of zoomed panels to fill more of the screen (preview only)
This commit is contained in:
parent
8a3a0245e0
commit
fc0bfd75ad
11 changed files with 396 additions and 198 deletions
|
@ -373,30 +373,9 @@
|
|||
"workspace::ActivatePane",
|
||||
8
|
||||
],
|
||||
"cmd-b": [
|
||||
"workspace::ToggleLeftDock",
|
||||
{ "focus": true }
|
||||
],
|
||||
"cmd-shift-b": [
|
||||
"workspace::ToggleLeftDock",
|
||||
{ "focus": false }
|
||||
],
|
||||
"cmd-r": [
|
||||
"workspace::ToggleRightDock",
|
||||
{ "focus": true }
|
||||
],
|
||||
"cmd-shift-r": [
|
||||
"workspace::ToggleRightDock",
|
||||
{ "focus": false }
|
||||
],
|
||||
"cmd-j": [
|
||||
"workspace::ToggleBottomDock",
|
||||
{ "focus": true }
|
||||
],
|
||||
"cmd-shift-j": [
|
||||
"workspace::ToggleBottomDock",
|
||||
{ "focus": false }
|
||||
],
|
||||
"cmd-b": "workspace::ToggleLeftDock",
|
||||
"cmd-r": "workspace::ToggleRightDock",
|
||||
"cmd-j": "workspace::ToggleBottomDock",
|
||||
"cmd-shift-f": "workspace::NewSearch",
|
||||
"cmd-k cmd-t": "theme_selector::Toggle",
|
||||
"cmd-k cmd-s": "zed::OpenKeymap",
|
||||
|
|
|
@ -22,7 +22,7 @@ const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
|
|||
actions!(terminal_panel, [ToggleFocus]);
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
cx.add_action(TerminalPanel::add_terminal);
|
||||
cx.add_action(TerminalPanel::new_terminal);
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
|
@ -79,7 +79,7 @@ impl TerminalPanel {
|
|||
cx.window_context().defer(move |cx| {
|
||||
if let Some(this) = this.upgrade(cx) {
|
||||
this.update(cx, |this, cx| {
|
||||
this.add_terminal(&Default::default(), cx);
|
||||
this.add_terminal(cx);
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -220,7 +220,19 @@ impl TerminalPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_terminal(&mut self, _: &workspace::NewTerminal, cx: &mut ViewContext<Self>) {
|
||||
fn new_terminal(
|
||||
workspace: &mut Workspace,
|
||||
_: &workspace::NewTerminal,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
let Some(this) = workspace.focus_panel::<Self>(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
this.update(cx, |this, cx| this.add_terminal(cx))
|
||||
}
|
||||
|
||||
fn add_terminal(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let workspace = self.workspace.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let pane = this.read_with(&cx, |this, _| this.pane.clone())?;
|
||||
|
@ -361,7 +373,7 @@ impl Panel for TerminalPanel {
|
|||
|
||||
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
|
||||
if active && self.pane.read(cx).items_len() == 0 {
|
||||
self.add_terminal(&Default::default(), cx)
|
||||
self.add_terminal(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ use workspace::{
|
|||
notifications::NotifyResultExt,
|
||||
pane, register_deserializable_item,
|
||||
searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle},
|
||||
Pane, ToolbarItemLocation, Workspace, WorkspaceId,
|
||||
NewCenterTerminal, Pane, ToolbarItemLocation, Workspace, WorkspaceId,
|
||||
};
|
||||
|
||||
pub use terminal::TerminalSettings;
|
||||
|
@ -66,10 +66,10 @@ pub fn init(cx: &mut AppContext) {
|
|||
terminal_panel::init(cx);
|
||||
terminal::init(cx);
|
||||
|
||||
cx.add_action(TerminalView::deploy);
|
||||
|
||||
register_deserializable_item::<TerminalView>(cx);
|
||||
|
||||
cx.add_action(TerminalView::deploy);
|
||||
|
||||
//Useful terminal views
|
||||
cx.add_action(TerminalView::send_text);
|
||||
cx.add_action(TerminalView::send_keystroke);
|
||||
|
@ -101,7 +101,7 @@ impl TerminalView {
|
|||
///Create a new Terminal in the current working directory or the user's home directory
|
||||
pub fn deploy(
|
||||
workspace: &mut Workspace,
|
||||
_: &workspace::NewTerminal,
|
||||
_: &NewCenterTerminal,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
let strategy = settings::get::<TerminalSettings>(cx);
|
||||
|
|
|
@ -89,7 +89,8 @@ pub struct Workspace {
|
|||
pub breadcrumbs: Interactive<ContainedText>,
|
||||
pub disconnected_overlay: ContainedText,
|
||||
pub modal: ContainerStyle,
|
||||
pub zoomed_foreground: ContainerStyle,
|
||||
pub zoomed_panel_foreground: ContainerStyle,
|
||||
pub zoomed_pane_foreground: ContainerStyle,
|
||||
pub zoomed_background: ContainerStyle,
|
||||
pub notification: ContainerStyle,
|
||||
pub notifications: Notifications,
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn init(cx: &mut AppContext) {
|
|||
|
||||
pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||
open_new(&app_state, cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Left, false, cx);
|
||||
workspace.toggle_dock(DockPosition::Left, cx);
|
||||
let welcome_page = cx.add_view(|cx| WelcomePage::new(workspace, cx));
|
||||
workspace.add_item_to_center(Box::new(welcome_page.clone()), cx);
|
||||
cx.focus(&welcome_page);
|
||||
|
|
|
@ -180,7 +180,7 @@ impl Dock {
|
|||
}
|
||||
|
||||
pub fn has_focus(&self, cx: &WindowContext) -> bool {
|
||||
self.active_panel()
|
||||
self.visible_panel()
|
||||
.map_or(false, |panel| panel.has_focus(cx))
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ impl Dock {
|
|||
self.active_panel_index
|
||||
}
|
||||
|
||||
pub fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
|
||||
pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
|
||||
if open != self.is_open {
|
||||
self.is_open = open;
|
||||
if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
|
||||
|
@ -212,11 +212,6 @@ impl Dock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toggle_open(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.set_open(!self.is_open, cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn set_panel_zoomed(
|
||||
&mut self,
|
||||
panel: &AnyViewHandle,
|
||||
|
@ -259,7 +254,7 @@ impl Dock {
|
|||
cx.focus(&panel);
|
||||
}
|
||||
} else if T::should_close_on_event(event)
|
||||
&& this.active_panel().map_or(false, |p| p.id() == panel.id())
|
||||
&& this.visible_panel().map_or(false, |p| p.id() == panel.id())
|
||||
{
|
||||
this.set_open(false, cx);
|
||||
}
|
||||
|
@ -315,12 +310,16 @@ impl Dock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn active_panel(&self) -> Option<&Rc<dyn PanelHandle>> {
|
||||
let entry = self.active_entry()?;
|
||||
pub fn visible_panel(&self) -> Option<&Rc<dyn PanelHandle>> {
|
||||
let entry = self.visible_entry()?;
|
||||
Some(&entry.panel)
|
||||
}
|
||||
|
||||
fn active_entry(&self) -> Option<&PanelEntry> {
|
||||
pub fn active_panel(&self) -> Option<&Rc<dyn PanelHandle>> {
|
||||
Some(&self.panel_entries.get(self.active_panel_index)?.panel)
|
||||
}
|
||||
|
||||
fn visible_entry(&self) -> Option<&PanelEntry> {
|
||||
if self.is_open {
|
||||
self.panel_entries.get(self.active_panel_index)
|
||||
} else {
|
||||
|
@ -329,7 +328,7 @@ impl Dock {
|
|||
}
|
||||
|
||||
pub fn zoomed_panel(&self, cx: &WindowContext) -> Option<Rc<dyn PanelHandle>> {
|
||||
let entry = self.active_entry()?;
|
||||
let entry = self.visible_entry()?;
|
||||
if entry.panel.is_zoomed(cx) {
|
||||
Some(entry.panel.clone())
|
||||
} else {
|
||||
|
@ -362,7 +361,7 @@ impl Dock {
|
|||
}
|
||||
|
||||
pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> {
|
||||
if let Some(active_entry) = self.active_entry() {
|
||||
if let Some(active_entry) = self.visible_entry() {
|
||||
Empty::new()
|
||||
.into_any()
|
||||
.contained()
|
||||
|
@ -399,7 +398,7 @@ impl View for Dock {
|
|||
}
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||
if let Some(active_entry) = self.active_entry() {
|
||||
if let Some(active_entry) = self.visible_entry() {
|
||||
let style = self.style(cx);
|
||||
ChildView::new(active_entry.panel.as_any(), cx)
|
||||
.contained()
|
||||
|
@ -417,7 +416,7 @@ impl View for Dock {
|
|||
|
||||
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
if cx.is_self_focused() {
|
||||
if let Some(active_entry) = self.active_entry() {
|
||||
if let Some(active_entry) = self.visible_entry() {
|
||||
cx.focus(active_entry.panel.as_any());
|
||||
} else {
|
||||
cx.focus_parent();
|
||||
|
@ -504,13 +503,22 @@ impl View for PanelButtons {
|
|||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, {
|
||||
let tooltip_action =
|
||||
tooltip_action.as_ref().map(|action| action.boxed_clone());
|
||||
move |_, this, cx| {
|
||||
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||
cx.window_context().defer(move |cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel(dock_position, panel_ix, cx)
|
||||
});
|
||||
});
|
||||
if let Some(tooltip_action) = &tooltip_action {
|
||||
let window_id = cx.window_id();
|
||||
let view_id = this.workspace.id();
|
||||
let tooltip_action = tooltip_action.boxed_clone();
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
cx.dispatch_action(
|
||||
window_id,
|
||||
view_id,
|
||||
&*tooltip_action,
|
||||
)
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -2,8 +2,8 @@ mod dragged_item_receiver;
|
|||
|
||||
use super::{ItemHandle, SplitDirection};
|
||||
use crate::{
|
||||
item::WeakItemHandle, toolbar::Toolbar, AutosaveSetting, Item, NewFile, NewSearch, NewTerminal,
|
||||
ToggleZoom, Workspace, WorkspaceSettings,
|
||||
item::WeakItemHandle, toolbar::Toolbar, AutosaveSetting, Item, NewCenterTerminal, NewFile,
|
||||
NewSearch, ToggleZoom, Workspace, WorkspaceSettings,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
|
@ -150,7 +150,6 @@ pub enum Event {
|
|||
pub struct Pane {
|
||||
items: Vec<Box<dyn ItemHandle>>,
|
||||
activation_history: Vec<usize>,
|
||||
is_active: bool,
|
||||
zoomed: bool,
|
||||
active_item_index: usize,
|
||||
last_focused_view_by_item: HashMap<usize, AnyWeakViewHandle>,
|
||||
|
@ -255,7 +254,6 @@ impl Pane {
|
|||
Self {
|
||||
items: Vec::new(),
|
||||
activation_history: Vec::new(),
|
||||
is_active: true,
|
||||
zoomed: false,
|
||||
active_item_index: 0,
|
||||
last_focused_view_by_item: Default::default(),
|
||||
|
@ -323,15 +321,6 @@ impl Pane {
|
|||
&self.workspace
|
||||
}
|
||||
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.is_active
|
||||
}
|
||||
|
||||
pub fn set_active(&mut self, is_active: bool, cx: &mut ViewContext<Self>) {
|
||||
self.is_active = is_active;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn has_focus(&self) -> bool {
|
||||
self.has_focus
|
||||
}
|
||||
|
@ -1219,7 +1208,7 @@ impl Pane {
|
|||
AnchorCorner::TopRight,
|
||||
vec![
|
||||
ContextMenuItem::action("New File", NewFile),
|
||||
ContextMenuItem::action("New Terminal", NewTerminal),
|
||||
ContextMenuItem::action("New Terminal", NewCenterTerminal),
|
||||
ContextMenuItem::action("New Search", NewSearch),
|
||||
],
|
||||
cx,
|
||||
|
@ -1343,7 +1332,7 @@ impl Pane {
|
|||
None
|
||||
};
|
||||
|
||||
let pane_active = self.is_active;
|
||||
let pane_active = self.has_focus;
|
||||
|
||||
enum Tabs {}
|
||||
let mut row = Flex::row().scrollable::<Tabs>(1, autoscroll, cx);
|
||||
|
@ -1722,7 +1711,7 @@ impl View for Pane {
|
|||
let mut tab_row = Flex::row()
|
||||
.with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
|
||||
|
||||
if self.is_active {
|
||||
if self.has_focus {
|
||||
let render_tab_bar_buttons = self.render_tab_bar_buttons.clone();
|
||||
tab_row.add_child(
|
||||
(render_tab_bar_buttons)(self, cx)
|
||||
|
@ -1813,6 +1802,7 @@ impl View for Pane {
|
|||
if !self.has_focus {
|
||||
self.has_focus = true;
|
||||
cx.emit(Event::Focus);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
self.toolbar.update(cx, |toolbar, cx| {
|
||||
|
@ -1847,6 +1837,7 @@ impl View for Pane {
|
|||
self.toolbar.update(cx, |toolbar, cx| {
|
||||
toolbar.pane_focus_update(false, cx);
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
|
|
|
@ -53,6 +53,7 @@ use std::{
|
|||
cmp, env,
|
||||
future::Future,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
str,
|
||||
sync::{atomic::AtomicUsize, Arc},
|
||||
time::Duration,
|
||||
|
@ -103,24 +104,6 @@ pub trait Modal: View {
|
|||
#[derive(Clone, PartialEq)]
|
||||
pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
||||
|
||||
#[derive(Copy, Clone, Default, Deserialize, PartialEq)]
|
||||
pub struct ToggleLeftDock {
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Deserialize, PartialEq)]
|
||||
pub struct ToggleBottomDock {
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Deserialize, PartialEq)]
|
||||
pub struct ToggleRightDock {
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
}
|
||||
|
||||
actions!(
|
||||
workspace,
|
||||
[
|
||||
|
@ -137,22 +120,21 @@ actions!(
|
|||
ActivateNextPane,
|
||||
FollowNextCollaborator,
|
||||
NewTerminal,
|
||||
NewCenterTerminal,
|
||||
ToggleTerminalFocus,
|
||||
NewSearch,
|
||||
Feedback,
|
||||
Restart,
|
||||
Welcome,
|
||||
ToggleZoom,
|
||||
ToggleLeftDock,
|
||||
ToggleRightDock,
|
||||
ToggleBottomDock,
|
||||
]
|
||||
);
|
||||
|
||||
actions!(zed, [OpenSettings]);
|
||||
|
||||
impl_actions!(
|
||||
workspace,
|
||||
[ToggleLeftDock, ToggleBottomDock, ToggleRightDock]
|
||||
);
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct OpenPaths {
|
||||
pub paths: Vec<PathBuf>,
|
||||
|
@ -268,14 +250,14 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
|||
cx.add_action(|workspace: &mut Workspace, _: &ActivateNextPane, cx| {
|
||||
workspace.activate_next_pane(cx)
|
||||
});
|
||||
cx.add_action(|workspace: &mut Workspace, action: &ToggleLeftDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Left, action.focus, cx);
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ToggleLeftDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Left, cx);
|
||||
});
|
||||
cx.add_action(|workspace: &mut Workspace, action: &ToggleRightDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, action.focus, cx);
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx);
|
||||
});
|
||||
cx.add_action(|workspace: &mut Workspace, action: &ToggleBottomDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Bottom, action.focus, cx);
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ToggleBottomDock, cx| {
|
||||
workspace.toggle_dock(DockPosition::Bottom, cx);
|
||||
});
|
||||
cx.add_action(Workspace::activate_pane_at_index);
|
||||
|
||||
|
@ -485,6 +467,7 @@ pub struct Workspace {
|
|||
remote_entity_subscription: Option<client::Subscription>,
|
||||
modal: Option<AnyViewHandle>,
|
||||
zoomed: Option<AnyWeakViewHandle>,
|
||||
zoomed_position: Option<DockPosition>,
|
||||
center: PaneGroup,
|
||||
left_dock: ViewHandle<Dock>,
|
||||
bottom_dock: ViewHandle<Dock>,
|
||||
|
@ -689,6 +672,7 @@ impl Workspace {
|
|||
weak_self: weak_handle.clone(),
|
||||
modal: None,
|
||||
zoomed: None,
|
||||
zoomed_position: None,
|
||||
center: PaneGroup::new(center_pane.clone()),
|
||||
panes: vec![center_pane.clone()],
|
||||
panes_by_item: Default::default(),
|
||||
|
@ -887,10 +871,15 @@ impl Workspace {
|
|||
|
||||
was_visible = dock.is_open()
|
||||
&& dock
|
||||
.active_panel()
|
||||
.visible_panel()
|
||||
.map_or(false, |active_panel| active_panel.id() == panel.id());
|
||||
dock.remove_panel(&panel, cx);
|
||||
});
|
||||
|
||||
if panel.is_zoomed(cx) {
|
||||
this.zoomed_position = Some(new_position);
|
||||
}
|
||||
|
||||
dock = match panel.read(cx).position(cx) {
|
||||
DockPosition::Left => &this.left_dock,
|
||||
DockPosition::Bottom => &this.bottom_dock,
|
||||
|
@ -909,14 +898,17 @@ impl Workspace {
|
|||
dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, true, cx));
|
||||
if panel.has_focus(cx) {
|
||||
this.zoomed = Some(panel.downgrade().into_any());
|
||||
this.zoomed_position = Some(panel.read(cx).position(cx));
|
||||
}
|
||||
} else if T::should_zoom_out_on_event(event) {
|
||||
this.zoom_out(cx);
|
||||
} else if T::is_focus_event(event) {
|
||||
if panel.is_zoomed(cx) {
|
||||
this.zoomed = Some(panel.downgrade().into_any());
|
||||
this.zoomed_position = Some(panel.read(cx).position(cx));
|
||||
} else {
|
||||
this.zoomed = None;
|
||||
this.zoomed_position = None;
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -1486,89 +1478,110 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toggle_dock(
|
||||
&mut self,
|
||||
dock_side: DockPosition,
|
||||
focus: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
pub fn toggle_dock(&mut self, dock_side: DockPosition, cx: &mut ViewContext<Self>) {
|
||||
let dock = match dock_side {
|
||||
DockPosition::Left => &self.left_dock,
|
||||
DockPosition::Bottom => &self.bottom_dock,
|
||||
DockPosition::Right => &self.right_dock,
|
||||
};
|
||||
let mut focus_center = false;
|
||||
let mut zoom_out = false;
|
||||
dock.update(cx, |dock, cx| {
|
||||
let open = !dock.is_open();
|
||||
dock.set_open(open, cx);
|
||||
let other_is_zoomed = self.zoomed.is_some() && self.zoomed_position != Some(dock_side);
|
||||
let was_visible = dock.is_open() && !other_is_zoomed;
|
||||
dock.set_open(!was_visible, cx);
|
||||
|
||||
if let Some(active_panel) = dock.active_panel() {
|
||||
if was_visible {
|
||||
if active_panel.has_focus(cx) {
|
||||
focus_center = true;
|
||||
}
|
||||
} else {
|
||||
if active_panel.is_zoomed(cx) {
|
||||
cx.focus(active_panel.as_any());
|
||||
}
|
||||
zoom_out = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if dock.read(cx).is_open() && focus {
|
||||
cx.focus(dock);
|
||||
} else {
|
||||
if zoom_out {
|
||||
self.zoom_out_everything_except(dock_side, cx);
|
||||
}
|
||||
if focus_center {
|
||||
cx.focus_self();
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
self.serialize_workspace(cx);
|
||||
}
|
||||
|
||||
pub fn toggle_panel(
|
||||
&mut self,
|
||||
position: DockPosition,
|
||||
panel_index: usize,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let dock = match position {
|
||||
DockPosition::Left => &mut self.left_dock,
|
||||
DockPosition::Bottom => &mut self.bottom_dock,
|
||||
DockPosition::Right => &mut self.right_dock,
|
||||
};
|
||||
let active_item = dock.update(cx, move |dock, cx| {
|
||||
if dock.is_open() && dock.active_panel_index() == panel_index {
|
||||
dock.set_open(false, cx);
|
||||
None
|
||||
} else {
|
||||
dock.set_open(true, cx);
|
||||
dock.activate_panel(panel_index, cx);
|
||||
dock.active_panel().cloned()
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(active_item) = active_item {
|
||||
if active_item.has_focus(cx) {
|
||||
cx.focus_self();
|
||||
} else {
|
||||
cx.focus(active_item.as_any());
|
||||
}
|
||||
} else {
|
||||
cx.focus_self();
|
||||
}
|
||||
|
||||
self.serialize_workspace(cx);
|
||||
|
||||
cx.notify();
|
||||
pub fn focus_panel<T: Panel>(&mut self, cx: &mut ViewContext<Self>) -> Option<ViewHandle<T>> {
|
||||
self.show_or_hide_panel::<T>(cx, |_, _| true)?
|
||||
.as_any()
|
||||
.clone()
|
||||
.downcast()
|
||||
}
|
||||
|
||||
pub fn toggle_panel_focus<T: Panel>(&mut self, cx: &mut ViewContext<Self>) {
|
||||
for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
|
||||
self.show_or_hide_panel::<T>(cx, |panel, cx| !panel.has_focus(cx));
|
||||
}
|
||||
|
||||
fn show_or_hide_panel<T: Panel>(
|
||||
&mut self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
show: impl Fn(&dyn PanelHandle, &mut ViewContext<Dock>) -> bool,
|
||||
) -> Option<Rc<dyn PanelHandle>> {
|
||||
for (dock, position) in [
|
||||
self.left_dock.clone(),
|
||||
self.bottom_dock.clone(),
|
||||
self.right_dock.clone(),
|
||||
]
|
||||
.into_iter()
|
||||
.zip(
|
||||
[
|
||||
DockPosition::Left,
|
||||
DockPosition::Bottom,
|
||||
DockPosition::Right,
|
||||
]
|
||||
.into_iter(),
|
||||
) {
|
||||
if let Some(panel_index) = dock.read(cx).panel_index_for_type::<T>() {
|
||||
let active_item = dock.update(cx, |dock, cx| {
|
||||
dock.set_open(true, cx);
|
||||
let mut focus_center = false;
|
||||
let mut zoom_out = false;
|
||||
let panel = dock.update(cx, |dock, cx| {
|
||||
dock.activate_panel(panel_index, cx);
|
||||
dock.active_panel().cloned()
|
||||
});
|
||||
if let Some(active_item) = active_item {
|
||||
if active_item.has_focus(cx) {
|
||||
cx.focus_self();
|
||||
} else {
|
||||
cx.focus(active_item.as_any());
|
||||
|
||||
let panel = dock.active_panel().cloned();
|
||||
if let Some(panel) = panel.as_ref() {
|
||||
let should_show = show(&**panel, cx);
|
||||
if should_show {
|
||||
dock.set_open(true, cx);
|
||||
cx.focus(panel.as_any());
|
||||
zoom_out = true;
|
||||
} else {
|
||||
if panel.is_zoomed(cx) {
|
||||
dock.set_open(false, cx);
|
||||
}
|
||||
focus_center = true;
|
||||
}
|
||||
}
|
||||
panel
|
||||
});
|
||||
|
||||
if zoom_out {
|
||||
self.zoom_out_everything_except(position, cx);
|
||||
}
|
||||
if focus_center {
|
||||
cx.focus_self();
|
||||
}
|
||||
|
||||
self.serialize_workspace(cx);
|
||||
cx.notify();
|
||||
break;
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||
|
@ -1580,6 +1593,36 @@ impl Workspace {
|
|||
self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||
self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||
self.zoomed = None;
|
||||
self.zoomed_position = None;
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn zoom_out_everything_except(
|
||||
&mut self,
|
||||
except_position: DockPosition,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
for pane in &self.panes {
|
||||
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
||||
}
|
||||
|
||||
if except_position != DockPosition::Left {
|
||||
self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||
}
|
||||
|
||||
if except_position != DockPosition::Bottom {
|
||||
self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||
}
|
||||
|
||||
if except_position != DockPosition::Right {
|
||||
self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||
}
|
||||
|
||||
if self.zoomed_position != Some(except_position) {
|
||||
self.zoomed = None;
|
||||
self.zoomed_position = None;
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -1780,11 +1823,7 @@ impl Workspace {
|
|||
|
||||
fn handle_pane_focused(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
|
||||
if self.active_pane != pane {
|
||||
self.active_pane
|
||||
.update(cx, |pane, cx| pane.set_active(false, cx));
|
||||
self.active_pane = pane.clone();
|
||||
self.active_pane
|
||||
.update(cx, |pane, cx| pane.set_active(true, cx));
|
||||
self.status_bar.update(cx, |status_bar, cx| {
|
||||
status_bar.set_active_pane(&self.active_pane, cx);
|
||||
});
|
||||
|
@ -1797,6 +1836,7 @@ impl Workspace {
|
|||
} else {
|
||||
self.zoomed = None;
|
||||
}
|
||||
self.zoomed_position = None;
|
||||
|
||||
self.update_followers(
|
||||
proto::update_followers::Variant::UpdateActiveView(proto::UpdateActiveView {
|
||||
|
@ -1855,6 +1895,7 @@ impl Workspace {
|
|||
pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
|
||||
if pane.read(cx).has_focus() {
|
||||
self.zoomed = Some(pane.downgrade().into_any());
|
||||
self.zoomed_position = None;
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -2663,7 +2704,7 @@ impl Workspace {
|
|||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
pane.is_active(),
|
||||
pane.has_focus(),
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -2691,7 +2732,7 @@ impl Workspace {
|
|||
fn build_serialized_docks(this: &Workspace, cx: &AppContext) -> DockStructure {
|
||||
let left_dock = this.left_dock.read(cx);
|
||||
let left_visible = left_dock.is_open();
|
||||
let left_active_panel = left_dock.active_panel().and_then(|panel| {
|
||||
let left_active_panel = left_dock.visible_panel().and_then(|panel| {
|
||||
Some(
|
||||
cx.view_ui_name(panel.as_any().window_id(), panel.id())?
|
||||
.to_string(),
|
||||
|
@ -2700,7 +2741,7 @@ impl Workspace {
|
|||
|
||||
let right_dock = this.right_dock.read(cx);
|
||||
let right_visible = right_dock.is_open();
|
||||
let right_active_panel = right_dock.active_panel().and_then(|panel| {
|
||||
let right_active_panel = right_dock.visible_panel().and_then(|panel| {
|
||||
Some(
|
||||
cx.view_ui_name(panel.as_any().window_id(), panel.id())?
|
||||
.to_string(),
|
||||
|
@ -2709,7 +2750,7 @@ impl Workspace {
|
|||
|
||||
let bottom_dock = this.bottom_dock.read(cx);
|
||||
let bottom_visible = bottom_dock.is_open();
|
||||
let bottom_active_panel = bottom_dock.active_panel().and_then(|panel| {
|
||||
let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| {
|
||||
Some(
|
||||
cx.view_ui_name(panel.as_any().window_id(), panel.id())?
|
||||
.to_string(),
|
||||
|
@ -2891,7 +2932,7 @@ impl Workspace {
|
|||
DockPosition::Right => &self.right_dock,
|
||||
DockPosition::Bottom => &self.bottom_dock,
|
||||
};
|
||||
let active_panel = dock.read(cx).active_panel()?;
|
||||
let active_panel = dock.read(cx).visible_panel()?;
|
||||
let element = if Some(active_panel.id()) == self.zoomed.as_ref().map(|zoomed| zoomed.id()) {
|
||||
dock.read(cx).render_placeholder(cx)
|
||||
} else {
|
||||
|
@ -3092,10 +3133,40 @@ impl View for Workspace {
|
|||
.with_children(self.zoomed.as_ref().and_then(|zoomed| {
|
||||
enum ZoomBackground {}
|
||||
let zoomed = zoomed.upgrade(cx)?;
|
||||
|
||||
let mut foreground_style;
|
||||
match self.zoomed_position {
|
||||
Some(DockPosition::Left) => {
|
||||
foreground_style =
|
||||
theme.workspace.zoomed_panel_foreground;
|
||||
foreground_style.margin.left = 0.;
|
||||
foreground_style.margin.top = 0.;
|
||||
foreground_style.margin.bottom = 0.;
|
||||
}
|
||||
Some(DockPosition::Right) => {
|
||||
foreground_style =
|
||||
theme.workspace.zoomed_panel_foreground;
|
||||
foreground_style.margin.right = 0.;
|
||||
foreground_style.margin.top = 0.;
|
||||
foreground_style.margin.bottom = 0.;
|
||||
}
|
||||
Some(DockPosition::Bottom) => {
|
||||
foreground_style =
|
||||
theme.workspace.zoomed_panel_foreground;
|
||||
foreground_style.margin.left = 0.;
|
||||
foreground_style.margin.right = 0.;
|
||||
foreground_style.margin.bottom = 0.;
|
||||
}
|
||||
None => {
|
||||
foreground_style =
|
||||
theme.workspace.zoomed_pane_foreground;
|
||||
}
|
||||
}
|
||||
|
||||
Some(
|
||||
ChildView::new(&zoomed, cx)
|
||||
.contained()
|
||||
.with_style(theme.workspace.zoomed_foreground)
|
||||
.with_style(foreground_style)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_style(theme.workspace.zoomed_background)
|
||||
|
@ -3445,10 +3516,6 @@ fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
|
|||
Some(vec2f(width as f32, height as f32))
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -4029,6 +4096,128 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
|
||||
|
||||
let panel = workspace.update(cx, |workspace, cx| {
|
||||
let panel = cx.add_view(|_| TestPanel::new(DockPosition::Right));
|
||||
workspace.add_panel(panel.clone(), cx);
|
||||
|
||||
workspace
|
||||
.right_dock()
|
||||
.update(cx, |right_dock, cx| right_dock.set_open(true, cx));
|
||||
|
||||
panel
|
||||
});
|
||||
|
||||
// Transfer focus from center to panel
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Transfer focus from panel to center
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(!panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Close the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(!panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Open the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(!panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Focus and zoom panel
|
||||
panel.update(cx, |panel, cx| {
|
||||
cx.focus_self();
|
||||
panel.set_zoomed(true, cx)
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Transfer focus to the center closes the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(!panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Transfering focus back to the panel keeps it zoomed
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Close the dock while it is zoomed
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(workspace.zoomed.is_none());
|
||||
assert!(!panel.has_focus(cx));
|
||||
});
|
||||
|
||||
// Opening the dock, when it's zoomed, retains focus
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(workspace.zoomed.is_some());
|
||||
assert!(panel.has_focus(cx));
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_panels(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
@ -4052,7 +4241,7 @@ mod tests {
|
|||
|
||||
let left_dock = workspace.left_dock();
|
||||
assert_eq!(
|
||||
left_dock.read(cx).active_panel().unwrap().id(),
|
||||
left_dock.read(cx).visible_panel().unwrap().id(),
|
||||
panel_1.id()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -4062,7 +4251,12 @@ mod tests {
|
|||
|
||||
left_dock.update(cx, |left_dock, cx| left_dock.resize_active_panel(1337., cx));
|
||||
assert_eq!(
|
||||
workspace.right_dock().read(cx).active_panel().unwrap().id(),
|
||||
workspace
|
||||
.right_dock()
|
||||
.read(cx)
|
||||
.visible_panel()
|
||||
.unwrap()
|
||||
.id(),
|
||||
panel_2.id()
|
||||
);
|
||||
|
||||
|
@ -4078,10 +4272,10 @@ mod tests {
|
|||
// Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right.
|
||||
// Since it was the only panel on the left, the left dock should now be closed.
|
||||
assert!(!workspace.left_dock().read(cx).is_open());
|
||||
assert!(workspace.left_dock().read(cx).active_panel().is_none());
|
||||
assert!(workspace.left_dock().read(cx).visible_panel().is_none());
|
||||
let right_dock = workspace.right_dock();
|
||||
assert_eq!(
|
||||
right_dock.read(cx).active_panel().unwrap().id(),
|
||||
right_dock.read(cx).visible_panel().unwrap().id(),
|
||||
panel_1.id()
|
||||
);
|
||||
assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||
|
@ -4096,7 +4290,12 @@ mod tests {
|
|||
// And the right dock is unaffected in it's displaying of panel_1
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert_eq!(
|
||||
workspace.right_dock().read(cx).active_panel().unwrap().id(),
|
||||
workspace
|
||||
.right_dock()
|
||||
.read(cx)
|
||||
.visible_panel()
|
||||
.unwrap()
|
||||
.id(),
|
||||
panel_1.id()
|
||||
);
|
||||
});
|
||||
|
@ -4111,7 +4310,7 @@ mod tests {
|
|||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).active_panel().unwrap().id(),
|
||||
left_dock.read(cx).visible_panel().unwrap().id(),
|
||||
panel_1.id()
|
||||
);
|
||||
assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||
|
@ -4145,7 +4344,7 @@ mod tests {
|
|||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).active_panel().unwrap().id(),
|
||||
left_dock.read(cx).visible_panel().unwrap().id(),
|
||||
panel_1.id()
|
||||
);
|
||||
assert!(panel_1.is_focused(cx));
|
||||
|
@ -4159,7 +4358,7 @@ mod tests {
|
|||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).active_panel().unwrap().id(),
|
||||
left_dock.read(cx).visible_panel().unwrap().id(),
|
||||
panel_1.id()
|
||||
);
|
||||
});
|
||||
|
@ -4168,6 +4367,14 @@ mod tests {
|
|||
panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomIn));
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Left));
|
||||
});
|
||||
|
||||
// Move panel to another dock while it is zoomed
|
||||
panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx));
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// If focus is transferred to another view that's not a panel or another pane, we still show
|
||||
|
@ -4176,12 +4383,14 @@ mod tests {
|
|||
focus_receiver.update(cx, |_, cx| cx.focus_self());
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// If focus is transferred elsewhere in the workspace, the panel is no longer zoomed.
|
||||
workspace.update(cx, |_, cx| cx.focus_self());
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// If focus is transferred again to another view that's not a panel or a pane, we won't
|
||||
|
@ -4189,18 +4398,21 @@ mod tests {
|
|||
focus_receiver.update(cx, |_, cx| cx.focus_self());
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// When focus is transferred back to the panel, it is zoomed again.
|
||||
panel_1.update(cx, |_, cx| cx.focus_self());
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// Emitting a ZoomOut event unzooms the panel.
|
||||
panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomOut));
|
||||
workspace.read_with(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// Emit closed event on panel 1, which is active
|
||||
|
@ -4208,8 +4420,8 @@ mod tests {
|
|||
|
||||
// Now the left dock is closed, because panel_1 was the active panel
|
||||
workspace.read_with(cx, |workspace, cx| {
|
||||
let left_dock = workspace.left_dock();
|
||||
assert!(!left_dock.read(cx).is_open());
|
||||
let right_dock = workspace.right_dock();
|
||||
assert!(!right_dock.read(cx).is_open());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -89,18 +89,9 @@ pub fn menus() -> Vec<Menu<'static>> {
|
|||
MenuItem::action("Zoom Out", super::DecreaseBufferFontSize),
|
||||
MenuItem::action("Reset Zoom", super::ResetBufferFontSize),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action(
|
||||
"Toggle Left Dock",
|
||||
workspace::ToggleLeftDock { focus: false },
|
||||
),
|
||||
MenuItem::action(
|
||||
"Toggle Right Dock",
|
||||
workspace::ToggleRightDock { focus: false },
|
||||
),
|
||||
MenuItem::action(
|
||||
"Toggle Bottom Dock",
|
||||
workspace::ToggleBottomDock { focus: false },
|
||||
),
|
||||
MenuItem::action("Toggle Left Dock", workspace::ToggleLeftDock),
|
||||
MenuItem::action("Toggle Right Dock", workspace::ToggleRightDock),
|
||||
MenuItem::action("Toggle Bottom Dock", workspace::ToggleBottomDock),
|
||||
MenuItem::submenu(Menu {
|
||||
name: "Editor Layout",
|
||||
items: vec![
|
||||
|
|
|
@ -354,7 +354,7 @@ pub fn initialize_workspace(
|
|||
.map_or(false, |entry| entry.is_dir())
|
||||
})
|
||||
{
|
||||
workspace.toggle_dock(project_panel_position, false, cx);
|
||||
workspace.toggle_dock(project_panel_position, cx);
|
||||
}
|
||||
|
||||
workspace.add_panel(terminal_panel, cx)
|
||||
|
|
|
@ -119,14 +119,18 @@ export default function workspace(colorScheme: ColorScheme) {
|
|||
cursor: "Arrow",
|
||||
},
|
||||
zoomedBackground: {
|
||||
padding: 10,
|
||||
cursor: "Arrow",
|
||||
background: withOpacity(background(colorScheme.lowest), 0.5)
|
||||
background: withOpacity(background(colorScheme.lowest), 0.85)
|
||||
},
|
||||
zoomedForeground: {
|
||||
zoomedPaneForeground: {
|
||||
margin: 10,
|
||||
shadow: colorScheme.modalShadow,
|
||||
border: border(colorScheme.highest, { overlay: true }),
|
||||
},
|
||||
zoomedPanelForeground: {
|
||||
margin: 18,
|
||||
border: border(colorScheme.highest, { overlay: true }),
|
||||
},
|
||||
dock: {
|
||||
left: {
|
||||
border: border(layer, { right: true }),
|
||||
|
|
Loading…
Reference in a new issue