From 0158083599d6bebca259f8916ed75bb9b315b937 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 3 Sep 2024 23:15:44 +0800 Subject: [PATCH] dock: Fix panel zoom sometimes is not work. #197 (#211) This is because the `PanelEvent::ZoomIn` is called 2 times when we click the menu (I don't why, not found the source). So just split Zoom in, Zoom out as two difference methods to avoid this. --- crates/ui/src/dock/mod.rs | 21 ++++++++------- crates/ui/src/dock/panel.rs | 4 +-- crates/ui/src/dock/stack_panel.rs | 45 ++++++++++++++++++------------- crates/ui/src/dock/tab_panel.rs | 9 ++++++- 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/crates/ui/src/dock/mod.rs b/crates/ui/src/dock/mod.rs index af354f57..e0630821 100644 --- a/crates/ui/src/dock/mod.rs +++ b/crates/ui/src/dock/mod.rs @@ -3,7 +3,7 @@ mod stack_panel; mod tab_panel; use gpui::{ - actions, div, prelude::FluentBuilder, AnyWeakView, InteractiveElement as _, IntoElement, + actions, div, prelude::FluentBuilder, AnyView, InteractiveElement as _, IntoElement, ParentElement as _, Render, SharedString, Styled, View, ViewContext, }; pub use panel::*; @@ -16,7 +16,7 @@ actions!(dock, [ToggleZoom, ClosePanel]); pub struct DockArea { id: SharedString, root: View, - zoom_view: Option, + zoom_view: Option, } impl DockArea { @@ -37,13 +37,13 @@ impl DockArea { self.id.clone() } - /// Toggles the zoom view. - pub fn toggle_zoom(&mut self, panel: View

, cx: &mut ViewContext) { - if self.zoom_view.is_some() { - self.zoom_view = None; - } else { - self.zoom_view = Some(panel.downgrade().into()); - } + pub fn set_zoomed_in(&mut self, panel: View

, cx: &mut ViewContext) { + self.zoom_view = Some(panel.into()); + cx.notify(); + } + + pub fn set_zoomed_out(&mut self, cx: &mut ViewContext) { + self.zoom_view = None; cx.notify(); } @@ -55,12 +55,13 @@ impl DockArea { impl Render for DockArea { fn render(&mut self, _: &mut ViewContext) -> impl IntoElement { + // println!("Rendering dock area"); div() .id("dock-area") .size_full() .overflow_hidden() .map(|this| { - if let Some(zoom_view) = self.zoom_view.as_ref().and_then(|view| view.upgrade()) { + if let Some(zoom_view) = self.zoom_view.clone() { this.child(zoom_view) } else { this.child(self.root.clone()) diff --git a/crates/ui/src/dock/panel.rs b/crates/ui/src/dock/panel.rs index 727e01ab..ed56dab7 100644 --- a/crates/ui/src/dock/panel.rs +++ b/crates/ui/src/dock/panel.rs @@ -24,9 +24,7 @@ pub trait Panel: EventEmitter + FocusableView { pub trait PanelView: 'static + Send + Sync { /// The title of the panel, default is `None`. - fn title(&self, _cx: &WindowContext) -> SharedString { - t!("Dock.Unnamed").into() - } + fn title(&self, _cx: &WindowContext) -> SharedString; fn closeable(&self, cx: &WindowContext) -> bool; diff --git a/crates/ui/src/dock/stack_panel.rs b/crates/ui/src/dock/stack_panel.rs index 4b3e3643..4466445a 100644 --- a/crates/ui/src/dock/stack_panel.rs +++ b/crates/ui/src/dock/stack_panel.rs @@ -23,7 +23,11 @@ pub struct StackPanel { panel_group: View, } -impl Panel for StackPanel {} +impl Panel for StackPanel { + fn title(&self, _cx: &gpui::WindowContext) -> gpui::SharedString { + "StackPanel".into() + } +} impl StackPanel { pub fn new(axis: Axis, cx: &mut ViewContext) -> Self { @@ -52,7 +56,7 @@ impl StackPanel { } /// Return the index of the panel. - pub fn index_of_panel

(&self, panel: View

) -> Option + pub(crate) fn index_of_panel

(&self, panel: &View

) -> Option where P: Panel, { @@ -157,30 +161,33 @@ impl StackPanel { P: Panel, { // If the panel is already in the stack, return. - if let Some(_) = self.index_of_panel(panel.clone()) { + if let Some(_) = self.index_of_panel(&panel) { return; } - let dock_area = dock_area.clone(); cx.subscribe(&panel, move |_, panel, event, cx| match event { - PanelEvent::ZoomIn | PanelEvent::ZoomOut => { - if let Some(dock) = dock_area.upgrade() { - dock.update(cx, |dock, cx| { - dock.toggle_zoom(panel.clone(), cx); - }); - } + PanelEvent::ZoomIn => { + let _ = dock_area.update(cx, |dock, cx| { + dock.set_zoomed_in(panel.clone(), cx); + }); + } + PanelEvent::ZoomOut => { + let _ = dock_area.update(cx, |dock, cx| dock.set_zoomed_out(cx)); } }) .detach(); let view = cx.view().clone(); - let panel1 = panel.clone(); - cx.window_context().defer(move |cx| { - // If the panel is a TabPanel, set its parent to this. - if let Ok(tab_panel) = panel1.view().downcast::() { - tab_panel.update(cx, |tab_panel, _| tab_panel.set_parent(view)); - } else if let Ok(stack_panel) = panel1.view().downcast::() { - stack_panel.update(cx, |stack_panel, _| stack_panel.parent = Some(view)); + cx.window_context().defer({ + let panel = panel.clone(); + + move |cx| { + // If the panel is a TabPanel, set its parent to this. + if let Ok(tab_panel) = panel.view().downcast::() { + tab_panel.update(cx, |tab_panel, _| tab_panel.set_parent(view)); + } else if let Ok(stack_panel) = panel.view().downcast::() { + stack_panel.update(cx, |stack_panel, _| stack_panel.parent = Some(view)); + } } }); @@ -203,7 +210,7 @@ impl StackPanel { where P: Panel, { - if let Some(ix) = self.index_of_panel(panel) { + if let Some(ix) = self.index_of_panel(&panel) { self.panels.remove(ix); self.panel_group.update(cx, |view, cx| { view.remove_child(ix, cx); @@ -224,7 +231,7 @@ impl StackPanel { ) where P: Panel, { - if let Some(ix) = self.index_of_panel(old_panel) { + if let Some(ix) = self.index_of_panel(&old_panel) { self.panels[ix] = Arc::new(new_panel.clone()); self.panel_group.update(cx, |view, cx| { view.replace_child(Self::new_resizable_panel(new_panel.clone(), None), ix, cx); diff --git a/crates/ui/src/dock/tab_panel.rs b/crates/ui/src/dock/tab_panel.rs index 22c3f330..0b88c677 100644 --- a/crates/ui/src/dock/tab_panel.rs +++ b/crates/ui/src/dock/tab_panel.rs @@ -20,6 +20,7 @@ use crate::{ use super::{ClosePanel, DockArea, Panel, PanelView, StackPanel, ToggleZoom}; +#[derive(Debug)] pub enum PanelEvent { ZoomIn, ZoomOut, @@ -449,7 +450,7 @@ impl TabPanel { let parent_axis = stack_panel.read(cx).axis; let ix = stack_panel .read(cx) - .index_of_panel(cx.view().clone()) + .index_of_panel(&cx.view()) .unwrap_or_default(); if parent_axis.is_vertical() && placement.is_vertical() { @@ -523,6 +524,12 @@ impl TabPanel { } impl Panel for TabPanel { + fn title(&self, cx: &WindowContext) -> gpui::SharedString { + self.active_panel() + .map(|panel| panel.title(cx)) + .unwrap_or("Empty Tab".into()) + } + fn closeable(&self, cx: &WindowContext) -> bool { self.active_panel() .map(|panel| panel.closeable(cx))