@ -46,7 +46,7 @@ DOCUMENTATION
- GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE / ENGINE
- HOW A SIMPLE APPLICATION MAY LOOK LIKE
- HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
- USING GAMEPAD / KEYBOAR D NAVIGATION CONTROLS
- USING KEYBOARD / GAMEPA D NAVIGATION CONTROLS
- API BREAKING CHANGES ( read me when you update ! )
- FREQUENTLY ASKED QUESTIONS ( FAQ )
- Read all answers online : https : //www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
@ -345,13 +345,14 @@ CODE
}
USING GAMEPAD / KEYBOAR D NAVIGATION CONTROLS
USING KEYBOARD / GAMEPA D NAVIGATION CONTROLS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- The gamepad / keyboar d navigation is fairly functional and keeps being improved .
- The keyboard / gamepa d navigation is fairly functional and keeps being improved .
- Gamepad support is particularly useful to use Dear ImGui on a console system ( e . g . PlayStation , Switch , Xbox ) without a mouse !
- The initial focus was to support game controllers , but keyboard is becoming increasingly and decently usable .
- Keyboard :
- Application : Set io . ConfigFlags | = ImGuiConfigFlags_NavEnableKeyboard to enable .
- Arrow keys to move . Space or Enter to activate ( on a slider / drag : Space will tweak with arrow , Enter will input text ) .
- When keyboard navigation is active ( io . NavActive + ImGuiConfigFlags_NavEnableKeyboard ) ,
the io . WantCaptureKeyboard flag will be set . For more advanced uses , you may want to read from :
- io . NavActive : true when a window is focused and it doesn ' t have the ImGuiWindowFlags_NoNavInputs flag set .
@ -1002,8 +1003,8 @@ static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSetti
static void WindowSettingsHandler_WriteAll ( ImGuiContext * , ImGuiSettingsHandler * , ImGuiTextBuffer * buf ) ;
// Platform Dependents default implementation for IO functions
static const char * GetClipboardTextFn_DefaultImpl ( void * user_data ) ;
static void SetClipboardTextFn_DefaultImpl ( void * user_data , const char * text ) ;
static const char * GetClipboardTextFn_DefaultImpl ( void * user_data_ctx ) ;
static void SetClipboardTextFn_DefaultImpl ( void * user_data_ctx , const char * text ) ;
static void SetPlatformImeDataFn_DefaultImpl ( ImGuiViewport * viewport , ImGuiPlatformImeData * data ) ;
namespace ImGui
@ -1255,12 +1256,9 @@ ImGuiIO::ImGuiIO()
ConfigMemoryCompactTimer = 60.0f ;
// Platform Functions
// Note: Initialize() will setup default clipboard/ime handlers.
BackendPlatformName = BackendRendererName = NULL ;
BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL ;
GetClipboardTextFn = GetClipboardTextFn_DefaultImpl ; // Platform dependent default implementations
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl ;
ClipboardUserData = NULL ;
SetPlatformImeDataFn = SetPlatformImeDataFn_DefaultImpl ;
// Input (NB: we already have memset zero the entire structure!)
MousePos = ImVec2 ( - FLT_MAX , - FLT_MAX ) ;
@ -1279,8 +1277,8 @@ ImGuiIO::ImGuiIO()
// FIXME: Should in theory be called "AddCharacterEvent()" to be consistent with new API
void ImGuiIO : : AddInputCharacter ( unsigned int c )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ImGuiContext & g = * Ctx ;
if ( c = = 0 | | ! AppAcceptingEvents )
return ;
@ -1392,10 +1390,10 @@ static ImGuiInputEvent* FindLatestInputEvent(ImGuiInputEventType type, int arg =
void ImGuiIO : : AddKeyAnalogEvent ( ImGuiKey key , bool down , float analog_value )
{
//if (e->Down) { IMGUI_DEBUG_LOG_IO("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); }
IM_ASSERT ( Ctx ! = NULL ) ;
if ( key = = ImGuiKey_None | | ! AppAcceptingEvents )
return ;
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
ImGuiContext & g = * Ctx ;
IM_ASSERT ( ImGui : : IsNamedKeyOrModKey ( key ) ) ; // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API.
IM_ASSERT ( ! ImGui : : IsAliasKey ( key ) ) ; // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events.
IM_ASSERT ( key ! = ImGuiMod_Shortcut ) ; // We could easily support the translation here but it seems saner to not accept it (TestEngine perform a translation itself)
@ -1470,8 +1468,8 @@ void ImGuiIO::SetAppAcceptingEvents(bool accepting_events)
// Queue a mouse move event
void ImGuiIO : : AddMousePosEvent ( float x , float y )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ImGuiContext & g = * Ctx ;
if ( ! AppAcceptingEvents )
return ;
@ -1494,8 +1492,8 @@ void ImGuiIO::AddMousePosEvent(float x, float y)
void ImGuiIO : : AddMouseButtonEvent ( int mouse_button , bool down )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ImGuiContext & g = * Ctx ;
IM_ASSERT ( mouse_button > = 0 & & mouse_button < ImGuiMouseButton_COUNT ) ;
if ( ! AppAcceptingEvents )
return ;
@ -1517,8 +1515,8 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
// Queue a mouse wheel event (some mouse/API may only have a Y component)
void ImGuiIO : : AddMouseWheelEvent ( float wheel_x , float wheel_y )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ImGuiContext & g = * Ctx ;
// Filter duplicate (unlike most events, wheel values are relative and easy to filter)
if ( ! AppAcceptingEvents | | ( wheel_x = = 0.0f & & wheel_y = = 0.0f ) )
@ -1555,8 +1553,8 @@ void ImGuiIO::AddMouseViewportEvent(ImGuiID viewport_id)
void ImGuiIO : : AddFocusEvent ( bool focused )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( & g . IO = = this & & " Can only add events to current context. " ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ImGuiContext & g = * Ctx ;
// Filter duplicate
const ImGuiInputEvent * latest_event = FindLatestInputEvent ( ImGuiInputEventType_Focus ) ;
@ -2765,6 +2763,8 @@ static void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* clipper, int it
ImGuiListClipper : : ImGuiListClipper ( )
{
memset ( this , 0 , sizeof ( * this ) ) ;
Ctx = ImGui : : GetCurrentContext ( ) ;
IM_ASSERT ( Ctx ! = NULL ) ;
ItemsCount = - 1 ;
}
@ -2775,7 +2775,7 @@ ImGuiListClipper::~ImGuiListClipper()
void ImGuiListClipper : : Begin ( int items_count , float items_height )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
ImGuiWindow * window = g . CurrentWindow ;
IMGUI_DEBUG_LOG_CLIPPER ( " Clipper: Begin(%d,%.2f) in '%s' \n " , items_count , items_height , window - > Name ) ;
@ -2800,7 +2800,7 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
void ImGuiListClipper : : End ( )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
if ( ImGuiListClipperData * data = ( ImGuiListClipperData * ) TempData )
{
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
@ -2832,7 +2832,7 @@ void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
static bool ImGuiListClipper_StepInternal ( ImGuiListClipper * clipper )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * clipper - > Ctx ;
ImGuiWindow * window = g . CurrentWindow ;
ImGuiListClipperData * data = ( ImGuiListClipperData * ) clipper - > TempData ;
IM_ASSERT ( data ! = NULL & & " Called ImGuiListClipper::Step() too many times, or before ImGuiListClipper::Begin() ? " ) ;
@ -2955,7 +2955,7 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
bool ImGuiListClipper : : Step ( )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
bool need_items_height = ( ItemsHeight < = 0.0f ) ;
bool ret = ImGuiListClipper_StepInternal ( this ) ;
if ( ret & & ( DisplayStart = = DisplayEnd ) )
@ -3056,20 +3056,12 @@ void ImGui::PopStyleColor(int count)
}
}
struct ImGuiStyleVarInfo
{
ImGuiDataType Type ;
ImU32 Count ;
ImU32 Offset ;
void * GetVarPtr ( ImGuiStyle * style ) const { return ( void * ) ( ( unsigned char * ) style + Offset ) ; }
} ;
static const ImGuiCol GWindowDockStyleColors [ ImGuiWindowDockStyleCol_COUNT ] =
{
ImGuiCol_Text , ImGuiCol_Tab , ImGuiCol_TabHovered , ImGuiCol_TabActive , ImGuiCol_TabUnfocused , ImGuiCol_TabUnfocusedActive
} ;
static const ImGuiStyle VarInfo GStyleVarInfo [ ] =
static const ImGuiDataVarInfo GStyleVarInfo [ ] =
{
{ ImGuiDataType_Float , 1 , ( ImU32 ) IM_OFFSETOF ( ImGuiStyle , Alpha ) } , // ImGuiStyleVar_Alpha
{ ImGuiDataType_Float , 1 , ( ImU32 ) IM_OFFSETOF ( ImGuiStyle , DisabledAlpha ) } , // ImGuiStyleVar_DisabledAlpha
@ -3101,39 +3093,39 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] =
{ ImGuiDataType_Float , 2 , ( ImU32 ) IM_OFFSETOF ( ImGuiStyle , SeparatorTextPadding ) } , // ImGuiStyleVar_SeparatorTextPadding
} ;
static const ImGuiStyleVarInfo * GetStyleVarInfo ( ImGuiStyleVar idx )
const ImGuiDataVarInfo * ImGui : : GetStyleVarInfo ( ImGuiStyleVar idx )
{
IM_ASSERT ( idx > = 0 & & idx < ImGuiStyleVar_COUNT ) ;
IM_ASSERT ( IM_ARRAYSIZE ( GStyleVarInfo ) = = ImGuiStyleVar_COUNT ) ;
IM_STATIC_ ASSERT ( IM_ARRAYSIZE ( GStyleVarInfo ) = = ImGuiStyleVar_COUNT ) ;
return & GStyleVarInfo [ idx ] ;
}
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , float val )
{
const ImGuiStyleVarInfo * var_info = GetStyleVarInfo ( idx ) ;
ImGuiContext & g = * GImGui ;
const ImGuiDataVarInfo * var_info = GetStyleVarInfo ( idx ) ;
if ( var_info - > Type = = ImGuiDataType_Float & & var_info - > Count = = 1 )
{
ImGuiContext & g = * GImGui ;
float * pvar = ( float * ) var_info - > GetVarPtr ( & g . Style ) ;
g . StyleVarStack . push_back ( ImGuiStyleMod ( idx , * pvar ) ) ;
* pvar = val ;
return ;
}
IM_ASSERT ( 0 & & " Called PushStyleVar() float variant but variable is not a float ! " ) ;
IM_ASSERT_USER_ERROR ( 0 , " Called PushStyleVar() variant with wrong type !" ) ;
}
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , const ImVec2 & val )
{
const ImGuiStyleVarInfo * var_info = GetStyleVarInfo ( idx ) ;
ImGuiContext & g = * GImGui ;
const ImGuiDataVarInfo * var_info = GetStyleVarInfo ( idx ) ;
if ( var_info - > Type = = ImGuiDataType_Float & & var_info - > Count = = 2 )
{
ImGuiContext & g = * GImGui ;
ImVec2 * pvar = ( ImVec2 * ) var_info - > GetVarPtr ( & g . Style ) ;
g . StyleVarStack . push_back ( ImGuiStyleMod ( idx , * pvar ) ) ;
* pvar = val ;
return ;
}
IM_ASSERT ( 0 & & " Called PushStyleVar() ImVec2 variant but variable is not a ImVec2 ! " ) ;
IM_ASSERT_USER_ERROR ( 0 , " Called PushStyleVar() variant with wrong type !" ) ;
}
void ImGui : : PopStyleVar ( int count )
@ -3148,7 +3140,7 @@ void ImGui::PopStyleVar(int count)
{
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
ImGuiStyleMod & backup = g . StyleVarStack . back ( ) ;
const ImGuiStyle VarInfo * info = GetStyleVarInfo ( backup . VarIdx ) ;
const ImGuiData VarInfo * info = GetStyleVarInfo ( backup . VarIdx ) ;
void * data = info - > GetVarPtr ( & g . Style ) ;
if ( info - > Type = = ImGuiDataType_Float & & info - > Count = = 1 ) { ( ( float * ) data ) [ 0 ] = backup . BackupFloat [ 0 ] ; }
else if ( info - > Type = = ImGuiDataType_Float & & info - > Count = = 2 ) { ( ( float * ) data ) [ 0 ] = backup . BackupFloat [ 0 ] ; ( ( float * ) data ) [ 1 ] = backup . BackupFloat [ 1 ] ; }
@ -3566,6 +3558,12 @@ void ImGui::Initialize()
// Setup default localization table
LocalizeRegisterEntries ( GLocalizationEntriesEnUS , IM_ARRAYSIZE ( GLocalizationEntriesEnUS ) ) ;
// Setup default platform clipboard/IME handlers.
g . IO . GetClipboardTextFn = GetClipboardTextFn_DefaultImpl ; // Platform dependent default implementations
g . IO . SetClipboardTextFn = SetClipboardTextFn_DefaultImpl ;
g . IO . ClipboardUserData = ( void * ) & g ; // Default implementation use the ImGuiContext as user data (ideally those would be arguments to the function)
g . IO . SetPlatformImeDataFn = SetPlatformImeDataFn_DefaultImpl ;
// Create default viewport
ImGuiViewportP * viewport = IM_NEW ( ImGuiViewportP ) ( ) ;
viewport - > ID = IMGUI_VIEWPORT_DEFAULT_ID ;
@ -3704,9 +3702,10 @@ void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type)
//-----------------------------------------------------------------------------
// ImGuiWindow is mostly a dumb struct. It merely has a constructor and a few helper methods
ImGuiWindow : : ImGuiWindow ( ImGuiContext * con te xt , const char * name ) : DrawListInst ( NULL )
ImGuiWindow : : ImGuiWindow ( ImGuiContext * ctx , const char * name ) : DrawListInst ( NULL )
{
memset ( this , 0 , sizeof ( * this ) ) ;
Ctx = ctx ;
Name = ImStrdup ( name ) ;
NameBufLen = ( int ) strlen ( name ) + 1 ;
ID = ImHashStr ( name ) ;
@ -3728,7 +3727,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst
SettingsOffset = - 1 ;
DockOrder = - 1 ;
DrawList = & DrawListInst ;
DrawList - > _Data = & context - > DrawListSharedData ;
DrawList - > _Data = & Ctx - > DrawListSharedData ;
DrawList - > _OwnerName = Name ;
IM_PLACEMENT_NEW ( & WindowClass ) ImGuiWindowClass ( ) ;
}
@ -3744,7 +3743,7 @@ ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
{
ImGuiID seed = IDStack . back ( ) ;
ImGuiID id = ImHashStr ( str , str_end ? ( str_end - str ) : 0 , seed ) ;
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
if ( g . DebugHookIdInfo = = id )
ImGui : : DebugHookIdInfo ( id , ImGuiDataType_String , str , str_end ) ;
return id ;
@ -3754,7 +3753,7 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
{
ImGuiID seed = IDStack . back ( ) ;
ImGuiID id = ImHashData ( & ptr , sizeof ( void * ) , seed ) ;
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
if ( g . DebugHookIdInfo = = id )
ImGui : : DebugHookIdInfo ( id , ImGuiDataType_Pointer , ptr , NULL ) ;
return id ;
@ -3764,7 +3763,7 @@ ImGuiID ImGuiWindow::GetID(int n)
{
ImGuiID seed = IDStack . back ( ) ;
ImGuiID id = ImHashData ( & n , sizeof ( n ) , seed ) ;
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * Ctx ;
if ( g . DebugHookIdInfo = = id )
ImGui : : DebugHookIdInfo ( id , ImGuiDataType_S32 , ( void * ) ( intptr_t ) n , NULL ) ;
return id ;
@ -3858,7 +3857,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
if ( id )
{
g . ActiveIdIsAlive = id ;
g . ActiveIdSource = ( g . NavActivateId = = id | | g . NavActivateInputId = = id | | g . Nav JustMovedToId = = id ) ? ( ImGuiInputSource ) ImGuiInputSource_Nav : ImGuiInputSource_Mouse ;
g . ActiveIdSource = ( g . NavActivateId = = id | | g . NavJustMovedToId = = id ) ? ( ImGuiInputSource ) ImGuiInputSource_Nav : ImGuiInputSource_Mouse ;
}
// Clear declaration of inputs claimed by the widget
@ -4089,14 +4088,14 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
}
// This is also inlined in ItemAdd()
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect!
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set g.LastItemData.DisplayRect.
void ImGui : : SetLastItemData ( ImGuiID item_id , ImGuiItemFlags in_flags , ImGuiItemStatusFlags item_flags , const ImRect & item_rect )
{
ImGuiContext & g = * GImGui ;
g . LastItemData . ID = item_id ;
g . LastItemData . InFlags = in_flags ;
g . LastItemData . StatusFlags = item_flags ;
g . LastItemData . Rect = item_rect ;
g . LastItemData . Rect = g . LastItemData . NavRect = item_rect ;
}
float ImGui : : CalcWrapWidthForPos ( const ImVec2 & pos , float wrap_pos_x )
@ -4766,6 +4765,11 @@ void ImGui::NewFrame()
UpdateDebugToolStackQueries ( ) ;
if ( g . DebugLocateFrames > 0 & & - - g . DebugLocateFrames = = 0 )
g . DebugLocateId = 0 ;
if ( g . DebugLogClipperAutoDisableFrames > 0 & & - - g . DebugLogClipperAutoDisableFrames = = 0 )
{
DebugLog ( " (Auto-disabled ImGuiDebugLogFlags_EventClipper to avoid spamming) \n " ) ;
g . DebugLogFlags & = ~ ImGuiDebugLogFlags_EventClipper ;
}
// Create implicit/fallback window - which we will only render it if the user has added something to it.
// We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
@ -5076,7 +5080,20 @@ void ImGui::EndFrame()
{
ImGuiViewport * viewport = FindViewportByID ( g . PlatformImeViewport ) ;
IMGUI_DEBUG_LOG_IO ( " Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f) \n " , ime_data - > WantVisible , ime_data - > InputPos . x , ime_data - > InputPos . y ) ;
g . IO . SetPlatformImeDataFn ( viewport ? viewport : GetMainViewport ( ) , ime_data ) ;
if ( viewport = = NULL )
viewport = GetMainViewport ( ) ;
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
if ( viewport - > PlatformHandleRaw = = NULL & & g . IO . ImeWindowHandle ! = NULL )
{
viewport - > PlatformHandleRaw = g . IO . ImeWindowHandle ;
g . IO . SetPlatformImeDataFn ( viewport , ime_data ) ;
viewport - > PlatformHandleRaw = NULL ;
}
else
# endif
{
g . IO . SetPlatformImeDataFn ( viewport , ime_data ) ;
}
}
// Hide implicit/fallback "Debug" window if it hasn't been used
@ -6485,7 +6502,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
ImGuiWindowStackData window_stack_data ;
window_stack_data . Window = window ;
window_stack_data . ParentLastItemDataBackup = g . LastItemData ;
window_stack_data . StackSizesOnBegin . SetToCurrentState ( ) ;
window_stack_data . StackSizesOnBegin . SetToContextState ( & g ) ;
g . CurrentWindowStack . push_back ( window_stack_data ) ;
if ( flags & ImGuiWindowFlags_ChildMenu )
g . BeginMenuCount + + ;
@ -6845,13 +6862,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
}
// [Test Engine] Register whole window in the item system
// [Test Engine] Register whole window in the item system (before submitting further decorations)
# ifdef IMGUI_ENABLE_TEST_ENGINE
if ( g . TestEngineHookItems )
{
IM_ASSERT ( window - > IDStack . Size = = 1 ) ;
window - > IDStack . Size = 0 ; // As window->IDStack[0] == window->ID here, make sure TestEngine doesn't erroneously see window as parent of itself.
IMGUI_TEST_ENGINE_ITEM_ADD ( window - > Rect ( ) , window - > ID ) ;
IMGUI_TEST_ENGINE_ITEM_ADD ( window - > ID , window - > Rect ( ) , NULL ) ;
IMGUI_TEST_ENGINE_ITEM_INFO ( window - > ID , window - > Name , ( g . HoveredWindow = = window ) ? ImGuiItemStatusFlags_HoveredRect : 0 ) ;
window - > IDStack . Size = 1 ;
}
@ -7142,10 +7159,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
DebugLocateItemResolveWithLastItem ( ) ;
# endif
// [Test Engine] Register title bar / tab
// [Test Engine] Register title bar / tab with MoveId.
# ifdef IMGUI_ENABLE_TEST_ENGINE
if ( ! ( window - > Flags & ImGuiWindowFlags_NoTitleBar ) )
IMGUI_TEST_ENGINE_ITEM_ADD ( g . LastItemData . Rect , g . LastItemData . ID ) ;
IMGUI_TEST_ENGINE_ITEM_ADD ( g . LastItemData . ID , g . LastItemData . Rect , & g . Last Item Data ) ;
# endif
}
else
@ -7276,7 +7293,7 @@ void ImGui::End()
g . BeginMenuCount - - ;
if ( window - > Flags & ImGuiWindowFlags_Popup )
g . BeginPopupStack . pop_back ( ) ;
g . CurrentWindowStack . back ( ) . StackSizesOnBegin . CompareWithCurrentState ( ) ;
g . CurrentWindowStack . back ( ) . StackSizesOnBegin . CompareWithContextState ( & g ) ;
g . CurrentWindowStack . pop_back ( ) ;
SetCurrentWindow ( g . CurrentWindowStack . Size = = 0 ? NULL : g . CurrentWindowStack . back ( ) . Window ) ;
if ( g . CurrentWindow )
@ -9714,9 +9731,9 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo
}
// Save current stack sizes for later compare
void ImGuiStackSizes : : SetToCurrentState ( )
void ImGuiStackSizes : : SetToContextState ( ImGuiContext * ctx )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * ctx ;
ImGuiWindow * window = g . CurrentWindow ;
SizeOfIDStack = ( short ) window - > IDStack . Size ;
SizeOfColorStack = ( short ) g . ColorStack . Size ;
@ -9730,9 +9747,9 @@ void ImGuiStackSizes::SetToCurrentState()
}
// Compare to detect usage errors
void ImGuiStackSizes : : CompareWithCurrentState ( )
void ImGuiStackSizes : : CompareWithContextState ( ImGuiContext * ctx )
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * ctx ;
ImGuiWindow * window = g . CurrentWindow ;
IM_UNUSED ( window ) ;
@ -9872,7 +9889,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
# ifdef IMGUI_ENABLE_TEST_ENGINE
if ( id ! = 0 )
IMGUI_TEST_ENGINE_ITEM_ADD ( nav_bb_arg ? * nav_bb_arg : bb , id ) ;
IMGUI_TEST_ENGINE_ITEM_ADD ( id , g . LastItemData . NavRect , & g . LastItemData ) ;
# endif
// Clipping test
@ -11740,7 +11757,7 @@ static void ImGui::NavUpdate()
NavUpdateCancelRequest ( ) ;
// Process manual activation request
g . NavActivateId = g . NavActivateDownId = g . NavActivatePressedId = g . NavActivateInputId = 0 ;
g . NavActivateId = g . NavActivateDownId = g . NavActivatePressedId = 0 ;
g . NavActivateFlags = ImGuiActivateFlags_None ;
if ( g . NavId ! = 0 & & ! g . NavDisableHighlight & & ! g . NavWindowingTarget & & g . NavWindow & & ! ( g . NavWindow - > Flags & ImGuiWindowFlags_NoNavInputs ) )
{
@ -11755,12 +11772,12 @@ static void ImGui::NavUpdate()
}
if ( ( g . ActiveId = = 0 | | g . ActiveId = = g . NavId ) & & input_pressed )
{
g . NavActivateInputI d = g . NavId ;
g . NavActivateId = g . NavId ;
g . NavActivateFlags = ImGuiActivateFlags_PreferInput ;
}
if ( ( g . ActiveId = = 0 | | g . ActiveId = = g . NavId ) & & activate_down )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = g . NavId ) & & ( activate_down | | input_down ) )
g . NavActivateDownId = g . NavId ;
if ( ( g . ActiveId = = 0 | | g . ActiveId = = g . NavId ) & & activate_pressed )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = g . NavId ) & & ( activate_pressed | | input_pressed ) )
g . NavActivatePressedId = g . NavId ;
}
if ( g . NavWindow & & ( g . NavWindow - > Flags & ImGuiWindowFlags_NoNavInputs ) )
@ -11772,9 +11789,6 @@ static void ImGui::NavUpdate()
// FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
if ( g . NavNextActivateId ! = 0 )
{
if ( g . NavNextActivateFlags & ImGuiActivateFlags_PreferInput )
g . NavActivateInputId = g . NavNextActivateId ;
else
g . NavActivateId = g . NavActivateDownId = g . NavActivatePressedId = g . NavNextActivateId ;
g . NavActivateFlags = g . NavNextActivateFlags ;
}
@ -11930,16 +11944,21 @@ void ImGui::NavUpdateCreateMoveRequest()
}
// When using gamepad, we project the reference nav bounding box into window visible area.
// This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad all movements are relative
// (can't focus a visible object like we can with the mouse).
// This is to allow resuming navigation inside the visible area after doing a large amount of scrolling,
// since with gamepad all movements are relative (can't focus a visible object like we can with the mouse).
if ( g . NavMoveSubmitted & & g . NavInputSource = = ImGuiInputSource_Gamepad & & g . NavLayer = = ImGuiNavLayer_Main & & window ! = NULL ) // && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded))
{
bool clamp_x = ( g . NavMoveFlags & ( ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapX ) ) = = 0 ;
bool clamp_y = ( g . NavMoveFlags & ( ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapY ) ) = = 0 ;
ImRect inner_rect_rel = WindowRectAbsToRel ( window , ImRect ( window - > InnerRect . Min - ImVec2 ( 1 , 1 ) , window - > InnerRect . Max + ImVec2 ( 1 , 1 ) ) ) ;
// Take account of changing scroll to handle triggering a new move request on a scrolling frame. (#6171)
// Otherwise 'inner_rect_rel' would be off on the move result frame.
inner_rect_rel . Translate ( CalcNextScrollFromScrollTargetAndClamp ( window ) - window - > Scroll ) ;
if ( ( clamp_x | | clamp_y ) & & ! inner_rect_rel . Contains ( window - > NavRectRel [ g . NavLayer ] ) )
{
//IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n");
IMGUI_DEBUG_LOG_NAV ( " [nav] NavMoveRequest: clamp NavRectRel for gamepad move \n " ) ;
float pad_x = ImMin ( inner_rect_rel . GetWidth ( ) , window - > CalcFontSize ( ) * 0.5f ) ;
float pad_y = ImMin ( inner_rect_rel . GetHeight ( ) , window - > CalcFontSize ( ) * 0.5f ) ; // Terrible approximation for the intent of starting navigation from first fully visible item
inner_rect_rel . Min . x = clamp_x ? ( inner_rect_rel . Min . x + pad_x ) : - FLT_MAX ;
@ -18392,9 +18411,9 @@ static void ImGui::DockSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettings
// Win32 clipboard implementation
// We use g.ClipboardHandlerData for temporary storage to ensure it is freed on Shutdown()
static const char * GetClipboardTextFn_DefaultImpl ( void * )
static const char * GetClipboardTextFn_DefaultImpl ( void * user_data_ctx )
{
ImGuiContext & g = * G ImGui;
ImGuiContext & g = * ( ImGuiContext * ) user_data_ctx ;
g . ClipboardHandlerData . clear ( ) ;
if ( ! : : OpenClipboard ( NULL ) )
return NULL ;
@ -18455,8 +18474,9 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
}
}
static const char * GetClipboardTextFn_DefaultImpl ( void * )
static const char * GetClipboardTextFn_DefaultImpl ( void * user_data_ctx )
{
ImGuiContext & g = * ( ImGuiContext * ) user_data_ctx ;
if ( ! main_clipboard )
PasteboardCreate ( kPasteboardClipboard , & main_clipboard ) ;
PasteboardSynchronize ( main_clipboard ) ;
@ -18474,7 +18494,6 @@ static const char* GetClipboardTextFn_DefaultImpl(void*)
CFDataRef cf_data ;
if ( PasteboardCopyItemFlavorData ( main_clipboard , item_id , CFSTR ( " public.utf8-plain-text " ) , & cf_data ) = = noErr )
{
ImGuiContext & g = * GImGui ;
g . ClipboardHandlerData . clear ( ) ;
int length = ( int ) CFDataGetLength ( cf_data ) ;
g . ClipboardHandlerData . resize ( length + 1 ) ;
@ -18491,15 +18510,15 @@ static const char* GetClipboardTextFn_DefaultImpl(void*)
# else
// Local Dear ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers.
static const char * GetClipboardTextFn_DefaultImpl ( void * )
static const char * GetClipboardTextFn_DefaultImpl ( void * user_data_ctx )
{
ImGuiContext & g = * G ImGui;
ImGuiContext & g = * ( ImGuiContext * ) user_data_ctx ;
return g . ClipboardHandlerData . empty ( ) ? NULL : g . ClipboardHandlerData . begin ( ) ;
}
static void SetClipboardTextFn_DefaultImpl ( void * , const char * text )
static void SetClipboardTextFn_DefaultImpl ( void * user_data_ctx , const char * text )
{
ImGuiContext & g = * G ImGui;
ImGuiContext & g = * ( ImGuiContext * ) user_data_ctx ;
g . ClipboardHandlerData . clear ( ) ;
const char * text_end = text + strlen ( text ) ;
g . ClipboardHandlerData . resize ( ( int ) ( text_end - text ) + 1 ) ;
@ -18521,10 +18540,6 @@ static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatf
{
// Notify OS Input Method Editor of text input position
HWND hwnd = ( HWND ) viewport - > PlatformHandleRaw ;
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
if ( hwnd = = 0 )
hwnd = ( HWND ) ImGui : : GetIO ( ) . ImeWindowHandle ;
# endif
if ( hwnd = = 0 )
return ;
@ -19280,7 +19295,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
DebugLocateItemOnHover ( g . NavId ) ;
Text ( " NavInputSource: %s " , GetInputSourceName ( g . NavInputSource ) ) ;
Text ( " NavActive: %d, NavVisible: %d " , g . IO . NavActive , g . IO . NavVisible ) ;
Text ( " NavActivateId/DownId/PressedId/InputId : %08X/ %08X/%08X/%08X " , g . NavActivateId , g . NavActivateDownId , g . NavActivatePressedId , g . NavActivateInput Id ) ;
Text ( " NavActivateId/DownId/PressedId: %08X/%08X/%08X " , g . NavActivateId , g . NavActivateDownId , g . NavActivatePressedId ) ;
Text ( " NavActivateFlags: %04X " , g . NavActivateFlags ) ;
Text ( " NavDisableHighlight: %d, NavDisableMouseHover: %d " , g . NavDisableHighlight , g . NavDisableMouseHover ) ;
Text ( " NavFocusScopeId = 0x%08X " , g . NavFocusScopeId ) ;
@ -19922,7 +19937,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
SameLine ( ) ; CheckboxFlags ( " Focus " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventFocus ) ;
SameLine ( ) ; CheckboxFlags ( " Popup " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventPopup ) ;
SameLine ( ) ; CheckboxFlags ( " Nav " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventNav ) ;
SameLine ( ) ; CheckboxFlags ( " Clipper " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventClipper ) ;
SameLine ( ) ; if ( CheckboxFlags ( " Clipper " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventClipper ) ) { g . DebugLogClipperAutoDisableFrames = 2 ; } if ( IsItemHovered ( ) ) SetTooltip ( " Clipper log auto-disabled after 2 frames " ) ;
SameLine ( ) ; CheckboxFlags ( " IO " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventIO ) ;
SameLine ( ) ; CheckboxFlags ( " Docking " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventDocking ) ;
SameLine ( ) ; CheckboxFlags ( " Viewport " , & g . DebugLogFlags , ImGuiDebugLogFlags_EventViewport ) ;