tiles: To support close panel. (#674)
- Add `remove_panel` method to DockArea.
This commit is contained in:
parent
5cf11ffe1b
commit
9732c3b7e8
4 changed files with 121 additions and 7 deletions
|
|
@ -276,6 +276,17 @@ impl Dock {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
/// Remove item from the Dock.
|
||||
pub fn remove_panel(
|
||||
&mut self,
|
||||
panel: Arc<dyn PanelView>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.panel.remove_panel(panel, window, cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn render_resize_handle(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let axis = self.placement.axis();
|
||||
let view = cx.entity().clone();
|
||||
|
|
|
|||
|
|
@ -368,6 +368,32 @@ impl DockItem {
|
|||
}
|
||||
}
|
||||
|
||||
/// Remove a panel from the dock item.
|
||||
pub fn remove_panel(&self, panel: Arc<dyn PanelView>, window: &mut Window, cx: &mut App) {
|
||||
match self {
|
||||
DockItem::Tabs { view, .. } => {
|
||||
view.update(cx, |tab_panel, cx| {
|
||||
tab_panel.remove_panel(panel, window, cx);
|
||||
});
|
||||
}
|
||||
DockItem::Split { items, view, .. } => {
|
||||
// For each child item, set collapsed state
|
||||
for item in items {
|
||||
item.remove_panel(panel.clone(), window, cx);
|
||||
}
|
||||
view.update(cx, |split, cx| {
|
||||
split.remove_panel(panel, window, cx);
|
||||
});
|
||||
}
|
||||
DockItem::Tiles { view, .. } => {
|
||||
view.update(cx, |tiles, cx| {
|
||||
tiles.remove(panel, window, cx);
|
||||
});
|
||||
}
|
||||
DockItem::Panel { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_collapsed(&self, collapsed: bool, window: &mut Window, cx: &mut App) {
|
||||
match self {
|
||||
DockItem::Tabs { view, .. } => {
|
||||
|
|
@ -567,6 +593,7 @@ impl DockArea {
|
|||
}
|
||||
|
||||
/// Determine if the dock area is locked.
|
||||
#[inline]
|
||||
pub fn is_locked(&self) -> bool {
|
||||
self.locked
|
||||
}
|
||||
|
|
@ -674,8 +701,6 @@ impl DockArea {
|
|||
}
|
||||
|
||||
/// Add a panel item to the dock area at the given placement.
|
||||
///
|
||||
/// If the left, bottom, right dock is not present, it will set the dock at the placement.
|
||||
pub fn add_panel(
|
||||
&mut self,
|
||||
panel: Arc<dyn PanelView>,
|
||||
|
|
@ -732,6 +757,56 @@ impl DockArea {
|
|||
}
|
||||
}
|
||||
|
||||
/// Remove panel from the DockArea at the given placement.
|
||||
pub fn remove_panel(
|
||||
&mut self,
|
||||
panel: Arc<dyn PanelView>,
|
||||
placement: DockPlacement,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
match placement {
|
||||
DockPlacement::Left => {
|
||||
if let Some(dock) = self.left_dock.as_mut() {
|
||||
dock.update(cx, |dock, cx| {
|
||||
dock.remove_panel(panel, window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
DockPlacement::Right => {
|
||||
if let Some(dock) = self.right_dock.as_mut() {
|
||||
dock.update(cx, |dock, cx| {
|
||||
dock.remove_panel(panel, window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
DockPlacement::Bottom => {
|
||||
if let Some(dock) = self.bottom_dock.as_mut() {
|
||||
dock.update(cx, |dock, cx| {
|
||||
dock.remove_panel(panel, window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
DockPlacement::Center => {
|
||||
self.items.remove_panel(panel, window, cx);
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
/// Remove a panel from all docks.
|
||||
pub fn remove_panel_from_all_docks(
|
||||
&mut self,
|
||||
panel: Arc<dyn PanelView>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.remove_panel(panel.clone(), DockPlacement::Center, window, cx);
|
||||
self.remove_panel(panel.clone(), DockPlacement::Left, window, cx);
|
||||
self.remove_panel(panel.clone(), DockPlacement::Right, window, cx);
|
||||
self.remove_panel(panel.clone(), DockPlacement::Bottom, window, cx);
|
||||
}
|
||||
|
||||
/// Load the state of the DockArea from the DockAreaState.
|
||||
///
|
||||
/// See also [DockeArea::dump].
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ pub struct TabPanel {
|
|||
collapsed: bool,
|
||||
/// When drag move, will get the placement of the panel to be split
|
||||
will_split_placement: Option<Placement>,
|
||||
/// Is TabPanel used in Tiles.
|
||||
in_tiles: bool,
|
||||
}
|
||||
|
||||
impl Panel for TabPanel {
|
||||
|
|
@ -158,9 +160,15 @@ impl TabPanel {
|
|||
zoomed: false,
|
||||
collapsed: false,
|
||||
closable: true,
|
||||
in_tiles: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark the TabPanel as being used in Tiles.
|
||||
pub(super) fn set_in_tiles(&mut self, in_tiles: bool) {
|
||||
self.in_tiles = in_tiles;
|
||||
}
|
||||
|
||||
pub(super) fn set_parent(&mut self, view: WeakEntity<StackPanel>) {
|
||||
self.stack_panel = Some(view);
|
||||
}
|
||||
|
|
@ -1063,6 +1071,20 @@ impl TabPanel {
|
|||
if let Some(panel) = self.active_panel(cx) {
|
||||
self.remove_panel(panel, window, cx);
|
||||
}
|
||||
|
||||
// Remove self from the parent DockArea.
|
||||
// This is ensure to remove from Tiles
|
||||
if self.panels.is_empty() && self.in_tiles {
|
||||
let tab_panel = Arc::new(cx.entity());
|
||||
window.defer(cx, {
|
||||
let dock_area = self.dock_area.clone();
|
||||
move |window, cx| {
|
||||
_ = dock_area.update(cx, |this, cx| {
|
||||
this.remove_panel_from_all_docks(tab_panel, window, cx);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1088,7 +1110,10 @@ impl Render for TabPanel {
|
|||
zoomable: self.zoomable(cx),
|
||||
active_panel,
|
||||
};
|
||||
if !state.draggable {
|
||||
|
||||
// 1. When is the final panel in the dock, it will not able to close.
|
||||
// 2. When is in the Tiles, it will always able to close (by active panel state).
|
||||
if !state.draggable && !self.in_tiles {
|
||||
state.closable = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -361,10 +361,13 @@ impl Tiles {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
assert!(
|
||||
item.panel.view().downcast::<TabPanel>().is_ok(),
|
||||
"only allows to add TabPanel type"
|
||||
);
|
||||
let Ok(tab_panel) = item.panel.view().downcast::<TabPanel>() else {
|
||||
panic!("only allows to add TabPanel type")
|
||||
};
|
||||
|
||||
tab_panel.update(cx, |tab_panel, _| {
|
||||
tab_panel.set_in_tiles(true);
|
||||
});
|
||||
|
||||
self.panels.push(item.clone());
|
||||
window.defer(cx, {
|
||||
|
|
|
|||
Loading…
Reference in a new issue