ocornut / imgui

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

Nested table in fixed-width column gets squashed #6586

Open rudolfwalter opened 1 year ago

rudolfwalter commented 1 year ago

Version/Branch of Dear ImGui:

Version: 1.89.7 Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp Compiler: MSVC Operating System: Windows 10

My Issue/Question:

I'm trying to define a somewhat complicated layout using nested tables, and I'm running into a problem.

I want to put a nested table into a fixed-width column of a parent table. My expectation was that the fixed-width column would neatly hug the nested table, just like it does with simple widgets. What happens instead is that the nested table gets squashed to (near-)zero width, at least visually.

Sizing-wise, the nested table still provides a minimum preferred width to the window – ie, in the below example, you can see the length of the label of the checkbox affecting the window if you add the AlwaysAutoResize flag.

Note: I tried this on docking branch versions 1.89.1 and 1.89.7, it happens on both.

Screenshots/Video

Result of the example code below: image

Standalone, minimal, complete and verifiable example:

ImGui::Begin("Bug");
if (ImGui::BeginTable("outer", 2))
{
    ImGui::TableSetupColumn("1", ImGuiTableColumnFlags_WidthFixed);
    ImGui::TableSetupColumn("2");

    ImGui::TableNextColumn();
    if (ImGui::BeginTable("inner", 1))
    {
        ImGui::TableNextColumn();
        bool b = true;
        ImGui::Checkbox("mycheckbox", &b); //BUG: this gets squashed

        ImGui::EndTable();
    }

    ImGui::TableNextColumn();
    ImGui::Text("hello");

    ImGui::EndTable();
}
ImGui::End();
ocornut commented 1 year ago

Hello,

I don't have resources to go in depth into this now, but at lowest-level this is somewhat similar to the cause leading to #6421. Except that here "interestingly" it leads to a secondary issue as not only you are not getting the layout you want, but the checkbox doesn't look clipped at the emitted width bubbled up in a way leading to draw call merge across both tables.

I'm sure there is a solution but it's a rather tricky thing to untangle.

( Random notes for my own records:

In EndTable() if you replace:

outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));

With

outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth);

It will appear to fix your specific issue but has other side-effects. image

I will investigate this eventually, the failing table_reported_size_outer test has a test bed (right-click "Run GUI Func") showcase the problem: image

Here with a "small" window width (the "container"):

I suspect the solution is:

)

rudolfwalter commented 1 year ago

Thank you for all those details!

The change to EndTable() that you suggested does indeed fix this particular issue; however I'm not familiar enough with the internals of dear imgui to be able to imagine what side effects it might have.

The work-around I came up with on my own was to replace the EndTable() of the nested table with the following:

float table_width = ImGui::GetCurrentContext()->CurrentTable->ColumnsAutoFitWidth;
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGui::EndTable();
ImGui::Dummy(ImVec2(table_width, 0));
ImGui::PopStyleVar();

This has the potential advantage of being localized, instead of affecting all tables. (ColumnsAutoFitWidth is private of course, but to me that seems neither better nor worse than patching the source code.)