Skip to content
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

ImGuiChildFlags_ResizeX/ImGuiChildFlags_ResizeY dont render a "grab border", if the window is rendered with ImGuiWindowFlags_NoBackground #7194

Closed
firesgc opened this issue Jan 3, 2024 · 5 comments

Comments

@firesgc
Copy link

firesgc commented Jan 3, 2024

Hi!

I render my child windows with ImGuiWindowFlags_NoBackground, and for this reason, I don't see the resizing borders.
I have modified the static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) function like this:

static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
{
    ImGuiContext& g = *GImGui;
    float rounding = window->WindowRounding;
    float border_size = window->WindowBorderSize;
    if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
        window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);

    if (window->ChildFlags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY))
    {
        int resize_border_mask = 0x00;
        if (window->Flags & ImGuiWindowFlags_ChildWindow)
            resize_border_mask |= ((window->ChildFlags & ImGuiChildFlags_ResizeX) ? 0x02 : 0) | ((window->ChildFlags & ImGuiChildFlags_ResizeY) ? 0x08 : 0);
        else
            resize_border_mask = g.IO.ConfigWindowsResizeFromEdges ? 0x0F : 0x00;
        for (int border_n = 0; border_n < 4; border_n++)
        {
            if ((resize_border_mask & (1 << border_n)) == 0)
                continue;

            const ImGuiResizeBorderDef& def = resize_border_def[border_n];
            const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f);
            const ImU32 border_col = GetColorU32(ImGuiCol_Separator);
            window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle);
            window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f);
            window->DrawList->PathStroke(border_col, 0, ImMax(2.0f, border_size)); // Thicker than usual
        }
    }
....

Is there a better solution to fix the issue without modifying ImGui directly? I don't want to "port" my fix with each new release.

Thank you for the awesome library!

@ocornut
Copy link
Owner

ocornut commented Jan 4, 2024

For normal windows ImGuiWindowFlags_NoBackground hide the four outer borders, which seems to make sense.

I am not sure what ImGuiWindowFlags_NoBackground would mean for Child Windows, this was never properly specced/defined.
The borders both serve as a delimiter in the parent window, and are specified separately via ImGuiChildFlags_Border, so they are special in some way and we could decide that _NoBackground would still show the border of child windows, but it would also make it a bit inconsistent.

Why not using SetNextWindowBgAlpha(0.0f) or PushStyleColor(ImGuiCol_WindowBg, 0) prior to BeginChild() ?

@firesgc
Copy link
Author

firesgc commented Jan 4, 2024

Thanks for the hint!

SetNextWindowBgAlpha() works, but my "workaround" will draw only a line on the side that is sizable. So, from a visual point of view/user expierence, it's easier to understand and looks cleaner.

SetNextWindowBgAlpha:
OldWay

Drawing the lines in RenderWindowOuterBorders:
NewWay

If it isn't easy to solve, I will probably just modify the function with each update. It isn't a big deal; I just wanted to know if I can achieve the same without modifying the library.

@ocornut
Copy link
Owner

ocornut commented Jan 4, 2024

You are right it makes a difference, I think we can work toward this change.
Why using ImGuiCol_Separator and not ImGuiCol_Border ? it seems inconsistent. I would use _Border here. That's how the child border is normally displayed (AddRect call above).

ocornut added a commit that referenced this issue Jan 4, 2024
@ocornut
Copy link
Owner

ocornut commented Jan 4, 2024

I have a pushed a fix for this a1b0682

Contrary to your code I am using regular border size (pulled via style.ChildBorderSize) and ImGuiCol_Border because that's more consistent. To get exactly the effect you have with your mod you may need to increase the size and alter color to match separator.

The distinction between Borders and Separators is tricky/ambiguous, as evidently using child resize flags is a convenient way to replace a separator.

@ocornut ocornut closed this as completed Jan 4, 2024
@firesgc
Copy link
Author

firesgc commented Jan 5, 2024

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants