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.
This commit is contained in:
parent
0834ac0394
commit
0158083599
4 changed files with 46 additions and 33 deletions
|
|
@ -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<StackPanel>,
|
||||
zoom_view: Option<AnyWeakView>,
|
||||
zoom_view: Option<AnyView>,
|
||||
}
|
||||
|
||||
impl DockArea {
|
||||
|
|
@ -37,13 +37,13 @@ impl DockArea {
|
|||
self.id.clone()
|
||||
}
|
||||
|
||||
/// Toggles the zoom view.
|
||||
pub fn toggle_zoom<P: Panel>(&mut self, panel: View<P>, cx: &mut ViewContext<Self>) {
|
||||
if self.zoom_view.is_some() {
|
||||
self.zoom_view = None;
|
||||
} else {
|
||||
self.zoom_view = Some(panel.downgrade().into());
|
||||
}
|
||||
pub fn set_zoomed_in<P: Panel>(&mut self, panel: View<P>, cx: &mut ViewContext<Self>) {
|
||||
self.zoom_view = Some(panel.into());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn set_zoomed_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.zoom_view = None;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
|
@ -55,12 +55,13 @@ impl DockArea {
|
|||
|
||||
impl Render for DockArea {
|
||||
fn render(&mut self, _: &mut ViewContext<Self>) -> 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())
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@ pub trait Panel: EventEmitter<PanelEvent> + 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ pub struct StackPanel {
|
|||
panel_group: View<ResizablePanelGroup>,
|
||||
}
|
||||
|
||||
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>) -> Self {
|
||||
|
|
@ -52,7 +56,7 @@ impl StackPanel {
|
|||
}
|
||||
|
||||
/// Return the index of the panel.
|
||||
pub fn index_of_panel<P>(&self, panel: View<P>) -> Option<usize>
|
||||
pub(crate) fn index_of_panel<P>(&self, panel: &View<P>) -> Option<usize>
|
||||
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::<TabPanel>() {
|
||||
tab_panel.update(cx, |tab_panel, _| tab_panel.set_parent(view));
|
||||
} else if let Ok(stack_panel) = panel1.view().downcast::<Self>() {
|
||||
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::<TabPanel>() {
|
||||
tab_panel.update(cx, |tab_panel, _| tab_panel.set_parent(view));
|
||||
} else if let Ok(stack_panel) = panel.view().downcast::<Self>() {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue