Skip to main content

gpui_base/dock/layout/
node.rs

1use gpui::{Axis, Bounds, EntityId, Pixels};
2
3/// Stable container identity. Survives structural edits and normalization so
4/// the `DockArea` view cache does not tear down and rebuild entities.
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
6pub struct NodeId(u64);
7
8impl NodeId {
9    pub(crate) fn from_u64(raw: u64) -> Self {
10        Self(raw)
11    }
12
13    pub fn as_u64(self) -> u64 {
14        self.0
15    }
16}
17
18/// Stable panel identity. Wraps the `EntityId` of the panel entity so the
19/// layout algebra can be exercised without an `App`.
20#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
21pub struct PanelId(u64);
22
23impl PanelId {
24    pub fn from_u64(raw: u64) -> Self {
25        Self(raw)
26    }
27
28    pub fn as_u64(self) -> u64 {
29        self.0
30    }
31}
32
33impl From<EntityId> for PanelId {
34    fn from(id: EntityId) -> Self {
35        Self(id.as_u64())
36    }
37}
38
39/// One panel placed on a tiles canvas.
40#[derive(Clone, Copy, PartialEq, Debug)]
41pub struct TilePanel {
42    panel: PanelId,
43    bounds: Bounds<Pixels>,
44    z_index: usize,
45}
46
47impl TilePanel {
48    pub fn new(panel: PanelId, bounds: Bounds<Pixels>) -> Self {
49        Self {
50            panel,
51            bounds,
52            z_index: 0,
53        }
54    }
55
56    pub fn with_z_index(mut self, z_index: usize) -> Self {
57        self.z_index = z_index;
58        self
59    }
60
61    pub fn with_bounds(mut self, bounds: Bounds<Pixels>) -> Self {
62        self.bounds = bounds;
63        self
64    }
65
66    pub fn panel(&self) -> PanelId {
67        self.panel
68    }
69
70    pub fn bounds(&self) -> Bounds<Pixels> {
71        self.bounds
72    }
73
74    pub fn z_index(&self) -> usize {
75        self.z_index
76    }
77}
78
79/// The shape of one container. Private: every mutation goes through
80/// [`PaneTree`] so normalization always runs.
81///
82/// [`PaneTree`]: super::PaneTree
83#[derive(Clone, PartialEq, Debug)]
84pub(crate) enum NodeKind {
85    Split {
86        axis: Axis,
87        children: Vec<PaneNode>,
88        sizes: Vec<Option<Pixels>>,
89    },
90    Tabs {
91        panels: Vec<PanelId>,
92        active_ix: usize,
93    },
94    Tiles {
95        panels: Vec<TilePanel>,
96    },
97}
98
99/// Borrowed read-only projection of a node.
100pub enum PaneRef<'a> {
101    Split {
102        axis: Axis,
103        children: &'a [PaneNode],
104        sizes: &'a [Option<Pixels>],
105    },
106    Tabs {
107        panels: &'a [PanelId],
108        active_ix: usize,
109    },
110    Tiles {
111        panels: &'a [TilePanel],
112    },
113}
114
115#[derive(Clone, PartialEq, Debug)]
116pub struct PaneNode {
117    id: NodeId,
118    kind: NodeKind,
119}
120
121impl PaneNode {
122    pub(crate) fn new(id: NodeId, kind: NodeKind) -> Self {
123        Self { id, kind }
124    }
125
126    pub fn id(&self) -> NodeId {
127        self.id
128    }
129
130    pub fn kind(&self) -> PaneRef<'_> {
131        match &self.kind {
132            NodeKind::Split {
133                axis,
134                children,
135                sizes,
136            } => PaneRef::Split {
137                axis: *axis,
138                children,
139                sizes,
140            },
141            NodeKind::Tabs { panels, active_ix } => PaneRef::Tabs {
142                panels,
143                active_ix: *active_ix,
144            },
145            NodeKind::Tiles { panels } => PaneRef::Tiles { panels },
146        }
147    }
148
149    pub(crate) fn kind_mut(&mut self) -> &mut NodeKind {
150        &mut self.kind
151    }
152
153    pub(crate) fn kind_ref(&self) -> &NodeKind {
154        &self.kind
155    }
156
157    /// Depth-first pre-order walk over this node and its descendants.
158    pub fn walk(&self, f: &mut impl FnMut(&PaneNode)) {
159        f(self);
160        if let NodeKind::Split { children, .. } = &self.kind {
161            for child in children {
162                child.walk(f);
163            }
164        }
165    }
166}