ocornut / imgui

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

ImGuiWindowFlags_AlwaysAutoResize is ignored for docked windows #6326

Open aardappel opened 1 year ago

aardappel commented 1 year ago

Version/Branch of Dear ImGui:

Version: Today (2023-4-12) Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp Compiler: VS2022 Operating System: Win10

My Issue/Question:

I have ImGuiWindowFlags_AlwaysAutoResize set on my windows, and I just enabled docking, however when docked and the content size changes (due to e.g. changing to a different tab) the docked window stays the same width and all content is clipped.

ocornut commented 1 year ago

Hello,

This has been discussed several times under various forms. IMHO the features are essentially incompatible:

I am curious how you would imagine this to work?

aardappel commented 1 year ago

Sorry, did search for a combination of ImGuiWindowFlags_AlwaysAutoResize and dock / docking on google and github and came up blank.

In my case I just have 1 (or 2) docked windows that are not even touching (i.e. just using docking to allow the user neatly anchor them to the left or right of the screen to their preference), so resizing these would just change their width and wouldn't affect anything else, but I appreciate that in the general case this gets difficult.

+----+--------------------+----+
|    |                    |    |
| W1 |         GAME       | W2 |
|    |                    |    |
+----+--------------------+----+

Currently, instead of docking, W1 is floating and resizing as it needs to.

Surely I can currently programmatically change the size of a docked window, and the docked layout would respond, so it seems it would also be possible to similarly automatically inject that new size. Given that you indicate that this is by default undesirable, it could maybe be a flag for people that have simple layouts like mine:

ImGuiDockNodeFlags_AllowAutoResize  // Warning: this will attempt to change sizes of docked windows automatically if ImGuiWindowFlags_AlwaysAutoResize is set on a window, will likely make layouts jump around if you have many windows docked!

To your points:

ocornut commented 1 year ago

I'm afraid those problems are really difficult to solve.

Does it seem much of a problem that your W1/W2 window needs to be resized once by the user?

Sorry, did search for a combination of ImGuiWindowFlags_AlwaysAutoResize and dock / docking on google and github and came up blank.

I understand it may not be easy to find, at core the problem is: can a window enforce a size in the docking layout. So #6295 #4228 #3363 #2849 #2428 #2386 are essentially a variant of the same thing.

I believe it is desirable to solve this problem for certain uses (e.g. Toolbars, see https://github.com/ocornut/imgui/issues/2648#issuecomment-849741295) but that would probably come with some constraints. I guess it is unlikely we'll go much further than this toolbar proof-of-concept in the current incarnation of Docking, but it is something I will have in mind for Docking V3.

aardappel commented 1 year ago

I'm afraid those problems are really difficult to solve.

That's fine, I can understand it doesn't fit :) Floating windows work ok for our use case, docking would have been icing on the cake :)

Does it seem much of a problem that your W1/W2 window needs to be resized once by the user?

It's not just once. Switch to a different tab and now half of your UI is clipped. Switch back and now your UI contains lots of blank space obscuring your game view unnecessarily. You'd be adjusting all the time, for something ImGui can already do to perfection automatically?

ocornut commented 1 year ago

I agree that if there are specific constraints it should be possible, I’ll keep this in mind.

learn-more commented 7 months ago

For reference, this is how I handle this 'issue' now in a toy 6502 emulator:

void render() override
{
    menu_bar();

    ImGuiID dock = create_dockspace();  // if this returns non-zero, there is no existing dockspace config yet
    ImGuiID left = 0, right = 0, center = 0;
    if (dock)
    {
        ImGuiID tmp;
        ImGui::DockBuilderSplitNode(dock, ImGuiDir_Left, 0.2f, &left, &tmp);
        ImGui::DockBuilderSplitNode(tmp, ImGuiDir_Right, 0.50f, &right, &center);
    }

    if (show_demo)
        ImGui::ShowDemoWindow(&show_demo);

    Registers state = emu.state();

    if (left)
    {
        ImGuiWindowClass cls;
        cls.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoResize;
        ImGui::SetNextWindowClass(&cls);
        ImGui::SetNextWindowDockID(left);
    }
    float width = registers::render(state);
    if (left)
    {
        // Workaround to fake an 'auto-sized' dock node, override the width
        auto dock_node = ImGui::DockBuilderGetNode(left);
        dock_node->Size.x = dock_node->SizeRef.x = width;
    }
    if (right)
        ImGui::SetNextWindowDockID(right);
    memory::render(state.PC, emu.memory());

    if (dock)
        ImGui::DockBuilderFinish(dock);
}

The whole dance with the if (node) etc is to make sure the user can dock/undock after the initial dock nodes are created. The fixed size window returns the size it 'wants', and this is then forced on the dock node.