fret_core/dock/op.rs
1use crate::{AppWindowId, DockNodeId, DropZone, PanelKey, Rect, WindowAnchor};
2
3/// High-level docking operations emitted by the UI layer and applied by the app layer.
4///
5/// This is the transaction vocabulary that enables persistence, undo/redo, and plugins
6/// without letting UI widgets mutate the dock graph ad-hoc.
7#[derive(Debug, Clone, PartialEq)]
8pub enum DockOp {
9 SetActiveTab {
10 tabs: DockNodeId,
11 active: usize,
12 },
13
14 ClosePanel {
15 window: AppWindowId,
16 panel: PanelKey,
17 },
18
19 MovePanel {
20 source_window: AppWindowId,
21 panel: PanelKey,
22 target_window: AppWindowId,
23 target_tabs: DockNodeId,
24 zone: DropZone,
25 insert_index: Option<usize>,
26 },
27
28 /// Move a panel into a window that currently has no dock root tabs.
29 ///
30 /// This creates the initial root tab stack for `target_window` and inserts `panel` into it.
31 MovePanelToEmptyDockSpace {
32 source_window: AppWindowId,
33 panel: PanelKey,
34 target_window: AppWindowId,
35 },
36
37 /// Move an entire tab stack ("dock node") as a group.
38 ///
39 /// This is used for editor-grade interactions like dragging the tab bar empty space to
40 /// undock/move the whole group, rather than a single tab.
41 MoveTabs {
42 source_window: AppWindowId,
43 source_tabs: DockNodeId,
44 target_window: AppWindowId,
45 target_tabs: DockNodeId,
46 zone: DropZone,
47 insert_index: Option<usize>,
48 },
49
50 /// Move an entire tab stack ("dock node") into a window that currently has no dock root tabs.
51 ///
52 /// This creates the initial root tab stack for `target_window` and moves the whole group.
53 MoveTabsToEmptyDockSpace {
54 source_window: AppWindowId,
55 source_tabs: DockNodeId,
56 target_window: AppWindowId,
57 },
58
59 FloatPanelToWindow {
60 source_window: AppWindowId,
61 panel: PanelKey,
62 new_window: AppWindowId,
63 },
64
65 /// Request creating a new floating OS window and moving the panel into it.
66 ///
67 /// This is interpreted by the app/runner layer, because `fret-core` does not own window creation.
68 RequestFloatPanelToNewWindow {
69 source_window: AppWindowId,
70 panel: PanelKey,
71 anchor: Option<WindowAnchor>,
72 },
73
74 /// Request creating a new floating OS window and moving an entire tab stack ("tabs node") into it.
75 ///
76 /// This is interpreted by the app/runner layer, because `fret-core` does not own window creation.
77 ///
78 /// Note: `panel` is a representative panel key used for correlating window creation and for
79 /// policy hooks; the runtime is responsible for moving the full `source_tabs` contents.
80 RequestFloatTabsToNewWindow {
81 source_window: AppWindowId,
82 source_tabs: DockNodeId,
83 panel: PanelKey,
84 anchor: Option<WindowAnchor>,
85 },
86
87 /// Float a panel into an in-window floating dock container (ImGui docking, viewports disabled).
88 ///
89 /// This does not create a new OS window; the floating container is rendered within
90 /// `target_window`'s dock host.
91 FloatPanelInWindow {
92 source_window: AppWindowId,
93 panel: PanelKey,
94 target_window: AppWindowId,
95 rect: Rect,
96 },
97
98 /// Float a whole tab stack into an in-window floating dock container.
99 FloatTabsInWindow {
100 source_window: AppWindowId,
101 source_tabs: DockNodeId,
102 target_window: AppWindowId,
103 rect: Rect,
104 },
105
106 /// Update the bounds of an in-window floating dock container.
107 SetFloatingRect {
108 window: AppWindowId,
109 floating: DockNodeId,
110 rect: Rect,
111 },
112
113 /// Raise an in-window floating dock container above other floating containers in the window.
114 RaiseFloating {
115 window: AppWindowId,
116 floating: DockNodeId,
117 },
118
119 /// Merge an in-window floating dock container back into an existing tab stack.
120 MergeFloatingInto {
121 window: AppWindowId,
122 floating: DockNodeId,
123 target_tabs: DockNodeId,
124 },
125
126 /// Merge all panels from `source_window` into `target_tabs` in `target_window`, then remove
127 /// the dock root for `source_window`.
128 ///
129 /// Recommended default behavior when a floating window is closed is to merge its panels back
130 /// into the main window rather than discarding them.
131 MergeWindowInto {
132 source_window: AppWindowId,
133 target_window: AppWindowId,
134 target_tabs: DockNodeId,
135 },
136
137 /// Update a split node's normalized `fractions` (length must match `children.len()`).
138 SetSplitFractions {
139 split: DockNodeId,
140 fractions: Vec<f32>,
141 },
142
143 /// Atomically update multiple split nodes' normalized `fractions`.
144 ///
145 /// This is intended for editor-grade splitter drags where a single pointer interaction may
146 /// need to update nested same-axis splits to avoid oscillation.
147 SetSplitFractionsMany {
148 updates: Vec<SplitFractionsUpdate>,
149 },
150
151 SetSplitFractionTwo {
152 split: DockNodeId,
153 first_fraction: f32,
154 },
155}
156
157#[derive(Debug, Clone, PartialEq)]
158pub struct SplitFractionsUpdate {
159 pub split: DockNodeId,
160 pub fractions: Vec<f32>,
161}