Compare commits

...

15 Commits

Author SHA1 Message Date
Alexandre
11930b0231 Removed dummy file, time for fun 2026-09-28 16:05:44 +02:00
Alexandre
45e12fb3fb Added dummy file 2026-09-28 15:54:44 +02:00
ocornut
aa0181478b imgui_freetype: tweak rounding code. (#9348, #9233) 2026-09-25 14:22:08 +02:00
ocornut
5c6a86a9d2 imgui_freetype: fixed ExtraSizeScale (used by embedded ProggyForever) leading to non-pixel aligned vertical offset. (#9348, #9233) + Added ImRoundPositive64(), ImRoundSigned64(). 2026-09-25 14:22:08 +02:00
Brenton Bostick
e728936797 Docs: fixed typos/repeated words. (#9555) 2026-09-24 14:33:24 +02:00
Daniel Castonguay
623ba46120 DrawList: fixed dangling ImDrawList::_OwnerName when using animated label. (#9552) 2026-09-23 16:04:56 +02:00
ocornut
cc072ca90e Tables: comments for saving fix when using ImGuiTableFlags_Sortable and no user changes were made. (#9519, #9108)
Because SortOrder save is gated, it doesn't guarantee every column gets an .ini entry. Amend 1d7b37dc9b.
We set ImGuiTableFlags_Reorderable but technically any other field would work, tho ImGuiTableFlags_Reorderable makes more sense.
2026-09-22 17:13:16 +02:00
ocornut
a6784c378f Tables: fixed reconcile path being needlessly taken on first frame of every table. (#9108) 2026-09-22 16:54:13 +02:00
ocornut
7bfc192814 Tables: tweak struct packing. 2026-09-22 16:48:51 +02:00
ocornut
d12321803d Popups: reworked GetMousePosOnOpeningCurrentPopup() to be legal to call within the BeginPopup/EndPopup scope of a popup which was just closed. (#9551) 2026-09-22 15:57:40 +02:00
ocornut
58d7570b8b ImGuiTextFilterItem: shallow renames. 2026-09-21 18:26:00 +02:00
ocornut
6cf8332f93 ImGuiTextFilterItem: added MatchIncludesMask support field for e.g. ImGuiTextFilterMultiMatch. 2026-09-21 16:52:48 +02:00
ocornut
e19fea020f ImGuiTextFilter: moved ImGuiTextFilterItem to internals. (#2435) 2026-09-21 15:12:59 +02:00
ocornut
d5c68c301a ImGuiTextFilter: reworked filter to make space an AND operator. Demo: tweaked demo.
Removed FilterOp, MinWordSize added a few commits ago.
2026-09-21 14:29:04 +02:00
ocornut
420f179341 Backends: fixed Clang -Wold-style-cast warnings.
Amend 8e17468
2026-09-18 22:31:58 +02:00
28 changed files with 173 additions and 97 deletions

View File

@ -101,6 +101,11 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState()
{
return (ImGui_ImplDX10_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// Functions
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
{

View File

@ -46,7 +46,6 @@ struct ImGui_ImplDX10_RenderState
//ID3D10SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
//ID3D10SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
};
static inline ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState() { return (ImGui_ImplDX10_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -103,6 +103,11 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState()
{
return (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// Functions
static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
{

View File

@ -48,7 +48,6 @@ struct ImGui_ImplDX11_RenderState
//ID3D11SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
//ID3D11SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
};
static inline ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState() { return (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -133,6 +133,11 @@ static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState()
{
return (ImGui_ImplDX12_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// Buffers used during the rendering of a frame
struct ImGui_ImplDX12_RenderBuffers
{

View File

@ -74,8 +74,7 @@ struct ImGui_ImplDX12_RenderState
ID3D12Device* Device;
ID3D12GraphicsCommandList* CommandList;
};
static inline ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState() { return (ImGui_ImplDX12_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState();
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy initialization API Obsoleted in 1.91.5

View File

@ -276,6 +276,11 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState()
{
return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
struct ImGui_ImplOpenGL3_VtxAttribState

View File

@ -76,7 +76,6 @@ struct ImGui_ImplOpenGL3_RenderState
unsigned int CurrentSampler; // (GLuint) Used if UseBindSampler == true (and are available), otherwise always 0
unsigned int CurrentTexParameterFilter; // (GLuint) Used if UseTexParameterFilter == true
};
static inline ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState() { return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -114,7 +114,7 @@ extern "C" {
#define GLAPI extern
#endif
/* glcorearb.h is for use with OpenGL core profile implementations.
** It should should be placed in the same directory as gl.h and
** It should be placed in the same directory as gl.h and
** included as <GL/glcorearb.h>.
**
** glcorearb.h includes only APIs in the latest OpenGL core profile

View File

@ -94,6 +94,11 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState()
{
return (ImGui_ImplSDLGPU3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
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)
{
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();

View File

@ -59,7 +59,6 @@ struct ImGui_ImplSDLGPU3_RenderState
{
SDL_GPUDevice* Device;
};
static inline ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState() { return (ImGui_ImplSDLGPU3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -76,6 +76,11 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState()
{
return (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// Functions
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
{

View File

@ -51,7 +51,6 @@ struct ImGui_ImplSDLRenderer2_RenderState
{
SDL_Renderer* Renderer;
};
static inline ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState() { return (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -81,6 +81,11 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState()
{
return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
// Functions
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
{

View File

@ -51,7 +51,6 @@ struct ImGui_ImplSDLRenderer3_RenderState
SDL_Renderer* Renderer;
SDL_ScaleMode CurrentScaleMode; // Current scale mode during render. Set to SDL_SCALEMODE_INVALID to use "SetSamplerFromTex" mode.
};
static inline ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState() { return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState();
#endif // #ifndef IMGUI_DISABLE

View File

@ -459,6 +459,11 @@ static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState()
{
return (ImGui_ImplVulkan_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
// Get the Vulkan function pointers used by the current backend.
// If no backend is available, return the currently loaded global function pointers (ImGuiImplVulkanFuncs).

View File

@ -175,8 +175,7 @@ struct ImGui_ImplVulkan_RenderState
VkPipeline Pipeline;
VkPipelineLayout PipelineLayout;
};
static inline ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState() { return (ImGui_ImplVulkan_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState();
//-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers

View File

@ -129,6 +129,11 @@ static ImGui_ImplWGPU_Data* ImGui_ImplWGPU_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState()
{
return (ImGui_ImplWGPU_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
}
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------

View File

@ -81,8 +81,7 @@ struct ImGui_ImplWGPU_RenderState
WGPUDevice Device;
WGPURenderPassEncoder RenderPassEncoder;
};
static inline ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState() { return (ImGui_ImplWGPU_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
IMGUI_IMPL_API ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState();
//-------------------------------------------------------------------------
// Internal Helpers

View File

@ -68,12 +68,17 @@ Other Changes:
- Using <> scrolling buttons while the selected Tab is at either end of the
section mid-section but not fully visible always makes it fully visible
(before eventually selecting a Tab in the leading/trailing section)
- Tables:
- Fixed a bug restoring correct .ini columns order when table use is Sortable
but had no user changes. (regression from 1.92.9). (#9519, #9108)
- Selectable:
- Fixed `ImGuiSelectableFlags_SelectOnNav` triggering during NavInit.
- Fonts:
- Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic
to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of
ProggyClean on most Apple/Retina setups by default.
- imgui_freetype: Fixed blurryness rendering `AddFontDefaultVector()`. Caused by a
non-pixel aligned offset caused by `ExtraSizeScale`. (#9348, #9233) [@redpartizan, @RDMCz]
- ColorEdit:
- ColorButton, ColorEdit, ColorPicker: cancel-out alpha caused by BeginDisabled() so
disabled color buttons have the same color as non-disabled oness. (#9511)
@ -83,9 +88,13 @@ Other Changes:
- Amended context menu right-click opening code to check that the right-click
hasn't been owned by another items. This is more correct and also necessary
to avoid Drags/Sliders cancelling also triggering a cancel menu. (#8564, #9534)
- Reworked `GetMousePosOnOpeningCurrentPopup()` to be legal to call within the
BeginPopup/EndPopup scope of a popup which was just closed. (#9551) [@jkunstwald]
- ImGuiTextFilter:
- Added support for space ' ' as separator, which is more standard. (#2435, #30)
- Added support for quoted "xxx" blocks to e.g. match words sequences. (#2435)
- Added support for space as an "and" filter, which is the standard. (#2435, #30)
e.g. w/ filter 'hello world' (without quotes) both words needs to be in input data.
- Added support for double-quoted "xxx" blocks to e.g. match words sequences. (#2435)
e.g. w/ filter "hello world" the exact sequence needs to be in input data.
- Fixed filtering when mixing "include" and "-exclude" keyword so that an "-exclude"
match always filters out. (#2435) [@kudaba, @ocornut]
- Added `DrawWithHint()` function. (#6206, #6395, #6447)
@ -117,6 +126,7 @@ Other Changes:
- Added optional `platform_io.DrawCallback_SetSamplerFromTex` standard backend-agnostic
draw callback for requesting to use the sampler associated already associated to a texture.
Currently only supported by the OpenGL2/3 and SDLRenderer3 backend. (#9378)
- Fixed dangling ImDrawList::_OwnerName when using animated label. (#9552) [@ubi-dcastonguay]
- Demo:
- Added `Widgets->Mixed Values` section. (#5518, #5677, #6865)
- Style Editor: fixed style/colors combo box applying style when opening Combo.
@ -137,7 +147,7 @@ Other Changes:
don't have the equivalent of `SDL_SetTextureScaleMode()` and the callback won't work with them.
- Vulkan: added for support for multiple Vulkan contexts with custom loaders. (#6616) [@lstalmir]
- WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()`
when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU]
when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU]
- WebGPU: update to build with wgpu-native 29.0+. (#9377, #9532, #9530) [@lucascompython, @ivan-enzhaev]
- Examples:
- MSVC: disabled /JMC in Visual Studio projects (unnecessary overhead).
@ -1747,7 +1757,7 @@ Non-breaking Fonts/Textures related changes:
- Fonts: ImFontAtlas::AddFontXXX() can fail more gracefully if error handling is configured
to not assert (this will be better exposed via future font flags).
- Fonts: added style.FontScaleBase scaling factor (previously called io.FontGlobalScale).
- Fonts: added style.FontScaleDpi scaling factor. This is designed to be be changed on
- Fonts: added style.FontScaleDpi scaling factor. This is designed to be changed on
per-monitor/per-viewport basis, which `io.ConfigDpiScaleFonts` does automatically.
(which is why it is separate from FontScaleBase).
- Fonts: added optional font_size parameter to ImGui::PushFont() function.
@ -2902,7 +2912,7 @@ Other changes:
- Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854)
[@martin-ejdestig]
- Examples: SDL3: Remove use of SDL_HINT_IME_NATIVE_UI since new SDL_HINT_IME_IMPLEMENTED_UI
values has a more suitable default for our case case.
values has a more suitable default for our case.
- Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan
returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671)
[@AndreiNego, @ocornut]
@ -4855,7 +4865,7 @@ Other Changes:
- ColorPicker4: Fixed picker being unable to select exact 1.0f color when dragging toward the edges
of the SV square (previously picked 0.999989986f). (#3517) [@rokups]
- Menus: Fixed vertical alignments of MenuItem() calls within a menu bar (broken in 1.84). (#4538)
- Menus: Improve closing logic when moving diagonally in empty between between parent and child menus to
- Menus: Improve closing logic when moving diagonally in empty space between parent and child menus to
accommodate for varying font size and dpi.
- Menus: Fixed crash when navigating left inside a child window inside a sub-menu. (#4510).
- Menus: Fixed an assertion happening in some situations when closing nested menus (broken in 1.83). (#4640)

View File

@ -230,7 +230,7 @@ CODE
This is to increase compatibility, increase maintainability and facilitate use from other languages.
- C++: ImVec2/ImVec4 do not expose math operators by default, because it is expected that you use your own math types.
See FAQ "How can I use my own math types instead of ImVec2/ImVec4?" for details about setting up imconfig.h for that.
We can can optionally export math operators for ImVec2/ImVec4 using IMGUI_DEFINE_MATH_OPERATORS, which we use internally.
We can optionally export math operators for ImVec2/ImVec4 using IMGUI_DEFINE_MATH_OPERATORS, which we use internally.
- C++: pay attention that ImVector<> manipulates plain-old-data and does not honor construction/destruction
(so don't use ImVector in your code or at our own risk!).
- Building: We don't use nor mandate a build system for the main library.
@ -3094,9 +3094,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) //-V1077
{
InputBuf[0] = 0;
FilterOp = '|';
MinWordSize = 1;
_CountExclude = _CountInclude = 0;
_CountExclude = 0;
if (default_filter)
{
ImStrncpy(InputBuf, default_filter, IM_COUNTOF(InputBuf));
@ -3118,14 +3116,15 @@ bool ImGuiTextFilter::DrawWithHint(const char* label, const char* hint)
return value_changed;
}
// Parse filter and split into items
// Parse filter and split into a format optimal for PassFilter()
void ImGuiTextFilter::Build()
{
_Items.resize(0);
_CountExclude = _CountInclude = 0;
IM_ASSERT(FilterOp == '|' || FilterOp == '&');
_CountExclude = 0;
const char* buf_e = InputBuf + ImStrlen(InputBuf);
const char* word_e;
int seq_start_idx = -1;
for (const char* word_b = InputBuf; word_b < buf_e; word_b = word_e + 1)
{
// Trim blanks
@ -3151,20 +3150,33 @@ void ImGuiTextFilter::Build()
}
// Min length
if (word_e - word_b < MinWordSize)
continue;
if (word_e - word_b > 0)
{
// Add to list. The '-' is not stored in items but implicitly inferred using (n < CountExclude).
// FIXME-OPT: as items are derived from user input buffer and we expect the insert() to behave sanely.
if (is_excl)
{
_Items.insert(_Items.Data + _CountExclude, ImGuiTextFilterItem(word_b, word_e));
_CountExclude++;
if (seq_start_idx != -1)
seq_start_idx++;
}
else
{
if (seq_start_idx == -1)
seq_start_idx = _Items.Size;
_Items.insert(_Items.Data + _Items.Size, ImGuiTextFilterItem(word_b, word_e));
_Items.Data[seq_start_idx].CountInclude++;
}
}
// Add to list
// The '-' is not stored in items but implicitly inferred using (n < CountExclude).
// FIXME-OPT: about ~push_front(): as N is derived from user inputs we expect this to be fine.
_Items.insert(is_excl ? _Items.Data : _Items.Data + _Items.Size, ImGuiTextFilter::ImGuiTextFilterItem(word_b, word_e));
if (is_excl)
_CountExclude++;
else
_CountInclude++;
// Next sequence
if (word_e[0] == ',')
seq_start_idx = -1;
}
}
// FIXME: Could use a specialized ImStristr() + pre-convert our filter to uppercase.
bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
{
if (_Items.Size == 0)
@ -3173,24 +3185,28 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
text = text_end = "";
// Filters are sorted so that '-' ones are always leading.
int n;
for (n = 0; n < _CountExclude; n++)
if (ImStristr(text, text_end, _Items.Data[n].Begin, _Items.Data[n].End) != NULL)
ImGuiTextFilterItem* seq = _Items.Data;
ImGuiTextFilterItem* seq_excl_end = _Items.Data + _CountExclude;
for (; seq < seq_excl_end; seq++)
if (ImStristr(text, text_end, seq->Begin, seq->Begin + seq->Len) != NULL)
return false;
const bool is_and_filter = (FilterOp == '&');
for (; n < _Items.Size; n++)
{
const bool is_match = ImStristr(text, text_end, _Items.Data[n].Begin, _Items.Data[n].End) != NULL;
if (is_match && !is_and_filter) // or incl 1 -> true
return true; // or incl 0 -> continue
if (!is_match && is_and_filter) // and incl 1 -> continue
return false; // and incl 0 -> false
}
// When no inclusion are specified (only exclusions) we implicitly pass
if (_CountInclude == 0)
// Process includes
ImGuiTextFilterItem* seq_end = _Items.Data + _Items.Size;
if (seq == seq_end) // When no inclusion are specified (only exclusions) we implicitly pass
return true;
return is_and_filter;
while (seq < seq_end)
{
ImGuiTextFilterItem* seq_incl_end = seq + seq->CountInclude;
IM_ASSERT_PARANOID(seq->CountInclude > 0 && seq_incl_end <= seq_end);
for (; seq < seq_incl_end; seq++)
if (ImStristr(text, text_end, seq->Begin, seq->Begin + seq->Len) == NULL)
break;
if (seq == seq_incl_end) // All matched
return true;
seq = seq_incl_end; // Try next
}
return false;
}
//-----------------------------------------------------------------------------
@ -7739,6 +7755,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
size_t buf_len = (size_t)window->NameBufLen;
window->Name = ImStrdupcpy(window->Name, &buf_len, name);
window->NameBufLen = (int)buf_len;
window->DrawList->_OwnerName = window->Name;
}
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
@ -10253,12 +10270,11 @@ void ImGui::TeleportMousePos(const ImVec2& pos)
//IMGUI_DEBUG_LOG_IO("TeleportMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y);
}
// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup()
{
ImGuiContext& g = *GImGui;
if (g.BeginPopupStack.Size > 0)
return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos;
return g.BeginPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos;
return g.IO.MousePos;
}
@ -12064,7 +12080,7 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
}
scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]);
}
scroll[axis] = ImRound64(ImMax(scroll[axis], 0.0f));
scroll[axis] = ImRoundPositive64(ImMax(scroll[axis], 0.0f));
if (!window->Collapsed && !window->SkipItems)
scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]);
}
@ -12843,7 +12859,7 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags
// This is a helper to handle the simplest case of associating one named popup to one given widget.
// - To create a popup associated to the last item, you generally want to pass a NULL value to str_id.
// - To create a popup with a specific identifier, pass it in str_id.
// - This is useful when using using BeginPopupContextItem() on an item which doesn't have an identifier, e.g. a Text() call.
// - This is useful when using BeginPopupContextItem() on an item which doesn't have an identifier, e.g. a Text() call.
// - This is useful when multiple code locations may want to manipulate/open the same popup, given an explicit id.
// - You may want to handle the whole on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
// This is essentially the same as:

20
imgui.h
View File

@ -2785,7 +2785,8 @@ struct ImGuiOnceUponAFrame
operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; }
};
// Helper: Parse and apply text filters e.g. 'aaa bbb -ccc'.
// Helper: Parse and apply text filters e.g. 'aaa bbb' (all), 'aaa,bbb' (any), '-aaa' (exclude), '"Hello, world"' (exact sequence)
struct ImGuiTextFilterItem;
struct ImGuiTextFilter
{
IMGUI_API ImGuiTextFilter(const char* default_filter = "");
@ -2801,21 +2802,10 @@ struct ImGuiTextFilter
inline bool Draw(const char* label, float width) { if (width != 0.0f) ImGui::SetNextItemWidth(width); return Draw(label); }
#endif
// [Internal] Don't use! Will be replaced with ImStrv.
struct ImGuiTextFilterItem
{
const char* Begin;
const char* End;
ImGuiTextFilterItem(const char* b, const char* e) { Begin = b; End = e; }
};
// [Internal] Members
// Members
char InputBuf[256]; // User input buffer
char FilterOp; // == '|' (any) pr '&' (all)
ImU8 MinWordSize; // == 1
int _CountExclude; // >= 0
int _CountInclude; // >= 0
ImVector<ImGuiTextFilterItem> _Items; // Pre-parsed, trimmed, reordered items
int _CountExclude; // [Internal] >= 0 count of leading exclude
ImVector<ImGuiTextFilterItem> _Items; // [Internal] Pre-parsed, trimmed, reordered items
};
// Helper: Growable text buffer for logging/accumulating text

View File

@ -3943,15 +3943,24 @@ static void DemoWindowWidgetsTextFilter()
static ImGuiTextFilter filter;
ImGui::Text("Filter usage:\n"
" \"\" display all lines\n"
" \"xxx\" display lines containing \"xxx\"\n"
" \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n"
" \"-xxx\" hide lines containing \"xxx\"");
" xxx display lines containing \"xxx\"\n"
" xxx yyy display lines containing \"xxx\" and \"yyy\"\n"
" \"xxx yyy\" display lines containing \"xxx yyy\"\n"
" xxx,yyy display lines containing \"xxx\" or \"yyy\"\n"
" -xxx hide lines containing \"xxx\"");
ImGui::SetNextItemWidth(-FLT_MIN);
filter.DrawWithHint("##Filter", "Filter (incl -excl)");
const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
for (int i = 0; i < IM_COUNTOF(lines); i++)
if (filter.PassFilter(lines[i]))
ImGui::BulletText("%s", lines[i]);
if (ImGui::BeginChild("##items", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 15), ImGuiChildFlags_FrameStyle))
{
const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
for (const char* item : lines)
if (filter.PassFilter(item))
ImGui::TextUnformatted(item);
for (const char* item : ExampleNames)
if (filter.PassFilter(item))
ImGui::TextUnformatted(item);
}
ImGui::EndChild();
ImGui::TreePop();
}
}

View File

@ -4776,6 +4776,7 @@ static bool ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig
stbtt_GetFontVMetrics(&bd_font_data->FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
baked->Ascent = ImCeil(unscaled_ascent * scale_for_layout);
baked->Descent = ImFloor(unscaled_descent * scale_for_layout);
// FIXME: round to rasterizer density? (#9348)
}
return true;
}

View File

@ -368,6 +368,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
// - Helper: ImPool<>
// - Helper: ImChunkStream<>
// - Helper: ImGuiTextIndex
// - Helper: ImGuiTextFilterItem
// - Helper: ImGuiStorage
//-----------------------------------------------------------------------------
@ -536,8 +537,9 @@ inline ImVec2 ImTrunc(const ImVec2& v) { return
inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only.
inline float ImCeilFast(float f) { int i = (int)f; return (float)(i + (f > (float)i)); } // Consider using the the bit-hack version (search for "0x1p120f").
inline float ImRoundPositive64(float f) { return (float)(ImS64)(f + 0.5f); } // Positive values only.
inline float ImRoundSigned64(float f) { return (float)(ImS64)(f >= 0.0f ? f + 0.5f : f - 0.5f); }
inline float ImCeilFast(float f) { int i = (int)f; return (float)(i + (f > (float)i)); } // Consider using the bit-hack version (search for "0x1p120f").
inline int ImModPositive(int a, int b) { return (a + b) % b; }
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
@ -836,6 +838,16 @@ struct ImGuiTextIndex
void append(const char* base, int old_size, int new_size);
};
// [Internal] Types
struct ImGuiTextFilterItem
{
const char* Begin; // Pointer within parent's buffer
int Len; // Length of text (non-zero terminated)
short CountInclude; // Number of consecutive items forming an end chain. >0 when beginning of an AND chain, =0 otherwise.
unsigned short MatchIncludesMask; // Storage for multi-sources versions of PassFilter(). Unused by core library.
ImGuiTextFilterItem(const char* b, const char* e) { IM_ASSERT(e > b); Begin = b; Len = (int)(e - b); CountInclude = 0; MatchIncludesMask = 0; }
};
// Helper: ImGuiPackedDate (sizeof() == 2)
// Store a date in a way that is efficient to read/write in text form. If we stored e.g. number of days since Epoch we'd need costlier back and forth.
// This is specifically designed to be able to prune old .ini data.
@ -894,7 +906,7 @@ struct IMGUI_API ImDrawListSharedData
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas (== FontAtlas->TexUvLines)
ImFontAtlas* FontAtlas; // Current font atlas
ImFont* Font; // Current font (used for simplified AddText overload)
float FontSize; // Current font size (used for for simplified AddText overload)
float FontSize; // Current font size (used for simplified AddText overload)
float FontScale; // Current font scale (== FontSize / Font->FontSize)
float CurveTessellationMaxError; // Tessellation tolerance when using PathBezierCurveTo()
float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
@ -3126,9 +3138,9 @@ struct IMGUI_API ImGuiTable
ImDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per columns to avoid switching clip rect constantly
ImGuiTableInstanceData InstanceDataFirst;
ImVector<ImGuiTableInstanceData> InstanceDataExtra; // FIXME-OPT: Using a small-vector pattern would be good.
ImGuiTableColumnSortSpecs SortSpecsSingle;
ImVector<ImGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good.
ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs()
ImVector<ImGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good.
ImGuiTableColumnSortSpecs SortSpecsSingle;
ImGuiTableColumnIdx SortSpecsCount;
ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount)
ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns using fixed width (<= ColumnsCount)
@ -3160,6 +3172,7 @@ struct IMGUI_API ImGuiTable
ImS8 NavLayer; // ImGuiNavLayer at the time of BeginTable().
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
bool IsNewTable;
bool IsInitializing;
bool IsReconcileMode;
bool IsSortSpecsDirty;

View File

@ -375,7 +375,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
const int previous_frame_active = table->LastFrameActive;
const int instance_no = (previous_frame_active != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
const ImGuiTableFlags previous_flags = table->Flags;
const bool is_new_table = (previous_frame_active == -1);
table->ID = id;
table->Flags = flags;
table->LastFrameActive = g.FrameCount;
@ -384,6 +383,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->IsLayoutLocked = false;
table->InnerWidth = inner_width;
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
table->IsNewTable = (previous_frame_active == -1);
temp_data->UserOuterSize = outer_size;
// Instance data (for instance 0, TableID == TableInstanceID)
@ -585,7 +585,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (table->IsInitializing)
{
// Initialize
if (is_new_table)
if (table->IsNewTable)
{
table->SettingsOffset = -1;
table->IsSettingsRequestLoad = true;
@ -1756,7 +1756,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
ImGuiTableColumn* column = &table->Columns[column_idx];
// If topology change goes into reconcile mode
if (table->IsReconcileMode == false && column->ID != column_id)
if (table->IsReconcileMode == false && column->ID != column_id && !table->IsNewTable)
{
table->IsReconcileMode = true;
table->TempData->ReconcileColumnsRequests.reserve(table->ColumnsCount - column_idx);
@ -3970,12 +3970,10 @@ void ImGui::TableSaveSettings(ImGuiTable* table)
if (column->DisplayOrder != n)
settings->SaveFlags |= ImGuiTableFlags_Reorderable;
if (column->SortOrder != -1)
settings->SaveFlags |= ImGuiTableFlags_Sortable;
settings->SaveFlags |= ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable; // Because SortOrder saving itself is gated, make sure every column is saved (#9519)
if (column->IsUserEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) == 0))
settings->SaveFlags |= ImGuiTableFlags_Hideable;
}
if (table->Flags & ImGuiTableFlags_Sortable)
settings->SaveFlags |= ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable;
settings->SaveFlags &= table->Flags;
settings->RefScale = save_ref_scale ? table->RefScale : 0.0f;

View File

@ -4795,7 +4795,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
IM_ASSERT(buf != NULL && buf_size >= 0);
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys)
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key)
IM_ASSERT(!((flags & ImGuiInputTextFlags_ElideLeft) && (flags & ImGuiInputTextFlags_Multiline))); // Multiline does not not work with left-trimming
IM_ASSERT(!((flags & ImGuiInputTextFlags_ElideLeft) && (flags & ImGuiInputTextFlags_Multiline))); // Multiline does not work with left-trimming
IM_ASSERT((flags & ImGuiInputTextFlags_WordWrap) == 0 || (flags & ImGuiInputTextFlags_Password) == 0); // WordWrap does not work with Password mode.
IM_ASSERT((flags & ImGuiInputTextFlags_WordWrap) == 0 || (flags & ImGuiInputTextFlags_Multiline) != 0); // WordWrap does not work in single-line mode.

View File

@ -7,6 +7,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2026/09/25: fixed handling of ExtraSizeScale.
// 2025/06/11: refactored for the new ImFontLoader architecture, and ImGuiBackendFlags_RendererHasTextures support.
// 2024/10/17: added plutosvg support for SVG Fonts (seems faster/better than lunasvg). Enable by using '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG'. (#7927)
// 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
@ -463,11 +464,13 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
// Read metrics
FT_Size_Metrics metrics = bd_baked_data->FtSize->metrics;
const float scale = 1.0f / (rasterizer_density * src->ExtraSizeScale);
baked->Ascent = (float)FT_CEIL(metrics.ascender) * scale; // The pixel extents above the baseline in pixels (typically positive).
baked->Descent = (float)FT_CEIL(metrics.descender) * scale; // The extents below the baseline in pixels (typically negative).
baked->Ascent = ((float)metrics.ascender / FT_SCALEFACTOR) * scale; // The pixel extents above the baseline in pixels (typically positive).
baked->Descent = ((float)metrics.descender / FT_SCALEFACTOR) * scale; // The extents below the baseline in pixels (typically negative).
//LineSpacing = (float)FT_CEIL(metrics.height) * scale; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
//LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * scale; // The spacing in pixels between one row's descent and the next row's ascent.
//MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * scale; // This field gives the maximum horizontal cursor advance for all glyphs in the font.
baked->Ascent = ImRoundSigned64(baked->Ascent * rasterizer_density) / rasterizer_density;
baked->Descent = ImRoundSigned64(baked->Descent * rasterizer_density) / rasterizer_density;
}
return true;
}