From 64502c1803b871e6c6ec743cb71d67376c769c6b Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Fri, 9 Oct 2026 02:23:48 +0300 Subject: [PATCH] fix(widgets): honor rounded panel padding Apply configured padding to borderless child panels and restore the caller style immediately after child creation. Cover the content origin and style-lifetime contract with a header-only regression test. --- .../widgets/containers/rounded_panel.ipp | 10 ++- ...test_rounded_panel_padding_header_only.cpp | 76 +++++++++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 tests/test_rounded_panel_padding_header_only.cpp diff --git a/include/imguix/widgets/containers/rounded_panel.ipp b/include/imguix/widgets/containers/rounded_panel.ipp index 7f9edd1..ca7deb3 100644 --- a/include/imguix/widgets/containers/rounded_panel.ipp +++ b/include/imguix/widgets/containers/rounded_panel.ipp @@ -344,8 +344,9 @@ namespace ImGuiX::Widgets { rounded_panel_stack().push_back(state); - // Keep the override alive across the whole BeginChild/EndChild pair. - // Nested RoundedPanel calls naturally follow the ImGui style stack. + // WindowPadding configures the child being created. Restore the + // caller's style before rendering content so nested windows and + // popups keep their own theme metrics. ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, padding); @@ -353,12 +354,14 @@ namespace ImGuiX::Widgets { const bool child_open = ImGui::BeginChild( id, panel_size, - ImGuiChildFlags_None, + ImGuiChildFlags_AlwaysUseWindowPadding, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + ImGui::PopStyleVar(); + if (config.clip_mode == RoundedPanelClipMode::CoverCorners && border_thickness > 0.0f) { @@ -413,7 +416,6 @@ namespace ImGuiX::Widgets { } ImGui::EndChild(); - ImGui::PopStyleVar(); ImDrawList* draw_list = ImGui::GetForegroundDrawList(); diff --git a/tests/test_rounded_panel_padding_header_only.cpp b/tests/test_rounded_panel_padding_header_only.cpp new file mode 100644 index 0000000..77bf479 --- /dev/null +++ b/tests/test_rounded_panel_padding_header_only.cpp @@ -0,0 +1,76 @@ +#define IMGUIX_HEADER_ONLY + +#include + +#include + +#include +#include + +namespace { + + bool nearly_equal(const float lhs, const float rhs) { + return std::fabs(lhs - rhs) < 0.01f; + } + +} // namespace + +int main() { + ImGui::CreateContext(); + + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize = ImVec2(640.0f, 480.0f); + io.DeltaTime = 1.0f / 60.0f; + + unsigned char* pixels = nullptr; + int atlas_width = 0; + int atlas_height = 0; + io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height); + + ImGuiStyle& style = ImGui::GetStyle(); + const ImVec2 original_padding = style.WindowPadding; + const ImVec2 panel_padding(18.0f, 16.0f); + + ImGui::NewFrame(); + ImGui::SetNextWindowPos(ImVec2(20.0f, 20.0f)); + ImGui::SetNextWindowSize(ImVec2(400.0f, 300.0f)); + ImGui::Begin("##rounded_panel_padding_test", nullptr, + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize); + + ImGuiX::Widgets::RoundedPanelConfig config; + config.padding = panel_padding; + config.border_thickness = 0.0f; + config.clip_mode = ImGuiX::Widgets::RoundedPanelClipMode::PaddedContent; + + const bool panel_open = + ImGuiX::Widgets::BeginRoundedPanel("##panel", ImVec2(240.0f, 160.0f), config); + const ImVec2 child_position = ImGui::GetWindowPos(); + const ImVec2 content_position = ImGui::GetCursorScreenPos(); + const ImVec2 active_style_padding = style.WindowPadding; + + ImGuiX::Widgets::EndRoundedPanel(); + ImGui::End(); + ImGui::Render(); + + const bool content_uses_requested_padding = + nearly_equal(content_position.x - child_position.x, panel_padding.x) && + nearly_equal(content_position.y - child_position.y, panel_padding.y); + const bool caller_style_restored = nearly_equal(active_style_padding.x, original_padding.x) && + nearly_equal(active_style_padding.y, original_padding.y); + + ImGui::DestroyContext(); + + if (!panel_open) { + std::cerr << "rounded panel child was unexpectedly clipped\n"; + return 1; + } + if (!content_uses_requested_padding) { + std::cerr << "rounded panel did not apply its requested child padding\n"; + return 1; + } + if (!caller_style_restored) { + std::cerr << "rounded panel leaked its child padding into caller content\n"; + return 1; + } + return 0; +}