Skip to main content

fret_core/dock/
apply.rs

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}