@ -904,10 +904,12 @@ static void ErrorCheckEndFrame();
static void ErrorCheckBeginEndCompareStacksSize ( ImGuiWindow * window , bool write ) ;
// Misc
static void UpdateSettings ( ) ;
static void UpdateMouseInputs ( ) ;
static void UpdateMouseWheel ( ) ;
static bool UpdateManualResize ( ImGuiWindow * window , const ImVec2 & size_auto_fit , int * border_held , int resize_grip_count , ImU32 resize_grip_col [ 4 ] ) ;
static void UpdateTabFocus ( ) ;
static void UpdateDebugToolItemPicker ( ) ;
static bool UpdateWindowManualResize ( ImGuiWindow * window , const ImVec2 & size_auto_fit , int * border_held , int resize_grip_count , ImU32 resize_grip_col [ 4 ] ) ;
static void RenderWindowOuterBorders ( ImGuiWindow * window ) ;
static void RenderWindowDecorations ( ImGuiWindow * window , const ImRect & title_bar_rect , bool title_bar_is_highlight , int resize_grip_count , const ImU32 resize_grip_col [ 4 ] , float resize_grip_draw_size ) ;
static void RenderWindowTitleBarContents ( ImGuiWindow * window , const ImRect & title_bar_rect , const char * name , bool * p_open ) ;
@ -3495,6 +3497,42 @@ void ImGui::UpdateMouseWheel()
}
}
void ImGui : : UpdateTabFocus ( )
{
ImGuiContext & g = * GImGui ;
// Pressing TAB activate widget focus
g . FocusTabPressed = ( g . NavWindow & & g . NavWindow - > Active & & ! ( g . NavWindow - > Flags & ImGuiWindowFlags_NoNavInputs ) & & ! g . IO . KeyCtrl & & IsKeyPressedMap ( ImGuiKey_Tab ) ) ;
if ( g . ActiveId = = 0 & & g . FocusTabPressed )
{
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
g . FocusRequestNextWindow = g . NavWindow ;
g . FocusRequestNextCounterRegular = INT_MAX ;
if ( g . NavId ! = 0 & & g . NavIdTabCounter ! = INT_MAX )
g . FocusRequestNextCounterTabStop = g . NavIdTabCounter + 1 + ( g . IO . KeyShift ? - 1 : 1 ) ;
else
g . FocusRequestNextCounterTabStop = g . IO . KeyShift ? - 1 : 0 ;
}
// Turn queued focus request into current one
g . FocusRequestCurrWindow = NULL ;
g . FocusRequestCurrCounterRegular = g . FocusRequestCurrCounterTabStop = INT_MAX ;
if ( g . FocusRequestNextWindow ! = NULL )
{
ImGuiWindow * window = g . FocusRequestNextWindow ;
g . FocusRequestCurrWindow = window ;
if ( g . FocusRequestNextCounterRegular ! = INT_MAX & & window - > DC . FocusCounterRegular ! = - 1 )
g . FocusRequestCurrCounterRegular = ImModPositive ( g . FocusRequestNextCounterRegular , window - > DC . FocusCounterRegular + 1 ) ;
if ( g . FocusRequestNextCounterTabStop ! = INT_MAX & & window - > DC . FocusCounterTabStop ! = - 1 )
g . FocusRequestCurrCounterTabStop = ImModPositive ( g . FocusRequestNextCounterTabStop , window - > DC . FocusCounterTabStop + 1 ) ;
g . FocusRequestNextWindow = NULL ;
g . FocusRequestNextCounterRegular = g . FocusRequestNextCounterTabStop = INT_MAX ;
}
g . NavIdTabCounter = INT_MAX ;
}
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
void ImGui : : UpdateHoveredWindowAndCaptureFlags ( )
{
@ -3595,28 +3633,8 @@ void ImGui::NewFrame()
// Check and assert for various common IO and Configuration mistakes
NewFrameSanityChecks ( ) ;
// Load settings on first frame (if not explicitly loaded manually before)
if ( ! g . SettingsLoaded )
{
IM_ASSERT ( g . SettingsWindows . empty ( ) ) ;
if ( g . IO . IniFilename )
LoadIniSettingsFromDisk ( g . IO . IniFilename ) ;
g . SettingsLoaded = true ;
}
// Save settings (with a delay after the last modification, so we don't spam disk too much)
if ( g . SettingsDirtyTimer > 0.0f )
{
g . SettingsDirtyTimer - = g . IO . DeltaTime ;
if ( g . SettingsDirtyTimer < = 0.0f )
{
if ( g . IO . IniFilename ! = NULL )
SaveIniSettingsToDisk ( g . IO . IniFilename ) ;
else
g . IO . WantSaveIniSettings = true ; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
g . SettingsDirtyTimer = 0.0f ;
}
}
// Load settings on first frame, save settings when modified (after a delay)
UpdateSettings ( ) ;
g . Time + = g . IO . DeltaTime ;
g . WithinFrameScope = true ;
@ -3625,6 +3643,12 @@ void ImGui::NewFrame()
g . WindowsActiveCount = 0 ;
g . MenusIdSubmittedThisFrame . resize ( 0 ) ;
// Calculate frame-rate for the user, as a purely luxurious feature
g . FramerateSecPerFrameAccum + = g . IO . DeltaTime - g . FramerateSecPerFrame [ g . FramerateSecPerFrameIdx ] ;
g . FramerateSecPerFrame [ g . FramerateSecPerFrameIdx ] = g . IO . DeltaTime ;
g . FramerateSecPerFrameIdx = ( g . FramerateSecPerFrameIdx + 1 ) % IM_ARRAYSIZE ( g . FramerateSecPerFrame ) ;
g . IO . Framerate = ( g . FramerateSecPerFrameAccum > 0.0f ) ? ( 1.0f / ( g . FramerateSecPerFrameAccum / ( float ) IM_ARRAYSIZE ( g . FramerateSecPerFrame ) ) ) : FLT_MAX ;
// Setup current font and draw list shared data
g . IO . Fonts - > Locked = true ;
SetCurrentFont ( GetDefaultFont ( ) ) ;
@ -3655,7 +3679,7 @@ void ImGui::NewFrame()
if ( g . DragDropActive & & g . DragDropPayload . SourceId = = g . ActiveId )
KeepAliveID ( g . DragDropPayload . SourceId ) ;
// Clear reference to active widget if the widget isn't alive anymore
// Update HoveredId data
if ( ! g . HoveredIdPreviousFrame )
g . HoveredIdTimer = 0.0f ;
if ( ! g . HoveredIdPreviousFrame | | ( g . HoveredId & & g . ActiveId = = g . HoveredId ) )
@ -3667,6 +3691,8 @@ void ImGui::NewFrame()
g . HoveredIdPreviousFrame = g . HoveredId ;
g . HoveredId = 0 ;
g . HoveredIdAllowOverlap = false ;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
if ( g . ActiveIdIsAlive ! = g . ActiveId & & g . ActiveIdPreviousFrame = = g . ActiveId & & g . ActiveId ! = 0 )
ClearActiveID ( ) ;
if ( g . ActiveId )
@ -3683,8 +3709,9 @@ void ImGui::NewFrame()
g . TempInputId = 0 ;
if ( g . ActiveId = = 0 )
{
g . ActiveIdUsingNavDirMask = g . ActiveIdUsingNavInputMask = 0 ;
g . ActiveIdUsingKeyInputMask = 0 ;
g . ActiveIdUsingNavDirMask = 0x00 ;
g . ActiveIdUsingNavInputMask = 0x00 ;
g . ActiveIdUsingKeyInputMask = 0x00 ;
}
// Drag and drop
@ -3704,12 +3731,6 @@ void ImGui::NewFrame()
// Update mouse input state
UpdateMouseInputs ( ) ;
// Calculate frame-rate for the user, as a purely luxurious feature
g . FramerateSecPerFrameAccum + = g . IO . DeltaTime - g . FramerateSecPerFrame [ g . FramerateSecPerFrameIdx ] ;
g . FramerateSecPerFrame [ g . FramerateSecPerFrameIdx ] = g . IO . DeltaTime ;
g . FramerateSecPerFrameIdx = ( g . FramerateSecPerFrameIdx + 1 ) % IM_ARRAYSIZE ( g . FramerateSecPerFrame ) ;
g . IO . Framerate = ( g . FramerateSecPerFrameAccum > 0.0f ) ? ( 1.0f / ( g . FramerateSecPerFrameAccum / ( float ) IM_ARRAYSIZE ( g . FramerateSecPerFrame ) ) ) : FLT_MAX ;
// Find hovered window
// (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
UpdateHoveredWindowAndCaptureFlags ( ) ;
@ -3730,36 +3751,8 @@ void ImGui::NewFrame()
// Mouse wheel scrolling, scale
UpdateMouseWheel ( ) ;
// Pressing TAB activate widget focus
g . FocusTabPressed = ( g . NavWindow & & g . NavWindow - > Active & & ! ( g . NavWindow - > Flags & ImGuiWindowFlags_NoNavInputs ) & & ! g . IO . KeyCtrl & & IsKeyPressedMap ( ImGuiKey_Tab ) ) ;
if ( g . ActiveId = = 0 & & g . FocusTabPressed )
{
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
g . FocusRequestNextWindow = g . NavWindow ;
g . FocusRequestNextCounterRegular = INT_MAX ;
if ( g . NavId ! = 0 & & g . NavIdTabCounter ! = INT_MAX )
g . FocusRequestNextCounterTabStop = g . NavIdTabCounter + 1 + ( g . IO . KeyShift ? - 1 : 1 ) ;
else
g . FocusRequestNextCounterTabStop = g . IO . KeyShift ? - 1 : 0 ;
}
// Turn queued focus request into current one
g . FocusRequestCurrWindow = NULL ;
g . FocusRequestCurrCounterRegular = g . FocusRequestCurrCounterTabStop = INT_MAX ;
if ( g . FocusRequestNextWindow ! = NULL )
{
ImGuiWindow * window = g . FocusRequestNextWindow ;
g . FocusRequestCurrWindow = window ;
if ( g . FocusRequestNextCounterRegular ! = INT_MAX & & window - > DC . FocusCounterRegular ! = - 1 )
g . FocusRequestCurrCounterRegular = ImModPositive ( g . FocusRequestNextCounterRegular , window - > DC . FocusCounterRegular + 1 ) ;
if ( g . FocusRequestNextCounterTabStop ! = INT_MAX & & window - > DC . FocusCounterTabStop ! = - 1 )
g . FocusRequestCurrCounterTabStop = ImModPositive ( g . FocusRequestNextCounterTabStop , window - > DC . FocusCounterTabStop + 1 ) ;
g . FocusRequestNextWindow = NULL ;
g . FocusRequestNextCounterRegular = g . FocusRequestNextCounterTabStop = INT_MAX ;
}
g . NavIdTabCounter = INT_MAX ;
// Update legacy TAB focus
UpdateTabFocus ( ) ;
// Mark all windows as not visible and compact unused memory.
IM_ASSERT ( g . WindowsFocusOrder . Size = = g . Windows . Size ) ;
@ -4972,7 +4965,7 @@ ImGuiID ImGui::GetWindowResizeID(ImGuiWindow* window, int n)
// Handle resize for: Resize Grips, Borders, Gamepad
// Return true when using auto-fit (double click on resize grip)
static bool ImGui : : Update ManualResize( ImGuiWindow * window , const ImVec2 & size_auto_fit , int * border_held , int resize_grip_count , ImU32 resize_grip_col [ 4 ] )
static bool ImGui : : Update Window ManualResize( ImGuiWindow * window , const ImVec2 & size_auto_fit , int * border_held , int resize_grip_count , ImU32 resize_grip_col [ 4 ] )
{
ImGuiContext & g = * GImGui ;
ImGuiWindowFlags flags = window - > Flags ;
@ -5645,7 +5638,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const int resize_grip_count = g . IO . ConfigWindowsResizeFromEdges ? 2 : 1 ; // Allow resize from lower-left if we have the mouse cursor feedback for it.
const float resize_grip_draw_size = IM_FLOOR ( ImMax ( g . FontSize * 1.35f , window - > WindowRounding + 1.0f + g . FontSize * 0.2f ) ) ;
if ( ! window - > Collapsed )
if ( Update ManualResize( window , size_auto_fit , & border_held , resize_grip_count , & resize_grip_col [ 0 ] ) )
if ( Update Window ManualResize( window , size_auto_fit , & border_held , resize_grip_count , & resize_grip_col [ 0 ] ) )
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true ;
window - > ResizeBorderHeld = ( signed char ) border_held ;
@ -9444,6 +9437,34 @@ void ImGui::LogButtons()
// [SECTION] SETTINGS
//-----------------------------------------------------------------------------
// Called by NewFrame()
void ImGui : : UpdateSettings ( )
{
// Load settings on first frame (if not explicitly loaded manually before)
ImGuiContext & g = * GImGui ;
if ( ! g . SettingsLoaded )
{
IM_ASSERT ( g . SettingsWindows . empty ( ) ) ;
if ( g . IO . IniFilename )
LoadIniSettingsFromDisk ( g . IO . IniFilename ) ;
g . SettingsLoaded = true ;
}
// Save settings (with a delay after the last modification, so we don't spam disk too much)
if ( g . SettingsDirtyTimer > 0.0f )
{
g . SettingsDirtyTimer - = g . IO . DeltaTime ;
if ( g . SettingsDirtyTimer < = 0.0f )
{
if ( g . IO . IniFilename ! = NULL )
SaveIniSettingsToDisk ( g . IO . IniFilename ) ;
else
g . IO . WantSaveIniSettings = true ; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
g . SettingsDirtyTimer = 0.0f ;
}
}
}
void ImGui : : MarkIniSettingsDirty ( )
{
ImGuiContext & g = * GImGui ;