@ -656,7 +656,7 @@ static ImRect GetVisibleRect();
static void CloseInactivePopups ( ImGuiWindow * ref_window ) ;
static void ClosePopupToLevel ( int remaining ) ;
static ImGuiWindow * GetFrontMostModalRootWindow ( ) ;
static ImVec2 FindBestPopupWindowPos ( const ImVec2 & base_pos , const ImVec2 & size , int * last_dir , const ImRect & rect_to_avoid ) ;
static ImVec2 FindBestPopupWindowPos ( const ImVec2 & base_pos , const ImVec2 & size , ImGuiDir * last_dir , const ImRect & rect_to_avoid ) ;
static bool InputTextFilterCharacter ( unsigned int * p_char , ImGuiInputTextFlags flags , ImGuiTextEditCallback callback , void * user_data ) ;
static int InputTextCalcTextLenAndLineCount ( const char * text_begin , const char * * out_text_end ) ;
@ -1845,7 +1845,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
AutoFitFramesX = AutoFitFramesY = - 1 ;
AutoFitOnlyGrows = false ;
AutoFitChildAxises = 0x00 ;
AutoPosLastDirection = - 1 ;
AutoPosLastDirection = ImGuiDir_None ;
HiddenFrames = 0 ;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing ;
SetWindowPosVal = SetWindowPosPivot = ImVec2 ( FLT_MAX , FLT_MAX ) ;
@ -4017,28 +4017,39 @@ static void CheckStacksSize(ImGuiWindow* window, bool write)
IM_ASSERT ( p_backup = = window - > DC . StackSizesBackup + IM_ARRAYSIZE ( window - > DC . StackSizesBackup ) ) ;
}
static ImVec2 FindBestPopupWindowPos ( const ImVec2 & base_pos , const ImVec2 & size , int * last_dir , const ImRect & r_inner )
static ImVec2 FindBestPopupWindowPos ( const ImVec2 & base_pos , const ImVec2 & size , ImGuiDir * last_dir , const ImRect & r_avoid )
{
const ImGuiStyle & style = GImGui - > Style ;
// Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it.
// r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.)
// r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it.
ImVec2 safe_padding = style . DisplaySafeAreaPadding ;
ImRect r_outer ( GetVisibleRect ( ) ) ;
r_outer . Expand ( ImVec2 ( ( size . x - r_outer . GetWidth ( ) > safe_padding . x * 2 ) ? - safe_padding . x : 0.0f , ( size . y - r_outer . GetHeight ( ) > safe_padding . y * 2 ) ? - safe_padding . y : 0.0f ) ) ;
ImVec2 base_pos_clamped = ImClamp ( base_pos , r_outer . Min , r_outer . Max - size ) ;
//GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
//GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
for ( int n = ( * last_dir ! = - 1 ) ? - 1 : 0 ; n < 4 ; n + + ) // Last, Right, down, up, left. (Favor last used direction).
const ImGuiDir dir_prefered_order [ ImGuiDir_Count_ ] = { ImGuiDir_Right , ImGuiDir_Down , ImGuiDir_Up , ImGuiDir_Left } ;
for ( int n = ( * last_dir ! = ImGuiDir_None ) ? - 1 : 0 ; n < ImGuiDir_Count_ ; n + + )
{
const int dir = ( n = = - 1 ) ? * last_dir : n;
ImRect rect ( dir = = 0 ? r_inner . Max . x : r_outer . Min . x , dir = = 1 ? r_inner . Max . y : r_outer . Min . y , dir = = 3 ? r_inner . Min . x : r_outer . Max . x , dir = = 2 ? r_inner . Min . y : r_outer . Max . y ) ;
if ( rect. GetWidth ( ) < size . x | | rect . GetHeight ( ) < size . y )
const ImGuiDir dir = ( n = = - 1 ) ? * last_dir : dir_prefered_order[ n] ;
float avail_w = ( dir = = ImGuiDir_Left ? r_avoid . Min . x : r_outer . Max . x ) - ( dir = = ImGuiDir_Right ? r_avoid . Max . x : r_outer . Min . x ) ;
if ( avail_w < size . x )
continue ;
float avail_h = ( dir = = ImGuiDir_Down ? r_avoid . Min . y : r_outer . Max . y ) - ( dir = = ImGuiDir_Down ? r_avoid . Max . y : r_outer . Min . y ) ;
if ( avail_h < size . y )
continue ;
ImVec2 pos ;
pos . x = ( dir = = ImGuiDir_Left ) ? r_avoid . Min . x - size . x : ( dir = = ImGuiDir_Right ) ? r_avoid . Max . x : base_pos_clamped . x ;
pos . y = ( dir = = ImGuiDir_Up ) ? r_avoid . Min . y - size . y : ( dir = = ImGuiDir_Down ) ? r_avoid . Max . y : base_pos_clamped . y ;
* last_dir = dir ;
return ImVec2 ( dir = = 0 ? r_inner . Max . x : dir = = 3 ? r_inner . Min . x - size . x : base_pos_clamped . x , dir = = 1 ? r_inner . Max . y : dir = = 2 ? r_inner . Min . y - size . y : base_pos_clamped . y ) ;
return pos;
}
// Fallback, try to keep within display
* last_dir = - 1 ;
* last_dir = ImGuiDir_None ;
ImVec2 pos = base_pos ;
pos . x = ImMax ( ImMin ( pos . x + size . x , r_outer . Max . x ) - size . x , r_outer . Min . x ) ;
pos . y = ImMax ( ImMin ( pos . y + size . y , r_outer . Max . y ) - size . y , r_outer . Min . y ) ;
@ -4382,7 +4393,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if ( window_just_activated_by_user )
{
// Popup first latch mouse position, will position itself when it appears next frame
window - > AutoPosLastDirection = - 1 ;
window - > AutoPosLastDirection = ImGuiDir_None ;
if ( ( flags & ImGuiWindowFlags_Popup ) ! = 0 & & ! window_pos_set_by_api )
window - > PosFloat = g . IO . MousePos ;
}
@ -4523,9 +4534,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if ( ( flags & ImGuiWindowFlags_Tooltip ) ! = 0 & & ! window_pos_set_by_api )
{
ImVec2 ref_pos = g . IO . MousePos ;
ImRect rect_to_avoid ( ref_pos . x - 16 , ref_pos . y - 8 , ref_pos . x + 24 , ref_pos . y + 24 ) ; // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead ?
ImRect rect_to_avoid ( ref_pos . x - 16 , ref_pos . y - 8 , ref_pos . x + 24 , ref_pos . y + 24 ) ; // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point ?
window - > PosFloat = FindBestPopupWindowPos ( ref_pos , window - > Size , & window - > AutoPosLastDirection , rect_to_avoid ) ;
if ( window - > AutoPosLastDirection = = - 1 )
if ( window - > AutoPosLastDirection = = ImGuiDir_None )
window - > PosFloat = ref_pos + ImVec2 ( 2 , 2 ) ; // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
}