@ -2538,11 +2538,9 @@ void ImGuiStorage::SetInt(ImGuiID key, int val)
{
ImGuiStoragePair * it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
{
Data . insert ( it , ImGuiStoragePair ( key , val ) ) ;
return ;
}
it - > val_i = val ;
else
it - > val_i = val ;
}
void ImGuiStorage : : SetBool ( ImGuiID key , bool val )
@ -2554,22 +2552,18 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
{
ImGuiStoragePair * it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
{
Data . insert ( it , ImGuiStoragePair ( key , val ) ) ;
return ;
}
it - > val_f = val ;
else
it - > val_f = val ;
}
void ImGuiStorage : : SetVoidPtr ( ImGuiID key , void * val )
{
ImGuiStoragePair * it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
{
Data . insert ( it , ImGuiStoragePair ( key , val ) ) ;
return ;
}
it - > val_p = val ;
else
it - > val_p = val ;
}
void ImGuiStorage : : SetAllInt ( int v )
@ -4098,13 +4092,21 @@ bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flag
static inline float CalcDelayFromHoveredFlags ( ImGuiHoveredFlags flags )
{
ImGuiContext & g = * GImGui ;
if ( flags & ImGuiHoveredFlags_DelayShort )
return g . Style . HoverDelayShort ;
if ( flags & ImGuiHoveredFlags_DelayNormal )
return g . Style . HoverDelayNormal ;
if ( flags & ImGuiHoveredFlags_DelayShort )
return g . Style . HoverDelayShort ;
return 0.0f ;
}
static ImGuiHoveredFlags ApplyHoverFlagsForTooltip ( ImGuiHoveredFlags user_flags , ImGuiHoveredFlags shared_flags )
{
// Allow instance flags to override shared flags
if ( user_flags & ( ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal ) )
shared_flags & = ~ ( ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal ) ;
return user_flags | shared_flags ;
}
// This is roughly matching the behavior of internal-facing ItemHoverable()
// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
// - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
@ -4122,7 +4124,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false ;
if ( flags & ImGuiHoveredFlags_ForTooltip )
flags | = g . Style . HoverFlagsForTooltipNav ;
flags = ApplyHoverFlagsForTooltip ( flags , g . Style . HoverFlagsForTooltipNav ) ;
}
else
{
@ -4132,7 +4134,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false ;
if ( flags & ImGuiHoveredFlags_ForTooltip )
flags | = g . Style . HoverFlagsForTooltipMouse ;
flags = ApplyHoverFlagsForTooltip ( flags , g . Style . HoverFlagsForTooltipMouse ) ;
IM_ASSERT ( ( flags & ( ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy ) ) = = 0 ) ; // Flags not supported by this function
@ -5686,18 +5688,28 @@ ImVec2 ImGui::GetItemRectSize()
return g . LastItemData . Rect . GetSize ( ) ;
}
bool ImGui : : BeginChildEx ( const char * name , ImGuiID id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags flags )
bool ImGui : : BeginChild ( const char * str_id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags window_flags )
{
ImGuiID id = GetCurrentWindow ( ) - > GetID ( str_id ) ;
return BeginChildEx ( str_id , id , size_arg , border , window_flags ) ;
}
bool ImGui : : BeginChild ( ImGuiID id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags window_flags )
{
IM_ASSERT ( id ! = 0 ) ;
return BeginChildEx ( NULL , id , size_arg , border , window_flags ) ;
}
bool ImGui : : BeginChildEx ( const char * name , ImGuiID id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags window_flags )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * parent_window = g . CurrentWindow ;
flags | = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking ;
flags | = ( parent_window - > Flags & ImGuiWindowFlags_NoMove ) ; // Inherit the NoMove flag
window_flags | = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking ;
window_flags | = ( parent_window - > Flags & ImGuiWindowFlags_NoMove ) ; // Inherit the NoMove flag
// Size
const ImVec2 content_avail = GetContentRegionAvail ( ) ;
ImVec2 size = ImTrunc ( size_arg ) ;
const int auto_fit_axises = ( ( size . x = = 0.0f ) ? ( 1 < < ImGuiAxis_X ) : 0x00 ) | ( ( size . y = = 0.0f ) ? ( 1 < < ImGuiAxis_Y ) : 0x00 ) ;
if ( size . x < = 0.0f )
size . x = ImMax ( content_avail . x + size . x , 4.0f ) ; // Arbitrary minimum child size (0.0f causing too many issues)
if ( size . y < = 0.0f )
@ -5714,12 +5726,13 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
const float backup_border_size = g . Style . ChildBorderSize ;
if ( ! border )
g . Style . ChildBorderSize = 0.0f ;
bool ret = Begin ( temp_window_name , NULL , flags ) ;
// Begin into window
const bool ret = Begin ( temp_window_name , NULL , window_flags ) ;
g . Style . ChildBorderSize = backup_border_size ;
ImGuiWindow * child_window = g . CurrentWindow ;
child_window - > ChildId = id ;
child_window - > AutoFitChildAxises = ( ImS8 ) auto_fit_axises ;
// Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
// While this is not really documented/defined, it seems that the expected thing to do.
@ -5727,11 +5740,11 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
parent_window - > DC . CursorPos = child_window - > Pos ;
// Process navigation-in immediately so NavInit can run on first frame
// Can enter a child if (A) it has navigata ble items or (B) it can be scrolled.
// Can enter a child if (A) it has navigable items or (B) it can be scrolled.
const ImGuiID temp_id_for_activation = ImHashStr ( " ##Child " , 0 , id ) ;
if ( g . ActiveId = = temp_id_for_activation )
ClearActiveID ( ) ;
if ( g . NavActivateId = = id & & ! ( flags & ImGuiWindowFlags_NavFlattened ) & & ( child_window - > DC . NavLayersActiveMask ! = 0 | | child_window - > DC . NavWindowHasScrollY ) )
if ( g . NavActivateId = = id & & ! ( window_ flags & ImGuiWindowFlags_NavFlattened ) & & ( child_window - > DC . NavLayersActiveMask ! = 0 | | child_window - > DC . NavWindowHasScrollY ) )
{
FocusWindow ( child_window ) ;
NavInitWindow ( child_window , false ) ;
@ -5741,50 +5754,29 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
return ret ;
}
bool ImGui : : BeginChild ( const char * str_id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags extra_flags )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
return BeginChildEx ( str_id , window - > GetID ( str_id ) , size_arg , border , extra_flags ) ;
}
bool ImGui : : BeginChild ( ImGuiID id , const ImVec2 & size_arg , bool border , ImGuiWindowFlags extra_flags )
{
IM_ASSERT ( id ! = 0 ) ;
return BeginChildEx ( NULL , id , size_arg , border , extra_flags ) ;
}
void ImGui : : EndChild ( )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
ImGuiWindow * child_window = g . CurrentWindow ;
IM_ASSERT ( g . WithinEndChild = = false ) ;
IM_ASSERT ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ; // Mismatched BeginChild()/EndChild() calls
IM_ASSERT ( child_window - > Flags & ImGuiWindowFlags_ChildWindow ) ; // Mismatched BeginChild()/EndChild() calls
g . WithinEndChild = true ;
if ( window - > BeginCount > 1 )
{
End ( ) ;
}
else
ImVec2 child_size = child_window - > Size ;
End ( ) ;
if ( child_window - > BeginCount = = 1 )
{
ImVec2 sz = window - > Size ;
if ( window - > AutoFitChildAxises & ( 1 < < ImGuiAxis_X ) ) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
sz . x = ImMax ( 4.0f , sz . x ) ;
if ( window - > AutoFitChildAxises & ( 1 < < ImGuiAxis_Y ) )
sz . y = ImMax ( 4.0f , sz . y ) ;
End ( ) ;
ImGuiWindow * parent_window = g . CurrentWindow ;
ImRect bb ( parent_window - > DC . CursorPos , parent_window - > DC . CursorPos + sz ) ;
ItemSize ( sz ) ;
if ( ( window - > DC . NavLayersActiveMask ! = 0 | | window - > DC . NavWindowHasScrollY ) & & ! ( window - > Flags & ImGuiWindowFlags_NavFlattened ) )
ImRect bb ( parent_window - > DC . CursorPos , parent_window - > DC . CursorPos + child_size ) ;
ItemSize ( child_size ) ;
if ( ( child_window - > DC . NavLayersActiveMask ! = 0 | | child_window - > DC . NavWindowHasScrollY ) & & ! ( child_window - > Flags & ImGuiWindowFlags_NavFlattened ) )
{
ItemAdd ( bb , window - > ChildId ) ;
RenderNavHighlight ( bb , window - > ChildId ) ;
ItemAdd ( bb , child_window - > ChildId ) ;
RenderNavHighlight ( bb , child_window - > ChildId ) ;
// When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
if ( window - > DC . NavLayersActiveMask = = 0 & & window = = g . NavWindow )
if ( child_ window- > DC . NavLayersActiveMask = = 0 & & child_ window = = g . NavWindow )
RenderNavHighlight ( ImRect ( bb . Min - ImVec2 ( 2 , 2 ) , bb . Max + ImVec2 ( 2 , 2 ) ) , g . NavId , ImGuiNavHighlightFlags_TypeThin ) ;
}
else
@ -5793,10 +5785,10 @@ void ImGui::EndChild()
ItemAdd ( bb , 0 ) ;
// But when flattened we directly reach items, adjust active layer mask accordingly
if ( window - > Flags & ImGuiWindowFlags_NavFlattened )
parent_window - > DC . NavLayersActiveMaskNext | = window - > DC . NavLayersActiveMaskNext ;
if ( child_ window- > Flags & ImGuiWindowFlags_NavFlattened )
parent_window - > DC . NavLayersActiveMaskNext | = child_ window- > DC . NavLayersActiveMaskNext ;
}
if ( g . HoveredWindow = = window )
if ( g . HoveredWindow = = child_ window)
g . LastItemData . StatusFlags | = ImGuiItemStatusFlags_HoveredWindow ;
}
g . WithinEndChild = false ;
@ -6202,7 +6194,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
if ( hovered | | held )
g . MouseCursor = ( resize_grip_n & 1 ) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE ;
if ( held & & g . IO . MouseClickedCount [ 0 ] = = 2 & & resize_grip_n = = 0 )
if ( held & & g . IO . MouseClickedCount [ 0 ] = = 2 )
{
// Manual auto-fit when double-clicking
size_target = CalcWindowSizeAfterConstraint ( window , size_auto_fit ) ;
@ -6731,7 +6723,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window - > IDStack . push_back ( window - > ID ) ;
// Add to stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
g . CurrentWindow = window ;
ImGuiWindowStackData window_stack_data ;
window_stack_data . Window = window ;
@ -6749,6 +6740,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
// Add to focus scope stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
PushFocusScope ( window - > ID ) ;
window - > NavRootFocusScopeId = g . CurrentFocusScopeId ;
g . CurrentWindow = NULL ;
@ -7934,7 +7926,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
// for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache.
// We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow.
if ( flags & ImGuiHoveredFlags_ForTooltip )
flags | = g . Style . HoverFlagsForTooltipMouse ;
flags = ApplyHoverFlagsForTooltip ( flags , g . Style . HoverFlagsForTooltipMouse ) ;
if ( ( flags & ImGuiHoveredFlags_Stationary ) ! = 0 & & g . HoverWindowUnlockedStationaryId ! = ref_window - > ID )
return false ;
@ -9758,16 +9750,10 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
}
}
bool ImGui : : Shortcut ( ImGuiKeyChord key_chord , ImGuiID owner_id , ImGuiInputFlags flags )
// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
bool ImGui : : IsKeyChordPressed ( ImGuiKeyChord key_chord , ImGuiID owner_id , ImGuiInputFlags flags )
{
ImGuiContext & g = * GImGui ;
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
if ( ( flags & ImGuiInputFlags_RouteMask_ ) = = 0 )
flags | = ImGuiInputFlags_RouteFocused ;
if ( ! SetShortcutRouting ( key_chord , owner_id , flags ) )
return false ;
if ( key_chord & ImGuiMod_Shortcut )
key_chord = ConvertShortcutMod ( key_chord ) ;
ImGuiKey mods = ( ImGuiKey ) ( key_chord & ImGuiMod_Mask_ ) ;
@ -9778,11 +9764,22 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
ImGuiKey key = ( ImGuiKey ) ( key_chord & ~ ImGuiMod_Mask_ ) ;
if ( key = = ImGuiKey_None )
key = ConvertSingleModFlagToKey ( & g , mods ) ;
if ( ! IsKeyPressed ( key , owner_id , ( flags & ( ImGuiInputFlags_Repeat | ( ImGuiInputFlags ) ImGuiInputFlags_RepeatRateMask_ ) ) ) )
return false ;
IM_ASSERT ( ( flags & ~ ImGuiInputFlags_SupportedByShortcut ) = = 0 ) ; // Passing flags not supported by this function!
return true ;
}
bool ImGui : : Shortcut ( ImGuiKeyChord key_chord , ImGuiID owner_id , ImGuiInputFlags flags )
{
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
if ( ( flags & ImGuiInputFlags_RouteMask_ ) = = 0 )
flags | = ImGuiInputFlags_RouteFocused ;
if ( ! SetShortcutRouting ( key_chord , owner_id , flags ) )
return false ;
if ( ! IsKeyChordPressed ( key_chord , owner_id , flags ) )
return false ;
IM_ASSERT ( ( flags & ~ ImGuiInputFlags_SupportedByShortcut ) = = 0 ) ; // Passing flags not supported by this function!
return true ;
}