Windows: add resize grips for child windows with both ResizeX+ResizeY. Amends. (#8501)

This commit is contained in:
ocornut
2025-09-23 16:54:59 +02:00
parent 82e9a5e47d
commit e1aea42e45
2 changed files with 17 additions and 18 deletions

View File

@@ -43,6 +43,9 @@ Breaking Changes:
Other Changes:
- Windows: added lower-right resize grip on child windows using both
ImGuiChildFlags_ResizeX and ImGuiChildFlags_ResizeY flags. (#8501) [@aleksijuvani]
The grip is not visible before hovering to reduce clutter.
- IO: added ImGuiPlatformIO::ClearPlatformHandlers(), ClearRendererHandlers()
helpers to null all handlers. (#8945, #2769)
- Misc: Debuggers: added type formatters for the LLDB debuggers (e.g. Xcode,

View File

@@ -6647,18 +6647,19 @@ static ImGuiCol GetWindowBgColorIdx(ImGuiWindow* window)
return ImGuiCol_WindowBg;
}
static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, ImVec2 corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size)
static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target_arg, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size)
{
ImVec2 corner_target = corner_target_arg;
if (window->Flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
{
ImGuiWindow* parent_window = window->ParentWindow;
ImGuiWindowFlags parent_flags = parent_window->Flags;
ImRect corner_limit_rect = parent_window->InnerRect;
corner_limit_rect.Expand(ImVec2(-ImMax(parent_window->WindowPadding.x, parent_window->WindowBorderSize), -ImMax(parent_window->WindowPadding.y, parent_window->WindowBorderSize)));
ImRect limit_rect = parent_window->InnerRect;
limit_rect.Expand(ImVec2(-ImMax(parent_window->WindowPadding.x, parent_window->WindowBorderSize), -ImMax(parent_window->WindowPadding.y, parent_window->WindowBorderSize)));
if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar))
corner_target.x = ImClamp(corner_target.x, corner_limit_rect.Min.x, corner_limit_rect.Max.x);
corner_target.x = ImClamp(corner_target.x, limit_rect.Min.x, limit_rect.Max.x);
if (parent_flags & ImGuiWindowFlags_NoScrollbar)
corner_target.y = ImClamp(corner_target.y, corner_limit_rect.Min.y, corner_limit_rect.Max.y);
corner_target.y = ImClamp(corner_target.y, limit_rect.Min.y, limit_rect.Max.y);
}
ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left
ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right
@@ -6804,7 +6805,8 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
}
// Only lower-left grip is visible before hovering/activating
if (resize_grip_n == 0 || held || hovered)
const bool resize_grip_visible = held || hovered || (resize_grip_n == 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0);
if (resize_grip_visible)
resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
}
@@ -7655,21 +7657,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
handle_borders_and_resize_grips = false;
// Handle manual resize: Resize Grips, Borders, Gamepad
// Child windows can only be resized when they have the flags set. The resize grip allows resizing in both directions, so it should appear only if both flags are set.
int border_hovered = -1, border_held = -1;
ImU32 resize_grip_col[4] = {};
int resize_grip_count;
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) {
// Child windows can only be resized when they have the flags set. The resize grip allows resizing in both directions, so it should appear only if both flags are set.
if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY)) {
resize_grip_count = 1; // Child windows can only be resized in the layout direction, that is rightwards and downwards.
}
else {
resize_grip_count = 0;
}
}
else {
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
resize_grip_count = ((window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY)) ? 1 : 0;
else
resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
}
const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
if (handle_borders_and_resize_grips && !window->Collapsed)
if (int auto_fit_mask = UpdateWindowManualResize(window, size_auto_fit, &border_hovered, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))