1use super::*;
2
3impl DockGraph {
4 pub fn apply_op_checked(&mut self, op: &DockOp) -> Result<bool, DockOpApplyError> {
5 match op {
6 DockOp::SetActiveTab { tabs, active } => {
7 let Some(node) = self.nodes.get(*tabs) else {
8 return Err(DockOpApplyError {
9 kind: DockOpApplyErrorKind::TabsNodeNotFound { tabs: *tabs },
10 });
11 };
12 let DockNode::Tabs { tabs: list, .. } = node else {
13 return Err(DockOpApplyError {
14 kind: DockOpApplyErrorKind::NodeIsNotTabs { node: *tabs },
15 });
16 };
17 if *active >= list.len() {
18 return Err(DockOpApplyError {
19 kind: DockOpApplyErrorKind::ActiveOutOfBounds {
20 tabs: *tabs,
21 active: *active,
22 len: list.len(),
23 },
24 });
25 }
26 Ok(self.set_active_tab(*tabs, *active))
27 }
28 DockOp::ClosePanel { window, panel } => {
29 if self.close_panel(*window, panel.clone()) {
30 Ok(true)
31 } else {
32 Err(DockOpApplyError {
33 kind: DockOpApplyErrorKind::PanelNotFound {
34 window: *window,
35 panel: panel.clone(),
36 },
37 })
38 }
39 }
40 DockOp::RequestFloatPanelToNewWindow { .. } => Err(DockOpApplyError {
41 kind: DockOpApplyErrorKind::UnsupportedOp,
42 }),
43 DockOp::RequestFloatTabsToNewWindow { .. } => Err(DockOpApplyError {
44 kind: DockOpApplyErrorKind::UnsupportedOp,
45 }),
46 _ => Ok(self.apply_op(op)),
47 }
48 }
49
50 pub fn apply_op(&mut self, op: &DockOp) -> bool {
51 match op {
52 DockOp::SetActiveTab { tabs, active } => self.set_active_tab(*tabs, *active),
53 DockOp::ClosePanel { window, panel } => self.close_panel(*window, panel.clone()),
54 DockOp::MovePanel {
55 source_window,
56 panel,
57 target_window,
58 target_tabs,
59 zone,
60 insert_index,
61 } => self.move_panel_between_windows(
62 *source_window,
63 panel.clone(),
64 *target_window,
65 *target_tabs,
66 *zone,
67 *insert_index,
68 ),
69 DockOp::MovePanelToEmptyDockSpace {
70 source_window,
71 panel,
72 target_window,
73 } => {
74 if self.window_root(*target_window).is_some() {
75 return false;
76 }
77 self.float_panel_to_window(*source_window, panel.clone(), *target_window)
78 }
79 DockOp::MoveTabs {
80 source_window,
81 source_tabs,
82 target_window,
83 target_tabs,
84 zone,
85 insert_index,
86 } => self.move_tabs_between_windows(
87 *source_window,
88 *source_tabs,
89 *target_window,
90 *target_tabs,
91 *zone,
92 *insert_index,
93 ),
94 DockOp::MoveTabsToEmptyDockSpace {
95 source_window,
96 source_tabs,
97 target_window,
98 } => {
99 if self.window_root(*target_window).is_some() {
100 return false;
101 }
102 self.float_tabs_to_window(*source_window, *source_tabs, *target_window)
103 }
104 DockOp::FloatPanelToWindow {
105 source_window,
106 panel,
107 new_window,
108 } => self.float_panel_to_window(*source_window, panel.clone(), *new_window),
109 DockOp::RequestFloatPanelToNewWindow { .. } => false,
110 DockOp::RequestFloatTabsToNewWindow { .. } => false,
111 DockOp::FloatPanelInWindow {
112 source_window,
113 panel,
114 target_window,
115 rect,
116 } => self.float_panel_in_window(*source_window, panel.clone(), *target_window, *rect),
117 DockOp::FloatTabsInWindow {
118 source_window,
119 source_tabs,
120 target_window,
121 rect,
122 } => self.float_tabs_in_window(*source_window, *source_tabs, *target_window, *rect),
123 DockOp::SetFloatingRect {
124 window,
125 floating,
126 rect,
127 } => self.set_floating_rect(*window, *floating, *rect),
128 DockOp::RaiseFloating { window, floating } => self.raise_floating(*window, *floating),
129 DockOp::MergeFloatingInto {
130 window,
131 floating,
132 target_tabs,
133 } => self.merge_floating_into(*window, *floating, *target_tabs),
134 DockOp::MergeWindowInto {
135 source_window,
136 target_window,
137 target_tabs,
138 } => {
139 if source_window == target_window {
140 return false;
141 }
142 if !matches!(self.nodes.get(*target_tabs), Some(DockNode::Tabs { .. })) {
143 return false;
144 }
145 if self
146 .root_for_node_in_window_forest(*target_window, *target_tabs)
147 .is_none()
148 {
149 return false;
150 }
151
152 let panels = self.collect_panels_in_window(*source_window);
153 for panel in panels {
154 let _ = self.move_panel_between_windows(
155 *source_window,
156 panel,
157 *target_window,
158 *target_tabs,
159 DropZone::Center,
160 None,
161 );
162 }
163 let _ = self.remove_window_root(*source_window);
164 let _ = self.window_floatings.remove(source_window);
165 true
166 }
167 DockOp::SetSplitFractions { split, fractions } => {
168 self.update_split_fractions(*split, fractions.clone())
169 }
170 DockOp::SetSplitFractionsMany { updates } => {
171 let mut changed = false;
172 for u in updates {
173 changed |= self.update_split_fractions(u.split, u.fractions.clone());
174 }
175 changed
176 }
177 DockOp::SetSplitFractionTwo {
178 split,
179 first_fraction,
180 } => self.update_split_two(*split, *first_fraction),
181 }
182 }
183}