Menus: adjust closing logic to accomodate for varying font size and dpi + remove seemingly redundant use of g.NavActivateId where pressed was enough.

This commit is contained in:
ocornut 2021-09-03 16:34:38 +02:00
parent 5ee40c8d34
commit 528104a89b
2 changed files with 11 additions and 18 deletions

View File

@ -49,6 +49,7 @@ Other Changes:
to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615) to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615)
- Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when - Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when
the NavEnableSetMousePos config flag is set. the NavEnableSetMousePos config flag is set.
- Menus: adjust closing logic to accomodate for varying font size and dpi.
- PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini] - PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini]
- IO: Added 'io.WantCaptureMouseUnlessPopupClose' alternative to `io.WantCaptureMouse'. (#4480) - IO: Added 'io.WantCaptureMouseUnlessPopupClose' alternative to `io.WantCaptureMouse'. (#4480)
This allows apps to receive the click on void when that click is used to close popup (by default, This allows apps to receive the click on void when that click is used to close popup (by default,

View File

@ -1581,7 +1581,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
bool pressed = ButtonBehavior(bb, id, &hovered, &held); bool pressed = ButtonBehavior(bb, id, &hovered, &held);
const ImGuiID popup_id = ImHashStr("##ComboPopup", 0, id); const ImGuiID popup_id = ImHashStr("##ComboPopup", 0, id);
bool popup_open = IsPopupOpen(popup_id, ImGuiPopupFlags_None); bool popup_open = IsPopupOpen(popup_id, ImGuiPopupFlags_None);
if ((pressed || g.NavActivateId == id) && !popup_open) if (pressed && !popup_open)
{ {
OpenPopupEx(popup_id, ImGuiPopupFlags_None); OpenPopupEx(popup_id, ImGuiPopupFlags_None);
popup_open = true; popup_open = true;
@ -6870,37 +6870,29 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
// Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu // Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_toward_other_child_menu = false; bool moving_toward_other_child_menu = false;
ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL; ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL;
if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar)) if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar))
{ {
// FIXME-DPI: Values should be derived from a master "scale" factor. float ref_unit = g.FontSize; // FIXME-DPI
ImRect next_window_rect = child_menu_window->Rect(); ImRect next_window_rect = child_menu_window->Rect();
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta);
ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // add a bit of extra slack.
ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues (FIXME: ??)
tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +ref_unit * 8.0f);
moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
//GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG] //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_other_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
} }
// FIXME: Hovering a disabled BeginMenu or MenuItem won't close us
if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu) if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
want_close = true; want_close = true;
if (!menu_is_open && hovered && pressed) // Click to open // Open
if (!menu_is_open && pressed) // Click/activate to open
want_open = true; want_open = true;
else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
want_open = true; want_open = true;
if (g.NavActivateId == id)
{
want_close = menu_is_open;
want_open = !menu_is_open;
}
if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
{ {
want_open = true; want_open = true;