From 0fefe537733604085a19a98ccf6e33a248e59721 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 8 Dec 2023 14:44:41 +0200 Subject: [PATCH 1/2] zzz --- crates/terminal_view2/src/terminal_panel.rs | 4 +- crates/workspace2/src/dock.rs | 5 +- crates/workspace2/src/pane.rs | 6 +- crates/workspace2/src/workspace2.rs | 279 +++++++++++--------- 4 files changed, 158 insertions(+), 136 deletions(-) diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index b8db12381b..787b411c5d 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -214,13 +214,13 @@ impl TerminalPanel { event: &pane::Event, cx: &mut ViewContext, ) { - match event { + match dbg!(event) { pane::Event::ActivateItem { .. } => self.serialize(cx), pane::Event::RemoveItem { .. } => self.serialize(cx), pane::Event::Remove => cx.emit(PanelEvent::Close), pane::Event::ZoomIn => cx.emit(PanelEvent::ZoomIn), pane::Event::ZoomOut => cx.emit(PanelEvent::ZoomOut), - pane::Event::Focus => cx.emit(PanelEvent::Focus), + pane::Event::Focus => cx.emit(dbg!(PanelEvent::Focus)), pane::Event::AddItem { item } => { if let Some(workspace) = self.workspace.upgrade() { diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 7bae7bc419..067f657f80 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -1,8 +1,8 @@ use crate::{status_bar::StatusItemView, Axis, Workspace}; use gpui::{ div, px, Action, AnchorCorner, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, - FocusHandle, FocusableView, IntoElement, ParentElement, Render, SharedString, Styled, - Subscription, View, ViewContext, VisualContext, WeakView, WindowContext, + FocusHandle, Focusable, FocusableView, IntoElement, ParentElement, Render, SharedString, + Styled, Subscription, View, ViewContext, VisualContext, WeakView, WindowContext, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -10,6 +10,7 @@ use std::sync::Arc; use ui::{h_stack, ContextMenu, IconButton, Tooltip}; use ui::{prelude::*, right_click_menu}; +#[derive(Debug)] pub enum PanelEvent { ChangePosition, ZoomIn, diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 3b1c00994f..0645227cf2 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1493,7 +1493,7 @@ impl Pane { .child(label); right_click_menu(ix).trigger(tab).menu(|cx| { - ContextMenu::build(cx, |menu, cx| { + ContextMenu::build(cx, |menu, _| { menu.action("Close", CloseActiveItem { save_intent: None }.boxed_clone()) .action("Close Others", CloseInactiveItems.boxed_clone()) .separator() @@ -2057,13 +2057,13 @@ impl Render for Pane { .overflow_hidden() .on_focus_in({ let this = this.clone(); - move |event, cx| { + move |_, cx| { this.update(cx, |this, cx| this.focus_in(cx)).ok(); } }) .on_focus_out({ let this = this.clone(); - move |event, cx| { + move |_, cx| { this.update(cx, |this, cx| this.focus_out(cx)).ok(); } }) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 251f0685b0..fcf0f78b86 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -1558,6 +1558,7 @@ impl Workspace { self.dismiss_zoomed_items_to_reveal(Some(dock_side), cx); } + dbg!("~~~~~~~~~~~~ ???????", focus_center); if focus_center { self.active_pane.update(cx, |pane, cx| pane.focus(cx)) } @@ -1738,8 +1739,10 @@ impl Workspace { } pub fn add_item(&mut self, item: Box, cx: &mut ViewContext) { - self.active_pane - .update(cx, |pane, cx| pane.add_item(item, true, true, None, cx)); + self.active_pane.update(cx, |pane, cx| { + dbg!(pane.items_len()); + pane.add_item(item, true, true, None, cx) + }); } pub fn split_item( @@ -2039,7 +2042,14 @@ impl Workspace { } fn handle_pane_focused(&mut self, pane: View, cx: &mut ViewContext) { + // TODO kb remove + eprintln!( + "########## handle_pane_focused acrive: {}, new: {}", + self.active_pane.read(cx).items_len(), + pane.read(cx).items_len() + ); if self.active_pane != pane { + dbg!("########## got new pane to activate",); self.active_pane = pane.clone(); self.status_bar.update(cx, |status_bar, cx| { status_bar.set_active_pane(&self.active_pane, cx); @@ -2233,6 +2243,7 @@ impl Workspace { } fn remove_pane(&mut self, pane: View, cx: &mut ViewContext) { + dbg!("?????@@@@@@@@@@ remove pane"); if self.center.remove(&pane).unwrap() { self.force_remove_pane(&pane, cx); self.unfollow(&pane, cx); @@ -2241,8 +2252,14 @@ impl Workspace { self.panes_by_item.remove(&removed_item.item_id()); } + dbg!("######### removed the pane", self.panes.len()); + // cx.focus_self(); + cx.notify(); } else { + dbg!( + "??????????? during pane removal, we decided to spare the pane and not removed it (main pane)" + ); self.active_item_path_changed(cx); } } @@ -4400,9 +4417,12 @@ fn parse_pixel_size_env_var(value: &str) -> Option> { #[cfg(test)] mod tests { use super::*; - use crate::item::{ - test::{TestItem, TestProjectItem}, - ItemEvent, + use crate::{ + dock::test::TestPanel, + item::{ + test::{TestItem, TestProjectItem}, + ItemEvent, + }, }; use fs::FakeFs; use gpui::TestAppContext; @@ -4975,153 +4995,154 @@ mod tests { }); } - // #[gpui::test] - // async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { - // init_test(cx); - // let fs = FakeFs::new(cx.executor()); + #[gpui::test] + async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.background_executor.clone()); - // let project = Project::test(fs, [], cx).await; - // let window = cx.add_window(|cx| Workspace::test_new(project, cx)); - // let workspace = window.root(cx); + let project = Project::test(fs, [], cx).await; + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx).unwrap(); - // let panel = workspace.update(cx, |workspace, cx| { - // let panel = cx.build_view(|_| TestPanel::new(DockPosition::Right)); - // workspace.add_panel(panel.clone(), cx); + cx.update_window(window.into(), |_, cx| { + let panel = workspace.update(cx, |workspace, cx| { + let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + workspace.add_panel(panel.clone(), cx); - // workspace - // .right_dock() - // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + workspace + .right_dock() + .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + panel + }); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + pane.update(cx, |pane, cx| { + let item = cx.build_view(|cx| TestItem::new(cx)); + pane.add_item(Box::new(item), true, true, None, cx); + }); - // panel - // }); + // Transfer focus from center to panel + workspace.update(cx, |workspace, cx| { + workspace.toggle_panel_focus::(cx); + }); - // let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); - // pane.update(cx, |pane, cx| { - // let item = cx.build_view(|_| TestItem::new(cx)); - // pane.add_item(Box::new(item), true, true, None, cx); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + assert!(panel.focus_handle(cx).is_focused(cx)); + }); - // // Transfer focus from center to panel - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); + // Transfer focus from panel to center + workspace.update(cx, |workspace, cx| { + workspace.toggle_panel_focus::(cx); + }); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + assert!(!panel.focus_handle(cx).is_focused(cx)); + }); - // // Transfer focus from panel to center - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); + // Close the dock + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx); + }); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + assert!(!panel.focus_handle(cx).is_focused(cx)); + }); - // // Close the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); + // Open the dock + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx); + }); - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + assert!(panel.focus_handle(cx).is_focused(cx)); + }); - // // Open the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); + // Focus and zoom panel + panel.update(cx, |panel, cx| { + cx.focus_self(); + panel.set_zoomed(true, cx) + }); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + assert!(panel.is_zoomed(cx)); + assert!(panel.focus_handle(cx).is_focused(cx)); + }); - // // Focus and zoom panel - // panel.update(cx, |panel, cx| { - // cx.focus_self(); - // panel.set_zoomed(true, cx) - // }); + // Transfer focus to the center closes the dock + workspace.update(cx, |workspace, cx| { + workspace.toggle_panel_focus::(cx); + }); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(!workspace.right_dock().read(cx).is_open()); + assert!(panel.is_zoomed(cx)); + assert!(!panel.focus_handle(cx).is_focused(cx)); + }); - // // Transfer focus to the center closes the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); + // Transferring focus back to the panel keeps it zoomed + workspace.update(cx, |workspace, cx| { + workspace.toggle_panel_focus::(cx); + }); - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + assert!(panel.is_zoomed(cx)); + assert!(panel.focus_handle(cx).is_focused(cx)); + }); - // // Transferring focus back to the panel keeps it zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); + // Close the dock while it is zoomed + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx) + }); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(!workspace.right_dock().read(cx).is_open()); + assert!(panel.is_zoomed(cx)); + assert!(workspace.zoomed.is_none()); + assert!(!panel.focus_handle(cx).is_focused(cx)); + }); - // // Close the dock while it is zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); + // Opening the dock, when it's zoomed, retains focus + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx) + }); - // workspace.update(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)); - // }); + workspace.update(cx, |workspace, cx| { + assert!(workspace.right_dock().read(cx).is_open()); + assert!(panel.is_zoomed(cx)); + assert!(workspace.zoomed.is_some()); + assert!(panel.focus_handle(cx).is_focused(cx)); + }); - // // Opening the dock, when it's zoomed, retains focus - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); + // Unzoom and close the panel, zoom the active pane. + panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx) + }); + pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); - // workspace.update(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)); - // }); - - // // Unzoom and close the panel, zoom the active pane. - // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); - - // // Opening a dock unzooms the pane. - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // workspace.update(cx, |workspace, cx| { - // let pane = pane.read(cx); - // assert!(!pane.is_zoomed()); - // assert!(!pane.has_focus()); - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(workspace.zoomed.is_none()); - // }); - // } + // Opening a dock unzooms the pane. + workspace.update(cx, |workspace, cx| { + workspace.toggle_dock(DockPosition::Right, cx) + }); + workspace.update(cx, |workspace, cx| { + let pane = pane.read(cx); + // assert!(!pane.is_zoomed()); + assert!(!pane.focus_handle(cx).is_focused(cx)); + assert!(workspace.right_dock().read(cx).is_open()); + assert!(workspace.zoomed.is_none()); + }); + }) + .unwrap(); + } // #[gpui::test] // async fn test_panels(cx: &mut gpui::TestAppContext) { From d8a25dee3b88e0a233d8719b84d31f1a1348cd5d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 8 Dec 2023 16:57:59 +0100 Subject: [PATCH 2/2] WIP --- crates/workspace/src/workspace.rs | 13 +- crates/workspace2/src/dock.rs | 237 ++++++++++++++++++---------- crates/workspace2/src/workspace2.rs | 185 ++++++++++++++-------- 3 files changed, 284 insertions(+), 151 deletions(-) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 455c27a57e..12d271af18 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1025,11 +1025,13 @@ impl Workspace { if !panel.has_focus(cx) { cx.focus(&panel); } + dbg!("D"); 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) { dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, false, cx)); if this.zoomed_position == Some(prev_position) { + dbg!("Losing focus A"); this.zoomed = None; this.zoomed_position = None; } @@ -1038,9 +1040,11 @@ impl Workspace { let position = panel.read(cx).position(cx); this.dismiss_zoomed_items_to_reveal(Some(position), cx); if panel.is_zoomed(cx) { + dbg!("C"); this.zoomed = Some(panel.downgrade().into_any()); this.zoomed_position = Some(position); } else { + dbg!("Losing focus B"); this.zoomed = None; this.zoomed_position = None; } @@ -1831,7 +1835,7 @@ impl Workspace { self.dismiss_zoomed_items_to_reveal(Some(dock_side), cx); } - if focus_center { + if dbg!(focus_center) { cx.focus_self(); } @@ -1875,6 +1879,7 @@ impl Workspace { ) -> Option> { for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] { if let Some(panel_index) = dock.read(cx).panel_index_for_type::() { + dbg!(panel_index); let mut focus_center = false; let mut reveal_dock = false; let panel = dock.update(cx, |dock, cx| { @@ -1926,6 +1931,7 @@ impl Workspace { self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx)); self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx)); self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + dbg!("Losing focus C"); self.zoomed = None; self.zoomed_position = None; @@ -1969,6 +1975,7 @@ impl Workspace { } if self.zoomed_position != dock_to_reveal { + dbg!("losing D"); self.zoomed = None; self.zoomed_position = None; } @@ -2313,8 +2320,10 @@ impl Workspace { self.dismiss_zoomed_items_to_reveal(None, cx); if pane.read(cx).is_zoomed() { + dbg!("B"); self.zoomed = Some(pane.downgrade().into_any()); } else { + dbg!("losing focus E"); self.zoomed = None; } self.zoomed_position = None; @@ -2364,6 +2373,7 @@ impl Workspace { if pane == self.active_pane { pane.update(cx, |pane, cx| pane.set_zoomed(true, cx)); if pane.read(cx).has_focus() { + dbg!("A"); self.zoomed = Some(pane.downgrade().into_any()); self.zoomed_position = None; } @@ -2373,6 +2383,7 @@ impl Workspace { pane::Event::ZoomOut => { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); if self.zoomed_position.is_none() { + dbg!("losing focus F"); self.zoomed = None; } cx.notify(); diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 067f657f80..712c984118 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -1,8 +1,8 @@ use crate::{status_bar::StatusItemView, Axis, Workspace}; use gpui::{ div, px, Action, AnchorCorner, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, - FocusHandle, Focusable, FocusableView, IntoElement, ParentElement, Render, SharedString, - Styled, Subscription, View, ViewContext, VisualContext, WeakView, WindowContext, + FocusHandle, FocusableView, IntoElement, ParentElement, Render, SharedString, Styled, + Subscription, View, ViewContext, VisualContext, WeakView, WindowContext, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -287,86 +287,143 @@ impl Dock { workspace: WeakView, cx: &mut ViewContext, ) { + let self_view = cx.view().downgrade(); let subscriptions = [ cx.observe(&panel, |_, _, cx| cx.notify()), - cx.subscribe(&panel, move |this, panel, event, cx| match event { - PanelEvent::ChangePosition => { - let new_position = panel.read(cx).position(cx); + cx.window_context() + .subscribe(&panel, move |panel, event, cx| match dbg!(event) { + PanelEvent::ChangePosition => { + let new_position = panel.read(cx).position(cx); - let Ok(new_dock) = workspace.update(cx, |workspace, cx| { - if panel.is_zoomed(cx) { - workspace.zoomed_position = Some(new_position); - } - match new_position { - DockPosition::Left => &workspace.left_dock, - DockPosition::Bottom => &workspace.bottom_dock, - DockPosition::Right => &workspace.right_dock, - } - .clone() - }) else { - return; - }; - - let was_visible = this.is_open() - && this.visible_panel().map_or(false, |active_panel| { - active_panel.entity_id() == Entity::entity_id(&panel) - }); - - this.remove_panel(&panel, cx); - - new_dock.update(cx, |new_dock, cx| { - new_dock.add_panel(panel.clone(), workspace.clone(), cx); - if was_visible { - new_dock.set_open(true, cx); - new_dock.activate_panel(this.panels_len() - 1, cx); - } - }); - } - PanelEvent::ZoomIn => { - this.set_panel_zoomed(&panel.to_any(), true, cx); - if !panel.focus_handle(cx).contains_focused(cx) { - cx.focus_view(&panel); - } - workspace - .update(cx, |workspace, cx| { - workspace.zoomed = Some(panel.downgrade().into()); - workspace.zoomed_position = Some(panel.read(cx).position(cx)); - }) - .ok(); - } - PanelEvent::ZoomOut => { - this.set_panel_zoomed(&panel.to_any(), false, cx); - workspace - .update(cx, |workspace, cx| { - if workspace.zoomed_position == Some(this.position) { - workspace.zoomed = None; - workspace.zoomed_position = None; + let Ok(new_dock) = workspace.update(cx, |workspace, cx| { + if panel.is_zoomed(cx) { + workspace.zoomed_position = Some(new_position); } - cx.notify(); - }) - .ok(); - } - PanelEvent::Activate => { - if let Some(ix) = this - .panel_entries - .iter() - .position(|entry| entry.panel.entity_id() == Entity::entity_id(&panel)) - { - this.set_open(true, cx); - this.activate_panel(ix, cx); - cx.focus_view(&panel); + match new_position { + DockPosition::Left => &workspace.left_dock, + DockPosition::Bottom => &workspace.bottom_dock, + DockPosition::Right => &workspace.right_dock, + } + .clone() + }) else { + return; + }; + + let Ok(was_visible) = self_view.update(cx, |this, cx| { + this.is_open() + && this.visible_panel().map_or(false, |active_panel| { + active_panel.entity_id() == Entity::entity_id(&panel) + }) + }) else { + return; + }; + + self_view.update(cx, |this, cx| this.remove_panel(&panel, cx)); + + new_dock.update(cx, |new_dock, cx| { + new_dock.add_panel(panel.clone(), workspace.clone(), cx); + if was_visible { + new_dock.set_open(true, cx); + self_view.update(cx, |this, cx| { + new_dock.activate_panel(this.panels_len() - 1, cx) + }); + } + }); } - } - PanelEvent::Close => { - if this - .visible_panel() - .map_or(false, |p| p.entity_id() == Entity::entity_id(&panel)) - { - this.set_open(false, cx); + PanelEvent::ZoomIn => { + self_view.update(cx, |this, cx| { + this.set_panel_zoomed(&panel.to_any(), true, cx) + }); + if !panel.focus_handle(cx).contains_focused(cx) { + cx.focus_view(&panel); + } + workspace + .update(cx, |workspace, cx| { + workspace.zoomed = Some(panel.downgrade().into()); + workspace.zoomed_position = Some(panel.read(cx).position(cx)); + }) + .ok(); } - } - PanelEvent::Focus => todo!(), - }), + PanelEvent::ZoomOut => { + self_view.update(cx, |this, cx| { + this.set_panel_zoomed(&panel.to_any(), false, cx) + }); + workspace + .update(cx, |workspace, cx| { + if workspace.zoomed_position + == Some(self_view.update(cx, |this, cx| this.position).ok()) + .flatten() + { + dbg!("Losing focus A"); + workspace.zoomed = None; + workspace.zoomed_position = None; + } + cx.notify(); + }) + .ok(); + } + PanelEvent::Activate => { + if self_view + .update(cx, |this, cx| { + if let Some(ix) = this.panel_entries.iter().position(|entry| { + entry.panel.entity_id() == Entity::entity_id(&panel) + }) { + this.set_open(true, cx); + this.activate_panel(ix, cx); + return true; + } + false + }) + .ok() + .unwrap_or(false) + { + cx.focus_view(&panel); + } + } + PanelEvent::Close => { + self_view + .update(cx, |this, cx| { + if this + .visible_panel() + .map_or(false, |p| p.entity_id() == Entity::entity_id(&panel)) + { + this.set_open(false, cx); + } + }) + .ok(); + } + PanelEvent::Focus => { + let position = panel.read(cx).position(cx); + workspace + .update(cx, |this, cx| { + this.dismiss_zoomed_items_to_reveal(Some(position), cx) + }) + .ok(); + if panel.is_zoomed(cx) { + dbg!("C"); + workspace + .update(cx, |this, cx| { + this.zoomed = Some(panel.downgrade().into()); + this.zoomed_position = Some(position); + }) + .ok(); + } else { + workspace + .update(cx, |this, cx| { + dbg!("Losing focus B"); + this.zoomed = None; + this.zoomed_position = None; + }) + .ok(); + } + workspace + .update(cx, |this, cx| { + this.update_active_view_for_followers(cx); + }) + .ok(); + cx.notify(); + } + }), ]; // todo!() @@ -776,12 +833,18 @@ pub mod test { impl EventEmitter for TestPanel {} impl TestPanel { - pub fn new(position: DockPosition, cx: &mut WindowContext) -> Self { + pub fn new(position: DockPosition, cx: &mut ViewContext) -> Self { + cx.emit(PanelEvent::Focus); + let focus_handle = cx.focus_handle(); + cx.on_focus_in(&focus_handle, move |_, cx| { + cx.emit(PanelEvent::Focus); + }) + .detach(); Self { position, zoomed: false, active: false, - focus_handle: cx.focus_handle(), + focus_handle, size: 300., } } @@ -833,12 +896,24 @@ pub mod test { self.zoomed } - fn set_zoomed(&mut self, zoomed: bool, _cx: &mut ViewContext) { + fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext) { self.zoomed = zoomed; + let event = if zoomed { + PanelEvent::ZoomIn + } else { + PanelEvent::ZoomOut + }; + cx.emit(event) } - fn set_active(&mut self, active: bool, _cx: &mut ViewContext) { - self.active = active; + fn set_active(&mut self, active: bool, cx: &mut ViewContext) { + self.active = dbg!(active); + // let event = if active { + // PanelEvent::Activate + // } else { + // PanelEvent::Close + // }; + // cx.emit(event) } } diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index fcf0f78b86..f6971d5cfa 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -1542,13 +1542,16 @@ impl Workspace { dock.set_open(!was_visible, cx); if let Some(active_panel) = dock.active_panel() { + dbg!(dock_side); if was_visible { if active_panel.focus_handle(cx).contains_focused(cx) { focus_center = true; } } else { let focus_handle = &active_panel.focus_handle(cx); + dbg!(&focus_handle); cx.focus(focus_handle); + assert!(focus_handle.is_focused(cx)); reveal_dock = true; } } @@ -1558,7 +1561,7 @@ impl Workspace { self.dismiss_zoomed_items_to_reveal(Some(dock_side), cx); } - dbg!("~~~~~~~~~~~~ ???????", focus_center); + dbg!(focus_center); if focus_center { self.active_pane.update(cx, |pane, cx| pane.focus(cx)) } @@ -1604,6 +1607,7 @@ impl Workspace { ) -> Option> { for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] { if let Some(panel_index) = dock.read(cx).panel_index_for_type::() { + dbg!(panel_index); let mut focus_center = false; let mut reveal_dock = false; let panel = dock.update(cx, |dock, cx| { @@ -1616,9 +1620,9 @@ impl Workspace { panel.focus_handle(cx).focus(cx); reveal_dock = true; } else { - // if panel.is_zoomed(cx) { - // dock.set_open(false, cx); - // } + if panel.is_zoomed(cx) { + dock.set_open(false, cx); + } focus_center = true; } } @@ -1655,6 +1659,7 @@ impl Workspace { self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx)); self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx)); self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + dbg!("Losing focus C"); self.zoomed = None; self.zoomed_position = None; @@ -1698,6 +1703,7 @@ impl Workspace { } if self.zoomed_position != dock_to_reveal { + dbg!("losing D"); self.zoomed = None; self.zoomed_position = None; } @@ -2042,14 +2048,7 @@ impl Workspace { } fn handle_pane_focused(&mut self, pane: View, cx: &mut ViewContext) { - // TODO kb remove - eprintln!( - "########## handle_pane_focused acrive: {}, new: {}", - self.active_pane.read(cx).items_len(), - pane.read(cx).items_len() - ); if self.active_pane != pane { - dbg!("########## got new pane to activate",); self.active_pane = pane.clone(); self.status_bar.update(cx, |status_bar, cx| { status_bar.set_active_pane(&self.active_pane, cx); @@ -2060,8 +2059,10 @@ impl Workspace { self.dismiss_zoomed_items_to_reveal(None, cx); if pane.read(cx).is_zoomed() { + dbg!("B"); self.zoomed = Some(pane.downgrade().into()); } else { + dbg!("losing focus E"); self.zoomed = None; } self.zoomed_position = None; @@ -2112,6 +2113,7 @@ impl Workspace { if pane == self.active_pane { pane.update(cx, |pane, cx| pane.set_zoomed(true, cx)); if pane.read(cx).has_focus(cx) { + dbg!("A"); self.zoomed = Some(pane.downgrade().into()); self.zoomed_position = None; } @@ -2121,6 +2123,7 @@ impl Workspace { pane::Event::ZoomOut => { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); if self.zoomed_position.is_none() { + dbg!("losing focus F"); self.zoomed = None; } cx.notify(); @@ -5004,144 +5007,188 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx).unwrap(); - cx.update_window(window.into(), |_, cx| { - let panel = workspace.update(cx, |workspace, cx| { - let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); - workspace.add_panel(panel.clone(), cx); + let panel = window + .update(cx, |workspace, cx| { + let (panel, right_dock) = { + let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + workspace.add_panel(panel.clone(), cx); - workspace - .right_dock() - .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + (panel, workspace.right_dock().clone()) + }; + dbg!("A"); + right_dock.update(cx, |this, cx| this.set_open(true, cx)); + dbg!("B"); panel - }); - let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + }) + .unwrap(); + dbg!("C"); + let pane = cx + .update_window(window.into(), |_, cx| { + workspace.update(cx, |workspace, _| workspace.active_pane().clone()) + }) + .unwrap(); + cx.update_window(window.into(), |_, cx| { pane.update(cx, |pane, cx| { let item = cx.build_view(|cx| TestItem::new(cx)); pane.add_item(Box::new(item), true, true, None, cx); - }); - - // Transfer focus from center to panel + }) + }) + .unwrap(); + // Transfer focus from center to panel + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_panel_focus::(cx); }); - + }) + .unwrap(); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); // assert!(!panel.is_zoomed(cx)); assert!(panel.focus_handle(cx).is_focused(cx)); }); + }) + .unwrap(); - // Transfer focus from panel to center + // Transfer focus from panel to center + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_panel_focus::(cx); - }); - + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); // assert!(!panel.is_zoomed(cx)); assert!(!panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Close the dock + // Close the dock + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_dock(DockPosition::Right, cx); - }); - + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(!workspace.right_dock().read(cx).is_open()); // assert!(!panel.is_zoomed(cx)); assert!(!panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Open the dock + // Open the dock + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_dock(DockPosition::Right, cx); - }); + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); // assert!(!panel.is_zoomed(cx)); assert!(panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Focus and zoom panel + // Focus and zoom panel + cx.update_window(window.into(), |_, cx| { panel.update(cx, |panel, cx| { cx.focus_self(); panel.set_zoomed(true, cx) - }); + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); assert!(panel.is_zoomed(cx)); assert!(panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Transfer focus to the center closes the dock + // Transfer focus to the center closes the dock + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_panel_focus::(cx); - }); + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(!workspace.right_dock().read(cx).is_open()); assert!(panel.is_zoomed(cx)); assert!(!panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Transferring focus back to the panel keeps it zoomed + // Transferring focus back to the panel keeps it zoomed + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_panel_focus::(cx); }); + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); assert!(panel.is_zoomed(cx)); assert!(panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Close the dock while it is zoomed + // Close the dock while it is zoomed + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_dock(DockPosition::Right, cx) - }); + }) + }); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(!workspace.right_dock().read(cx).is_open()); assert!(panel.is_zoomed(cx)); assert!(workspace.zoomed.is_none()); assert!(!panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Opening the dock, when it's zoomed, retains focus + // Opening the dock, when it's zoomed, retains focus + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { workspace.toggle_dock(DockPosition::Right, cx) - }); - + }) + }); + cx.executor().run_until_parked(); + cx.update_window(window.into(), |_, cx| { workspace.update(cx, |workspace, cx| { assert!(workspace.right_dock().read(cx).is_open()); assert!(panel.is_zoomed(cx)); assert!(workspace.zoomed.is_some()); assert!(panel.focus_handle(cx).is_focused(cx)); - }); + }) + }); - // Unzoom and close the panel, zoom the active pane. - panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); - workspace.update(cx, |workspace, cx| { - workspace.toggle_dock(DockPosition::Right, cx) - }); - pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); + // // Unzoom and close the panel, zoom the active pane. + // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); - // Opening a dock unzooms the pane. - workspace.update(cx, |workspace, cx| { - workspace.toggle_dock(DockPosition::Right, cx) - }); - workspace.update(cx, |workspace, cx| { - let pane = pane.read(cx); - // assert!(!pane.is_zoomed()); - assert!(!pane.focus_handle(cx).is_focused(cx)); - assert!(workspace.right_dock().read(cx).is_open()); - assert!(workspace.zoomed.is_none()); - }); - }) - .unwrap(); + // // Opening a dock unzooms the pane. + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // workspace.update(cx, |workspace, cx| { + // let pane = pane.read(cx); + // // assert!(!pane.is_zoomed()); + // assert!(!pane.focus_handle(cx).is_focused(cx)); + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(workspace.zoomed.is_none()); + // }); } // #[gpui::test]