1mod apply;
2pub(super) mod layout;
3mod mutate;
4pub(super) mod op;
5mod persistence;
6mod query;
7use self::op::DockOp;
8use crate::{
9 PanelKey,
10 geometry::{Point, Px, Rect, Size},
11 ids::{AppWindowId, DockNodeId},
12};
13use slotmap::{Key, SlotMap};
14use std::collections::HashMap;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
17pub enum Axis {
18 Horizontal,
19 Vertical,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum DropZone {
24 Center,
25 Left,
26 Right,
27 Top,
28 Bottom,
29}
30
31#[derive(Debug, Clone)]
32pub enum DockNode {
33 Split {
34 axis: Axis,
35 children: Vec<DockNodeId>,
36 fractions: Vec<f32>,
37 },
38 Tabs {
39 tabs: Vec<PanelKey>,
40 active: usize,
41 },
42 Floating {
47 child: DockNodeId,
48 },
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum EdgeDockDecision {
57 InsertIntoSplit {
63 split: DockNodeId,
64 anchor_index: usize,
65 insert_index: usize,
66 },
67
68 WrapNewSplit,
70}
71
72#[derive(Debug, Clone, Copy, PartialEq)]
73pub struct DockFloatingWindow {
74 pub floating: DockNodeId,
75 pub rect: Rect,
76}
77
78#[derive(Debug, Default)]
79pub struct DockGraph {
80 nodes: SlotMap<DockNodeId, DockNode>,
81 window_roots: HashMap<AppWindowId, DockNodeId>,
82 window_floatings: HashMap<AppWindowId, Vec<DockFloatingWindow>>,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
86pub struct DockOpApplyError {
87 pub kind: DockOpApplyErrorKind,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub enum DockOpApplyErrorKind {
92 UnsupportedOp,
93 TabsNodeNotFound {
94 tabs: DockNodeId,
95 },
96 NodeIsNotTabs {
97 node: DockNodeId,
98 },
99 ActiveOutOfBounds {
100 tabs: DockNodeId,
101 active: usize,
102 len: usize,
103 },
104 PanelNotFound {
105 window: AppWindowId,
106 panel: PanelKey,
107 },
108 OperationFailed,
109}
110
111impl std::fmt::Display for DockOpApplyError {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 write!(f, "dock op apply error: {:?}", self.kind)
114 }
115}
116
117impl std::error::Error for DockOpApplyError {}
118
119impl DockGraph {
120 pub fn new() -> Self {
121 Self::default()
122 }
123
124 pub fn insert_node(&mut self, node: DockNode) -> DockNodeId {
125 self.nodes.insert(node)
126 }
127
128 pub fn node(&self, id: DockNodeId) -> Option<&DockNode> {
129 self.nodes.get(id)
130 }
131
132 pub fn node_mut(&mut self, id: DockNodeId) -> Option<&mut DockNode> {
133 self.nodes.get_mut(id)
134 }
135
136 pub fn set_window_root(&mut self, window: AppWindowId, root: DockNodeId) {
137 self.window_roots.insert(window, root);
138 }
139
140 pub fn window_root(&self, window: AppWindowId) -> Option<DockNodeId> {
141 self.window_roots.get(&window).copied()
142 }
143
144 pub fn remove_window_root(&mut self, window: AppWindowId) -> Option<DockNodeId> {
145 self.window_roots.remove(&window)
146 }
147
148 pub fn floating_windows(&self, window: AppWindowId) -> &[DockFloatingWindow] {
149 self.window_floatings
150 .get(&window)
151 .map(|v| v.as_slice())
152 .unwrap_or(&[])
153 }
154
155 pub fn floating_windows_mut(&mut self, window: AppWindowId) -> &mut Vec<DockFloatingWindow> {
156 self.window_floatings.entry(window).or_default()
157 }
158
159 }
162
163#[cfg(test)]
164mod tests;