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();
|
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 {
|
fn render_resize_handle(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let axis = self.placement.axis();
|
let axis = self.placement.axis();
|
||||||
let view = cx.entity().clone();
|
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) {
|
pub fn set_collapsed(&self, collapsed: bool, window: &mut Window, cx: &mut App) {
|
||||||
match self {
|
match self {
|
||||||
DockItem::Tabs { view, .. } => {
|
DockItem::Tabs { view, .. } => {
|
||||||
|
|
@ -567,6 +593,7 @@ impl DockArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if the dock area is locked.
|
/// Determine if the dock area is locked.
|
||||||
|
#[inline]
|
||||||
pub fn is_locked(&self) -> bool {
|
pub fn is_locked(&self) -> bool {
|
||||||
self.locked
|
self.locked
|
||||||
}
|
}
|
||||||
|
|
@ -674,8 +701,6 @@ impl DockArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a panel item to the dock area at the given placement.
|
/// 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(
|
pub fn add_panel(
|
||||||
&mut self,
|
&mut self,
|
||||||
panel: Arc<dyn PanelView>,
|
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.
|
/// Load the state of the DockArea from the DockAreaState.
|
||||||
///
|
///
|
||||||
/// See also [DockeArea::dump].
|
/// See also [DockeArea::dump].
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,8 @@ pub struct TabPanel {
|
||||||
collapsed: bool,
|
collapsed: bool,
|
||||||
/// When drag move, will get the placement of the panel to be split
|
/// When drag move, will get the placement of the panel to be split
|
||||||
will_split_placement: Option<Placement>,
|
will_split_placement: Option<Placement>,
|
||||||
|
/// Is TabPanel used in Tiles.
|
||||||
|
in_tiles: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Panel for TabPanel {
|
impl Panel for TabPanel {
|
||||||
|
|
@ -158,9 +160,15 @@ impl TabPanel {
|
||||||
zoomed: false,
|
zoomed: false,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
closable: true,
|
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>) {
|
pub(super) fn set_parent(&mut self, view: WeakEntity<StackPanel>) {
|
||||||
self.stack_panel = Some(view);
|
self.stack_panel = Some(view);
|
||||||
}
|
}
|
||||||
|
|
@ -1063,6 +1071,20 @@ impl TabPanel {
|
||||||
if let Some(panel) = self.active_panel(cx) {
|
if let Some(panel) = self.active_panel(cx) {
|
||||||
self.remove_panel(panel, window, 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),
|
zoomable: self.zoomable(cx),
|
||||||
active_panel,
|
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;
|
state.closable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -361,10 +361,13 @@ impl Tiles {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
assert!(
|
let Ok(tab_panel) = item.panel.view().downcast::<TabPanel>() else {
|
||||||
item.panel.view().downcast::<TabPanel>().is_ok(),
|
panic!("only allows to add TabPanel type")
|
||||||
"only allows to add TabPanel type"
|
};
|
||||||
);
|
|
||||||
|
tab_panel.update(cx, |tab_panel, _| {
|
||||||
|
tab_panel.set_in_tiles(true);
|
||||||
|
});
|
||||||
|
|
||||||
self.panels.push(item.clone());
|
self.panels.push(item.clone());
|
||||||
window.defer(cx, {
|
window.defer(cx, {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue