@ -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 ;
bool moving_toward_other_child_menu = false ;
if ( g . HoveredWindow = = window & & g . OpenPopupStack . Size > g . BeginPopupStack . Size & & g . OpenPopupStack [ g . BeginPopupStack . Size ] . SourceWindow = = window & & ! ( window - > Flags & ImGuiWindowFlags_MenuBar ) )
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 = child_menu_window - > Rect ( ) ;
// FIXME-DPI: Values should be derived from a master "scale" factor.
ImVec2 ta = g . IO . MousePos - g . IO . MouseDelta ;
ImRect next_window_rect = next_window - > Rect ( ) ;
ImVec2 tb = ( window - > Pos . x < child_menu_window - > Pos . x ) ? next_window_rect . GetTL ( ) : next_window_rect . GetTR ( ) ;
ImVec2 ta = g . IO . MousePos - g . IO . MouseDelta ;
ImVec2 tc = ( window - > Pos . x < child_menu_window - > Pos . x ) ? next_window_rect . GetBL ( ) : next_window_rect . GetBR ( ) ;
ImVec2 tb = ( window - > Pos . x < next_window - > Pos . x ) ? next_window_rect . GetTL ( ) : next_window_rect . GetTR ( ) ;
float extra = ImClamp ( ImFabs ( ta . x - tb . x ) * 0.30f , 5.0f , 30.0f ) ; // add a bit of extra slack.
ImVec2 tc = ( window - > Pos . x < next_window - > Pos . x ) ? next_window_rect . GetBL ( ) : next_window_rect . GetBR ( ) ;
ta . x + = ( window - > Pos . x < child_menu_window - > Pos . x ) ? - 0.5f : + 0.5f ; // to avoid numerical issues
float extra = ImClamp ( ImFabs ( ta . x - tb . x ) * 0.30f , 5.0f , 30.0f ) ; // add a bit of extra slack.
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?
ta . x + = ( window - > Pos . x < next_window - > Pos . x ) ? - 0.5f : + 0.5f ; // to avoid numerical issues
tc . y = ta . y + ImMin ( ( tc . y + extra ) - ta . y , + 100.0f ) ;
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?
moving_toward_other_child_menu = ImTriangleContainsPoint ( ta , tb , tc , g . IO . MousePos ) ;
tc . y = ta . y + ImMin ( ( tc . y + extra ) - ta . y , + 100.0f ) ;
//GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
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
}
}
}
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 ) ;
if ( ! menu_is_open & & hovered & & pressed ) // Click to open
want_open = ( ! menu_is_open & & hovered & & ! moving_within_opened_triangle ) | | ( ! menu_is_open & & hovered & & pressed ) ;
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 )
{
{