|
@@ -5947,31 +5947,36 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
if (menuset_is_open)
|
|
if (menuset_is_open)
|
|
g.NavWindow = backed_nav_window;
|
|
g.NavWindow = backed_nav_window;
|
|
|
|
|
|
- bool want_open = false, want_close = false;
|
|
|
|
|
|
+ bool want_open = false;
|
|
|
|
+ bool want_close = false;
|
|
if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
|
if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
|
{
|
|
{
|
|
|
|
+ // 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_within_opened_triangle = false;
|
|
|
|
- if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
|
|
|
|
|
+ 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;
|
|
|
|
+ if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
|
{
|
|
{
|
|
- if (ImGuiWindow* next_window = g.OpenPopupStack[g.BeginPopupStack.Size].Window)
|
|
|
|
- {
|
|
|
|
- // FIXME-DPI: Values should be derived from a master "scale" factor.
|
|
|
|
- ImRect next_window_rect = next_window->Rect();
|
|
|
|
- ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
|
|
|
|
- ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
|
|
|
|
- ImVec2 tc = (window->Pos.x < next_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.
|
|
|
|
- ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
|
|
|
|
- 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?
|
|
|
|
- tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
|
|
|
|
- moving_within_opened_triangle = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
|
|
|
|
- //window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); window->DrawList->PopClipRect(); // Debug
|
|
|
|
- }
|
|
|
|
|
|
+ // FIXME-DPI: Values should be derived from a master "scale" factor.
|
|
|
|
+ ImRect next_window_rect = child_menu_window->Rect();
|
|
|
|
+ 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 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.
|
|
|
|
+ ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
|
|
|
|
+ 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?
|
|
|
|
+ tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
|
|
|
|
+ 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]
|
|
}
|
|
}
|
|
|
|
+ if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
|
|
|
|
+ want_close = true;
|
|
|
|
|
|
- want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
|
|
|
|
- want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
|
|
|
|
|
|
+ if (!menu_is_open && hovered && pressed) // Click to open
|
|
|
|
+ want_open = true;
|
|
|
|
+ else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
|
|
|
|
+ want_open = true;
|
|
|
|
|
|
if (g.NavActivateId == id)
|
|
if (g.NavActivateId == id)
|
|
{
|
|
{
|