-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docking branch available for testing #2109
Comments
This is my second version of Docking (I developed a V1 during the year which didn't get released, and which I have completely scrapped, then a rebuilt a V2 from stratch. V2 has issues but is already very useful.). The development of this feature has been sponsored by Blizzard Entertainment and supporters on Patreon. The current branch scheme is The basic design is based on what Visual Studio do. When creating an explicit I'm also working on various features to manipulate dock nodes programmatically allowing to replicate what Unreal Engine is doing (each top-level editor have its own layout, and layout are copied/forked on demand). Some of those features are currently only exposed in imgui_internal.h but will slowly make it into the public API (they currently need a bit of rework). PreambleUPDATING
FEEDBACK
CONFIGURATION
* the current default is a little unexpected and may be changed in the future. I would recommend that you try it before toggling the option. DESIRABLE (NOT STRICTLY DOCKING) FEATURES TO ENABLE ALONG WITH DOCKING Note: All of this is enabled if you try one of the standard examples e.g. example_win32_directx11/, example_glfw_opengl3/, example_glfw_vulkan/, etc. Those paragraphs are useful if you want to integrate docking in your own application with your own back-end.
(if you have any issue related to viewports please post in #1542) DockingThe core Docking feature requires no new API. Whenever you are moving a window you can merge them into each others and split nodes. When You can play around with that anywhere in the demo, the merging of windows itself is super useful (even without any of the "splitting" feature usually associated to Docking). Settings and docking trees are persisting and references are tracked under the hood so when you restore a window it should be where you expect it to be: There are various useful subtleties and complications associated to the persistence model which are not conveyed in the GIF. I'm not going to detail everything right now, but basically if you have any feedback or issue, please report them (there WILL be issues). If you have keyboard navigation enabled, you can use CTRL+Tab to cycle through windows with the keyboard: You can re-order tabs by dragging them horizontal. You can click the button on the upper-left corner to open a menu listing all the tabs by name. You can click and drag this button to undock an entire node when it is docking (so you can redock it elsewhere): What should persist:
What doesn't persist on restart:
APIAs pointed out above many operation can be done without any API. (This is not a complete documentation, merely enough to get you started with basic uses. More advanced programmatic manipulation of docking are currently exposed only in imgui_internal.h as There is
Using some combination of flag As with regular window, if you call There is a The There are 2 new demos Picture: This is a dockspace, the upper-right node is the empty document root node
If you have multiple dockspace each behind their own tabs (aka nested tabs), the Tab Bars and TabsThe docking system is in charge of creating tabs, but you can use the tab-bar/tabs system as regular low-level widgets, unrelated to Docking.
API
See the demo under Demo->Layout->Tabs And Demo->Examples Menu->Documents Standalone tab-bars (not part of the docking system) are not currently saving their order/selected persistently. TODOnot an exhaustive list, posted for informative pupose
|
The viewport part does not seem to be working properly on macOS with the glfw_opengl3 example. If I disable |
@Ylannl Thanks! Anything related to viewport please report in the viewport thread #1542 (**edit: for Mac/Linux please report to #2117). By the look of it, it looks like the clipping rectangles are not projected from the global coordinates space to each window’s space. Will have to inspect but last time I tried the glfw+gl demo on Mac OSX it worked for me. Will try again when I have the chance. |
Hey this is great news! Is there a way to set initial position of the docked window? I am looking to have some kind of default placement of newly opened windows. |
Same question. Having ability to setup default layout either by default setting or programmatically will be really helpful. |
All the programmatic stuff are currently hidden in Given EDITED Oct 6: Removed ImGuIContext* ctx parameter You can create an initial layout, e.g.
In order to only call it once you may use e.g.
(Note that I just pushed a fix for DockBuilderSplitNode for a bug I introduced yesterday) |
@Alzathar Interesting! Do you have a retina screen? I do, perhaps that is related? I'm on macOS 10.14 btw, but also noticed this on the viewport branch on macOS 10.13. @ocornut Thanks for the great work on ImGui. I'm very exited about these new features! Sorry for posting in the wrong thread. |
@ocornut creating initial dock layout is clear, but what about setting initial dock placement of new window in already existing layout? Do we have to rebuild entire layout to dock new window into existing layout? |
@rokups You can use If you are building the whole hierarchy you have the ID, otherwise you can use e.g. Another possibility (which I was using in Docking V1) would be to tag node on creation, and being later able to find a dock node id given the tag, The problem is that node that can merged/split by the user. To be able to track through merge we need node to be able to carry multiple tags. Take some time to think about the problem and let me know if you have more ideas. @Alzathar @Ylannl Please move viewport related discussion to the viewport thread. |
@rokups Do you actually want "an empty undocked space" (there can be only one) or do you want the DocRoot node (which happens to be the only node that can be empty, but it might have other windows docking). What would do do if there's already a window in there? |
I think i want "empty undocked space". I tried |
That's exactly what this function does, dock windows. If you believe you are running into an issue try to build a repro.
The DocRoot node (the grey node) is essentially meant to represent that space (If there is an empty node it WILL be the DocRoot node) and it is up to the user to decide where it goes and how big it this. This matches VS behavior, rather than just looking for the "largest docked tab". It also behave differently sizing wise (if you resize your host OS windows you'll find that out). You should probably either use the DocRoot node (which ID is not possible to query yet, haha) or track the current DockID of the LATEST focused document/tool (up to you how to define document/tool) and use this DockID to dock new windows, I think either would make more sense to the user. EDIT You should never have to iterate the dock node hierarchy yourself, but we could provide helper functions to find DockID under different criteria: DocRoot node, largest node, last focused node, dock where a given window is hosted, with or without DockFamily filter, etc. EDIT2: The DocRoot node is now called CentralNode |
great news :D , it works perfectly on windows |
I think you need to add those defines are program-wide defines if you use Mingw. |
Took a bit of work going through the examples to update my application because I hadn't updated imgui in a while but docking and viewport seems to work just fine on OSX High Sierra (10.13.6) SDL2 + OpenGL2. The only slightly unintuitive bit is that I cannot interact with the translate gizmo if the window is undocked (it just drags the whole window) but that's likely my doing. |
@ocornut i created a small testcase of what i attempted. Please take a look. static int initialized = 0;
static int new_window = 0;
ImGuiWindowFlags flags = ImGuiWindowFlags_MenuBar;
flags |= ImGuiWindowFlags_NoDocking;
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::SetNextWindowSize(viewport->Size);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("DockSpace Demo", 0, flags);
ImGui::PopStyleVar();
if (ImGui::BeginMenuBar())
{
if (initialized == 0)
{
if (ImGui::Button("1. Initialize"))
initialized = 1;
}
if (initialized > 0 && new_window == 0)
{
if (ImGui::Button("2. New Window"))
new_window = 1;
}
ImGui::EndMenuBar();
}
ImGuiIO& io = ImGui::GetIO();
ImGuiID dockspace_id = ImGui::GetID("MyDockspace");
if (initialized == 1)
{
initialized = 2;
ImGuiContext* ctx = ImGui::GetCurrentContext();
ImGui::DockBuilderRemoveNode(ctx, dockspace_id); // Clear out existing layout
ImGui::DockBuilderAddNode(ctx, dockspace_id, ImGui::GetMainViewport()->Size); // Add empty node
ImGuiID dock_main_id = dockspace_id; // This variable will track the document node, however we are not using it here as we aren't docking anything into it.
ImGuiID dock_id_prop = ImGui::DockBuilderSplitNode(ctx, dock_main_id, ImGuiDir_Left, 0.20f, NULL, &dock_main_id);
ImGuiID dock_id_bottom = ImGui::DockBuilderSplitNode(ctx, dock_main_id, ImGuiDir_Down, 0.20f, NULL, &dock_main_id);
ImGui::DockBuilderDockWindow(ctx, "Log", dock_id_bottom);
ImGui::DockBuilderDockWindow(ctx, "Properties", dock_id_prop);
ImGui::DockBuilderFinish(ctx, dockspace_id);
}
ImGui::DockSpace(dockspace_id);
if (initialized == 2)
{
ImGui::Begin("Properties");
ImGui::End();
ImGui::Begin("Log");
ImGui::End();
}
if (new_window == 1)
{
// Should dock window to empty space, instead window is not docked anywhere.
ImGui::SetNextWindowDockId(dockspace_id, ImGuiCond_Once);
ImGui::Begin("New Window");
ImGui::End();
}
ImGui::End();
ImGui::PopStyleVar(); Click buttons in the menu bar to 1. initialize default layout and 2. create new window and dock it into empty space. Window is created but not docked anywhere. Do i do it wrong or is this a bug? And another question: is there a way to detect presence of this free undocked space? |
I want to make a dockspace transparent, while windows docked in it should keep their style. I tried many ways, e.g. ImGui::SetNextWindowBgAlpha(0);
ImGui::Begin("DockSpace Demo", 0, flags);
ImGuiID dockspace_id = ImGui::GetID("MyDockspace");
ImGui::DockSpace(dockspace_id);
ImGui::End(); however, all I managed to do is that everything became transparent. Is there a way to this? |
I am working on this right now, it should be available during the day. |
How could I dock visible window and undock it sometime later? |
usa isto ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiID dockspace_id = ImGui::GetID("MyDockspace"); |
Flag: |
@1aam2am1 Please open a separate issue with screenshots/gifs and details, thank you. |
Note the request at the top of this issue:
I'm not sure exactly what you're asking for and it'd probably help if you elaborated on the problem you're trying to solve. My gut says you could maybe use a combination of |
@bbi-yggy I can't speak for Omar, but there's an item on the todo list to merge it into master. |
Please read David’s message and create a new issue and remove duplicate messages here. Github doesn’t handle large threads well.
You can use IsWindowFocused() to tell if a window is focused, and the Begin() return value.
|
Hey, I just setup a DockSpace in my app to have a nice window layout and it works fine. While now trying to set a default layout, your sample code works with one caveat: This example returns NULL / a valid node independent of whether I have a previously changed layout (in the imgui.ini) so each time I start my app the layout gets reset. I'd like to only use my setup routine if the imgui.ini doesn't contain the [Docking][Data] section. Is there a native way to check this or would I need to check this manually by looking at the ini data myself? Kind regards and thank you for making ImGui, |
@irieger Please take note of the notice at the top of this issue:
|
Hi, sorry for leaving a question here, but is it possible to a main window with sub dockable windows inside just like Unreal Engine does? |
As noted in the main issue above, you should not be asking questions in this thread. I understand there's a lot to read there, but I suspect even just skimming over the screenshots would've answered your question. It sounds like what you're looking for is If that's not what you're looking for you should create a separate issue with a clearer example of what you want. |
I have pushed an experimental 'docking' branch:
https://github.com/ocornut/imgui/tree/docking
Effectively providing a long awaited official solution to the features discussed in #351 and #261.
TL;DR; You can benefit from good portion of docking features with no extra work or API call. Windows can be merged with each others, with or without partitioning the space.
Prefer creating separate New Issues for specific questions/issues, so they can more easily be closed when solved and not clutter this thread (which is already too big)
Please do not report issues without reading the 'Feedback' section of the next post and without reading the 'Contributing' document listed in there. The number of ambiguous, ill-formed questions and incomplete bug reports posted on this entire github is difficult to deal with. Thank you.
GIF (this is actually a gif from an older version which has some glitches, but you get the gist!)
Quick demo
You may checkout
docking
and build one the example e.g.example_win32_dx11/
,example_glfw_opengl3
,example_sdl_vulkan
to test this. Head to Demo>Configuration to see the global configuration flags. Note that multi-viewports are enabled by default in those demo but only well tested under Windows. If you have issues with them you can disable them via the Demo>Configuration pane or by commenting out the line that setsImGuiConfigFlags_ViewportsEnable
in the main.cpp of your example. Docking is functional without multi-viewports enabled.The text was updated successfully, but these errors were encountered: