@ -729,6 +729,14 @@ static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t)
static inline float ImLengthSqr ( const ImVec2 & lhs ) { return lhs . x * lhs . x + lhs . y * lhs . y ; }
static inline float ImLengthSqr ( const ImVec4 & lhs ) { return lhs . x * lhs . x + lhs . y * lhs . y + lhs . z * lhs . z + lhs . w * lhs . w ; }
static bool ImIsPointInTriangle ( const ImVec2 & p , const ImVec2 & a , const ImVec2 & b , const ImVec2 & c )
{
bool b1 = ( ( p . x - b . x ) * ( a . y - b . y ) - ( p . y - b . y ) * ( a . x - b . x ) ) < 0.0f ;
bool b2 = ( ( p . x - c . x ) * ( b . y - c . y ) - ( p . y - c . y ) * ( b . x - c . x ) ) < 0.0f ;
bool b3 = ( ( p . x - a . x ) * ( c . y - a . y ) - ( p . y - a . y ) * ( c . x - a . x ) ) < 0.0f ;
return ( ( b1 = = b2 ) & & ( b2 = = b3 ) ) ;
}
static int ImStricmp ( const char * str1 , const char * str2 )
{
int d ;
@ -7613,9 +7621,28 @@ bool ImGui::BeginMenu(const char* label)
bool want_open = false ;
if ( window - > Flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu ) )
{
if ( opened & & ! hovered & & g . HoveredWindow = = window & & g . HoveredIdPreviousFrame ! = 0 & & g . HoveredIdPreviousFrame ! = id )
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers so menus feel more reactive.
bool moving_within_opened_triangle = false ;
if ( g . HoveredWindow = = window & & g . OpenedPopupStack . size ( ) > g . CurrentPopupStack . size ( ) & & g . OpenedPopupStack [ g . CurrentPopupStack . size ( ) ] . ParentWindow = = window )
{
if ( ImGuiWindow * next_window = g . OpenedPopupStack [ g . CurrentPopupStack . size ( ) ] . Window )
{
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 ( fabsf ( ta . x - tb . x ) * 0.30f , 5.0f , 30.0f ) ; // add a bit of extra slack. all sizes are hard-coded in pixels, need some sort of pixel-to-window-size ratio for retina-like displays.
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
tc . y = ta . y + ImMin ( ( tc . y + extra ) - ta . y , + 100.0f ) ;
moving_within_opened_triangle = ImIsPointInTriangle ( g . IO . MousePos , ta , tb , tc ) ;
//window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? 0x80008000 : 0x80000080); window->DrawList->PopClipRect(); // Debug
}
}
if ( opened & & ! hovered & & g . HoveredWindow = = window & & g . HoveredIdPreviousFrame ! = 0 & & g . HoveredIdPreviousFrame ! = id & & ! moving_within_opened_triangle )
ClosePopup ( label ) ;
want_open = ( ! opened & & hovered ) ;
want_open = ( ! opened & & hovered & & ! moving_within_opened_triangle ) | | ( ! opened & & hovered & & pressed ) ;
}
else if ( opened & & pressed & & menuset_opened ) // menu-bar: click open menu to close
{