From a1b06823fe2d964a62fda99385499b218cf5cea5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 4 Jan 2024 17:23:30 +0100 Subject: [PATCH] Windows: BeginChild(): Resize borders rendered even when ImGuiWindowFlags_NoBackground is specified. (#1710, #7194) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 36 ++++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 12e437ac9..2369ea326 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,8 @@ Other changes: - Windows: BeginChild(): Fixed auto-resizing erroneously limiting size to host viewport minus padding. There are no limit to a child width/height. (#7063) [@Devyre] +- Windows: BeginChild(): Resize borders rendered even when ImGuiWindowFlags_NoBackground + is specified. (#1710, #7194) - Windows: Fixed some auto-resizing path using style.WindowMinSize.x (instead of x/y) for both axises since 1.90. (#7106) [@n0bodysec] - Scrolling: internal scrolling value is rounded instead of truncated, as a way to reduce diff --git a/imgui.cpp b/imgui.cpp index f5dc8f02f..11cdce207 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6082,28 +6082,40 @@ static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_ window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max); } +static void RenderWindowOuterSingleBorder(ImGuiWindow* window, int border_n, ImU32 border_col, float border_size) +{ + const ImGuiResizeBorderDef& def = resize_border_def[border_n]; + const float rounding = window->WindowRounding; + const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f); + 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, ImDrawFlags_None, border_size); +} + 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); - + const float border_size = window->WindowBorderSize; + const ImU32 border_col = GetColorU32(ImGuiCol_Border); + if (border_size > 0.0f && (window->Flags & ImGuiWindowFlags_NoBackground) == 0) + window->DrawList->AddRect(window->Pos, window->Pos + window->Size, border_col, window->WindowRounding, 0, window->WindowBorderSize); + else if (border_size > 0.0f) + { + if (window->ChildFlags & ImGuiChildFlags_ResizeX) // Similar code as 'resize_border_mask' computation in UpdateWindowManualResize() but we specifically only always draw explicit child resize border. + RenderWindowOuterSingleBorder(window, 1, border_col, border_size); + if (window->ChildFlags & ImGuiChildFlags_ResizeY) + RenderWindowOuterSingleBorder(window, 3, border_col, border_size); + } if (window->ResizeBorderHovered != -1 || window->ResizeBorderHeld != -1) { const int border_n = (window->ResizeBorderHeld != -1) ? window->ResizeBorderHeld : window->ResizeBorderHovered; - const ImGuiResizeBorderDef& def = resize_border_def[border_n]; - const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f); - const ImU32 border_col = GetColorU32((window->ResizeBorderHeld != -1) ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered); - 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 + const ImU32 border_col_resizing = GetColorU32((window->ResizeBorderHeld != -1) ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered); + RenderWindowOuterSingleBorder(window, border_n, border_col_resizing, ImMax(2.0f, window->WindowBorderSize)); // Thicker than usual } if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) { float y = window->Pos.y + window->TitleBarHeight() - 1; - window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize); + window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), border_col, g.Style.FrameBorderSize); } }