1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-02-26 14:51:46 +01:00

Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_vulkan.cpp
#	imgui_internal.h
This commit is contained in:
ocornut 2025-01-13 14:30:57 +01:00
commit d0d571e0d7
12 changed files with 122 additions and 53 deletions

View File

@ -154,6 +154,7 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
void ImGui_ImplMetal_Shutdown()
{
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
IM_UNUSED(bd);
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGui_ImplMetal_ShutdownMultiViewportSupport();
ImGui_ImplMetal_DestroyDeviceObjects();

View File

@ -28,6 +28,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2025-01-09: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify how many image sampler descriptors are expected to be available in descriptor pool. (#6642)
// 2025-01-06: Vulkan: Added more ImGui_ImplVulkanH_XXXX helper functions to simplify our examples.
// 2024-12-11: Vulkan: Fixed setting VkSwapchainCreateInfoKHR::preTransform for platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222)
// 2024-11-27: Vulkan: Make user-provided descriptor pool optional. As a convenience, when setting init_info->DescriptorPoolSize the backend will create one itself. (#8172, #4867)
@ -1052,8 +1053,9 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
check_vk_result(err);
}
if (v->DescriptorPoolSize)
if (v->DescriptorPoolSize != 0)
{
IM_ASSERT(v->DescriptorPoolSize > IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE);
VkDescriptorPoolSize pool_size = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, v->DescriptorPoolSize };
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;

View File

@ -62,14 +62,16 @@
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
#endif
// Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
// It is expected that as early as Q1 2025 the backend will use a few more descriptors. Use this value + number of desired calls to ImGui_ImplVulkan_AddTexture().
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (1) // Minimum per atlas
// Initialization data, for ImGui_ImplVulkan_Init()
// [Please zero-clear before use!]
// - About descriptor pool:
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
// - Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
// - It is expected that as early as Q1 2025 the backend will use a few more descriptors, so aim at 10 + number of desierd calls to ImGui_ImplVulkan_AddTexture().
// - About dynamic rendering:
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
struct ImGui_ImplVulkan_InitInfo

View File

@ -43,8 +43,19 @@ Breaking changes:
Other changes:
- Fixed issues with IsItemDeactivated() and IsItemDeactivatedAfterEdit() not
emitting a reliable signal when an item is deactivated externally: e.g.
via an explicit clear of focus, clear of active id, opening of modal etc.
(#5184, #5904, #6766, #8303, #8004)
- It used to work when the interruption happened in the frame before the
active item as submitted, but not after. It should work in both cases now.
- While this is not specific to a certain widgets, typically it would
mostly be noticeable on InputText() because it keeps ActiveId for a
longer time while allowing other interaction to happen.
- Error Handling: Fixed bugs recovering from within a table that created
a child window, and from nested child windows. (#1651)
- Error Handling: Turned common EndTable() and other TableXXX functions
fail cases into a recoverable error. (#1651, #8314)
- InputText: Fixed a bug where character replacements performed from a callback
were not applied when pasting from clipbard. (#8229)
- InputText: Fixed issue when activating a ReadOnly field when the underlying
@ -79,6 +90,10 @@ Other changes:
platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222) [@Zer0xFF]
- Backends: Vulkan: Added a few more ImGui_ImplVulkanH_XXX helper functions
primarily for the purpose of making our examples simpler.
- Backends: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify
how many image sampler descriptors are expected to be available in the provided
descriptor pool. Current backend needs 1 but it is expected that by end of Q1 2025
this number will grow (will staying a very small number). (#6642)
- Backends: DX11: Expose vertex constant buffer in ImGui_ImplDX11_RenderState.
Reset projection matrix in ImDrawCallback_ResetRenderState handlers. (#6969, #5834, #7468, #3590)
- Backends: DX10: Expose ImGui_ImplDX10_RenderState for completeness. (#6969, #5834, #7468, #3590)
@ -156,11 +171,12 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
Breaking changes:
- Commented out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before).
- io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022).
- io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022). Use IsKeyDown() instead.
- io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022).
- Pre-1.87 backends are not supported:
- backends need to call io.AddKeyEvent(), io.AddMouseEvent() instead of writing to io.KeysDown[], io.MouseDown[] fields.
- backends need to call io.AddKeyAnalogEvent() for gamepad values instead of writing to io.NavInputs[] fields.
- you can use IsKeyDown() instead of reading from io.KeysDown[].
- For more references:
- read 1.87 and 1.88 part of API BREAKING CHANGES in imgui.cpp or read Changelog for 1.87 and 1.88.
- read https://github.com/ocornut/imgui/issues/4921
@ -2656,6 +2672,7 @@ Breaking Changes:
- For all calls to IO new functions, the Dear ImGui context should be bound/current.
- Reworked IO keyboard input API: (#4921, #2625, #3724) [@thedmd, @ocornut]
- Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays.
- You can use IsKeyDown() instead of reading from io.KeysDown[].
- For keyboard modifiers, you can call io.AddKeyEvent() with ImGuiKey_ModXXX values,
obsoleting writing directly to io.KeyCtrl, io.KeyShift etc.
- Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices.

View File

@ -189,17 +189,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
}
// Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
{
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.maxSets = 0;
for (VkDescriptorPoolSize& pool_size : pool_sizes)
pool_info.maxSets += pool_size.descriptorCount;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);

View File

@ -177,17 +177,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
}
// Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
{
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.maxSets = 0;
for (VkDescriptorPoolSize& pool_size : pool_sizes)
pool_info.maxSets += pool_size.descriptorCount;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);

View File

@ -182,17 +182,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
}
// Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
{
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.maxSets = 0;
for (VkDescriptorPoolSize& pool_size : pool_sizes)
pool_info.maxSets += pool_size.descriptorCount;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);

View File

@ -178,17 +178,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
}
// Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
{
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.maxSets = 0;
for (VkDescriptorPoolSize& pool_size : pool_sizes)
pool_info.maxSets += pool_size.descriptorCount;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);

View File

@ -658,7 +658,7 @@ CODE
- Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only]
note: for all calls to IO new functions, the Dear ImGui context should be bound/current.
read https://github.com/ocornut/imgui/issues/4921 for details.
- 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unnecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details.
- 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(), ImGui::IsKeyDown(). Removed GetKeyIndex(), now unnecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details.
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
- Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() (+ call io.SetKeyEventNativeData() if you want legacy user code to stil function with legacy key codes).
@ -4002,9 +4002,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
ActiveIdSource = ImGuiInputSource_None;
ActiveIdMouseButton = -1;
ActiveIdPreviousFrame = 0;
ActiveIdPreviousFrameIsAlive = false;
ActiveIdPreviousFrameHasBeenEditedBefore = false;
ActiveIdPreviousFrameWindow = NULL;
memset(&DeactivatedItemData, 0, sizeof(DeactivatedItemData));
memset(&ActiveIdValueOnActivation, 0, sizeof(ActiveIdValueOnActivation));
LastActiveId = 0;
LastActiveIdTimer = 0.0f;
@ -4270,7 +4268,7 @@ void ImGui::Shutdown()
g.WindowsById.Clear();
g.NavWindow = NULL;
g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL;
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
g.ActiveIdWindow = NULL;
g.MovingWindow = NULL;
g.KeysRoutingTable.Clear();
@ -4460,6 +4458,13 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
g.MovingWindow = NULL;
}
// Store deactivate data
ImGuiDeactivatedItemData* deactivated_data = &g.DeactivatedItemData;
deactivated_data->ID = g.ActiveId;
deactivated_data->ElapseFrame = (g.LastItemData.ID == g.ActiveId) ? g.FrameCount : g.FrameCount + 1; // FIXME: OK to use LastItemData?
deactivated_data->HasBeenEditedBefore = g.ActiveIdHasBeenEditedBefore;
deactivated_data->IsAlive = (g.ActiveIdIsAlive == g.ActiveId);
// This could be written in a more general way (e.g associate a hook to ActiveId),
// but since this is currently quite an exception we'll leave it as is.
// One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveID()
@ -5378,11 +5383,8 @@ void ImGui::NewFrame()
g.ActiveIdTimer += g.IO.DeltaTime;
g.LastActiveIdTimer += g.IO.DeltaTime;
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow;
g.ActiveIdPreviousFrameHasBeenEditedBefore = g.ActiveIdHasBeenEditedBefore;
g.ActiveIdIsAlive = 0;
g.ActiveIdHasBeenEditedThisFrame = false;
g.ActiveIdPreviousFrameIsAlive = false;
g.ActiveIdIsJustActivated = false;
if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
g.TempInputId = 0;
@ -5391,6 +5393,9 @@ void ImGui::NewFrame()
g.ActiveIdUsingNavDirMask = 0x00;
g.ActiveIdUsingAllKeyboardKeys = false;
}
if (g.DeactivatedItemData.ElapseFrame < g.FrameCount)
g.DeactivatedItemData.ID = 0;
g.DeactivatedItemData.IsAlive = false;
// Record when we have been stationary as this state is preserved while over same item.
// FIXME: The way this is expressed means user cannot alter HoverStationaryDelay during the frame to use varying values.
@ -6101,13 +6106,13 @@ bool ImGui::IsItemDeactivated()
ImGuiContext& g = *GImGui;
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDeactivated)
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Deactivated) != 0;
return (g.ActiveIdPreviousFrame == g.LastItemData.ID && g.ActiveIdPreviousFrame != 0 && g.ActiveId != g.LastItemData.ID);
return (g.DeactivatedItemData.ID == g.LastItemData.ID && g.LastItemData.ID != 0 && g.DeactivatedItemData.ElapseFrame >= g.FrameCount);
}
bool ImGui::IsItemDeactivatedAfterEdit()
{
ImGuiContext& g = *GImGui;
return IsItemDeactivated() && (g.ActiveIdPreviousFrameHasBeenEditedBefore || (g.ActiveId == 0 && g.ActiveIdHasBeenEditedBefore));
return IsItemDeactivated() && g.DeactivatedItemData.HasBeenEditedBefore;
}
// == (GetItemID() == GetFocusID() && GetFocusID() != 0)
@ -11115,8 +11120,8 @@ void ImGui::KeepAliveID(ImGuiID id)
ImGuiContext& g = *GImGui;
if (g.ActiveId == id)
g.ActiveIdIsAlive = id;
if (g.ActiveIdPreviousFrame == id)
g.ActiveIdPreviousFrameIsAlive = true;
if (g.DeactivatedItemData.ID == id)
g.DeactivatedItemData.IsAlive = true;
}
// Declare item bounding box for clipping and interaction.
@ -11201,6 +11206,9 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
// window->DrawList->AddRect(g.LastItemData.NavRect.Min, g.LastItemData.NavRect.Max, IM_COL32(255,255,0,255)); // [DEBUG]
#endif
if (id != 0 && g.DeactivatedItemData.ID == id)
g.DeactivatedItemData.ElapseFrame = g.FrameCount;
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
if (is_rect_visible)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Visible;
@ -11560,7 +11568,7 @@ void ImGui::BeginGroup()
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
group_data.BackupHoveredIdIsAlive = g.HoveredId != 0;
group_data.BackupIsSameLine = window->DC.IsSameLine;
group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
group_data.BackupDeactivatedIdIsAlive = g.DeactivatedItemData.IsAlive;
group_data.EmitItem = true;
window->DC.GroupOffset.x = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffset.x;
@ -11611,11 +11619,11 @@ void ImGui::EndGroup()
// Also if you grep for LastItemId you'll notice it is only used in that context.
// (The two tests not the same because ActiveIdIsAlive is an ID itself, in order to be able to handle ActiveId being overwritten during the frame.)
const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId;
const bool group_contains_prev_active_id = (group_data.BackupActiveIdPreviousFrameIsAlive == false) && (g.ActiveIdPreviousFrameIsAlive == true);
const bool group_contains_deactivated_id = (group_data.BackupDeactivatedIdIsAlive == false) && (g.DeactivatedItemData.IsAlive == true);
if (group_contains_curr_active_id)
g.LastItemData.ID = g.ActiveId;
else if (group_contains_prev_active_id)
g.LastItemData.ID = g.ActiveIdPreviousFrame;
else if (group_contains_deactivated_id)
g.LastItemData.ID = g.DeactivatedItemData.ID;
g.LastItemData.Rect = group_bb;
// Forward Hovered flag
@ -11629,7 +11637,7 @@ void ImGui::EndGroup()
// Forward Deactivated flag
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDeactivated;
if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame)
if (group_contains_deactivated_id)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Deactivated;
g.GroupStack.pop_back();

View File

@ -29,7 +29,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.91.7 WIP"
#define IMGUI_VERSION_NUM 19164
#define IMGUI_VERSION_NUM 19165
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch

View File

@ -140,6 +140,7 @@ struct ImGuiContext; // Main Dear ImGui context
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum)
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function.
struct ImGuiDockContext; // Docking system context
struct ImGuiDockRequest; // Docking system dock/undock queued request
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
@ -1081,7 +1082,7 @@ struct IMGUI_API ImGuiGroupData
ImVec2 BackupCurrLineSize;
float BackupCurrLineTextBaseOffset;
ImGuiID BackupActiveIdIsAlive;
bool BackupActiveIdPreviousFrameIsAlive;
bool BackupDeactivatedIdIsAlive;
bool BackupHoveredIdIsAlive;
bool BackupIsSameLine;
bool EmitItem;
@ -1266,11 +1267,11 @@ struct ImGuiNextItemData
struct ImGuiLastItemData
{
ImGuiID ID;
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_ (called 'InFlags' before v1.91.4).
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
ImRect Rect; // Full rectangle
ImRect NavRect; // Navigation scoring rectangle (not displayed)
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set.
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags are set.
ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set.
ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set..
ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set..
@ -1333,6 +1334,15 @@ struct ImGuiPtrOrIndex
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
};
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
struct ImGuiDeactivatedItemData
{
ImGuiID ID;
int ElapseFrame;
bool HasBeenEditedBefore;
bool IsAlive;
};
//-----------------------------------------------------------------------------
// [SECTION] Popup support
//-----------------------------------------------------------------------------
@ -2302,9 +2312,7 @@ struct ImGuiContext
ImGuiWindow* ActiveIdWindow;
ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad
ImGuiID ActiveIdPreviousFrame;
bool ActiveIdPreviousFrameIsAlive;
bool ActiveIdPreviousFrameHasBeenEditedBefore;
ImGuiWindow* ActiveIdPreviousFrameWindow;
ImGuiDeactivatedItemData DeactivatedItemData;
ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX.
ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.

View File

@ -1337,7 +1337,11 @@ void ImGui::EndTable()
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
return;
}
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
@ -1560,8 +1564,12 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
if (table->DeclColumnsCount >= table->ColumnsCount)
{
@ -1634,7 +1642,11 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
@ -1711,9 +1723,11 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL);
if (!table)
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
if (column_n < 0)
column_n = table->CurrentColumn;
@ -3034,7 +3048,11 @@ void ImGui::TableHeadersRow()
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
@ -3079,7 +3097,12 @@ void ImGui::TableHeader(const char* label)
return;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
IM_ASSERT(table->CurrentColumn != -1);
const int column_n = table->CurrentColumn;
ImGuiTableColumn* column = &table->Columns[column_n];
@ -3254,7 +3277,11 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
ImGuiTable* table = g.CurrentTable;
ImGuiWindow* window = g.CurrentWindow;
ImDrawList* draw_list = window->DrawList;
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
if (max_label_width == 0.0f)