Updated Docking (markdown)

omar
2025-10-14 17:47:29 +02:00
parent 50a478d8bb
commit 40f13ba486

@@ -1,6 +1,6 @@
- Development Thread: https://github.com/ocornut/imgui/issues/2109
- Search Issues: https://github.com/ocornut/imgui/labels/docking
- See: [Glossary -> Docking terms](Glossary#docking-terms).
- Old Development Thread: https://github.com/ocornut/imgui/issues/2109
![Docked windows](https://user-images.githubusercontent.com/8225057/97541627-c0dea300-19c5-11eb-9416-8bb255e189a1.png)
<BR>_Docked windows_
@@ -9,22 +9,35 @@
#### Where to find it?
Docking is currently available in the [docking](https://github.com/ocornut/imgui/tree/docking) branch. This is a well maintained branch and most large teams have been using this branch for a while. It is safe and recommended to use that branch. The branch also include the [Multi-viewports](https://github.com/ocornut/imgui/wiki/Multi-Viewports) feature.
Docking is currently available in the [docking](https://github.com/ocornut/imgui/tree/docking) branch.
- This is a well maintained branch and most large teams have been using this branch for a while.
- It is safe and recommended to use that branch.
- The branch also include the [Multi-viewports](https://github.com/ocornut/imgui/wiki/Multi-Viewports) feature.
- Since July 2023, releases are also tagged for docking, e.g. `v1.92.0` `v1.92.0-docking`.
#### How can I enable docking?
`ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;`
Enable config flag:
- `ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;`
Create a fullscreen dockspace (optional)
- `ImGui::DockSpaceOverViewport();`
That's pretty much it.
There are 4 additional docked related configuration flags in the io structure which you may toy with.
There are additional docked related configuration flags in the ImGuiIO structure which you may toy with.
#### Why is not merged to master?
#### Why is not merged to master???
(Please note that the following paragraphs have been written by a overly cautious person)
(This is the most asked question ever)
<BR>TL;DR; I am not happy with the current state of the code. I am a cautious person.
Several advanced features (mostly in imgui_internal.h), such as tight interaction with native multi-viewports, or the DockBuilder are still expecting api changes. I am also not particularly happy with how some aspects of the code are current implemented, and considering to maybe rewrite all of docking from scratch a third time!
- I want to rewrite it from scratch a third time (1st version was never released).
- DockBuilder API is kept in imgui_internal.h because it is not great.
- Many open issues don't have easy enough fixes, which suggests the code being too complex or fragile compared to the quality I strive for.
- Some core concepts needs to be re-implemented or redesigned.
- I have been incrementally adding automated tests to [imgui_test_suite](https://github.com/ocornut/imgui_test_engine) in order to facilitate rewriting the code.
However, you can benefit from a lot of docking features without being impacted by any of this. **The largest amount of interactions you'll have with the docking system are at end-user level and do not require API calls**. By just enabling the config flag above and calling 1-2 functions you can benefit from 90% of Docking features. Even the hypothetical full rewrite of Docking system is not expected to impact most users. API that are most at risk of changing are hidden in `imgui_internal.h` for this reason, and even so, if they do change, we'll make reasonable effort to document the reasoning the update path.
However, you can benefit from a lot of docking features without being impacted by any of this. **The largest amount of interactions you'll have with the docking system are at end-user level and do not require API calls**. By just enabling the config flag above and calling a few functions you can benefit from 90% of Docking features. Even the hypothetical full rewrite of Docking system is not expected to impact most users. API that are most at risk of changing are hidden in `imgui_internal.h` for this reason, and even so, if they do change, we'll make reasonable effort to document the reasoning the update path.
In addition, Docking will only move forward with feedback from users, so the more people using it, the closer we are to a reach mergeable version. TL;DR; is totally fine to use for most users.
@@ -58,18 +71,75 @@ Dock by dragging windows from their title tab or tab (hold SHIFT to disable dock
![capture_docking_wiki_gifs_0004](https://user-images.githubusercontent.com/19151258/92583366-e3dcb880-f29a-11ea-8a21-b503a2801c87.gif)
#### Settings, Persistence model
## Dockspace
- Explain how/why the data persist
If you want to dock window on the edge of your screen (rather than only into other windows), most application can do:
```cpp
ImGui::NewFrame();
#### Dockspace
// Create a dockspace in main viewport.
ImGui::DockSpaceOverViewport();
```
or
```cpp
ImGui::NewFrame();
- Explain dockspace (~~ node positioned within an existing window)
- Explain central node
// Create a dockspace in main viewport, where central node is transparent.
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
```
#### Dockbuider api
`DockSpaceOverViewport()` is a helper which:
- Create an invisible window covering the given viewport.
- Then submits a `DockSpace()` into it.
#### Debugging
That's pretty much what it does.
- Metrics window.
- Enable `IMGUI_DEBUG_LOG_DOCKING()`
A `DockSpace()` is an arbitrary location inside a window, where other windows may be docked into.
- Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame!
- Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked. e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with `ImGuiDockNodeFlags_KeepAliveOnly`, otherwise windows docked into it will automatically be undocked if the dockspace stops being visible.
## Programmatically setting up docking layout (DockBuider api)
Unfortunately, there is no great API for this yet. I am sorry! I know everyone is asking for this!
- There _is_ a DockBuilder API in imgui_internal.h. **It's not great, it is unfinished, and not well documented** (you can find more examples if you search in Issues).
- An alternative is to manually create desired settings, save them using `SaveIniSettingsXXX()` function, strip the data to whatever is necessary to you and call `LoadIniSettingsXXX()`.
DockBuilder API idiomatic example:
```cpp
#include "imgui_internal.h"
ImGuiID dockspace_id = ImGui::GetID("My Dockspace");
ImGuiViewport* viewport = ImGui::GetMainViewport();
// Create settings
if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr)
{
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
ImGuiID dock_id_left = 0;
ImGuiID dock_id_main = dockspace_id;
ImGui::DockBuilderSplitNode(dock_id_main, ImGuiDir_Left, 0.20f, &dock_id_left, &dock_id_main);
ImGuiID dock_id_left_top = 0;
ImGuiID dock_id_left_bottom = 0;
ImGui::DockBuilderSplitNode(dock_id_left, ImGuiDir_Down, 0.50f, &dock_id_left_top, &dock_id_left_bottom);
ImGui::DockBuilderDockWindow("Game", dock_id_main);
ImGui::DockBuilderDockWindow("Properties", dock_id_left_top);
ImGui::DockBuilderDockWindow("Scene", dock_id_left_bottom);
ImGui::DockBuilderFinish(dockspace_id);
}
// Submit dockspace
ImGui::DockSpaceOverViewport(dockspace_id, viewport, ImGuiDockNodeFlags_PassthruCentralNode);
```
- I expect to redesign this before it reaches the public API.
### Debugging
- Use the [Debug Log](https://github.com/ocornut/imgui/wiki/Debug-Tools#debug-log) to log docking events.
- Use the [Metrics/Debugger Window](https://github.com/ocornut/imgui/wiki/Debug-Tools#metricsdebugger-window)'s Docking section to browse internal docking data.
### More
- TODO: explain what data is persisting in .ini file, how and why.