dock: Ensure add panel to StackPanel is type of TabPanel or StackPanel. (#862)

This commit is contained in:
Jason Lee 2025-05-17 22:41:11 +08:00
parent 1e2cc8315a
commit 769b1887d0

View file

@ -99,7 +99,19 @@ impl StackPanel {
self.panels.iter().position(|p| p == &panel) self.panels.iter().position(|p| p == &panel)
} }
fn assert_panel_is_valid(&self, panel: &Arc<dyn PanelView>) {
assert!(
panel.view().downcast::<TabPanel>().is_ok()
|| panel.view().downcast::<StackPanel>().is_ok(),
"Panel must be a `TabPanel` or `StackPanel`"
);
}
/// Add a panel at the end of the stack. /// Add a panel at the end of the stack.
///
/// If `size` is `None`, the panel will be given the average size of all panels in the stack.
///
/// The `panel` must be a [`TabPanel`] or [`StackPanel`].
pub fn add_panel( pub fn add_panel(
&mut self, &mut self,
panel: Arc<dyn PanelView>, panel: Arc<dyn PanelView>,
@ -111,6 +123,9 @@ impl StackPanel {
self.insert_panel(panel, self.panels.len(), size, dock_area, window, cx); self.insert_panel(panel, self.panels.len(), size, dock_area, window, cx);
} }
/// Add a panel at the [`Placement`].
///
/// The `panel` must be a [`TabPanel`] or [`StackPanel`].
pub fn add_panel_at( pub fn add_panel_at(
&mut self, &mut self,
panel: Arc<dyn PanelView>, panel: Arc<dyn PanelView>,
@ -131,6 +146,9 @@ impl StackPanel {
); );
} }
/// Insert a panel at the index.
///
/// The `panel` must be a [`TabPanel`] or [`StackPanel`].
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn insert_panel_at( pub fn insert_panel_at(
&mut self, &mut self,
@ -153,6 +171,8 @@ impl StackPanel {
} }
/// Insert a panel at the index. /// Insert a panel at the index.
///
/// The `panel` must be a [`TabPanel`] or [`StackPanel`].
pub fn insert_panel_before( pub fn insert_panel_before(
&mut self, &mut self,
panel: Arc<dyn PanelView>, panel: Arc<dyn PanelView>,
@ -166,6 +186,8 @@ impl StackPanel {
} }
/// Insert a panel after the index. /// Insert a panel after the index.
///
/// The `panel` must be a [`TabPanel`] or [`StackPanel`].
pub fn insert_panel_after( pub fn insert_panel_after(
&mut self, &mut self,
panel: Arc<dyn PanelView>, panel: Arc<dyn PanelView>,
@ -187,6 +209,8 @@ impl StackPanel {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
self.assert_panel_is_valid(&panel);
// If the panel is already in the stack, return. // 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.clone()) {
return; return;
@ -241,13 +265,18 @@ impl StackPanel {
} }
/// Remove panel from the stack. /// Remove panel from the stack.
///
/// If `ix` is not found, do nothing.
pub fn remove_panel( pub fn remove_panel(
&mut self, &mut self,
panel: Arc<dyn PanelView>, panel: Arc<dyn PanelView>,
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if let Some(ix) = self.index_of_panel(panel.clone()) { let Some(ix) = self.index_of_panel(panel.clone()) else {
return;
};
self.panels.remove(ix); self.panels.remove(ix);
self.state.update(cx, |state, cx| { self.state.update(cx, |state, cx| {
state.remove_panel(ix, cx); state.remove_panel(ix, cx);
@ -255,9 +284,6 @@ impl StackPanel {
cx.emit(PanelEvent::LayoutChanged); cx.emit(PanelEvent::LayoutChanged);
self.remove_self_if_empty(window, cx); self.remove_self_if_empty(window, cx);
} else {
println!("Panel not found in stack panel.");
}
} }
/// Replace the old panel with the new panel at same index. /// Replace the old panel with the new panel at same index.