|
1 | | -// Docking demo — `imgui = { ..., features = ["docking"] }`. |
2 | | -// The imgui.app facade auto-enables ImGuiConfigFlags_DockingEnable when the |
3 | | -// feature is active; DockSpaceOverViewport turns the whole window into a |
4 | | -// dock host, so the two panels below can be dragged into / split around it. |
| 1 | +// Docking + multi-viewport demo — |
| 2 | +// imgui = { ..., features = ["docking", "viewports"] } |
| 3 | +// |
| 4 | +// On the first frame, DockBuilder splits the dockspace into an IDE-style |
| 5 | +// layout (Scene | Viewport | Inspector, Console at the bottom). Every pane is |
| 6 | +// a real dock node: drag any tab to re-split, stack, or float it. |
| 7 | +// With `viewports`, drag a tab OUTSIDE the main window and it detaches into |
| 8 | +// its own OS window; the "Detached" panel below starts outside on purpose. |
5 | 9 | import imgui.core; |
6 | 10 | import imgui.app; |
7 | 11 |
|
8 | 12 | int main() { |
9 | 13 | return ImGui::App::run({.title = "mcpp imgui docking demo"}, [] { |
10 | | - const auto dockspace = ImGui::DockSpaceOverViewport(); |
| 14 | + auto dockspace = ImGui::DockSpaceOverViewport(); |
11 | 15 |
|
12 | | - // Pre-dock both panels into the dockspace on first run; they remain |
13 | | - // freely draggable/splittable afterwards. |
14 | | - ImGui::SetNextWindowDockID(dockspace, ImGui::Cond_FirstUseEver); |
15 | | - ImGui::Begin("Toolbox"); |
16 | | - ImGui::TextUnformatted("Drag this panel onto the dockspace."); |
17 | | - ImGui::TextUnformatted("Docked: "); |
18 | | - ImGui::TextUnformatted(ImGui::IsWindowDocked() ? "yes" : "no"); |
| 16 | + static bool layout_built = false; |
| 17 | + if (!layout_built) { |
| 18 | + layout_built = true; |
| 19 | + const auto root = dockspace; |
| 20 | + auto left = ImGui::DockBuilderSplitNode( |
| 21 | + dockspace, ImGui::Dir_Left, 0.22f, nullptr, &dockspace); |
| 22 | + auto down = ImGui::DockBuilderSplitNode( |
| 23 | + dockspace, ImGui::Dir_Down, 0.28f, nullptr, &dockspace); |
| 24 | + auto right = ImGui::DockBuilderSplitNode( |
| 25 | + dockspace, ImGui::Dir_Right, 0.30f, nullptr, &dockspace); |
| 26 | + ImGui::DockBuilderDockWindow("Scene", left); |
| 27 | + ImGui::DockBuilderDockWindow("Console", down); |
| 28 | + ImGui::DockBuilderDockWindow("Inspector", right); |
| 29 | + ImGui::DockBuilderDockWindow("Viewport", dockspace); |
| 30 | + ImGui::DockBuilderFinish(root); |
| 31 | + } |
| 32 | + |
| 33 | + ImGui::Begin("Scene"); |
| 34 | + ImGui::TextUnformatted("Scene tree pane (left split)."); |
| 35 | + ImGui::TextUnformatted(ImGui::IsWindowDocked() ? "docked: yes" : "docked: no"); |
| 36 | + ImGui::End(); |
| 37 | + |
| 38 | + ImGui::Begin("Viewport"); |
| 39 | + ImGui::TextUnformatted("Central pane. Drag any tab to"); |
| 40 | + ImGui::TextUnformatted("re-split / stack / float it."); |
19 | 41 | ImGui::End(); |
20 | 42 |
|
21 | | - ImGui::SetNextWindowDockID(dockspace, ImGui::Cond_FirstUseEver); |
22 | 43 | ImGui::Begin("Inspector"); |
23 | | - ImGui::TextUnformatted("Split me against the Toolbox."); |
| 44 | + ImGui::TextUnformatted("Properties pane (right split)."); |
| 45 | + ImGui::End(); |
| 46 | + |
| 47 | + ImGui::Begin("Console"); |
| 48 | + ImGui::TextUnformatted("Log pane (bottom split)."); |
| 49 | + ImGui::End(); |
| 50 | + |
| 51 | + // Starts OUTSIDE the main window: with `viewports` this is a real, |
| 52 | + // separate OS window from the very first frame. |
| 53 | + const auto* main_vp = ImGui::GetMainViewport(); |
| 54 | + ImGui::SetNextWindowPos( |
| 55 | + ImVec2{main_vp->Pos.x + main_vp->Size.x + 60.0f, main_vp->Pos.y + 80.0f}, |
| 56 | + ImGui::Cond_FirstUseEver); |
| 57 | + ImGui::Begin("Detached"); |
| 58 | + ImGui::TextUnformatted("I live in my own OS window."); |
| 59 | + ImGui::TextUnformatted("Drag me back inside to re-dock."); |
24 | 60 | ImGui::End(); |
25 | 61 | }); |
26 | 62 | } |
0 commit comments