ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.01k stars 10.28k forks source link

With Docking enabled, Docked windows do not respect ImGuiWindow_NoResize #3363

Open P-Squiddy opened 4 years ago

P-Squiddy commented 4 years ago
Dear ImGui 1.78 WIP (17703)
--------------------------------
sizeof(size_t): 4, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _MSC_VER=1800
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx11
io.ConfigFlags: 0x0000C441
 NavEnableKeyboard
 DockingEnable
 ViewportsEnable
 DpiEnableScaleViewports
 DpiEnableScaleFonts
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigWindowsMemoryCompactTimer = 60.0f
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1264.00,761.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Using the Win32 backend with D3D11, if I set a window as ImGuiWindowFlags_NoResize, then Dock any window inside of it, the window is resizable, regardless of the docked windows state. I tried to set ImGuiDockNodeFlags_NoResize as well, but it didn't affect it.

if this is expected behavior, is there a workaround for this?

https://drive.google.com/file/d/1l7BCIhMzcCYCVzfUJvTom53Z_hPlIpku/view?usp=sharing

{
    static float f = 0.0f;
    static int counter = 0;

    ImGui::Begin("Hello, world!",NULL, ImGuiWindowFlags_NoResize);                          // Create a window called "Hello, world!" and append into it.

    ImGui::Text("This is some useful text.");               // Display some text (you can use a format strings too)
    ImGui::Checkbox("Demo Window", &show_demo_window);      // Edit bools storing our window open/close state
    ImGui::Checkbox("Another Window", &show_another_window);

    ImGui::SliderFloat("float", &f, 0.0f, 1.0f);            // Edit 1 float using a slider from 0.0f to 1.0f
    ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color

    if (ImGui::Button("Button"))                            // Buttons return true when clicked (most widgets return true when edited/activated)
        counter++;
    ImGui::SameLine();
    ImGui::Text("counter = %d", counter);

    ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
    ImGui::End();
}

// 3. Show another simple window.
if (show_another_window)
{
    ImGui::Begin("Another Window", &show_another_window);   // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
    ImGui::Text("Hello from another window!");
    if (ImGui::Button("Close Me"))
        show_another_window = false;
    ImGui::End();
}
ocornut commented 4 years ago

Constraining sizes is kind of conflicting with lots of the functionality of Docking, see #2849, #2690, #2428 (probably more threads).

What do you expect should be the desirable behavior in your example? I honestly don't know the answer. If _NoResize was affecting all touching nodes it would be a severe constraints which I believe lots of people would treat an as issue (it could essentially lock down resizing an entire dock tree).

We would need something along those lines to get e.g. Toolbars to work, but it opens lots of questions e.g.

It's a rather wide and open problem. Additionally, it would be useful if you could describe your specific use case in concrete term.

P-Squiddy commented 4 years ago

My expected behavior would be that if object B is docked inside object A, and object A has specified that it should NOT resize, object B should "inherit" that behavior (regardless of where the dock occurs).

In this case, I assume that since I've explicitly told ImGui I did not want to be able to resize object A, everything attached to that should follow the same constraints -- especially if the position to where it is docked is a Tab, vs Separation (i.e. docked in the middle square, vs North, South, East, West). The dock then becomes the template regarding widths/heights. As it is now, I can resize object B to be, say, 2x larger than the object it's going to be docked within, and the dock will shrink it to that space. If i then undock object B, object B does not return to its pre-docked size of 2x larger.

I could also see it being beneficial to be able to tell object A it couldn't resize, but tell object B that it COULD (explicitly) which would create a behavior where you could resize ONLY the "resizable portion", while leaving the other portions the same size.

My rational for this being that I, the programmer, told ImGui I did (or did not) want something (explicitly), therefore it is my responsibility to create something that adheres to that.

P-Squiddy commented 4 years ago

Perhaps a solution to this is either if the dock itself is marked _NoSize, it is not resizable (meaning that you mark a node as being the dock), or if all the windows in a dock are marked _NoSize, it is not resizable.

I believe this could work if you could explicitly create a dock, opposed to every window is potentially a dock.