dock: Add DockItem::panel (#464)

**Description**:
Improve the flexibility of `DockArea`, sometime user won't need a
`TabPanel`, just display some message or UI elements. Curren implement
only allow use Tab or Split. So this PR will add `Plain` to `DockItem`,
user can put anything which implement `PanelView` trait.

**Usage**:
```rust
let left_panels = DockItem::panel(Arc::new(<- PanelView ->));

_ = dock_area.update(cx, |view, cx| {
    view.set_version(DOCK_AREA.version, cx);
    view.set_left_dock(left_panels, Some(px(260.)), true, cx);
    view.set_center(dock_item, cx);
    view.set_dock_collapsible(
        Edges {
            left: false,
            ..Default::default()
        },
        cx,
    );
});
```

**Screenshot**
<img width="1300" alt="image"
src="https://github.com/user-attachments/assets/a01e427c-50f1-4509-82d1-76cc016aa7b3">
This commit is contained in:
reya 2024-12-05 10:12:08 +07:00 committed by GitHub
parent bc7dfb877b
commit 07a8e70d1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 0 deletions

View file

@ -188,6 +188,9 @@ impl Dock {
}
});
}
DockItem::Panel { .. } => {
// Not supported
}
}
}
@ -367,6 +370,7 @@ impl Render for Dock {
.map(|this| match &self.panel {
DockItem::Split { view, .. } => this.child(view.clone()),
DockItem::Tabs { view, .. } => this.child(view.clone()),
DockItem::Panel { view, .. } => this.child(view.clone().view()),
})
.child(self.render_resize_handle(cx))
.child(DockElement {

View file

@ -68,17 +68,21 @@ pub struct DockArea {
/// DockItem is a tree structure that represents the layout of the dock.
#[derive(Clone)]
pub enum DockItem {
/// Split layout
Split {
axis: gpui::Axis,
items: Vec<DockItem>,
sizes: Vec<Option<Pixels>>,
view: View<StackPanel>,
},
/// Tab layout
Tabs {
items: Vec<Arc<dyn PanelView>>,
active_ix: usize,
view: View<TabPanel>,
},
/// Panel layout
Panel { view: Arc<dyn PanelView> },
}
impl DockItem {
@ -140,6 +144,11 @@ impl DockItem {
}
}
/// Create DockItem with panel layout
pub fn panel(panel: Arc<dyn PanelView>) -> Self {
Self::Panel { view: panel }
}
/// Create DockItem with tabs layout, items are displayed as tabs.
///
/// The `active_ix` is the index of the active tab, if `None` the first tab is active.
@ -192,6 +201,7 @@ impl DockItem {
match self {
Self::Split { view, .. } => Arc::new(view.clone()),
Self::Tabs { view, .. } => Arc::new(view.clone()),
Self::Panel { view, .. } => view.clone(),
}
}
@ -202,6 +212,7 @@ impl DockItem {
items.iter().find_map(|item| item.find_panel(panel.clone()))
}
Self::Tabs { items, .. } => items.iter().find(|item| *item == &panel).cloned(),
Self::Panel { view } => Some(view.clone()),
}
}
@ -237,6 +248,7 @@ impl DockItem {
stack_panel.add_panel(new_item.view(), None, dock_area.clone(), cx);
});
}
Self::Panel { .. } => {}
}
}
@ -253,6 +265,7 @@ impl DockItem {
item.set_collapsed(collapsed, cx);
}
}
DockItem::Panel { .. } => {}
}
}
@ -261,6 +274,7 @@ impl DockItem {
match self {
DockItem::Tabs { view, .. } => Some(view.clone()),
DockItem::Split { view, .. } => view.read(cx).left_top_tab_panel(true, cx),
DockItem::Panel { .. } => None,
}
}
@ -269,6 +283,7 @@ impl DockItem {
match self {
DockItem::Tabs { view, .. } => Some(view.clone()),
DockItem::Split { view, .. } => view.read(cx).right_top_tab_panel(true, cx),
DockItem::Panel { .. } => None,
}
}
}
@ -640,6 +655,9 @@ impl DockArea {
DockItem::Tabs { .. } => {
// We subscribe to the tab panel event in StackPanel's insert_panel
}
DockItem::Panel { .. } => {
// Not supported
}
}
}
@ -707,6 +725,7 @@ impl DockArea {
match &self.items {
DockItem::Split { view, .. } => view.clone().into_any_element(),
DockItem::Tabs { view, .. } => view.clone().into_any_element(),
DockItem::Panel { view, .. } => view.clone().view().into_any_element(),
}
}