Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible area (e.g. when window is collapsed and moved in a corner)to facilitate moving the window away. (#3825)

This commit is contained in:
ocornut
2021-02-18 17:21:12 +01:00
parent 0ecdf8167c
commit a8f76c23a4
3 changed files with 16 additions and 5 deletions

View File

@ -782,22 +782,30 @@ bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
}
// Button to close a window
bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size)
bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
// We intentionally allow interaction when clipped so that a mechanical Alt,Right,Validate sequence close a window.
// (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible).
// Tweak 1: Shrink hit-testing area if button covers an abnormally large proportion of the visible region. That's in order to facilitate moving the window away. (#3825)
// This may better be applied as a general hit-rect reduction mechanism for all widgets to ensure the area to move window is always accessible?
const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
bool is_clipped = !ItemAdd(bb, id);
ImRect bb_interact = bb;
const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea();
if (area_to_visible_ratio < 1.5f)
bb_interact.Expand(ImFloor(bb_interact.GetSize() * -0.25f));
// Tweak 2: We intentionally allow interaction when clipped so that a mechanical Alt,Right,Activate sequence can always close a window.
// (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible).
bool is_clipped = !ItemAdd(bb_interact, id);
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
bool pressed = ButtonBehavior(bb_interact, id, &hovered, &held);
if (is_clipped)
return pressed;
// Render
// FIXME: Clarify this mess
ImU32 col = GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered);
ImVec2 center = bb.GetCenter();
if (hovered)