Skip to main content

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}