-
-
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
Seeking help on implementing and saving docking layouts #4033
Comments
I don't know why you would need to do that. ini saving (to disk or text/memory) is where we store data including docking layout so that answers your question. Since 1.77 you should be able to save/load ini data while the session is running. (#2573). It hasn't been exercised very widely, and #3215 seemingly had a problem (which contradicted my own research, suggesting there's another problem lurking ;) but it is something you can investigate. The value returned by
Again this is all handled by the existing saving/loading functions so I would first question why you are not using them.
I'm not sure I understand your question. Your video seems to show a dockspace covering the entire viewport. |
The reason I'm not using the already existing save functionality is that I need to save (and restore) multiple docking layouts (potentially one for each function key). As far as I understood the .ini file feature, it only saves a single layout, and once the layout is locally modified, I can't restore it to a previously saved configuration. Is there an API for saving and restoring multiple layouts? That would be perfect.
Doh! I was looking for that in the examples folder. Found it! The last time I tried, it wasn't possible to force a window to stay in the background. When focused or resized, it became the new foreground window covering other windows behind. Does this behaviour change with Docking? |
…tings API. Related: ocornut#4033
As noted in the issue Omar linked, you can use the settings API for this by managing them manually. I made a quick and dirty test demonstrating it here: PathogenDavid@8de138d Launch Edit: Diff for posterity: diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp
index d6378d80..a6459db1 100644
--- a/examples/example_win32_directx11/main.cpp
+++ b/examples/example_win32_directx11/main.cpp
@@ -6,6 +6,7 @@
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
#include <d3d11.h>
+#include <stdio.h>
#include <tchar.h>
// Data
@@ -14,6 +15,11 @@ static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
static IDXGISwapChain* g_pSwapChain = NULL;
static ID3D11RenderTargetView* g_mainRenderTargetView = NULL;
+#define SAVED_LATYOUT_COUNT 12
+static char* saved_layouts[SAVED_LATYOUT_COUNT];
+static size_t saved_layout_sizes[SAVED_LATYOUT_COUNT];
+static int current_layout = 0;
+
// Forward declarations of helper functions
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
@@ -114,6 +120,41 @@ int main(int, char**)
if (done)
break;
+ // Check if the user requested a layout change
+ unsigned int desired_layout = current_layout;
+ for (unsigned int i = 0; i < IM_ARRAYSIZE(saved_layouts); i++)
+ {
+ unsigned int key_code = VK_F1 + i;
+
+ if (io.KeysDown[key_code])
+ {
+ desired_layout = i;
+ }
+ }
+
+ if (desired_layout != current_layout)
+ {
+ printf("Changing layout F%d -> F%d\n", current_layout + 1, desired_layout + 1);
+
+ // Save the current layout
+ ImGui::MemFree((void*)saved_layouts[current_layout]);
+
+ size_t settings_size = 0;
+ const char* settings = ImGui::SaveIniSettingsToMemory(&settings_size);
+
+ saved_layouts[current_layout] = (char*)ImGui::MemAlloc(settings_size);
+ memcpy(saved_layouts[current_layout], settings, settings_size);
+ saved_layout_sizes[current_layout] = settings_size;
+
+ // Load the requested layout
+ // (Or if there is no layout in that slot, use the current layout for that slot.)
+ current_layout = desired_layout;
+ if (saved_layouts[current_layout] != nullptr)
+ {
+ ImGui::LoadIniSettingsFromMemory(saved_layouts[current_layout]);
+ }
+ }
+
// Start the Dear ImGui frame
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
@@ -175,6 +216,13 @@ int main(int, char**)
}
// Cleanup
+ for (unsigned int i = 0; i < IM_ARRAYSIZE(saved_layouts); i++)
+ {
+ ImGui::MemFree(saved_layouts[i]);
+ saved_layouts[i] = nullptr;
+ saved_layout_sizes[i] = 0;
+ }
+
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(); |
Thanks David, given the valuable example I think you may paste it inline in your message so it is more likely to stay visible for future readers :)
When searching for help I would suggest to always grep within the file system entirely: imgui_demo.cpp(293): if (show_app_dockspace) ShowExampleAppDockSpace(&show_app_dockspace); // Process the Docking app first, as explicit DockSpace() nodes needs to be submitted early (read comments function)
imgui_demo.cpp(294): if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); // Process the Document app next, as it may also use a DockSpace()
imgui_demo.cpp(7461):// Demonstrate using DockSpace() to create an explicit docking node within an existing window.
imgui_demo.cpp(7464):// DockSpace() and DockSpaceOverViewport() are only useful to construct a central docking
imgui_demo.cpp(7503): // When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
imgui_demo.cpp(7509): // This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
imgui_demo.cpp(7527): ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
imgui_demo.cpp(7561): "This demo app only demonstrate the use of ImGui::DockSpace() which allows you to manually create a docking node _within_ another window. This is useful so you can decorate your main (e.g. with a menu bar)." "\n\n"
imgui_demo.cpp(7562): "ImGui::DockSpace() comes with one hard constraint: it needs to be submitted _before_ any window which may be docked into it. Therefore, if you use a dock spot as the central point of ou'll probably want it to be part of the very first window you are submitting to imgui every frame." "\n\n"
imgui_demo.cpp(7563): "(NB: because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node, because that window is submitted as part of the NewFrame() call. An that you can create your own implicit \"Debug##2\" window after calling DockSpace() and leave it in the window stack for anyone to use.)"
imgui_demo.cpp(7794): ImGui::DockSpace(dockspace_id); Please note that There's also a function
The aforementioned example use |
@PathogenDavid thank your for the example. I think, I can manage from here.
I am really sorry. I appreciate that your taking this time. Maybe rephrasing... "There are 2 new demos: Demo Window → Examples → Documents" into something like "The application menu of demo.cpp now includes two new examples" would help inattentive people like me. |
Thanks Thomas. It's ok and it's good that we have some redundancy and extra cross-links and references on the GitHub, your questions are useful.
As mentioned in #3215 it is possible you'll run into issues (which I couldn't repro). If you do and you think they are related you can comment in #3215. Some tangential notes:
|
Done 76902c4 |
One more note on documentation: I would personally prefer links/lists to useful references/issues/examples over incomplete wiki-pages like this one. Even though it spent many hours (trying to) reading the available documentation and examples, I'm always surprised how much is already possible with ImGui. Often things are not really evident to me (e.g. that there is an layout API for ini-files). And I struggle with questions of "is it possible" more frequently than "how is possible". Crosslinking the documentation would really help me a lot. |
@ocornut I never delete branches, but not a bad idea. I added a diff for posterity.
@pixtur No problem, glad I could help!
To be fair this isn't really the original intended purpose of these functions, but yeah it'd probably be helpful if the settings section of |
Version/Branch of Dear ImGui:
Version: 1.78
Branch: docking
Back-end/Renderer/Compiler/OS
Back-ends: imgui.et
Compiler: c# / .net
Operating System: win10
My Issue/Question:
In our application users can customize, save, and switch between different window layouts with the function keys. Since docking is now available in imgui.net I wanted to replace this early implementation with a proper window docking. The integration of the basic docking functionality worked great. I then tried to read the API description in #2109, the glossary and the wiki. I also tried to wrap my head around the API description in imgui.h but it seems to be missing some detail.
I'm looking for advice, documentation or example code on the following topics:
ImGui.SetNextWindowDockID()
to attach a window to another DockingSpace, but I callingImGui.GetWindowDockID()
didn't yield into an ID that I can use with that method. How would i be able to also set things like splitting directions and child order?Screenshots/Video
This is how our layout systems looks currently:
T3.ImGui.Test.2021-04-10.17-45-40.mp4
The text was updated successfully, but these errors were encountered: