diff --git a/crates/ui/src/dock/mod.rs b/crates/ui/src/dock/mod.rs index dc570a4f..aadd69de 100644 --- a/crates/ui/src/dock/mod.rs +++ b/crates/ui/src/dock/mod.rs @@ -442,6 +442,11 @@ impl DockArea { self.bounds } + /// Return the items of the dock area. + pub fn items(&self) -> &DockItem { + &self.items + } + /// Subscribe to the tiles item drag item drop event fn subscribe_tiles_item_drop( &mut self, diff --git a/crates/ui/src/dock/panel.rs b/crates/ui/src/dock/panel.rs index ebc8fc89..0586a1c5 100644 --- a/crates/ui/src/dock/panel.rs +++ b/crates/ui/src/dock/panel.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc}; use crate::{button::Button, popup_menu::PopupMenu}; use gpui::{ - AnyElement, AnyView, App, Entity, EventEmitter, FocusHandle, Focusable, Global, Hsla, + AnyElement, AnyView, App, Entity, EntityId, EventEmitter, FocusHandle, Focusable, Global, Hsla, IntoElement, Render, SharedString, WeakEntity, Window, }; @@ -129,6 +129,7 @@ pub trait Panel: EventEmitter + Render + Focusable { #[allow(unused_variables)] pub trait PanelView: 'static + Send + Sync { fn panel_name(&self, cx: &App) -> &'static str; + fn panel_id(&self, cx: &App) -> EntityId; fn title(&self, window: &Window, cx: &App) -> AnyElement; fn title_style(&self, cx: &App) -> Option; fn closable(&self, cx: &App) -> bool; @@ -149,6 +150,10 @@ impl PanelView for Entity { self.read(cx).panel_name() } + fn panel_id(&self, _: &App) -> EntityId { + self.entity_id() + } + fn title(&self, window: &Window, cx: &App) -> AnyElement { self.read(cx).title(window, cx) } diff --git a/crates/ui/src/dock/tiles.rs b/crates/ui/src/dock/tiles.rs index 6f7b2fb1..b3a7dec7 100644 --- a/crates/ui/src/dock/tiles.rs +++ b/crates/ui/src/dock/tiles.rs @@ -13,7 +13,9 @@ use crate::{ v_flex, ActiveTheme, Icon, IconName, }; -use super::{DockArea, Panel, PanelEvent, PanelInfo, PanelState, PanelView, TabPanel, TileMeta}; +use super::{ + DockArea, Panel, PanelEvent, PanelInfo, PanelState, PanelView, StackPanel, TabPanel, TileMeta, +}; use gpui::{ actions, canvas, div, point, px, size, AnyElement, App, AppContext, Bounds, Context, DismissEvent, DragMoveEvent, Empty, EntityId, EventEmitter, FocusHandle, Focusable, Half, @@ -359,6 +361,11 @@ impl Tiles { window: &mut Window, cx: &mut Context, ) { + assert!( + item.panel.view().downcast::().is_ok(), + "only allows to add TabPanel type" + ); + self.panels.push(item.clone()); window.defer(cx, { let panel = item.panel.clone(); @@ -487,12 +494,20 @@ impl Tiles { } /// Returns the active panel, if any. - pub fn active_panel(&self) -> Option> { + pub fn active_panel(&self, cx: &App) -> Option> { let Some(active_index) = self.active_index else { return None; }; - self.panels.get(active_index).map(|item| item.panel.clone()) + self.panels.get(active_index).and_then(|item| { + if let Ok(tab_panel) = item.panel.view().downcast::() { + tab_panel.read(cx).active_panel(cx) + } else if let Ok(_) = item.panel.view().downcast::() { + None + } else { + Some(item.panel.clone()) + } + }) } fn set_active_index(&mut self, index: Option, cx: &mut Context) {