Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_sdlgpu3.cpp
#	imgui.cpp
This commit is contained in:
ocornut
2025-08-08 15:51:56 +02:00
11 changed files with 111 additions and 64 deletions

View File

@@ -2,7 +2,7 @@
// This needs to be used along with the SDL3 Platform Backend // This needs to be used along with the SDL3 Platform Backend
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID. // [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset). // [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures). // [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@@ -24,6 +24,8 @@
// CHANGELOG // CHANGELOG
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2025-08-08: *BREAKING* Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
// 2025-08-08: Expose SamplerDefault and SamplerCurrent in ImGui_ImplSDLGPU3_RenderState. Allow callback to change sampler.
// 2025-06-25: Mapping transfer buffer for texture update use cycle=true. Fixes artifacts e.g. on Metal backend. // 2025-06-25: Mapping transfer buffer for texture update use cycle=true. Fixes artifacts e.g. on Metal backend.
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture(). // 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
// 2025-04-28: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2025-04-28: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
@@ -38,11 +40,6 @@
#include "imgui_impl_sdlgpu3_shaders.h" #include "imgui_impl_sdlgpu3_shaders.h"
// SDL_GPU Data // SDL_GPU Data
struct ImGui_ImplSDLGPU3_Texture
{
SDL_GPUTexture* Texture = nullptr;
SDL_GPUTextureSamplerBinding TextureSamplerBinding = { nullptr, nullptr };
};
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData() // Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
struct ImGui_ImplSDLGPU3_FrameData struct ImGui_ImplSDLGPU3_FrameData
@@ -86,12 +83,13 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
} }
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height) static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, ImGui_ImplSDLGPU3_RenderState* render_state, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
{ {
//ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
render_state->SamplerCurrent = render_state->SamplerCurrent = bd->TexSampler;
// Bind graphics pipeline // Bind graphics pipeline
SDL_BindGPUGraphicsPipeline(render_pass,pipeline); SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
// Bind Vertex And Index Buffers // Bind Vertex And Index Buffers
if (draw_data->TotalVtxCount > 0) if (draw_data->TotalVtxCount > 0)
@@ -229,12 +227,19 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
if (pipeline == nullptr) if (pipeline == nullptr)
pipeline = bd->Pipeline; pipeline = bd->Pipeline;
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplSDLGPU3_RenderState render_state;
render_state.Device = bd->InitInfo.Device;
render_state.SamplerDefault = render_state.SamplerCurrent = bd->TexSampler;
platform_io.Renderer_RenderState = &render_state;
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0; int global_vtx_offset = 0;
@@ -249,7 +254,7 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height); ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
else else
pcmd->UserCallback(draw_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
@@ -276,9 +281,14 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
SDL_SetGPUScissor(render_pass,&scissor_rect); SDL_SetGPUScissor(render_pass,&scissor_rect);
// Bind DescriptorSet with font or user texture // Bind DescriptorSet with font or user texture
SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1); SDL_GPUTextureSamplerBinding texture_sampler_binding;
texture_sampler_binding.texture = (SDL_GPUTexture*)(intptr_t)pcmd->GetTexID();
texture_sampler_binding.sampler = render_state.SamplerCurrent;
SDL_BindGPUFragmentSamplers(render_pass, 0, &texture_sampler_binding, 1);
// Draw // Draw
// **IF YOU GET A CRASH HERE** In 1.92.2 on 2025/08/08 we have changed ImTextureID to store 'SDL_GPUTexture*' instead of storing 'SDL_GPUTextureSamplerBinding'.
// Any code loading custom texture using this backend needs to be updated.
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
} }
@@ -297,18 +307,13 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex) static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex)
{ {
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData; SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
if (backend_tex == nullptr) if (raw_tex != nullptr)
return; SDL_ReleaseGPUTexture(bd->InitInfo.Device, raw_tex);
SDL_GPUTextureSamplerBinding* binding = (SDL_GPUTextureSamplerBinding*)(intptr_t)tex->BackendUserData;
IM_ASSERT(backend_tex->Texture == binding->texture);
SDL_ReleaseGPUTexture(bd->InitInfo.Device, backend_tex->Texture);
IM_DELETE(backend_tex);
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
tex->SetTexID(ImTextureID_Invalid); tex->SetTexID(ImTextureID_Invalid);
tex->SetStatus(ImTextureStatus_Destroyed); tex->SetStatus(ImTextureStatus_Destroyed);
tex->BackendUserData = nullptr;
} }
void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex) void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
@@ -322,7 +327,6 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height); //IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr); IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32); IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
ImGui_ImplSDLGPU3_Texture* backend_tex = IM_NEW(ImGui_ImplSDLGPU3_Texture)();
// Create texture // Create texture
SDL_GPUTextureCreateInfo texture_info = {}; SDL_GPUTextureCreateInfo texture_info = {};
@@ -335,19 +339,16 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
texture_info.num_levels = 1; texture_info.num_levels = 1;
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1; texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
backend_tex->Texture = SDL_CreateGPUTexture(v->Device, &texture_info); SDL_GPUTexture* raw_tex = SDL_CreateGPUTexture(v->Device, &texture_info);
backend_tex->TextureSamplerBinding.texture = backend_tex->Texture; IM_ASSERT(raw_tex != nullptr && "Failed to create font texture, call SDL_GetError() for more info");
backend_tex->TextureSamplerBinding.sampler = bd->TexSampler;
IM_ASSERT(backend_tex->Texture && "Failed to create font texture, call SDL_GetError() for more info");
// Store identifiers // Store identifiers
tex->SetTexID((ImTextureID)(intptr_t)&backend_tex->TextureSamplerBinding); tex->SetTexID((ImTextureID)(intptr_t)raw_tex);
tex->BackendUserData = backend_tex;
} }
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates) if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
{ {
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData; SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32); IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before! // Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
@@ -385,7 +386,7 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
transfer_info.transfer_buffer = bd->TexTransferBuffer; transfer_info.transfer_buffer = bd->TexTransferBuffer;
SDL_GPUTextureRegion texture_region = {}; SDL_GPUTextureRegion texture_region = {};
texture_region.texture = backend_tex->Texture; texture_region.texture = raw_tex;
texture_region.x = (Uint32)upload_x; texture_region.x = (Uint32)upload_x;
texture_region.y = (Uint32)upload_y; texture_region.y = (Uint32)upload_y;
texture_region.w = (Uint32)upload_w; texture_region.w = (Uint32)upload_w;

View File

@@ -2,7 +2,7 @@
// This needs to be used along with the SDL3 Platform Backend // This needs to be used along with the SDL3 Platform Backend
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID. // [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset). // [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures). // [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@@ -50,4 +50,14 @@ IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually. // (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex); IMGUI_IMPL_API void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex);
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLGPU3_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplSDLGPU3_RenderState
{
SDL_GPUDevice* Device;
SDL_GPUSampler* SamplerDefault; // Default sampler (bilinear filtering)
SDL_GPUSampler* SamplerCurrent; // Current sampler (may be changed by callback)
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@@ -617,6 +617,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
VkDescriptorSet last_desc_set = VK_NULL_HANDLE;
int global_vtx_offset = 0; int global_vtx_offset = 0;
int global_idx_offset = 0; int global_idx_offset = 0;
for (const ImDrawList* draw_list : draw_data->CmdLists) for (const ImDrawList* draw_list : draw_data->CmdLists)
@@ -632,6 +633,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
else else
pcmd->UserCallback(draw_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
last_desc_set = VK_NULL_HANDLE;
} }
else else
{ {
@@ -657,7 +659,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Bind DescriptorSet with font or user texture // Bind DescriptorSet with font or user texture
VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->GetTexID(); VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->GetTexID();
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr); if (desc_set != last_desc_set)
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr);
last_desc_set = desc_set;
// Draw // Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);

View File

@@ -43,12 +43,24 @@ Breaking Changes:
- Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink.
Kept inline redirection enum (will obsolete). (#261, #351) Kept inline redirection enum (will obsolete). (#261, #351)
- Backends: SDL_GPU3: changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*,
which is more natural and easier for user to manage. If you need to change the current sampler,
you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
Other Changes: Other Changes:
- Fonts: fixed an issue when a font using MergeMode has a reference size
specified but the target font doesn't. Usually either all fonts should
have a reference size (only required when specifying e.g. GlyphOffset),
or none should have a reference size.
- Fonts: fixed a crash when changing texture format when using a legacy
backend. Most commonly would happen when calling GetTexDataAsRGBA32()
then immediately GetTexDataAsAlpha8(). (#8824)
- Windows: fixed an issue where resizable child windows would emit border - Windows: fixed an issue where resizable child windows would emit border
logic when hidden/non-visible (e.g. when in a docked window that is not logic when hidden/non-visible (e.g. when in a docked window that is not
selected), impacting code not checking for BeginChild() return value. (#8815) selected), impacting code not checking for BeginChild() return value. (#8815)
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
ImFontAtlas() was incorrectly cleared with zeroes. (#8860, #8745) [@cfillion]
- Tables: fixed TableGetRowIndex() which never correctly worked when using - Tables: fixed TableGetRowIndex() which never correctly worked when using
a clipper (it exists for consistency but is almost never used, as it is a clipper (it exists for consistency but is almost never used, as it is
often more convenient to use index in caller-code, whereas TableGetRowIndex() often more convenient to use index in caller-code, whereas TableGetRowIndex()
@@ -68,6 +80,9 @@ Other Changes:
any potential shrinking is applied. any potential shrinking is applied.
- Tabs: fixed tab bar underline not drawing below scroll buttons, when - Tabs: fixed tab bar underline not drawing below scroll buttons, when
they are enabled (minor regression from 1.90). (#6820, #4859, #5022, #5239) they are enabled (minor regression from 1.90). (#6820, #4859, #5022, #5239)
- Tabs: made scrolling buttons never keyboard/gamepad navigation candidates.
- Nav: fixed a bug where GamepadMenu button couldn't toggle between main and
menu layers while navigating a Modal window. (#8834)
- Error Handling: minor improvements to error handling for TableGetSortSpecs() - Error Handling: minor improvements to error handling for TableGetSortSpecs()
and TableSetBgColor() calls. (#1651, #8499) and TableSetBgColor() calls. (#1651, #8499)
- Misc: fixed building with IMGUI_DISABLE_DEBUG_TOOLS only. (#8796) - Misc: fixed building with IMGUI_DISABLE_DEBUG_TOOLS only. (#8796)
@@ -77,12 +92,18 @@ Other Changes:
- CI: Added SDL3 builds to MacOS and Windows. (#8819, #8778) [@scribam] - CI: Added SDL3 builds to MacOS and Windows. (#8819, #8778) [@scribam]
- CI: Updated Windows CI to use a more recent SDL2. (#8819, #8778) [@scribam] - CI: Updated Windows CI to use a more recent SDL2. (#8819, #8778) [@scribam]
- Examples: SDL3+Metal: added SDL3+Metal example. (#8827, #8825) [@shi-yan] - Examples: SDL3+Metal: added SDL3+Metal example. (#8827, #8825) [@shi-yan]
- Examples: SDL3+SDL_GPU: use SDL_WaitAndAcquireGPUSwapchainTexture() instead
of SDL_AcquireGPUSwapchainTexture(). (#8830) [@itsdanott]
- Backends: OpenGL3: add and call embedded loader shutdown in ImGui_ImplOpenGL3_Shutdown() - Backends: OpenGL3: add and call embedded loader shutdown in ImGui_ImplOpenGL3_Shutdown()
to facilitate multiple init/shutdown cycles in same process. (#8792) [@tim-rex] to facilitate multiple init/shutdown cycles in same process. (#8792) [@tim-rex]
- Backends: OpenGL2, OpenGL3: set GL_UNPACK_ALIGNMENT to 1 before updating - Backends: OpenGL2, OpenGL3: set GL_UNPACK_ALIGNMENT to 1 before updating
textures. (#8802) [@Daandelange] textures. (#8802) [@Daandelange]
- Backends: SDL_GPU3: expose current SDL_GPUSampler* in the ImGui_ImplSDLGPU3_RenderState
struct. (#8866, #8163, #7998, #7988)
- Backends: Vulkan: Fixed texture update corruption introduced in 1.92.0, - Backends: Vulkan: Fixed texture update corruption introduced in 1.92.0,
affecting some drivers/setups. (#8801, #8755, #8840) [@Retro52, @Miolith] affecting some drivers/setups. (#8801, #8755, #8840) [@Retro52, @Miolith]
- Backends: Vulkan: Avoid calling vkCmdBindDescriptorSets() when texture
has not changed. (#8666) [@micb25]
Docking+Viewports Branch: Docking+Viewports Branch:
@@ -113,6 +134,8 @@ Changes:
to pass full range of information into e.g. FreeType's face_index, as higher to pass full range of information into e.g. FreeType's face_index, as higher
bits are used from FreeType 2.6.1. (#8775) [@Valakor] bits are used from FreeType 2.6.1. (#8775) [@Valakor]
(the field has been erroneously reduced from 32-bits to 8-bit in 1.92.0) (the field has been erroneously reduced from 32-bits to 8-bit in 1.92.0)
- Fonts, Tables: fixed PushFont() having no effect when called after submitting
a hidden column. (#8865)
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value: - Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
ImTextureData() was incorrectly cleared with zeroes. (#8745) [@rachit7645] ImTextureData() was incorrectly cleared with zeroes. (#8745) [@rachit7645]
- Demo: Added "Text -> Font Size" demo section. (#8738) [@Demonese] - Demo: Added "Text -> Font Size" demo section. (#8738) [@Demonese]

View File

@@ -60,7 +60,7 @@ int main(int, char**)
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError()); printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
return -1; return -1;
} }
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_MAILBOX); SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
@@ -195,7 +195,7 @@ int main(int, char**)
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); // Acquire a GPU command buffer SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); // Acquire a GPU command buffer
SDL_GPUTexture* swapchain_texture; SDL_GPUTexture* swapchain_texture;
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture SDL_WaitAndAcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture
if (swapchain_texture != nullptr && !is_minimized) if (swapchain_texture != nullptr && !is_minimized)
{ {

View File

@@ -15,7 +15,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#include <windows.h> #include <windows.h>
#include <GL/GL.h> #include <GL/gl.h>
#include <tchar.h> #include <tchar.h>
// Data stored per platform window // Data stored per platform window

View File

@@ -400,6 +400,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
- likewise io.MousePos and GetMousePos() will use OS coordinates. - likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2025/08/08 (1.92.2) - Backends: SDL_GPU3: Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
- 2025/07/31 (1.92.2) - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. Kept inline redirection enum (will obsolete). - 2025/07/31 (1.92.2) - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. Kept inline redirection enum (will obsolete).
- 2025/06/25 (1.92.0) - Layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM - 2025/06/25 (1.92.0) - Layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM
to extend parent window/cell boundaries. Replaced with assert/tooltip that would already happens if previously using IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#5548, #4510, #3355, #1760, #1490, #4152, #150) to extend parent window/cell boundaries. Replaced with assert/tooltip that would already happens if previously using IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#5548, #4510, #3355, #1760, #1490, #4152, #150)
@@ -9447,11 +9448,14 @@ void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
g.Style.FontSizeBase = g.FontSizeBase; g.Style.FontSizeBase = g.FontSizeBase;
// Early out to avoid hidden window keeping bakes referenced and out of GC reach. // Early out to avoid hidden window keeping bakes referenced and out of GC reach.
// However this would leave a pretty subtle and damning error surface area if g.FontBaked was mismatching, so for now we null it. // However this would leave a pretty subtle and damning error surface area if g.FontBaked was mismatching.
// FIXME: perhaps g.FontSize should be updated? // FIXME: perhaps g.FontSize should be updated?
if (window != NULL && window->SkipItems) if (window != NULL && window->SkipItems)
if (g.CurrentTable == NULL || g.CurrentTable->CurrentColumn != -1) // See 8465#issuecomment-2951509561. Ideally the SkipItems=true in tables would be amended with extra data. {
ImGuiTable* table = g.CurrentTable;
if (table == NULL || (table->CurrentColumn != -1 && table->Columns[table->CurrentColumn].IsSkipItems == false)) // See 8465#issuecomment-2951509561 and #8865. Ideally the SkipItems=true in tables would be amended with extra data.
return; return;
}
// Restoring is pretty much only used by PopFont() // Restoring is pretty much only used by PopFont()
float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f; float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f;
@@ -14907,9 +14911,16 @@ static void ImGui::NavUpdateWindowing()
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && Shortcut(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_RouteAlways, owner_id); const bool start_toggling_with_gamepad = nav_gamepad_active && !g.NavWindowingTarget && Shortcut(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_RouteAlways, owner_id);
const bool start_windowing_with_gamepad = allow_windowing && start_toggling_with_gamepad;
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard! const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard!
bool just_started_windowing_from_null_focus = false; bool just_started_windowing_from_null_focus = false;
if (start_toggling_with_gamepad)
{
g.NavWindowingToggleLayer = true; // Gamepad starts toggling layer
g.NavWindowingToggleKey = ImGuiKey_NavGamepadMenu;
g.NavWindowingInputSource = g.NavInputSource = ImGuiInputSource_Gamepad;
}
if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (start_windowing_with_gamepad || start_windowing_with_keyboard)
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
{ {
@@ -14917,7 +14928,6 @@ static void ImGui::NavUpdateWindowing()
g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location
g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f); g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f);
g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer
g.NavWindowingInputSource = g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; g.NavWindowingInputSource = g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
if (g.NavWindow == NULL) if (g.NavWindow == NULL)
just_started_windowing_from_null_focus = true; just_started_windowing_from_null_focus = true;
@@ -22805,8 +22815,8 @@ void ImGui::DebugNodeFont(ImFont* font)
for (int src_n = 0; src_n < font->Sources.Size; src_n++) for (int src_n = 0; src_n < font->Sources.Size; src_n++)
{ {
ImFontConfig* src = font->Sources[src_n]; ImFontConfig* src = font->Sources[src_n];
if (TreeNode(src, "Input %d: \'%s\', Oversample: %d,%d, PixelSnapH: %d, Offset: (%.1f,%.1f)", if (TreeNode(src, "Input %d: \'%s\' [%d], Oversample: %d,%d, PixelSnapH: %d, Offset: (%.1f,%.1f)",
src_n, src->Name, src->OversampleH, src->OversampleV, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y)) src_n, src->Name, src->FontNo, src->OversampleH, src->OversampleV, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y))
{ {
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader; const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
Text("Loader: '%s'", loader->Name ? loader->Name : "N/A"); Text("Loader: '%s'", loader->Name ? loader->Name : "N/A");

18
imgui.h
View File

@@ -29,7 +29,7 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.2 WIP" #define IMGUI_VERSION "1.92.2 WIP"
#define IMGUI_VERSION_NUM 19213 #define IMGUI_VERSION_NUM 19214
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch. #define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
@@ -4228,24 +4228,24 @@ struct ImGuiPlatformImeData
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.92.0 (from June 2025) // OBSOLETED in 1.92.0 (from June 2025)
static inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); } inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); }
IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFont(NULL, style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows. IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFont(NULL, style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows.
// OBSOLETED in 1.91.9 (from February 2025) // OBSOLETED in 1.91.9 (from February 2025)
IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead. IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead.
// OBSOLETED in 1.91.0 (from July 2024) // OBSOLETED in 1.91.0 (from July 2024)
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); } inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
static inline void PopButtonRepeat() { PopItemFlag(); } inline void PopButtonRepeat() { PopItemFlag(); }
static inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); } inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
static inline void PopTabStop() { PopItemFlag(); } inline void PopTabStop() { PopItemFlag(); }
IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
// OBSOLETED in 1.90.0 (from September 2023) // OBSOLETED in 1.90.0 (from September 2023)
static inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); } inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
static inline void EndChildFrame() { EndChild(); } inline void EndChildFrame() { EndChild(); }
//static inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders //static inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
//static inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders //static inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
static inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); } inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
// OBSOLETED in 1.89.7 (from June 2023) // OBSOLETED in 1.89.7 (from June 2023)

View File

@@ -2637,6 +2637,7 @@ ImFontAtlas::ImFontAtlas()
TexMinHeight = 128; TexMinHeight = 128;
TexMaxWidth = 8192; TexMaxWidth = 8192;
TexMaxHeight = 8192; TexMaxHeight = 8192;
TexRef._TexID = ImTextureID_Invalid;
RendererHasTextures = false; // Assumed false by default, as apps can call e.g Atlas::Build() after backend init and before ImGui can update. RendererHasTextures = false; // Assumed false by default, as apps can call e.g Atlas::Build() after backend init and before ImGui can update.
TexNextUniqueID = 1; TexNextUniqueID = 1;
FontNextUniqueID = 1; FontNextUniqueID = 1;
@@ -3368,11 +3369,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
{ {
IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
if (atlas->TexData && atlas->TexData->Format != atlas->TexDesiredFormat) if (atlas->TexData && atlas->TexData->Format != atlas->TexDesiredFormat)
{ ImFontAtlasBuildClear(atlas);
ImVec2i new_tex_size = ImFontAtlasTextureGetSizeEstimate(atlas);
ImFontAtlasBuildDestroy(atlas);
ImFontAtlasTextureAdd(atlas, new_tex_size.x, new_tex_size.y);
}
if (atlas->Builder == NULL) if (atlas->Builder == NULL)
ImFontAtlasBuildInit(atlas); ImFontAtlasBuildInit(atlas);
@@ -4578,15 +4575,16 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
} }
src->FontLoaderData = bd_font_data; src->FontLoaderData = bd_font_data;
const float ref_size = src->DstFont->Sources[0]->SizePixels;
if (src->MergeMode && src->SizePixels == 0.0f) if (src->MergeMode && src->SizePixels == 0.0f)
src->SizePixels = src->DstFont->Sources[0]->SizePixels; src->SizePixels = ref_size;
if (src->SizePixels >= 0.0f) if (src->SizePixels >= 0.0f)
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f); bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
else else
bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f); bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f);
if (src->MergeMode && src->SizePixels != 0.0f) if (src->MergeMode && src->SizePixels != 0.0f && ref_size != 0.0f)
bd_font_data->ScaleFactor *= src->SizePixels / src->DstFont->Sources[0]->SizePixels; // FIXME-NEWATLAS: Should tidy up that a bit bd_font_data->ScaleFactor *= src->SizePixels / ref_size; // FIXME-NEWATLAS: Should tidy up that a bit
return true; return true;
} }

View File

@@ -2533,8 +2533,8 @@ struct ImGuiContext
float NavWindowingTimer; float NavWindowingTimer;
float NavWindowingHighlightAlpha; float NavWindowingHighlightAlpha;
ImGuiInputSource NavWindowingInputSource; ImGuiInputSource NavWindowingInputSource;
bool NavWindowingToggleLayer; bool NavWindowingToggleLayer; // Set while Alt or GamepadMenu is held, may be cleared by other operations, and processed when releasing the key.
ImGuiKey NavWindowingToggleKey; ImGuiKey NavWindowingToggleKey; // Keyboard/gamepad key used when toggling to menu layer.
ImVec2 NavWindowingAccumDeltaPos; ImVec2 NavWindowingAccumDeltaPos;
ImVec2 NavWindowingAccumDeltaSize; ImVec2 NavWindowingAccumDeltaSize;

View File

@@ -1846,7 +1846,7 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc
} }
ImQsort(items, (size_t)count, sizeof(ImGuiShrinkWidthItem), ShrinkWidthItemComparer); // Sort largest first, smallest last. ImQsort(items, (size_t)count, sizeof(ImGuiShrinkWidthItem), ShrinkWidthItemComparer); // Sort largest first, smallest last.
int count_same_width = 1; int count_same_width = 1;
while (width_excess > 0.0f && count_same_width < count) while (width_excess > 0.001f && count_same_width < count)
{ {
while (count_same_width < count && items[0].Width <= items[count_same_width].Width) while (count_same_width < count && items[0].Width <= items[count_same_width].Width)
count_same_width++; count_same_width++;
@@ -4950,7 +4950,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{ {
// Determine if we turn Enter into a \n character // Determine if we turn Enter into a \n character
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != io.KeyCtrl))
{ {
validated = true; validated = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline) if (io.ConfigInputTextEnterKeepActive && !is_multiline)
@@ -9703,7 +9703,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// Horizontal scrolling buttons // Horizontal scrolling buttons
// Important: note that TabBarScrollButtons() will alter BarRect.Max.x. // Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
const bool can_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) || (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyMixed); const bool can_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) || (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyMixed);
tab_bar->ScrollButtonEnabled = ((width_all_tabs_after_min_width_shrink > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll); const float width_all_tabs_to_use_for_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) ? tab_bar->WidthAllTabs : width_all_tabs_after_min_width_shrink;
tab_bar->ScrollButtonEnabled = ((width_all_tabs_to_use_for_scroll > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll);
if (tab_bar->ScrollButtonEnabled) if (tab_bar->ScrollButtonEnabled)
if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar)) if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar))
{ {
@@ -10101,7 +10102,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
PushStyleColor(ImGuiCol_Text, arrow_col); PushStyleColor(ImGuiCol_Text, arrow_col);
PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); PushItemFlag(ImGuiItemFlags_ButtonRepeat | ImGuiItemFlags_NoNav, true);
const float backup_repeat_delay = g.IO.KeyRepeatDelay; const float backup_repeat_delay = g.IO.KeyRepeatDelay;
const float backup_repeat_rate = g.IO.KeyRepeatRate; const float backup_repeat_rate = g.IO.KeyRepeatRate;
g.IO.KeyRepeatDelay = 0.250f; g.IO.KeyRepeatDelay = 0.250f;