Compare commits

..

29 Commits

Author SHA1 Message Date
Ben Carter
0af8ae979d Shadows: Added experimental texture-based shadows (stripped of dynamic tex config and back-end code)
(merged 10 commits, removing dynamic tex config, moved tex config to internal structs, removed back-end changes)
(squashed 2025-06-11, fixed conflict, doesn't build as-is)
Shadows: Added IMGUI_HAS_SHADOWS
Shadows: Demo code in Custom Rendering section. Added AddShadowRectFilled() variant. BeginMainMenuBar() disable shadows.
Shadows: Added initial version of convex shape shadow code.
(+stripped out of original polygon generation demo, moved to imgui_dev)
Shadows: Tweak demo to use AddShadowCircle() functions + fix warnings.
 (+ stripped old polygon generation code from commits)
Shadows: Convex shape shadow improvement/fixes
- Fixed pixel cracking on convex shadow edges
- Added convex shadow offset support
- Fixed some convex shadow fringing issues
- Added convex shadow demo code
Shadows: Added ImDrawShadowFlags, simplified API surface, reordered parameters
+ fix minor warnings
+ removed NGon variant for now.
Shadows: Re-added AddShadowNGon().
Shadows: Shallow styling tweaks and renaming for consistency.
Shadows: Fixes + two fixes for PVS Studio static analyzer.
Shadows: Fix for latest, reuse ImDrawList, remove ImDrawShadowFlags.
Shadows: Fix to support for colored-only font atlas. (4202)
Shadows: Fix broken shadows due to zero-clear added in 9417acc2.
Shadows: remove use of GetWindowContentRegionMax().
Shadows: WIP fixes for latest. (broken UV caching)
Shadows: WIP for latest (refreshing UV coordinates).
Demo: Add missing trailing null terminator to convex shape combo (9434)
2026-06-08 12:13:28 +02:00
ocornut
8936b58fe2 Version 1.92.8
Include minor bits: adjust activeid logging, tweak comments.
2026-05-12 16:30:30 +02:00
omar
eebaddd340 Docs: added SECURITY.md. 2026-05-11 19:03:08 +02:00
ocornut
73afb6b6e6 Fonts: clarify that ClearFonts() be useful over calling Clear(). 2026-05-11 17:45:59 +02:00
ocornut
b8f6c51af7 Fonts: move ClearFonts(), ClearInputData(), ClearTexData() implementation (no other changes) 2026-05-11 17:42:08 +02:00
ocornut
4ac473b2c7 Fixed BeginMenu() leading to window with is_resizable_width=true. Fix/amend 95bd1577d + ac1f57b. (#9355) 2026-05-11 16:35:40 +02:00
ocornut
ac1f57ba0c Fixed BeginMenu() leading to window with is_resizable_width=true. Fix/amend 95bd1577d. (#9355)
We should instead probably make BeginChild() not set on ImGuiWindowFlags_AlwaysAutoResize on either ResizeX or ResizeY, but that'll be done later.
2026-05-11 16:34:33 +02:00
ocornut
821a396556 Fixed warning on Clang 26. 2026-05-11 15:59:42 +02:00
manuel
2b31f65167 Examples: WebGPU+GLFW/SDL2/SDL3: wire up the IMGUI_WGVK_DIR path. (#9387)
The block was a stub - find Vulkan, detect Wayland/X11, set the SUPPORT_*_SURFACE defines that wgvk.c needs.
2026-05-11 15:42:16 +02:00
manuel
b58836f287 Backends: WebGPU: detect WGSL support at runtime instead of excluding WGVK at compile time. (#9387)
Previously WGVK was hard-disabled from WGSL via #if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK),
forcing the SPIRV fallback unconditionally. Now the WGSL path is attempted on all backends
and an empty stage_desc is returned when the module fails to compile letting the existing
SPIRV fallback at the call site kick in.
2026-05-11 15:38:27 +02:00
ocornut
bca5a69928 BeginMenu()/MenuItem(): fixed accidental triggering of child menu items when opening a menu inside a small host window forcing the child menu window to be repositioned under the mouse cursor. (#8233, #9394)
nb: ImGuiSelectableFlags_NoHoldingActiveID is not used anymore. Would remove remove once we remove the unnecessary call to Selectable() from MenuItem().
2026-05-11 15:32:39 +02:00
ocornut
eb453f2be6 Checkbox, Style: added ImGuiCol_CheckboxSelectedBg. (#9392) 2026-05-11 14:30:34 +02:00
ocornut
56b37bf93c Inputs: SetItemKeyOwner(): does not set ownership is key is already taken.
(#456, #2637, #2620, #2891, #3370, #3724, #4828, #5108, #5242, #5641)
2026-05-07 21:22:33 +02:00
ocornut
0eae77f783 Inputs: SetItemKeyOwner(): return true if ownership has been requested, which can to be checked to accurately gate further input test.
(#456, #2637, #2620, #2891, #3370, #3724, #4828, #5108, #5242, #5641)
2026-05-07 21:15:27 +02:00
ocornut
02ccd9f348 Scrolling, Inputs: using mouse wheel to scroll takes and keeps ownership of the corresponding keys while a wheeling window is locked.
Ref 4448d975d. (#2604, #3795)
2026-05-07 20:51:57 +02:00
ocornut
163b8670c8 Demo: added image viewer with magnifier and grid. 2026-05-07 20:20:05 +02:00
ocornut
a70b97ee48 Warning fixes. 2026-05-07 16:51:34 +02:00
ocornut
6df50a0667 (Breaking) DrawList: swapped the last two arguments of AddRect(), AddPolyline(), PathStroke(). thickness<>flags.
Added inline redirection functions when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is off.
Marked the old functions are =delete when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is on, to allow for better type-checking.
The aim is to be able to use/add flags to more ImDrawList functions, and making existing functions consistents was deemed very desirable.
2026-05-07 16:37:57 +02:00
ocornut
976c5c0f3a Textures: extract ImTextureDataQueueUpload() out of ImFontAtlasTextureBlockQueueUpload() (#8465)
Not atlas specific, in support of texture system.
2026-05-06 16:19:39 +02:00
Mikko Mononen
691b89baae ImDrawList: added AddLineH(), AddLineV() helpers. (#9360)
This commit is aimed to be a lossless transform. Further layout fixes in subsequent commits.
2026-04-28 17:04:54 +02:00
ocornut
c0b693b1d4 MultiSelect: Box-Select + Tables: fixed when using SpanAllColumns paths. (#9383, #7994)
Amend d1a8995 which didn't fix the thing it claimed to fix, as my naive last minute refactor broke it.
2026-04-28 15:58:21 +02:00
Alexander "FireFox" Ong
865a6dfa59 InputScalar: fixed not parsing user input when the display format is configured not to show the scalar value. (#9385)
Useful e.g. for displaying "mixed" inputs, where a single field might represent multiple different values.
2026-04-28 15:25:12 +02:00
Vlad
dee9b15bbe Backends: Metal: add sampler states and DrawCallback_SetSamplerLinear / DrawCallback_SetSamplerNearest callbacks. (#9381, #9371, #9378) 2026-04-28 15:09:23 +02:00
ocornut
d1a8995634 MultiSelect: Box-Select + Tables: fixed when using SpanAllColumns paths. (#9383, #7994)
Amend ac88294 + d7b40ab
2026-04-28 14:58:47 +02:00
ocornut
ab36fbaf48 Drag and Drop, Style: added ImGuiStyleVar_DragDropTargetRounding. (#9056)
+ readded rounding arg to RenderDragDropTargetRectEx().
2026-04-27 18:23:56 +02:00
ocornut
e3033c3975 Examples: moving example_win32_directx11 on top of the .sln makes it the default selected project. 2026-04-24 17:38:51 +02:00
ocornut
10c378cdfc InputInt, InputFloat, InputScalar: reinstated and fixed ImGuiInputTextFlags_EnterReturnsTrue. (#8665, #9299, #8065, #3946, #6284, #9117) 2026-04-24 15:15:19 +02:00
ocornut
db23a78c60 Internals: store ImGuiItemStatusFlags_EditedInternal bypassing ImGuiItemFlags_NoMarkEdited.
Convenient if the same signal is not passed via e.g. return value. (#8665, #9299, #8065, #3946, #6284, #9117)
2026-04-24 15:15:16 +02:00
ocornut
bda49826cf Backends: OpenGL3: build fix for WebGL/ES2/Emscripten. (#9378)
Amend 6b05f71 which was incorrectly labelled.
2026-04-24 12:26:21 +02:00
19 changed files with 1968 additions and 598 deletions

View File

@@ -5,8 +5,6 @@
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
// [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).
// Missing features or Issues:
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

View File

@@ -5,8 +5,6 @@
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
// [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).
// Missing features or Issues:
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -18,6 +16,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378)
// 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367)
// 2026-04-03: Metal: avoid redundant vertex buffer bind in SetupRenderState. (#9343)
@@ -79,6 +78,8 @@
@interface MetalContext : NSObject
@property (nonatomic, strong) id<MTLDevice> device;
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
@property (nonatomic, strong) id<MTLSamplerState> samplerStateLinear;
@property (nonatomic, strong) id<MTLSamplerState> samplerStateNearest;
@property (nonatomic, strong) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
@property (nonatomic, strong) NSMutableArray<MetalBuffer*>* bufferCache;
@@ -91,6 +92,7 @@
struct ImGui_ImplMetal_Data
{
MetalContext* SharedMetalContext;
id<MTLRenderCommandEncoder> RenderCommandEncoder;
ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
};
@@ -185,12 +187,15 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, id<MTLComman
[commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1];
[commandEncoder setRenderPipelineState:renderPipelineState];
[commandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateLinear atIndex:0];
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:vertexBufferOffset atIndex:0];
}
// Draw callbacks
static void ImGui_ImplMetal_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
static void ImGui_ImplMetal_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
static void ImGui_ImplMetal_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateLinear atIndex:0]; }
static void ImGui_ImplMetal_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateNearest atIndex:0]; }
// Metal Render function.
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
@@ -228,6 +233,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
MetalBuffer* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
bd->RenderCommandEncoder = commandEncoder;
ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
// Will project scissor/clipping rectangles into framebuffer space
@@ -306,6 +312,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
[sharedMetalContext.bufferCache addObject:indexBuffer];
}
}];
bd->RenderCommandEncoder = nil;
}
static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex)
@@ -382,7 +389,17 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
depthStencilDescriptor.depthWriteEnabled = NO;
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init];
samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear;
samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear;
samplerDescriptor.mipFilter = MTLSamplerMipFilterLinear;
bd->SharedMetalContext.samplerStateLinear = [device newSamplerStateWithDescriptor:samplerDescriptor];
samplerDescriptor.minFilter = MTLSamplerMinMagFilterNearest;
samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest;
samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest;
bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor];
#ifdef IMGUI_IMPL_METAL_CPP
[samplerDescriptor release];
[depthStencilDescriptor release];
#endif
@@ -399,6 +416,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
ImGui_ImplMetal_DestroyTexture(tex);
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
bd->SharedMetalContext.samplerStateLinear = nil;
bd->SharedMetalContext.samplerStateNearest = nil;
}
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
@@ -415,6 +434,8 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState;
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplMetal_DrawCallback_SetSamplerLinear;
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplMetal_DrawCallback_SetSamplerNearest;
bd->SharedMetalContext = [[MetalContext alloc] init];
bd->SharedMetalContext.device = device;
@@ -599,9 +620,9 @@ void ImGui_ImplMetal_Shutdown()
"}\n"
"\n"
"fragment half4 fragment_main(VertexOut in [[stage_in]],\n"
" texture2d<half, access::sample> texture [[texture(0)]]) {\n"
" constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n"
" half4 texColor = texture.sample(linearSampler, in.texCoords);\n"
" texture2d<half, access::sample> texture [[texture(0)]],\n"
" sampler textureSampler [[sampler(0)]]) {\n"
" half4 texColor = texture.sample(textureSampler, in.texCoords);\n"
" return half4(in.color) * texColor;\n"
"}\n";

View File

@@ -255,7 +255,9 @@ struct ImGui_ImplOpenGL3_Data
bool UseBufferSubData;
bool UseTexParameterToSetSampler;
GLuint NextSampler; // Used if !HasBindSampler && UseTexParameterToSetSampler.
GLuint TexSamplers[2]; // Used if IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER && HasBindSimpler (0=linear, 1=nearest).
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
GLuint TexSamplers[2]; // Used if HasBindSimpler. (0=linear, 1=nearest)
#endif
ImVector<char> TempBuffer;
@@ -404,8 +406,13 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
// Draw callbacks
static void ImGui_ImplOpenGL3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); if (bd->HasBindSampler) { glBindSampler(0, bd->TexSamplers[0]); } else { bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; } }
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); if (bd->HasBindSampler) { glBindSampler(0, bd->TexSamplers[1]); } else { bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; } }
#else
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; }
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; }
#endif
// OpenGL3 Render function.
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
@@ -944,7 +951,9 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
{
ImGui_ImplOpenGL3_InitLoader();
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
if (bd->TexSamplers[0]) { glDeleteSamplers(2, &bd->TexSamplers[0]); bd->TexSamplers[0] = bd->TexSamplers[1] = 0; }
#endif
if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }

View File

@@ -328,11 +328,31 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = (WGPUChainedStruct*)&wgsl_desc;
// Detect shader compilation errors by using an error scope.
// Flag to be passed into the validation callback `userdata1` pointer.
int validation_error = 0;
wgpuDevicePushErrorScope(bd->wgpuDevice, WGPUErrorFilter_Validation);
WGPUShaderModule module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
WGPUPopErrorScopeCallbackInfo pop_cb = {};
pop_cb.mode = WGPUCallbackMode_AllowSpontaneous;
pop_cb.callback = [](WGPUPopErrorScopeStatus, WGPUErrorType type, WGPUStringView, void* userdata1, void*)
{
if (type == WGPUErrorType_Validation)
*static_cast<int*>(userdata1) = 1;
};
pop_cb.userdata1 = &validation_error;
wgpuDevicePopErrorScope(bd->wgpuDevice, pop_cb);
WGPUProgrammableStageDescriptor stage_desc = {};
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
stage_desc.entryPoint = { "main", WGPU_STRLEN };
#endif
if (module && !validation_error)
{
stage_desc.module = module;
stage_desc.entryPoint = { "main", WGPU_STRLEN };
}
else if (module)
{
wgpuShaderModuleRelease(module);
}
return stage_desc;
}

View File

@@ -36,34 +36,56 @@ HOW TO UPDATE?
- Please report any issue!
-----------------------------------------------------------------------
VERSION 1.92.8 WIP (In Progress)
VERSION 1.92.8 (Released 2026-05-12)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.8
Breaking Changes:
- DrawList:
- Obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`,
- DrawList: swapped the last two arguments of `AddRect()`, `AddPolyline()`, `PathStroke()`.
- Before: `void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f);`
- After: `void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0);`
- Before: `void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);`
- After: `void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0);`
- Before: `void ImDrawList::PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f);`
- After: `void ImDrawList::PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);`
Added inline redirection functions when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is off.
Marked the old functions are =delete when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is on, to allow for better type-checking.
Effectively the typical call site is changing from:
- Before: `window->DrawList->AddRect(p_min, p_max, color, rounding, ImDrawFlags_None, border_size);`
- After: `window->DrawList->AddRect(p_min, p_max, color, rounding, border_size);`
Notes:
- Users of C++ and other languages with type-checking will be notified at compile-time of any mistakes.
- Users of high-level bindings or languages with no type-checking will be notified at runtime via an assert for invalid flags value.
If you are a binding maintainer consider doing something to facilitate transition or error detection.
- This is perhaps the worst breaking change in our history :( but it makes ImDrawList function signatures consistent.
As we are aiming to add flags and features to variety of ImDrawList functions, that consistency becomes more important.
The new order is also more convenient as `flags` are less frequently used than `thickness` in real code.
- As a general policy in Dear ImGui, all our flags default to 0 so ImDrawFlags_None was likely written 0 in some call sites.
- Consider adding `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h, even temporarily, to clean up legacy code.
- DrawList: obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`,
which is part of our new standard draw callbacks. (#9378)
Redirecting the earlier value into the later one when set, so both old and new code should work.
- Backends:
- Vulkan: redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. (#914)
This change allows us to facilitate changing samplers, in line with other backends. [@yaz0r, @ocornut]
- When creating your own descriptor pool (instead of letting backend creates its own):
- Before: need at least IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER.
- After: need at least IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
+ IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLER.
- Before: need at least `IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`.
- After: need at least `IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`.
+ `IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_SAMPLER`.
- When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler.
- Before: ImGui_ImplVulkan_AddTexture(VkSampler, VkImageView, VkImageLayout)
- After: ImGui_ImplVulkan_AddTexture(VkImageView, VkImageLayout)
- Before: `ImGui_ImplVulkan_AddTexture(VkSampler, VkImageView, VkImageLayout)`
- After: `ImGui_ImplVulkan_AddTexture(VkImageView, VkImageLayout)`
- Kept inline redirection function that ignores the sampler (will obsolete).
- DirectX10, DirectX11, SDLGPU3, Vulkan: removed samplers from ImGui_ImplXXXX_RenderState.
- DirectX10, DirectX11, SDLGPU3, Vulkan: removed samplers from `ImGui_ImplXXXX_RenderState`.
Prefer to use backend-agnostic DrawCallback_SetSamplerLinear which works everywhere! (#9378)
If there is a legit need/request for them or any render state we can always add them back.
Other Changes:
- DrawList:
- Added room in ImGuiPlatformIO for standard backend-agnostic draw callbacks. Those callbacks
- Added room in `ImGuiPlatformIO` for standard backend-agnostic draw callbacks. Those callbacks
are setup/provided by the backend and available in most of our standard backends.
They allow backend-agnostic code from e.g. switching to a Nearest/Point sampler without
messing with custom Renderer-specific callbacks.
@@ -73,12 +95,13 @@ Other Changes:
Note that some backends might not support all callbacks.
(#9378, #9371, #3590, #8926, #2973, #7485, #7468, #6969, #5118, #7616, #9173, #8322, #7230,
#5999, #6452, #5156, #7342, #7592, #7511)
- Made AddCallback() user data default to Null for convenience.
- Made `AddCallback()` user data default to Null for convenience.
- Added `AddLineH()`, `AddLineV()` helpers to draw horizontal and vertical lines. [@memononen]
- InputText:
- InputTextMultiline: fixed an issue processing deactivation logic when an active
multi-line edit is clipped due to being out of view.
- Fixed a crash when toggling ReadOnly while active. (#9354)
- CharFilter callback event sets CursorPos/SelectionStart/SelectionEnd. (#816)
- `CharFilter` callback event sets CursorPos/SelectionStart/SelectionEnd. (#816)
- Tables:
- Fixed issues reporting ideal size to parent window/container: (#9352, #7651)
- When both scrollbars are visible but only one of ScrollX/ScrollY was explicitly requested.
@@ -87,38 +110,70 @@ Other Changes:
- Fixed a single-axis auto-resizing feedback loop issue with nested containers
and varying scrollbar visibility. (#9352)
- Detect and report error when calling End() instead of EndPopup() on a popup. (#9351)
- Child windows with only ImGuiChildFlags_AutoResizeY flag keep using the proportional
default ItemWidth. (#9355)
- Child windows with only `ImGuiChildFlags_AutoResizeY` flag keep using the proportional
default `ItemWidth`. (#9355)
- Using mouse wheel to scroll takes and keeps ownership of the corresponding keys
(e.g. `ImGuiKey_MouseWheelY`) while a wheeling window is locked. (#2604, #3795)
- InputInt, InputFloat, InputScalar:
- Reinstated `ImGuiInputTextFlags_EnterReturnsTrue` support which was removed in 1.91.4.
(#8665, #9299, #8065, #3946, #6284, #9117)
- Fixed the fact that it didn't return true when validating same value.
- Fixed losing value when tabbing out or losing focus.
- Made it that pressing +/- step buttons also return true, which is in line
with 1.91.4 behavior.
- In a majority of cases you should use `IsItemDeactivatedAfterEdit()` instead,
but it still has a few edge cases flaws (to be addressed soon).
- Allow passing a format string that does not display the scalar value.
Parsing input with default format for the type. (#9385) [@FireFox2000000]
- Multi-Select:
- Fixed an issue using Multi-Select within a Table causing column width measurement to
be invalid when trailing column contents is not submitted in the last row. (#9341, #8250)
- Fixed an issue using Multi-Select within a Table with the right-most column visible,
which could lead to an extra vertical offset in the Header row. (#8250)
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect1d mode while scrolling.
- Multi-Select + Box-Select:
- Fixed an issue using `ImGuiMultiSelectFlags_BoxSelect1d` mode while scrolling.
Notably, using mouse wheel while holding a box-selection could lead items close to windows
edges from not being correctly unselected. (#7994, #8250, #7821, #7850, #7970)
- Box-Select: improved dirty/unclip rectangle logic for ImGuiMultiSelectFlags_BoxSelect2d.
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode, where
- Improved dirty/unclip rectangle logic for `ImGuiMultiSelectFlags_BoxSelect2d`.
- Fixed an issue using `ImGuiMultiSelectFlags_BoxSelect2d` mode, where
items out of view wouldn't be properly selected while scrolling while mouse cursor
is hovering outside of selection scope. (#7994, #1861, #6518)
- Box-Select: fixed an issue where items out of horizontal view would sometimes lead
- Fixed an issue where items out of horizontal view would sometimes lead
to incorrect merging of sequential selection requests while also scrolling fast
enough to overlap multiple rows during a frame. (#7994, #1861, #6518)
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode in a Table
while relying on the TableNextColumn() return value to perform coarse clipping. (#7994)
- Box-Select: disabled merging consecutive selection requests as we have no reliable
way of detecting if user has submitted all consecutives items without clipping gaps,
and ImGuiSelectionUserData is technically opaque storage. (#7994, #1861)
- Fixed an issue using `ImGuiMultiSelectFlags_BoxSelect2d` mode in a Table
while relying on the `TableNextColumn()` return value to perform coarse clipping. (#7994)
- Disabled merging consecutive selection requests as we have no reliable
way of detecting if user has submitted all consecutive items without clipping gaps,
and `ImGuiSelectionUserData` is technically opaque storage. (#7994, #1861)
(we will probably bring this back as a minor optimization if we have a way to for
user to tell us ImGuiSelectionUserData are indices)
- Box-Select: fixes for using accross nested child windows. (#8364)
user to tell us `ImGuiSelectionUserData` are indices)
- Fixes for using across nested child windows. (#8364)
- Box-Select + Clipper: fixed an issue selecting items while scrolling while a clipper
active. (#7994, #8250, #7821, #7850, #7970)
- Box-Select + Tables: fixed an issue using box-selection in a tables with
items straying out of columns boundaries. (#7994, #2221)
- Box-Select + Tables: fixed an issue when calling `BeginMultiSelect()` in a table
before layout has been locked (first row or headers row submitted). (#8250)
- Menus:
- BeginMenu()/MenuItem(): fixed accidental triggering of child menu items when
opening a menu inside a small host window forcing the child menu window to be
repositioned under the mouse cursor. (#8233, #9394)
Done by reworking `BeginMenu()`/`MenuItem()`: they previously avoiding taking
ActiveID + key/click ownership (in order to allow releasing button on another item).
Now they take them and release them once the mouse is moved outside item boundaries.
- Inputs:
- SetItemKeyOwner(): return true if ownership has been requested, which typically
needs to to checked for gating further tests. This is important as the function
may fail. (#456, #2637, #2620, #2891, #3370, #3724, #4828, #5108, #5242, #5641)
- SetItemKeyOwner(): does not set ownership is key is already taken. Effectively
this makes using `SetItemKeyOwner(ImGuiKey_MouseWheelY)` over an item work as
expected while not having item react if a scroll wheel is actively in progress.
May be subject to further redesign, e.g. conditional flags. Feedback welcome!
- Style:
- Checkbox: added `ImGuiCol_CheckboxSelectedBg` to change or accentuate the
background color of checked/mixed checkboxes. (#9392)
- Added `ImGuiStyleVar_DragDropTargetRounding`. (#9056)
- Fixed vertical scrollbar top coordinates when using thick borders on windows
with no title bar and no menu bar. (#9366)
- Fonts:
@@ -131,8 +186,12 @@ Other Changes:
- Tweaked assert triggering when first item height measurement fails, and made it
a better recoverable error. (#9350)
- Misc:
- Minor optimization: reduce redudant label scanning in common widgets.
- Added missing Test Engine hooks for PlotXXX(), VSliderXXX(), TableHeader().
- Minor optimization: reduce redundant label scanning in common widgets.
- Added missing Test Engine hooks for `PlotLines()`, `PlotHistogram()`, `VSliderXXX()`
and `TableHeader()` functions.
- Demo:
- Added simple demo for a scrollable/zoomable image viewer with a grid.
Available in `Examples->Image Viewer` and `Widgets->Images`.
- Backends:
- Added support for new standardized draw callbacks in most backends: (#9378)
- Allegro5: Reset n/a n/a
@@ -140,7 +199,7 @@ Other Changes:
- DX10: Reset SetSamplerLinear SetSamplerNearest
- DX11: Reset SetSamplerLinear SetSamplerNearest
- DX12: Reset SetSamplerLinear SetSamplerNearest
- Metal: Reset *missing* *missing*
- Metal: Reset SetSamplerLinear SetSamplerNearest
- OpenGL2: Reset SetSamplerLinear SetSamplerNearest
- OpenGL3+: Reset SetSamplerLinear SetSamplerNearest
- SDLGPU3: Reset SetSamplerLinear SetSamplerNearest
@@ -148,7 +207,7 @@ Other Changes:
- SDLRenderer3: Reset SetSamplerLinear SetSamplerNearest
- Vulkan: Reset SetSamplerLinear SetSamplerNearest
- WebGPU: Reset SetSamplerLinear SetSamplerNearest
(Vulkan backend by @yaz0r, others by @ocornut)
(Vulkan backend by @yaz0r, Metal by @ssh4net, others by @ocornut)
- GLFW: added a Win32-specific implementation of `ImGui_ImplGlfw_GetContentScaleXXXX`
functions for legacy GLFW 3.2. (#9003)
- Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads
@@ -158,14 +217,13 @@ Other Changes:
- SDL2: made `ImGui_ImplSDL2_GetContentScaleForWindow()`/`ImGui_ImplSDL2_GetContentScaleForDisplay()`
helpers return a minimum of 1.0f, as some Linux setup seems to report <1.0f value
and this breaks scaling border size. (#9369)
- WebGPU: always use SPIR-V shader on WGVK, as it cannot be detected at runtime. (#9316, #9246, #9257)
- WebGPU: rework choice/detection of using WGSL/SPIR-V shader on WGVK. (#9316, #9246, #9257, #9387)
- Examples:
- Update VS toolset in all .vcxproj from VS2015 (v140) to VS2017 (v141). The later is the
first that supports vcpkg. Onward we will likely stop testing building the library with VS2015.
- GLFW+Vulkan, SDL2+Vulkan, SDL3+Vulkan, Win32+Vulkan: reworked to create a descriptor pool with:
- IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
- IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLER.
- `IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`.
- `IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_SAMPLER`.
-----------------------------------------------------------------------

17
docs/SECURITY.md Normal file
View File

@@ -0,0 +1,17 @@
# Security Policy
Dear ImGui is primarily designed for developer tools and technical applications running trusted code and trusted data.
Given that the library was not designed as a hardened security boundary against hostile or intentionally malformed inputs:
consider not using it in a context where a crash (through e.g. intentionally malformed inputs) could lead to privilege elevation.
E.g. running in a privileged process and interacting with non-privileged clients feeding code or data to Dear ImGui.
Dear ImGui development efforts are focused on improving developer experience, usability, correctness, and robustness in real-world applications.
We will do our best to reduce e.g. crashes caused by common programmer mistakes.
However, the project does not specifically focus on adversarial fuzzing scenarios, allocation-failure hardening, or highly artificial edge cases that are unlikely to occur in normal usage.
## Reporting a Vulnerability
Considering the above policy, most things may be reported in GitHub Issues.
If you have a reason to disclose privately, please reach out to the contact address listed in README.

View File

@@ -146,6 +146,28 @@ else() # Native/Desktop build
endif()
if(IMGUI_WGVK_DIR)
find_package(Vulkan REQUIRED)
set(WGVK_PLATFORM_LIBS)
set(WGVK_PLATFORM_DEFS)
if(WIN32)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WIN32_SURFACE=1)
elseif(APPLE)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_METAL_SURFACE=1)
elseif(UNIX)
find_package(PkgConfig QUIET)
pkg_check_modules(WAYLAND_CLIENT QUIET wayland-client)
if(WAYLAND_CLIENT_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WAYLAND_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS ${WAYLAND_CLIENT_LIBRARIES})
endif()
find_package(X11 QUIET)
if(X11_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_XLIB_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS X11::X11)
endif()
list(APPEND WGVK_PLATFORM_LIBS m dl pthread)
endif()
set(LIBRARIES glfw Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
endif()
endif()
@@ -187,6 +209,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
if(IMGUI_WGVK_DIR)
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGVK")
target_compile_definitions(${IMGUI_EXECUTABLE} PRIVATE ${WGVK_PLATFORM_DEFS})
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
if (MSVC)
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)

View File

@@ -141,6 +141,28 @@ else() # Native/Desktop build
endif()
if(IMGUI_WGVK_DIR)
find_package(Vulkan REQUIRED)
set(WGVK_PLATFORM_LIBS)
set(WGVK_PLATFORM_DEFS)
if(WIN32)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WIN32_SURFACE=1)
elseif(APPLE)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_METAL_SURFACE=1)
elseif(UNIX)
find_package(PkgConfig QUIET)
pkg_check_modules(WAYLAND_CLIENT QUIET wayland-client)
if(WAYLAND_CLIENT_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WAYLAND_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS ${WAYLAND_CLIENT_LIBRARIES})
endif()
find_package(X11 QUIET)
if(X11_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_XLIB_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS X11::X11)
endif()
list(APPEND WGVK_PLATFORM_LIBS m dl pthread)
endif()
set(LIBRARIES glfw Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
endif()
endif()
@@ -183,6 +205,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
if(IMGUI_WGVK_DIR)
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGVK")
target_compile_definitions(${IMGUI_EXECUTABLE} PRIVATE ${WGVK_PLATFORM_DEFS})
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
if (MSVC)
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)

View File

@@ -141,6 +141,28 @@ else() # Native/Desktop build
endif()
if(IMGUI_WGVK_DIR)
find_package(Vulkan REQUIRED)
set(WGVK_PLATFORM_LIBS)
set(WGVK_PLATFORM_DEFS)
if(WIN32)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WIN32_SURFACE=1)
elseif(APPLE)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_METAL_SURFACE=1)
elseif(UNIX)
find_package(PkgConfig QUIET)
pkg_check_modules(WAYLAND_CLIENT QUIET wayland-client)
if(WAYLAND_CLIENT_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_WAYLAND_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS ${WAYLAND_CLIENT_LIBRARIES})
endif()
find_package(X11 QUIET)
if(X11_FOUND)
list(APPEND WGVK_PLATFORM_DEFS SUPPORT_XLIB_SURFACE=1)
list(APPEND WGVK_PLATFORM_LIBS X11::X11)
endif()
list(APPEND WGVK_PLATFORM_LIBS m dl pthread)
endif()
set(LIBRARIES glfw Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
endif()
endif()
@@ -182,6 +204,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
if(IMGUI_WGVK_DIR)
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGVK")
target_compile_definitions(${IMGUI_EXECUTABLE} PRIVATE ${WGVK_PLATFORM_DEFS})
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
if (MSVC)
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)

View File

@@ -3,12 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx9", "example_win32_directx9\example_win32_directx9.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "example_win32_directx10\example_win32_directx10.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"

View File

@@ -1,7 +0,0 @@
project "imgui"
kind "StaticLib"
files { "../*.h", "../*.cpp" }
vpaths { ["imgui"] = { "../*.cpp", "../*.h", "../misc/debuggers/*.natvis" } }
filter { "toolset:msc*" }
files { "../misc/debuggers/*.natvis" }

View File

@@ -1,322 +0,0 @@
-- We use Premake5 to generate project files (Visual Studio solutions, XCode solutions, Makefiles, etc.)
-- Download Premake5: at https://premake.github.io/download
-- YOU NEED PREMAKE 5.0.0-alpha10 or later
--------- HELP
-- To reduce friction for people who don't aren't used to Premake, we list some concrete usage examples.
if _ACTION == nil then
print "-----------------------------------------"
print " DEAR IMGUI EXAMPLES - PROJECT GENERATOR"
print "-----------------------------------------"
print "Usage:"
print " premake5 [generator] [options]"
print "Examples:"
print " premake5 vs2010"
print " premake5 vs2019 --with-sdl2 --with-vulkan"
print " premake5 xcode4 --with-glfw"
print " premake5 gmake2 --with-glfw --cc=clang"
print "Generators:"
print " codelite gmake gmake2 vs2008 vs2010 vs2012 vs2013 vs2015 vs2017 xcode4 etc."
print "Options:"
print " --with-dx9 Enable dear imgui DirectX 9 example"
print " --with-dx10 Enable dear imgui DirectX 10 example"
print " --with-dx11 Enable dear imgui DirectX 11 example"
print " --with-dx12 Enable dear imgui DirectX 12 example (vs2015+)"
print " --with-glfw Enable dear imgui GLFW examples"
print " --with-sdl2 Enable dear imgui SDL2 examples"
print " --with-vulkan Enable dear imgui Vulkan example"
print " --cc=clang Compile with Clang"
print " --cc=gcc Compile with GCC"
print "Project and object files will be created in the build/ folder. You can delete your build/ folder at any time."
print ""
end
---------- OPTIONS
newoption { trigger = "with-dx9", description="Enable dear imgui DirectX 9 example" }
newoption { trigger = "with-dx10", description="Enable dear imgui DirectX 10 example" }
newoption { trigger = "with-dx11", description="Enable dear imgui DirectX 11 example" }
newoption { trigger = "with-dx12", description="Enable dear imgui DirectX 12 example" }
newoption { trigger = "with-glfw", description="Enable dear imgui GLFW examples" }
newoption { trigger = "with-sdl2", description="Enable dear imgui SDL2 examples" }
newoption { trigger = "with-vulkan", description="Enable dear imgui Vulkan example" }
-- Enable/detect default options under Windows
if _ACTION ~= nil and ((os.istarget ~= nil and os.istarget("windows")) or (os.is ~= nil and os.is("windows"))) then
print("( enabling --with-dx9 )");
print("( enabling --with-dx10 )");
print("( enabling --with-dx11 )");
_OPTIONS["with-dx9"] = 1
_OPTIONS["with-dx10"] = 1
_OPTIONS["with-dx11"] = 1
if _ACTION >= "vs2015" then
print("( enabling --with-dx12 because compiler is " .. _ACTION .. " )");
_OPTIONS["with-dx12"] = 1
end
print("( enabling --with-glfw because GLFW is included in the libs/ folder )");
_OPTIONS["with-glfw"] = 1
if os.getenv("SDL2_DIR") then
print("( enabling --with-sdl2 because SDL2_DIR environment variable was found )");
_OPTIONS["with-sdl2"] = 1
end
if os.getenv("VULKAN_SDK") then
print("( enabling --with-vulkan because VULKAN_SDK environment variable was found )");
_OPTIONS["with-vulkan"] = 1
end
end
--------- HELPER FUNCTIONS
-- Helper function: add dear imgui source files into project
function imgui_as_src(fs_path, project_path)
if (project_path == nil) then project_path = fs_path; end; -- default to same virtual folder as the file system folder (in this project it would be ".." !)
files { fs_path .. "/*.cpp", fs_path .. "/*.h" }
includedirs { fs_path, fs_path .. "/backends" }
vpaths { [project_path] = { fs_path .. "/*.*", fs_path .. "/misc/debuggers/*.natvis" } } -- add in a specific folder of the Visual Studio project
filter { "toolset:msc*" }
files { fs_path .. "/misc/debuggers/*.natvis" }
filter {}
end
-- Helper function: add dear imgui as a library (uncomment the 'include "premake5-lib"' line)
--include "premake5-lib"
function imgui_as_lib(fs_path)
includedirs { fs_path, fs_path .. "/backends" }
links "imgui"
end
--------- SOLUTION, PROJECTS
workspace "imgui_examples"
configurations { "Debug", "Release" }
platforms { "x86", "x86_64" }
location "build/"
symbols "On"
warnings "Extra"
--flags { "FatalCompileWarnings"}
filter { "configurations:Debug" }
optimize "Off"
filter { "configurations:Release" }
optimize "On"
filter { "toolset:clang", "system:windows" }
buildoptions { "-Xclang", "-flto-visibility-public-std" } -- Remove "warning LNK4049: locally defined symbol ___std_terminate imported"
-- example_win32_directx11 (Win32 + DirectX 11)
-- We have DX11 as the first project because this is what Visual Studio uses
if (_OPTIONS["with-dx11"]) then
project "example_win32_directx11"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
files { "../backends/imgui_impl_win32.*", "../backends/imgui_impl_dx11.*", "example_win32_directx11/*.cpp", "example_win32_directx11/*.h", "README.txt" }
vpaths { ["sources"] = "./**" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100" }
includedirs { "$(DXSDK_DIR)/Include" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100", "platforms:x86" }
libdirs { "$(DXSDK_DIR)/Lib/x86" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100", "platforms:x86_64" }
libdirs { "$(DXSDK_DIR)/Lib/x64" }
filter { "system:windows" }
links { "d3d11", "d3dcompiler", "dxgi" }
end
-- example_win32_directx9 (Win32 + DirectX 9)
if (_OPTIONS["with-dx9"]) then
project "example_win32_directx9"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
files { "../backends/imgui_impl_win32.*", "../backends/imgui_impl_dx9.*", "example_win32_directx9/*.cpp", "example_win32_directx9/*.h", "README.txt" }
vpaths { ["sources"] = "./**" }
filter { "system:windows" }
links { "d3d9" }
end
-- example_win32_directx10 (Win32 + DirectX 10)
if (_OPTIONS["with-dx10"]) then
project "example_win32_directx10"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
files { "../backends/imgui_impl_win32.*", "../backends/imgui_impl_dx10.*", "example_win32_directx10/*.cpp", "example_win32_directx10/*.h", "README.txt" }
vpaths { ["sources"] = "./**" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100" }
includedirs { "$(DXSDK_DIR)/Include" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100", "platforms:x86" }
libdirs { "$(DXSDK_DIR)/Lib/x86" }
filter { "system:windows", "toolset:msc-v80 or msc-v90 or msc-v100", "platforms:x86_64" }
libdirs { "$(DXSDK_DIR)/Lib/x64" }
filter { "system:windows" }
links { "d3d10", "d3dcompiler", "dxgi" }
end
-- example_win32_directx12 (Win32 + DirectX 12)
if (_OPTIONS["with-dx12"]) then
project "example_win32_directx12"
kind "ConsoleApp"
systemversion "10.0.16299.0"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
files { "../backends/imgui_impl_win32.*", "../backends/imgui_impl_dx12.*", "example_win32_directx12/*.cpp", "example_win32_directx12/*.h", "README.txt" }
vpaths { ["sources"] = "./**" }
filter { "system:windows" }
links { "d3d12", "d3dcompiler", "dxgi" }
end
-- example_glfw_opengl2 (GLFW + OpenGL2)
if (_OPTIONS["with-glfw"]) then
project "example_glfw_opengl2"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
files { "../backends/imgui_impl_glfw.*", "../backends/imgui_impl_opengl2.*", "example_glfw_opengl2/*.h", "example_glfw_opengl2/*.cpp", "README.txt"}
vpaths { ["sources"] = "./**" }
includedirs { "libs/glfw/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "libs/glfw/lib-vc2010-32" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "libs/glfw/lib-vc2010-64" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "opengl32", "glfw3" }
filter { "system:linux" }
links { "glfw3" }
filter { "system:macosx" }
libdirs { "/usr/local/lib" }
links { "glfw" }
linkoptions { "-framework OpenGL" }
end
-- example_glfw_opengl3 (GLFW + OpenGL3)
if (_OPTIONS["with-glfw"]) then
project "example_glfw_opengl3"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_glfw.*", "../backends/imgui_impl_opengl3.*", "example_glfw_opengl3/*.h", "example_glfw_opengl3/*.cpp", "./README.txt" }
includedirs { "libs/glfw/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "libs/glfw/lib-vc2010-32" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "libs/glfw/lib-vc2010-64" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "opengl32", "glfw3" }
filter { "system:linux" }
links { "glfw3" }
filter { "system:macosx" }
libdirs { "/usr/local/lib" }
links { "glfw" }
linkoptions { "-framework OpenGL" }
end
-- example_glfw_vulkan (GLFW + Vulkan)
if (_OPTIONS["with-vulkan"]) then
project "example_glfw_vulkan"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_glfw*", "../backends/imgui_impl_vulkan.*", "example_glfw_vulkan/*.h", "example_glfw_vulkan/*.cpp", "./README.txt" }
includedirs { "libs/glfw/include", "%VULKAN_SDK%/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "libs/glfw/lib-vc2010-32", "%VULKAN_SDK%/lib32" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "libs/glfw/lib-vc2010-64", "%VULKAN_SDK%/lib" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "vulkan-1", "glfw3" }
filter { "system:linux" }
links { "glfw3" } -- FIXME: missing Vulkan. missing macosx version
end
-- example_null (no rendering)
if (true) then
project "example_null"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "example_null/*.h", "example_null/*.cpp", "./README.txt" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
end
-- example_sdl2_sdlrenderer2 (SDL2 + SDL_Renderer)
if (_OPTIONS["with-sdl2"]) then
project "example_sdl2_sdlrenderer2"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_sdl2*", "../backends/imgui_impl_sdlrenderer2.*", "example_sdl2_sdlrenderer2/*.h", "example_sdl2_sdlrenderer2/*.cpp", "./README.txt" }
includedirs { "%SDL2_DIR%/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "%SDL2_DIR%/lib/x86" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "%SDL2_DIR%/lib/x64" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "SDL2", "SDL2main" }
end
-- example_sdl2_opengl2 (SDL2 + OpenGL2)
if (_OPTIONS["with-sdl2"]) then
project "example_sdl2_opengl2"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_sdl2*", "../backends/imgui_impl_opengl2.*", "example_sdl2_opengl2/*.h", "example_sdl2_opengl2/*.cpp", "./README.txt" }
includedirs { "%SDL2_DIR%/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "%SDL2_DIR%/lib/x86" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "%SDL2_DIR%/lib/x64" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "SDL2", "SDL2main", "opengl32" }
end
-- example_sdl2_opengl3 (SDL2 + OpenGL3)
if (_OPTIONS["with-sdl2"]) then
project "example_sdl2_opengl3"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_sdl2*", "../backends/imgui_impl_opengl3.*", "example_sdl2_opengl3/*.h", "example_sdl2_opengl3/*.cpp", "./README.txt" }
includedirs { "%SDL2_DIR%/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "%SDL2_DIR%/lib/x86" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "%SDL2_DIR%/lib/x64" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "SDL2", "SDL2main", "opengl32" }
end
-- example_sdl2_vulkan (SDL2 + Vulkan)
if (_OPTIONS["with-sdl2"] and _OPTIONS["with-vulkan"]) then
project "example_sdl2_vulkan"
kind "ConsoleApp"
imgui_as_src ("..", "imgui")
--imgui_as_lib ("..")
vpaths { ["sources"] = "./**" }
files { "../backends/imgui_impl_sdl2*", "../backends/imgui_impl_vulkan.*", "example_sdl2_vulkan/*.h", "example_sdl2_vulkan/*.cpp", "./README.txt" }
includedirs { "%SDL2_DIR%/include", "%VULKAN_SDK%/include" }
filter { "system:windows", "platforms:x86" }
libdirs { "%SDL2_DIR%/lib/x86", "%VULKAN_SDK%/lib32" }
filter { "system:windows", "platforms:x86_64" }
libdirs { "%SDL2_DIR%/lib/x64", "%VULKAN_SDK%/lib" }
filter { "system:windows" }
ignoredefaultlibraries { "msvcrt" }
links { "SDL2", "SDL2main", "vulkan-1" }
end

181
imgui.cpp
View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (main code and documentation)
// Help:
@@ -395,7 +395,28 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2026/04/23 (1.92.8) - Obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`, which is part of our new standard draw callbacks. (#9378)
- 2026/05/07 (1.92.8) - DrawList: swapped the last two arguments of AddRect(), AddPolyline(), PathStroke().
- Before: void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f);
- After: void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0);
- Before: void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
- After: void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0);
- Before: void ImDrawList::PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f);
- After: void ImDrawList::PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
Added inline redirection functions when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is off.
Marked the old functions are =delete when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is on, to allow for better type-checking.
Effectively the typical call site is changing from:
- Before: window->DrawList->AddRect(p_min, p_max, color, rounding, ImDrawFlags_None, border_size);
- After: window->DrawList->AddRect(p_min, p_max, color, rounding, border_size);
Notes:
- Users of C++ and other languages with type-checking will be notified at compile-time of any mistakes.
- Users of high-level bindings or languages with no type-checking will be notified at runtime via an assert for invalid flags value.
If you are a binding maintainer consider doing something to facilitate transition or error detection.
- This is perhaps the worst breaking change in our history :( but it makes ImDrawList function signatures consistent.
As we are aiming to add flags and features to variety of ImDrawList functions, that consistency becomes more important.
The new order is also more convenient as `flags` are less frequently used than `thickness` in real code.
- As a general policy in Dear ImGui, all our flags default to 0 so ImDrawFlags_None was likely written 0 in some call sites.
- Consider adding `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h, even temporarily, to clean up legacy code.
- 2026/04/23 (1.92.8) - DrawList: obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`, which is part of our new standard draw callbacks. (#9378)
- 2026/04/22 (1.92.8) - Backends: Vulkan: redesigned to use separate ImageView + Sampler instead of Combined Image Sampler.
- When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler.
- When creating your own descriptor pool (instead of letting backend creates its own): need at least IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE + IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLER.
@@ -1400,6 +1421,7 @@ static void UpdateTexturesNewFrame();
static void UpdateTexturesEndFrame();
static void UpdateSettings();
static int UpdateWindowManualResize(ImGuiWindow* window, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
static void RenderWindowShadow(ImGuiWindow* window);
static void RenderWindowOuterBorders(ImGuiWindow* window);
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
@@ -1528,6 +1550,9 @@ ImGuiStyle::ImGuiStyle()
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
WindowShadowSize = 100.0f; // Size (in pixels) of window shadows.
WindowShadowOffsetDist = 0.0f; // Offset distance (in pixels) of window shadows from casting window.
WindowShadowOffsetAngle = IM_PI * 0.25f; // Offset angle of window shadows from casting window (0.0f = left, 0.5f*PI = bottom, 1.0f*PI = right, 1.5f*PI = top).
// Behaviors
HoverStationaryDelay = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary.
@@ -3659,6 +3684,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] =
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, DragDropTargetRounding)}, // ImGuiStyleVar_DragDropTargetRounding
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize
@@ -3759,6 +3785,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
case ImGuiCol_CheckMark: return "CheckMark";
case ImGuiCol_CheckboxSelectedBg: return "CheckboxSelectedBg";
case ImGuiCol_SliderGrab: return "SliderGrab";
case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
case ImGuiCol_Button: return "Button";
@@ -3800,6 +3827,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg";
case ImGuiCol_WindowShadow: return "WindowShadow";
}
IM_ASSERT(0);
return "Unknown";
@@ -3926,8 +3954,8 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
text_end_full = FindRenderedTextEnd(text);
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f);
//draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 6), IM_COL32(0, 0, 255, 255));
//draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y - 2), ImVec2(ellipsis_max_x, pos_max.y + 3), IM_COL32(0, 255, 0, 255));
//draw_list->AddLineV(pos_max.x, pos_min.y - 4, pos_max.y + 6, IM_COL32(0, 0, 255, 255));
//draw_list->AddLineV(ellipsis_max_x, pos_min.y - 2, pos_max.y + 3, IM_COL32(0, 255, 0, 255));
// FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels.
if (text_size.x > pos_max.x - pos_min.x)
@@ -3972,8 +4000,8 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders
const float border_size = g.Style.FrameBorderSize;
if (borders && border_size > 0.0f)
{
window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, border_size);
window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, border_size);
}
}
@@ -3984,8 +4012,8 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
const float border_size = g.Style.FrameBorderSize;
if (border_size > 0.0f)
{
window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, border_size);
window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, border_size);
}
}
@@ -4020,7 +4048,7 @@ void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFl
const float thickness = 2.0f;
if (flags & ImGuiNavRenderCursorFlags_Compact)
{
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, thickness);
}
else
{
@@ -4029,7 +4057,7 @@ void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFl
bool fully_visible = window->ClipRect.Contains(display_rect);
if (!fully_visible)
window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, thickness);
if (!fully_visible)
window->DrawList->PopClipRect();
}
@@ -4063,7 +4091,7 @@ void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCurso
float a_min = ImFmod((float)g.Time * 5.0f, 2.0f * IM_PI);
float a_max = a_min + IM_PI * 1.65f;
draw_list->PathArcTo(pos + ImVec2(14, -1) * scale, 6.0f * scale, a_min, a_max);
draw_list->PathStroke(col_fill, ImDrawFlags_None, 3.0f * scale);
draw_list->PathStroke(col_fill, 3.0f * scale);
}
draw_list->PopTexture();
}
@@ -4697,7 +4725,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
g.ActiveIdIsJustActivated = (g.ActiveId != id);
if (g.ActiveIdIsJustActivated)
{
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() old:0x%08X (window \"%s\") -> new:0x%08X (window \"%s\")\n", g.ActiveId, g.ActiveIdWindow ? g.ActiveIdWindow->Name : "", id, window ? window->Name : "");
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() 0x%08X in \"%s\"%*s(previously 0x%08X in \"%s\")\n", id, window ? window->Name : "",
ImMax(0, 20 - (int)(window ? strlen(window->Name) : 0)), "", g.ActiveId, g.ActiveIdWindow ? g.ActiveIdWindow->Name : "");
g.ActiveIdTimer = 0.0f;
g.ActiveIdHasBeenPressedBefore = false;
g.ActiveIdHasBeenEditedBefore = false;
@@ -4753,8 +4782,12 @@ void ImGui::MarkItemEdited(ImGuiID id)
// This marking is to be able to provide info for IsItemDeactivatedAfterEdit().
// ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need to fill the data.
ImGuiContext& g = *GImGui;
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_EditedInternal;
if (g.LastItemData.ItemFlags & ImGuiItemFlags_NoMarkEdited)
return;
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
if (g.ActiveId == id || g.ActiveId == 0)
{
// FIXME: Can't we fully rely on LastItemData yet?
@@ -4768,9 +4801,6 @@ void ImGui::MarkItemEdited(ImGuiID id)
// We accept 'ActiveIdPreviousFrame == id' for InputText() returning an edit after it has been taken ActiveId away (#4714)
// FIXME: This assert is getting a bit meaningless over time. It helped detect some unusual use cases but eventually it is becoming an unnecessary restriction.
IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id || g.NavJustMovedToId || (g.CurrentMultiSelect != NULL && g.BoxSelectState.IsActive));
//IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
}
bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
@@ -4935,7 +4965,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
{
g.HoveredIdPreviousFrameItemCount++;
if (g.DebugDrawIdConflictsId == id)
window->DrawList->AddRect(bb.Min - ImVec2(1,1), bb.Max + ImVec2(1,1), IM_COL32(255, 0, 0, 255), 0.0f, ImDrawFlags_None, 2.0f);
window->DrawList->AddRect(bb.Min - ImVec2(1,1), bb.Max + ImVec2(1,1), IM_COL32(255, 0, 0, 255), 0.0f, 2.0f);
}
#endif
@@ -5732,7 +5762,7 @@ void ImGui::NewFrame()
g.CurrentWindowStack.resize(0);
g.BeginPopupStack.resize(0);
g.ItemFlagsStack.resize(0);
g.ItemFlagsStack.push_back(ImGuiItemFlags_AutoClosePopups); // Default flags
g.ItemFlagsStack.push_back(ImGuiItemFlags_Default_); // Default flags
g.CurrentItemFlags = g.ItemFlagsStack.back();
g.GroupStack.resize(0);
@@ -5967,7 +5997,7 @@ static void ImGui::RenderDimmedBackgrounds()
if (window->DrawList->CmdBuffer.Size == 0)
window->DrawList->AddDrawCmd();
window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size);
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); // FIXME-DPI
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 3.0f); // FIXME-DPI
window->DrawList->PopClipRect();
}
}
@@ -7127,7 +7157,7 @@ static void RenderWindowOuterSingleBorder(ImGuiWindow* window, int border_n, ImU
const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f);
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle);
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f);
window->DrawList->PathStroke(border_col, ImDrawFlags_None, border_size);
window->DrawList->PathStroke(border_col, border_size);
}
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
@@ -7136,7 +7166,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
const float border_size = window->WindowBorderSize;
const ImU32 border_col = GetColorU32(ImGuiCol_Border);
if (border_size > 0.0f && (window->Flags & ImGuiWindowFlags_NoBackground) == 0)
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, border_col, window->WindowRounding, 0, window->WindowBorderSize);
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, border_col, window->WindowRounding, window->WindowBorderSize);
else if (border_size > 0.0f)
{
if (window->ChildFlags & ImGuiChildFlags_ResizeX) // Similar code as 'resize_border_mask' computation in UpdateWindowManualResize() but we specifically only always draw explicit child resize border.
@@ -7153,7 +7183,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
{
float y = window->Pos.y + window->TitleBarHeight - 1;
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size * 0.5f, y), ImVec2(window->Pos.x + window->Size.x - border_size * 0.5f, y), border_col, g.Style.FrameBorderSize);
window->DrawList->AddLineH(window->Pos.x + border_size * 0.5f, window->Pos.x + window->Size.x - border_size * 0.5f, y, border_col, g.Style.FrameBorderSize);
}
}
@@ -7201,12 +7231,17 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
if (bg_col & IM_COL32_A_MASK)
{
ImRect bg_rect(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size);
ImDrawFlags bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom;
ImDrawFlags bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersBottom;
ImDrawList* bg_draw_list = window->DrawList;
bg_draw_list->AddRectFilled(bg_rect.Min, bg_rect.Max, bg_col, window_rounding, bg_rounding_flags);
}
}
// Draw window shadow
if (style.WindowShadowSize > 0.0f && (!(flags & ImGuiWindowFlags_ChildWindow) || (flags & ImGuiWindowFlags_Popup)))
if (style.Colors[ImGuiCol_WindowShadow].w > 0.0f)
RenderWindowShadow(window);
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar))
{
@@ -7221,7 +7256,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
window->DrawList->AddLine(menu_bar_rect.GetBL() + ImVec2(window_border_size * 0.5f, 0.0f), menu_bar_rect.GetBR() - ImVec2(window_border_size * 0.5f, 0.0f), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
window->DrawList->AddLineH(menu_bar_rect.Min.x + window_border_size * 0.5f, menu_bar_rect.Max.x - window_border_size * 0.5f, menu_bar_rect.Max.y, GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
}
// Scrollbars
@@ -7255,6 +7290,16 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
}
void ImGui::RenderWindowShadow(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;
float shadow_size = style.WindowShadowSize;
ImU32 shadow_col = GetColorU32(ImGuiCol_WindowShadow);
ImVec2 shadow_offset = ImVec2(ImCos(style.WindowShadowOffsetAngle), ImSin(style.WindowShadowOffsetAngle)) * style.WindowShadowOffsetDist;
window->DrawList->AddShadowRect(window->Pos, window->Pos + window->Size, shadow_col, shadow_size, shadow_offset, ImDrawFlags_ShadowCutOutShapeBackground, window->WindowRounding);
}
// Render title text, collapse button, close button
void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open)
{
@@ -9011,7 +9056,7 @@ ImFont* ImGui::GetDefaultFont()
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
}
// EXPERIMENTAL: DO NOT USE YET.
// EXPERIMENTAL. Use ImTextureDataQueueUpload() to queue updates.
void ImGui::RegisterUserTexture(ImTextureData* tex)
{
ImGuiContext& g = *GImGui;
@@ -9135,6 +9180,12 @@ void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
g.FontBaked = (g.Font != NULL && window != NULL) ? g.Font->GetFontBaked(final_size) : NULL;
g.FontBakedScale = (g.FontBaked != NULL) ? (g.FontSize / g.FontBaked->Size) : 0.0f;
g.DrawListSharedData.FontScale = g.FontBakedScale;
if (g.Font)
{
ImFontAtlas* atlas = g.Font->OwnerAtlas;
g.DrawListSharedData.ShadowRectIds = &atlas->ShadowRectIds[0];
g.DrawListSharedData.ShadowRectUvs = &atlas->ShadowRectUvs[0];
}
}
// Exposed in case user may want to override setting density.
@@ -10341,15 +10392,21 @@ void ImGui::UpdateMouseWheel()
LockWheelingWindow(NULL, 0.0f);
}
ImVec2 wheel;
wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheelH : 0.0f;
wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheel : 0.0f;
//IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y);
ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!mouse_window || mouse_window->Collapsed)
return;
ImGuiID owner_id = mouse_window->ID;
ImVec2 wheel;
wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, owner_id) ? g.IO.MouseWheelH : 0.0f;
wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, owner_id) ? g.IO.MouseWheel : 0.0f;
//IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y);
if (g.WheelingWindow != NULL)
{
SetKeyOwner(ImGuiKey_MouseWheelX, owner_id);
SetKeyOwner(ImGuiKey_MouseWheelY, owner_id);
}
// Zoom / Scale window
// FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
@@ -10653,6 +10710,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id)
// - SetKeyOwner(..., None) : clears owner
// - SetKeyOwner(..., Any, !Lock) : illegal (assert)
// - SetKeyOwner(..., Any or None, Lock) : set lock
// Ownership is automatically released on the frame after a release, see code in UpdateKeyboardInputs().
void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags)
{
ImGuiContext& g = *GImGui;
@@ -10679,30 +10737,34 @@ void ImGui::SetKeyOwnersForKeyChord(ImGuiKeyChord key_chord, ImGuiID owner_id, I
if (key_chord & ~ImGuiMod_Mask_) { SetKeyOwner((ImGuiKey)(key_chord & ~ImGuiMod_Mask_), owner_id, flags); }
}
// This is more or less equivalent to:
// This is more or less equivalent to a fancier version of:
// if (IsItemHovered() || IsItemActive())
// SetKeyOwner(key, GetItemID());
// Extensive uses of that (e.g. many calls for a single item) may want to manually perform the tests once and then call SetKeyOwner() multiple times.
// More advanced usage scenarios may want to call SetKeyOwner() manually based on different condition.
// Worth noting is that only one item can be hovered and only one item can be active, therefore this usage pattern doesn't need to bother with routing and priority.
void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
bool ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.LastItemData.ID;
if (id == 0 || (g.HoveredId != id && g.ActiveId != id))
return;
return false;
if ((flags & ImGuiInputFlags_CondMask_) == 0)
flags |= ImGuiInputFlags_CondDefault_;
if ((g.HoveredId == id && (flags & ImGuiInputFlags_CondHovered)) || (g.ActiveId == id && (flags & ImGuiInputFlags_CondActive)))
{
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetItemKeyOwner) == 0); // Passing flags not supported by this function!
if (!TestKeyOwner(key, id))
return false;
SetKeyOwner(key, id, flags & ~ImGuiInputFlags_CondMask_);
return true;
}
return false;
}
void ImGui::SetItemKeyOwner(ImGuiKey key)
bool ImGui::SetItemKeyOwner(ImGuiKey key)
{
SetItemKeyOwner(key, ImGuiInputFlags_None);
return SetItemKeyOwner(key, ImGuiInputFlags_None);
}
// This is the only public API until we expose owner_id versions of the API as replacements.
@@ -12453,6 +12515,17 @@ bool ImGui::BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags ext
return false;
}
// As we bypass BeginChild(), set ImGuiChildFlags_AlwaysAutoResize as it is checked independently from ImGuiWindowFlags_AlwaysAutoResize for now (see #9355)
// Ideally we should remove setting ImGuiWindowFlags_AlwaysAutoResize in BeginChild().
if ((extra_window_flags & ImGuiWindowFlags_ChildWindow) && (extra_window_flags & ImGuiWindowFlags_AlwaysAutoResize))
{
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags)
g.NextWindowData.ChildFlags |= ImGuiChildFlags_AlwaysAutoResize;
else
g.NextWindowData.ChildFlags = ImGuiChildFlags_AlwaysAutoResize;
g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags;
}
char name[128];
IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu);
ImFormatString(name, IM_COUNTOF(name), "%s###Menu_%02d", label, g.BeginMenuDepth); // Recycle windows based on depth
@@ -15117,7 +15190,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
{
ImRect bb = g.DragDropTargetRect;
bb.Expand(-3.5f);
RenderDragDropTargetRectEx(GetForegroundDrawList(), bb);
RenderDragDropTargetRectEx(GetForegroundDrawList(), bb, g.Style.DragDropTargetRounding);
}
else if (draw_target_rect)
{
@@ -15148,16 +15221,16 @@ void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb)
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
if (push_clip_rect)
window->DrawList->PushClipRectFullScreen();
RenderDragDropTargetRectEx(window->DrawList, bb_display);
RenderDragDropTargetRectEx(window->DrawList, bb_display, g.Style.DragDropTargetRounding);
if (push_clip_rect)
window->DrawList->PopClipRect();
}
void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb)
void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding)
{
ImGuiContext& g = *GImGui;
draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), g.Style.DragDropTargetRounding, 0);
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), g.Style.DragDropTargetRounding, 0, g.Style.DragDropTargetBorderSize);
draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), rounding, 0);
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), rounding, g.Style.DragDropTargetBorderSize);
}
const ImGuiPayload* ImGui::GetDragDropPayload()
@@ -16259,7 +16332,7 @@ void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list)
draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding);
ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y);
ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y);
draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f);
draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, 2.0f);
draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding);
ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y);
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
@@ -16682,7 +16755,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
BulletText("Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name);
if (IsItemHovered())
GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min - ImVec2(1, 1), table->OuterRect.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f);
GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min - ImVec2(1, 1), table->OuterRect.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f);
Indent();
char buf[128];
for (int rect_n = 0; rect_n < TRT_Count; rect_n++)
@@ -16697,7 +16770,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImFormatString(buf, IM_COUNTOF(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) Col %d %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), column_n, trt_rects_names[rect_n]);
Selectable(buf);
if (IsItemHovered())
GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f);
GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f);
}
}
else
@@ -16706,7 +16779,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImFormatString(buf, IM_COUNTOF(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), trt_rects_names[rect_n]);
Selectable(buf);
if (IsItemHovered())
GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f);
GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f);
}
}
Unindent();
@@ -17114,7 +17187,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImRect r = Funcs::GetTableRect(table, cfg->ShowTablesRectsType, column_n);
ImU32 col = (table->HoveredColumnBody == column_n) ? IM_COL32(255, 255, 128, 255) : IM_COL32(255, 0, 128, 255);
float thickness = (table->HoveredColumnBody == column_n) ? 3.0f : 1.0f;
draw_list->AddRect(r.Min, r.Max, col, 0.0f, 0, thickness);
draw_list->AddRect(r.Min, r.Max, col, 0.0f, thickness);
}
}
else
@@ -17291,7 +17364,7 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con
{
ImDrawListFlags backup_flags = fg_draw_list->Flags;
fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f);
fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), 1.0f, ImDrawFlags_Closed);
fg_draw_list->Flags = backup_flags;
}
}
@@ -17319,7 +17392,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
for (int n = 0; n < 3; n++, idx_n++)
vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos));
if (show_mesh)
out_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f); // In yellow: mesh triangles
out_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), 1.0f, ImDrawFlags_Closed); // In yellow: mesh triangles
}
// Draw bounding boxes
if (show_aabb)
@@ -17600,8 +17673,8 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label)
{
ImDrawList* draw_list = GetForegroundDrawList(tab_bar->Window);
draw_list->AddRect(tab_bar->BarRect.Min, tab_bar->BarRect.Max, IM_COL32(255, 255, 0, 255));
draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255));
draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255));
draw_list->AddLineV(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255));
draw_list->AddLineV(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255));
}
if (open)
{
@@ -17930,8 +18003,8 @@ void ImGui::DebugDrawCursorPos(ImU32 col)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImVec2 pos = window->DC.CursorPos;
window->DrawList->AddLine(ImVec2(pos.x, pos.y - 3.0f), ImVec2(pos.x, pos.y + 4.0f), col, 1.0f);
window->DrawList->AddLine(ImVec2(pos.x - 3.0f, pos.y), ImVec2(pos.x + 4.0f, pos.y), col, 1.0f);
window->DrawList->AddLineV(pos.x, pos.y - 3.0f, pos.y + 4.0f, col, 1.0f);
window->DrawList->AddLineH(pos.x - 3.0f, pos.x + 4.0f, pos.y, col, 1.0f);
}
// Draw a 10px wide rectangle around CurposPos.x using Line Y1/Y2 in current window's DrawList
@@ -17942,9 +18015,9 @@ void ImGui::DebugDrawLineExtents(ImU32 col)
float curr_x = window->DC.CursorPos.x;
float line_y1 = (window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y);
float line_y2 = line_y1 + (window->DC.IsSameLine ? window->DC.PrevLineSize.y : window->DC.CurrLineSize.y);
window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y1), ImVec2(curr_x + 5.0f, line_y1), col, 1.0f);
window->DrawList->AddLine(ImVec2(curr_x - 0.5f, line_y1), ImVec2(curr_x - 0.5f, line_y2), col, 1.0f);
window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y2), ImVec2(curr_x + 5.0f, line_y2), col, 1.0f);
window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y1, col, 1.0f);
window->DrawList->AddLineV(curr_x - 0.5f, line_y1, line_y2, col, 1.0f);
window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y2, col, 1.0f);
}
// Draw last item rect in ForegroundDrawList (so it is always visible)
@@ -18314,7 +18387,7 @@ void ImGui::ShowFontSelector(const char* label)
"- Load additional fonts with io.Fonts->AddFontXXX() functions.\n"
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
"- Read FAQ and docs/FONTS.md for more details.\n"
"- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
"- Legacy backend: if you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
}
#endif // #if !defined(IMGUI_DISABLE_DEMO_WINDOWS) || !defined(IMGUI_DISABLE_DEBUG_TOOLS)

94
imgui.h
View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (headers)
// Help:
@@ -29,8 +29,8 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.8 WIP"
#define IMGUI_VERSION_NUM 19274
#define IMGUI_VERSION "1.92.8"
#define IMGUI_VERSION_NUM 19280
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
@@ -1092,10 +1092,11 @@ namespace ImGui
// Inputs Utilities: Key/Input Ownership [BETA]
// - One common use case would be to allow your items to disable standard inputs behaviors such
// as Tab or Alt key handling, Mouse Wheel scrolling, etc.
// e.g. Button(...); SetItemKeyOwner(ImGuiKey_MouseWheelY); to make hovering/activating a button disable wheel for scrolling.
// e.g. `Button(...); if (SetItemKeyOwner(ImGuiKey_MouseWheelY)) { ... }` to make hovering/activating a button disable wheel for scrolling.
// - Reminder ImGuiKey enum include access to mouse buttons and gamepad, so key ownership can apply to them.
// - The return value of SetItemKeyOwner() says if ownership has been requested for the item, which is a shortcut to calling yet non-public TestKeyOwner() function.
// - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version.
IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
IMGUI_API bool SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Return true when ownership has been set. Roughly equivalent to 'if (TestKeyOwner(key, GetItemID()) && (IsItemHovered() || IsItemActive())) { SetKeyOwner(key, GetItemID());'.
// Inputs Utilities: Mouse
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
@@ -1755,6 +1756,7 @@ enum ImGuiCol_
ImGuiCol_ScrollbarGrabHovered,
ImGuiCol_ScrollbarGrabActive,
ImGuiCol_CheckMark, // Checkbox tick and RadioButton circle
ImGuiCol_CheckboxSelectedBg, // Checkbox background when Selected, otherwise use FrameBg
ImGuiCol_SliderGrab,
ImGuiCol_SliderGrabActive,
ImGuiCol_Button,
@@ -1796,6 +1798,7 @@ enum ImGuiCol_
ImGuiCol_NavWindowingHighlight, // Highlight window when using Ctrl+Tab
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the Ctrl+Tab window list, when active
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active
ImGuiCol_WindowShadow, // Window shadows
ImGuiCol_COUNT,
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@@ -1852,6 +1855,7 @@ enum ImGuiStyleVar_
ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign
ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize
ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding
ImGuiStyleVar_DragDropTargetRounding, // float DragDropTargetRounding
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
ImGuiStyleVar_SeparatorSize, // float SeparatorSize
@@ -2328,7 +2332,7 @@ struct ImGuiStyle
ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes.
float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line.
float DragDropTargetRounding; // Radius of the drag and drop target frame.
float DragDropTargetRounding; // Radius of the drag and drop target frame. When <0.0f: use FrameRounding.
float DragDropTargetBorderSize; // Thickness of the drag and drop target border.
float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size.
float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers.
@@ -2348,6 +2352,10 @@ struct ImGuiStyle
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
float WindowShadowSize; // Size (in pixels) of window shadows. Set this to zero to disable shadows.
float WindowShadowOffsetDist; // Offset distance (in pixels) of window shadows from casting window.
float WindowShadowOffsetAngle; // Offset angle of window shadows from casting window (0.0f = left, 0.5f*PI = bottom, 1.0f*PI = right, 1.5f*PI = top).
// Colors
ImVec4 Colors[ImGuiCol_COUNT];
@@ -3239,16 +3247,15 @@ struct ImDrawListSplitter
};
// Flags for ImDrawList functions
// (Legacy: bit 0 must always correspond to ImDrawFlags_Closed to be backward compatible with old API using a bool. Bits 1..3 must be unused)
enum ImDrawFlags_
{
ImDrawFlags_None = 0,
ImDrawFlags_Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason)
ImDrawFlags_RoundCornersTopLeft = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01.
ImDrawFlags_RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02.
ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04.
ImDrawFlags_RoundCornersBottomRight = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08.
ImDrawFlags_RoundCornersNone = 1 << 8, // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag!
ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason)
ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight,
ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight,
ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft,
@@ -3256,6 +3263,9 @@ enum ImDrawFlags_
ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight,
ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified.
ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone,
ImDrawFlags_InvalidMask_ = (ImDrawFlags)0x8000000F,
ImDrawFlags_ShadowCutOutShapeBackground = 1 << 20, // Do not render the shadow shape under the objects to be shadowed to save on fill-rate or facilitate blending. Slower on CPU.
};
// Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
@@ -3321,7 +3331,9 @@ struct ImDrawList
// In future versions we will use textures to provide cheaper and higher-quality circles.
// Use AddNgon() and AddNgonFilled() functions if you need to guarantee a specific number of sides.
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size)
IMGUI_API void AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size)
IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size)
IMGUI_API void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f);
@@ -3342,7 +3354,7 @@ struct ImDrawList
// General polygon
// - Only simple polygons are supported by filling functions (no self-intersections, no holes).
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library.
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
@@ -3354,6 +3366,23 @@ struct ImDrawList
IMGUI_API void AddImageQuad(ImTextureRef tex_ref, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1 = ImVec2(0, 0), const ImVec2& uv2 = ImVec2(1, 0), const ImVec2& uv3 = ImVec2(1, 1), const ImVec2& uv4 = ImVec2(0, 1), ImU32 col = IM_COL32_WHITE);
IMGUI_API void AddImageRounded(ImTextureRef tex_ref, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags = 0);
// Shadows primitives
// [BETA] API
// - Add shadow for a object, with min/max or center/radius describing the object extents, and offset shifting the shadow.
// - Rounding parameters refer to the object itself, not the shadow!
// - By default, the area under the object is filled, because this is simpler to process.
// Using the ImDrawFlags_ShadowCutOutShapeBackground flag makes the function not render this area and leave a hole under the object.
// - Shadows w/ fill under the object: a bit faster for CPU, more pixels rendered, visible/darkening if used behind a transparent shape.
// Typically used by: small, frequent objects, opaque objects, transparent objects if shadow darkening isn't an issue.
// - Shadows w/ hole under the object: a bit slower for CPU, less pixels rendered, no difference if used behind a transparent shape.
// Typically used by: large, infrequent objects, transparent objects if exact blending/color matter.
// - FIXME-SHADOWS: 'offset' + ImDrawFlags_ShadowCutOutShapeBackground are not currently supported together with AddShadowCircle(), AddShadowConvexPoly(), AddShadowNGon().
#define IMGUI_HAS_SHADOWS 1
IMGUI_API void AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0, float obj_rounding = 0.0f);
IMGUI_API void AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0, int obj_num_segments = 12);
IMGUI_API void AddShadowConvexPoly(const ImVec2* points, int points_count, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0);
IMGUI_API void AddShadowNGon(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags, int obj_num_segments);
// Stateful path API, add points then finish with PathFillConvex() or PathStroke()
// - Important: filled shapes must always use clockwise winding order! The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
// so e.g. 'PathArcTo(center, radius, PI * -0.5f, PI)' is ok, whereas 'PathArcTo(center, radius, PI, PI * -0.5f)' won't have correct anti-aliasing when followed by PathFillConvex().
@@ -3362,7 +3391,7 @@ struct ImDrawList
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); }
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
inline void PathFillConcave(ImU32 col) { AddConcavePolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; }
inline void PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0) { AddPolyline(_Path.Data, _Path.Size, col, thickness, flags); _Path.Size = 0; }
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0);
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse
@@ -3410,8 +3439,15 @@ struct ImDrawList
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) { AddRect(p_min, p_max, col, rounding, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED.
inline void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) { AddPolyline(points, num_points, col, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED.
inline void PathStroke(ImU32 col, ImDrawFlags flags, float thickness) { PathStroke(col, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED.
inline void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.0
inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.0
#else
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding /*= 0.0f*/, ImDrawFlags flags /*= 0*/, float thickness /*= 1.0f*/) = delete;
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) = delete;
inline void PathStroke(ImU32 col, ImDrawFlags flags /*= 0*/, float thickness /*= 1.0f*/) = delete;
#endif
//inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
@@ -3523,6 +3559,7 @@ struct ImTextureData
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
// Functions
// - If GetPixels() functions asserts while being called by your render loop, it could be caused by calling ImFontAtlas::Clear() instead of ClearFonts()?
ImTextureData() { memset((void*)this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
~ImTextureData() { DestroyPixels(); }
IMGUI_API void Create(ImTextureFormat format, int w, int h);
@@ -3545,6 +3582,24 @@ struct ImTextureData
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
//-----------------------------------------------------------------------------
// [Internal] Shadow texture baking config
struct ImFontAtlasShadowTexConfig
{
int TexCornerSize; // Size of the corner areas.
int TexEdgeSize; // Size of the edge areas (and by extension the center). Changing this is normally unnecessary.
float TexFalloffPower; // The power factor for the shadow falloff curve.
float TexDistanceFieldOffset; // How much to offset the distance field by (allows over/under-shadowing, potentially useful for accommodating rounded corners on the "casting" shape).
bool TexBlur; // Do we want to Gaussian blur the shadow texture?
inline ImFontAtlasShadowTexConfig() { memset(this, 0, sizeof(*this)); }
IMGUI_API void SetupDefaults();
int GetRectTexPadding() const { return 2; } // Number of pixels of padding to add to the rectangular texture to avoid sampling artifacts at the edges.
int CalcRectTexSize() const { return TexCornerSize + TexEdgeSize + GetRectTexPadding(); } // The size of the texture area required for the actual 2x2 rectangle shadow texture (after the redundant corners have been removed). Padding is required here to avoid sampling artifacts at the edge adjoining the removed corners. int CalcConvexTexWidth() const; // The width of the texture area required for the convex shape shadow texture.
int GetConvexTexPadding() const { return 8; } // Number of pixels of padding to add to the convex shape texture to avoid sampling artifacts at the edges. This also acts as padding for the expanded corner triangles.
int CalcConvexTexWidth() const; // The width of the texture area required for the convex shape shadow texture.
int CalcConvexTexHeight() const; // The height of the texture area required for the convex shape shadow texture.
};
// A font input/source (we may rename this to ImFontSource in the future)
struct ImFontConfig
{
@@ -3678,13 +3733,13 @@ struct ImFontAtlas
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
IMGUI_API void RemoveFont(ImFont* font);
IMGUI_API void Clear(); // Clear everything (input fonts, output glyphs/textures).
IMGUI_API void Clear(); // Clear everything (fonts + textures). Don't call mid-frame!
IMGUI_API void ClearFonts(); // Clear input+output font data/glyphs. You can call this mid-frame if you load new fonts afterwards!
IMGUI_API void CompactCache(); // Compact cached glyphs and texture.
IMGUI_API void SetFontLoader(const ImFontLoader* font_loader); // Change font loader at runtime.
// As we are transitioning toward a new font system, we expect to obsolete those soon:
IMGUI_API void ClearInputData(); // [OBSOLETE] Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
IMGUI_API void ClearFonts(); // [OBSOLETE] Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
IMGUI_API void ClearTexData(); // [OBSOLETE] Clear CPU-side copy of the texture data. Saves RAM once the texture has been copied to graphics memory.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@@ -3796,6 +3851,11 @@ struct ImFontAtlas
int RefCount; // Number of contexts using this atlas
ImGuiContext* OwnerContext; // Context which own the atlas will be in charge of updating and destroying it.
// [Internal] Shadow data
ImFontAtlasRectId ShadowRectIds[2]; // IDs of rect for shadow textures
ImVec4 ShadowRectUvs[10]; // UV coordinates for shadow textures, 9 for the rectangle shadows and the final entry for the convex shape shadows
ImFontAtlasShadowTexConfig ShadowTexConfig; // Shadow texture baking config
// [Obsolete]
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy: You can request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. --> Prefer using a custom ImFontLoader.
@@ -4017,11 +4077,11 @@ struct ImGuiPlatformIO
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
void* Renderer_RenderState;
// Standard draw callbacks
// Standard draw callbacks provided by renderer backend.
ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state.
ImDrawCallback DrawCallback_SetSamplerLinear; // Request to set current texture sampling to Linear
ImDrawCallback DrawCallback_SetSamplerNearest; // Request to set current texture sampling to Nearest/Point
//ImDrawCallback DrawCallback_SetSamplerCustom; // Request to set current texture sampling using Backend Specific data.
ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear.
ImDrawCallback DrawCallback_SetSamplerNearest; // Request backend to set texture sampling to Nearest/Point.
//ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data.
//------------------------------------------------------------------
// Output

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (demo code)
// Help:
@@ -73,6 +73,7 @@ Index of this file:
// [SECTION] Demo Window / ShowDemoWindow()
// [SECTION] DemoWindowMenuBar()
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
// [SECTION] Helpers: ExampleImageViewer
// [SECTION] DemoWindowWidgetsBasic()
// [SECTION] DemoWindowWidgetsBullets()
// [SECTION] DemoWindowWidgetsCollapsingHeaders()
@@ -108,6 +109,7 @@ Index of this file:
// [SECTION] User Guide / ShowUserGuide()
// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
// [SECTION] Example App: Image Viewer / ShowExampleAppImageViewer()
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
@@ -238,6 +240,7 @@ static void ShowExampleAppAssetsBrowser(bool* p_open);
static void ShowExampleAppConsole(bool* p_open);
static void ShowExampleAppCustomRendering(bool* p_open);
static void ShowExampleAppDocuments(bool* p_open);
static void ShowExampleAppImageViewer(bool* p_open);
static void ShowExampleAppLog(bool* p_open);
static void ShowExampleAppLayout(bool* p_open);
static void ShowExampleAppPropertyEditor(bool* p_open, ImGuiDemoWindowData* demo_data);
@@ -308,6 +311,7 @@ struct ImGuiDemoWindowData
bool ShowAppConsole = false;
bool ShowAppCustomRendering = false;
bool ShowAppDocuments = false;
bool ShowAppImageViewer = false;
bool ShowAppLog = false;
bool ShowAppLayout = false;
bool ShowAppPropertyEditor = false;
@@ -353,6 +357,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (demo_data.ShowAppAssetsBrowser) { ShowExampleAppAssetsBrowser(&demo_data.ShowAppAssetsBrowser); }
if (demo_data.ShowAppConsole) { ShowExampleAppConsole(&demo_data.ShowAppConsole); }
if (demo_data.ShowAppCustomRendering) { ShowExampleAppCustomRendering(&demo_data.ShowAppCustomRendering); }
if (demo_data.ShowAppImageViewer) { ShowExampleAppImageViewer(&demo_data.ShowAppImageViewer); }
if (demo_data.ShowAppLog) { ShowExampleAppLog(&demo_data.ShowAppLog); }
if (demo_data.ShowAppLayout) { ShowExampleAppLayout(&demo_data.ShowAppLayout); }
if (demo_data.ShowAppPropertyEditor) { ShowExampleAppPropertyEditor(&demo_data.ShowAppPropertyEditor, &demo_data); }
@@ -677,6 +682,7 @@ static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
ImGui::MenuItem("Console", NULL, &demo_data->ShowAppConsole);
ImGui::MenuItem("Custom rendering", NULL, &demo_data->ShowAppCustomRendering);
ImGui::MenuItem("Documents", NULL, &demo_data->ShowAppDocuments);
ImGui::MenuItem("Image Viewer", NULL, &demo_data->ShowAppImageViewer);
ImGui::MenuItem("Log", NULL, &demo_data->ShowAppLog);
ImGui::MenuItem("Property editor", NULL, &demo_data->ShowAppPropertyEditor);
ImGui::MenuItem("Simple layout", NULL, &demo_data->ShowAppLayout);
@@ -708,7 +714,7 @@ static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
ImGui::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
ImGui::EndDisabled();
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
ImGui::TextDisabled("(see Demo->Configuration for details & more)");
ImGui::TextDisabled("(see Demo->Configuration for more)");
ImGui::EndMenu();
}
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
@@ -825,6 +831,87 @@ static ExampleTreeNode* ExampleTree_CreateDemoTree()
return node_L0;
}
//-----------------------------------------------------------------------------
// [SECTION] Helpers: ExampleImageViewer
//-----------------------------------------------------------------------------
struct ExampleImageViewerData
{
ImU32 ImageBgColor = IM_COL32(100, 100, 100, 255);
ImU32 GridColor = IM_COL32(255, 255, 255, 100);
bool GridEnabled = true;
bool ViewReset = true;
ImVec2 ViewOffset; // in image space
float Zoom = 10.0f;
float ZoomMin = 1.0f;
float ZoomMax = 10000.0f;
};
static void ExampleImageViewer_DrawOptions(ExampleImageViewerData* data)
{
ImGui::SetNextItemShortcut(ImGuiKey_G, ImGuiInputFlags_Tooltip); // | ImGuiInputFlags_RouteGlobal
ImGui::Checkbox("Grid", &data->GridEnabled);
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 10.0f);
float zoom_100 = data->Zoom * 100.0f;
if (ImGui::DragFloat("##Zoom", &zoom_100, 5.0f, data->ZoomMin * 100.0f, data->ZoomMax * 100.0f, "%.0f%%", ImGuiSliderFlags_AlwaysClamp))
data->Zoom = zoom_100 / 100.0f;
}
static void ExampleImageViewer_DrawCanvas(ExampleImageViewerData* data, ImVec2 canvas_size, ImTextureRef image_tex_ref, int image_w, int image_h)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImDrawList* draw_list = ImGui::GetWindowDrawList();
IM_ASSERT(canvas_size.x >= 0.0f && canvas_size.y >= 0.0f);
// Layout canvas
ImGui::InvisibleButton("##Canvas", canvas_size);
ImVec2 canvas_min = ImGui::GetItemRectMin();
ImVec2 canvas_max = ImGui::GetItemRectMax();
if (data->ViewReset)
data->ViewOffset = ImVec2((canvas_size.x * 0.5f / data->Zoom) - 0.5f, (canvas_size.y * 0.5f / data->Zoom) - 0.5f); // Add half a pixel padding
data->ViewReset = false;
// Handle inputs
if (ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY))
if (io.MouseWheel != 0.0f)
data->Zoom = IM_CLAMP(data->Zoom * (1.0f + io.MouseWheel * 0.10f), data->ZoomMin, data->ZoomMax);
float zoom = data->Zoom; // (float)(int)ViewZoom;
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0))
{
data->ViewOffset.x -= io.MouseDelta.x / zoom;
data->ViewOffset.y -= io.MouseDelta.y / zoom;
}
// Display image
ImVec2 image_min, image_max;
image_min.x = (float)(int)((canvas_min.x - (data->ViewOffset.x * zoom)) + (canvas_size.x * 0.5f));
image_min.y = (float)(int)((canvas_min.y - (data->ViewOffset.y * zoom)) + (canvas_size.y * 0.5f));
image_max.x = (float)(int)(image_min.x + image_w * zoom);
image_max.y = (float)(int)(image_min.y + image_h * zoom);
draw_list->AddRect(ImVec2(canvas_min.x - 1.0f, canvas_min.y - 1.0f), ImVec2(canvas_max.x + 1.0f, canvas_max.y + 1.0f), IM_COL32(255, 255, 255, 255));
draw_list->PushClipRect(canvas_min, canvas_max, true);
draw_list->AddRectFilled(image_min, image_max, data->ImageBgColor);
if (platform_io.DrawCallback_SetSamplerNearest != NULL)
draw_list->AddCallback(platform_io.DrawCallback_SetSamplerNearest);
draw_list->AddImage(image_tex_ref, image_min, image_max);
if (platform_io.DrawCallback_SetSamplerLinear != NULL)
draw_list->AddCallback(ImGui::GetPlatformIO().DrawCallback_SetSamplerLinear);
// Display grid lines for visible pixels
if (data->GridEnabled && zoom > 6.0f)
{
const float step = (float)zoom;
for (int px = (int)((canvas_min.x - image_min.x) / step); px <= (int)((canvas_max.x - image_min.x) / step); px++)
draw_list->AddLineV(image_min.x + px * step, canvas_min.y, canvas_max.y, data->GridColor, 1.0f);
for (int py = (int)((canvas_min.y - image_min.y) / step); py <= (int)((canvas_max.y - image_min.y) / step); py++)
draw_list->AddLineH(canvas_min.x, canvas_max.x, image_min.y + py * step, data->GridColor, 1.0f);
}
draw_list->PopClipRect();
}
//-----------------------------------------------------------------------------
// [SECTION] DemoWindowWidgetsBasic()
//-----------------------------------------------------------------------------
@@ -1802,40 +1889,29 @@ static void DemoWindowWidgetsImages()
// - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
// Grab the current texture identifier used by the font atlas.
ImTextureRef my_tex_id = io.Fonts->TexRef;
ImFontAtlas* atlas = io.Fonts;
ImTextureRef my_tex_id = atlas->TexRef;
float my_tex_w = (float)atlas->TexData->Width; // Regular user code should never have to care about TexData-> fields, but since we want to display the entire texture here, we pull Width/Height from it.
float my_tex_h = (float)atlas->TexData->Height;
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
// Regular user code should never have to care about TexData-> fields, but since we want to display the entire texture here, we pull Width/Height from it.
float my_tex_w = (float)io.Fonts->TexData->Width;
float my_tex_h = (float)io.Fonts->TexData->Height;
// Basic drawing
ImGui::SeparatorText("Image()/ImageWithBg() function");
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize));
ImGui::ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
ImGui::PopStyleVar();
{
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize));
ImGui::ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
if (ImGui::BeginItemTooltip())
{
float region_sz = 32.0f;
float region_x = io.MousePos.x - pos.x - region_sz * 0.5f;
float region_y = io.MousePos.y - pos.y - region_sz * 0.5f;
float zoom = 4.0f;
if (region_x < 0.0f) { region_x = 0.0f; }
else if (region_x > my_tex_w - region_sz) { region_x = my_tex_w - region_sz; }
if (region_y < 0.0f) { region_y = 0.0f; }
else if (region_y > my_tex_h - region_sz) { region_y = my_tex_h - region_sz; }
ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y);
ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz);
ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h);
ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h);
ImGui::ImageWithBg(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
}
// Fancy widget
ImGui::SeparatorText("Interactive Image Viewer");
static ExampleImageViewerData image_viewer;
ImVec2 canvas_size(ImGui::GetContentRegionAvail().x, my_tex_h * 2.0f);
ExampleImageViewer_DrawOptions(&image_viewer);
ExampleImageViewer_DrawCanvas(&image_viewer, canvas_size, my_tex_id, (int)my_tex_w, (int)my_tex_h);
IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons");
ImGui::SeparatorText("Textured Buttons");
ImGui::TextWrapped("And now some textured buttons..");
static int pressed_count = 0;
for (int i = 0; i < 8; i++)
@@ -8706,6 +8782,22 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
EndTabItem();
}
if (BeginTabItem("Shadows"))
{
Text("Window shadows:");
ColorEdit4("Color", (float*)&style.Colors[ImGuiCol_WindowShadow], ImGuiColorEditFlags_AlphaBar);
SameLine();
HelpMarker("Same as 'WindowShadow' in Colors tab.");
SliderFloat("Size", &style.WindowShadowSize, 0.0f, 128.0f, "%.1f");
SameLine();
HelpMarker("Set shadow size to zero to disable shadows.");
SliderFloat("Offset distance", &style.WindowShadowOffsetDist, 0.0f, 64.0f, "%.0f");
SliderAngle("Offset angle", &style.WindowShadowOffsetAngle);
EndTabItem();
}
EndTabBar();
}
PopItemWidth();
@@ -8827,7 +8919,7 @@ static void ShowExampleMenuFile()
IMGUI_DEMO_MARKER("Examples/Menu/Options");
static bool enabled = true;
ImGui::MenuItem("Enabled", "", &enabled);
ImGui::BeginChild("child", ImVec2(0, 60), ImGuiChildFlags_Borders);
ImGui::BeginChild("child", ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 5.0f), ImGuiChildFlags_Borders);
for (int i = 0; i < 10; i++)
ImGui::Text("Scrolling Text %d", i);
ImGui::EndChild();
@@ -9239,6 +9331,28 @@ static void ShowExampleAppConsole(bool* p_open)
console.Draw("Example: Console", p_open);
}
//-----------------------------------------------------------------------------
// [SECTION] Example App: Image Viewer / ShowExampleAppImageViewer()
//-----------------------------------------------------------------------------
static void ShowExampleAppImageViewer(bool* p_open)
{
ImFontAtlas* atlas = ImGui::GetIO().Fonts;
ImTextureRef tex_ref = atlas->TexRef; // We don't have access to other textures in this demo!
int tex_w = atlas->TexData->Width;
int tex_h = atlas->TexData->Height;
if (ImGui::Begin("Example: Image Viewer", p_open))
{
static ExampleImageViewerData image_viewer;
ExampleImageViewer_DrawOptions(&image_viewer);
ImVec2 canvas_size = ImGui::GetContentRegionAvail();
ImVec2 canvas_min_size = ImGui::IsWindowAppearing() ? ImVec2(3.0f * tex_w, 4.0f * tex_h) : ImVec2(1.0f, 1.0f);
canvas_size = ImVec2(IM_MAX(canvas_size.x, canvas_min_size.x), IM_MAX(canvas_size.y, canvas_min_size.y));
ExampleImageViewer_DrawCanvas(&image_viewer, canvas_size, tex_ref, tex_w, tex_h);
}
ImGui::End();
}
//-----------------------------------------------------------------------------
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
//-----------------------------------------------------------------------------
@@ -10131,20 +10245,20 @@ static void ShowExampleAppCustomRendering(bool* p_open)
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, th); x += sz + spacing; // Square
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, th, corners_tl_br); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, ImDrawFlags_Closed, th); x += sz + spacing; // Concave Shape
PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, th, ImDrawFlags_Closed); x += sz + spacing; // Concave Shape
//draw_list->AddPolyline(concave_shape, IM_COUNTOF(concave_shape), col, ImDrawFlags_Closed, th);
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddLineH(x, x + sz, y, col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddLineV(x, y, y + sz, col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
// Path
draw_list->PathArcTo(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, 3.141592f, 3.141592f * -0.5f);
draw_list->PathStroke(col, ImDrawFlags_None, th);
draw_list->PathStroke(col, th);
x += sz + spacing;
// Quadratic Bezier Curve (3 control points)
@@ -10278,9 +10392,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
{
const float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40));
draw_list->AddLineV(canvas_p0.x + x, canvas_p0.y, canvas_p1.y, IM_COL32(200, 200, 200, 40));
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
draw_list->AddLineH(canvas_p0.x, canvas_p1.x, canvas_p0.y + y, IM_COL32(200, 200, 200, 40));
}
for (int n = 0; n < points.Size; n += 2)
draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
@@ -10289,6 +10403,168 @@ static void ShowExampleAppCustomRendering(bool* p_open)
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Shadows"))
{
static float shadow_thickness = 40.0f;
static ImVec4 shadow_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
static bool shadow_filled = false;
static ImVec4 shape_color = ImVec4(0.9f, 0.6f, 0.3f, 1.0f);
static float shape_rounding = 0.0f;
static ImVec2 shadow_offset(0.0f, 0.0f);
static ImVec4 background_color = ImVec4(0.5f, 0.5f, 0.7f, 1.0f);
static bool wireframe = false;
static bool aa = true;
static int poly_shape_index = 0;
ImGui::Checkbox("Shadow filled", &shadow_filled);
ImGui::SameLine();
HelpMarker("This will fill the section behind the shape to shadow. It's often unnecessary and wasteful but provided for consistency.");
ImGui::Checkbox("Wireframe shapes", &wireframe);
ImGui::SameLine();
HelpMarker("This draws the shapes in wireframe so you can see the shadow underneath.");
ImGui::Checkbox("Anti-aliasing", &aa);
ImGui::DragFloat("Shadow Thickness", &shadow_thickness, 1.0f, 0.0f, 100.0f, "%.02f");
ImGui::SliderFloat2("Offset", (float*)&shadow_offset, -32.0f, 32.0f);
ImGui::SameLine();
HelpMarker("Note that currently circles/convex shapes do not support non-zero offsets for unfilled shadows.");
ImGui::ColorEdit4("Background Color", &background_color.x);
ImGui::ColorEdit4("Shadow Color", &shadow_color.x);
ImGui::ColorEdit4("Shape Color", &shape_color.x);
ImGui::DragFloat("Shape Rounding", &shape_rounding, 1.0f, 0.0f, 20.0f, "%.02f");
ImGui::Combo("Convex shape", &poly_shape_index, "Shape 1\0Shape 2\0Shape 3\0Shape 4\0Shape 4 (winding reversed)\0");
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImDrawListFlags old_flags = draw_list->Flags;
if (aa)
draw_list->Flags |= ~ImDrawListFlags_AntiAliasedFill;
else
draw_list->Flags &= ~ImDrawListFlags_AntiAliasedFill;
// Fill a strip of background
{
ImVec2 p = ImGui::GetCursorScreenPos();
draw_list->AddRectFilled(p, ImVec2(p.x + ImGui::GetContentRegionAvail().x, p.y + 200.0f), ImGui::GetColorU32(background_color));
}
// Rectangle
{
ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::Dummy(ImVec2(200.0f, 200.0f));
ImVec2 r1(p.x + 50.0f, p.y + 50.0f);
ImVec2 r2(p.x + 150.0f, p.y + 150.0f);
ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground;
draw_list->AddShadowRect(r1, r2, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_offset, draw_flags, shape_rounding);
if (wireframe)
draw_list->AddRect(r1, r2, ImGui::GetColorU32(shape_color), shape_rounding);
else
draw_list->AddRectFilled(r1, r2, ImGui::GetColorU32(shape_color), shape_rounding);
}
ImGui::SameLine();
// Circle
{
ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::Dummy(ImVec2(200.0f, 200.0f));
// FIXME-SHADOWS: Offset forced to zero when shadow is not filled because it isn't supported
float off = 10.0f;
ImVec2 r1(p.x + 50.0f + off, p.y + 50.0f + off);
ImVec2 r2(p.x + 150.0f - off, p.y + 150.0f - off);
ImVec2 center(p.x + 100.0f, p.y + 100.0f);
ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground;
draw_list->AddShadowCircle(center, 50.0f, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), draw_flags, 0);
if (wireframe)
draw_list->AddCircle(center, 50.0f, ImGui::GetColorU32(shape_color), 0);
else
draw_list->AddCircleFilled(center, 50.0f, ImGui::GetColorU32(shape_color), 0);
}
ImGui::SameLine();
// Convex shape
{
ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::Dummy(ImVec2(200.0f, 200.0f));
const ImVec2 poly_centre(pos.x + 50.0f, pos.y + 100.0f);
ImVec2 poly_points[8];
int poly_points_count = 0;
switch (poly_shape_index)
{
default:
case 0:
{
poly_points[0] = ImVec2(poly_centre.x - 32.0f, poly_centre.y);
poly_points[1] = ImVec2(poly_centre.x - 24.0f, poly_centre.y + 24.0f);
poly_points[2] = ImVec2(poly_centre.x, poly_centre.y + 32.0f);
poly_points[3] = ImVec2(poly_centre.x + 24.0f, poly_centre.y + 24.0f);
poly_points[4] = ImVec2(poly_centre.x + 32.0f, poly_centre.y);
poly_points[5] = ImVec2(poly_centre.x + 24.0f, poly_centre.y - 24.0f);
poly_points[6] = ImVec2(poly_centre.x, poly_centre.y - 32.0f);
poly_points[7] = ImVec2(poly_centre.x - 32.0f, poly_centre.y - 32.0f);
poly_points_count = 8;
break;
}
case 1:
{
poly_points[0] = ImVec2(poly_centre.x + 40.0f, poly_centre.y - 20.0f);
poly_points[1] = ImVec2(poly_centre.x, poly_centre.y + 32.0f);
poly_points[2] = ImVec2(poly_centre.x - 24.0f, poly_centre.y - 32.0f);
poly_points_count = 3;
break;
}
case 2:
{
poly_points[0] = ImVec2(poly_centre.x - 32.0f, poly_centre.y);
poly_points[1] = ImVec2(poly_centre.x, poly_centre.y + 32.0f);
poly_points[2] = ImVec2(poly_centre.x + 32.0f, poly_centre.y);
poly_points[3] = ImVec2(poly_centre.x, poly_centre.y - 32.0f);
poly_points_count = 4;
break;
}
case 3:
{
poly_points[0] = ImVec2(poly_centre.x - 4.0f, poly_centre.y - 20.0f);
poly_points[1] = ImVec2(poly_centre.x + 12.0f, poly_centre.y + 2.0f);
poly_points[2] = ImVec2(poly_centre.x + 8.0f, poly_centre.y + 16.0f);
poly_points[3] = ImVec2(poly_centre.x, poly_centre.y + 32.0f);
poly_points[4] = ImVec2(poly_centre.x - 16.0f, poly_centre.y - 32.0f);
poly_points_count = 5;
break;
}
case 4: // Same as test case 3 but with reversed winding
{
poly_points[0] = ImVec2(poly_centre.x - 16.0f, poly_centre.y - 32.0f);
poly_points[1] = ImVec2(poly_centre.x, poly_centre.y + 32.0f);
poly_points[2] = ImVec2(poly_centre.x + 8.0f, poly_centre.y + 16.0f);
poly_points[3] = ImVec2(poly_centre.x + 12.0f, poly_centre.y + 2.0f);
poly_points[4] = ImVec2(poly_centre.x - 4.0f, poly_centre.y - 20.0f);
poly_points_count = 5;
break;
}
}
// FIXME-SHADOWS: Offset forced to zero when shadow is not filled because it isn't supported
ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground;
draw_list->AddShadowConvexPoly(poly_points, poly_points_count, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), draw_flags);
if (wireframe)
draw_list->AddPolyline(poly_points, poly_points_count, ImGui::GetColorU32(shape_color), 1.0f, ImDrawFlags_Closed);
else
draw_list->AddConvexPolyFilled(poly_points, poly_points_count, ImGui::GetColorU32(shape_color));
}
draw_list->Flags = old_flags;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("BG/FG draw lists"))
{
IMGUI_DEMO_MARKER("Examples/Custom rendering/BG & FG draw lists");

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@@ -171,6 +171,7 @@ struct ImGuiOldColumns; // Storage data for a columns set for legacy
struct ImGuiPopupData; // Storage for current popup stack
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
struct ImGuiStyleShadowTexConfig; // Shadow Texture baking config
struct ImGuiStyleVarInfo; // Style variable information (e.g. to access style variables from an enum)
struct ImGuiTabBar; // Storage for a tab bar
struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
@@ -524,6 +525,7 @@ inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return
inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
inline float ImLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImSqrt(d); return fail_value; }
inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
inline float ImTrunc(float f) { return (float)(int)(f); }
inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
@@ -885,6 +887,9 @@ struct IMGUI_API ImDrawListSharedData
float ArcFastRadiusCutoff; // Cutoff radius after which arc drawing will fallback to slower PathArcTo()
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead)
int* ShadowRectIds; // IDs of rects for shadow texture (2 entries)
const ImVec4* ShadowRectUvs; // UV coordinates for shadow texture (10 entries)
ImDrawListSharedData();
~ImDrawListSharedData();
void SetCircleTessellationMaxError(float max_error);
@@ -1005,6 +1010,7 @@ enum ImGuiItemStatusFlags_
ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid.
ImGuiItemStatusFlags_HasShortcut = 1 << 10, // g.LastItemData.Shortcut valid. Set by SetNextItemShortcut() -> ItemAdd().
//ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Removed IN 1.90.1 (Dec 2023). The trigger is part of g.NavActivateId. See commit 54c1bdeceb.
ImGuiItemStatusFlags_EditedInternal = 1 << 11, // Similar to ImGuiItemStatusFlags_Edited but bypassing ImGuiItemFlags_NoMarkEdited.
// Additional status + semantic for ImGuiTestEngine
#ifdef IMGUI_ENABLE_TEST_ENGINE
@@ -1210,6 +1216,7 @@ struct IMGUI_API ImGuiMenuColumns
};
// Internal temporary state for deactivating InputText() instances.
// Store as part of ImGuiDeactivatedItemData?
struct IMGUI_API ImGuiInputTextDeactivatedState
{
ImGuiID ID; // widget id owning the text state (which just got deactivated)
@@ -1455,6 +1462,7 @@ struct ImGuiPtrOrIndex
};
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
// Also see ImGuiInputTextDeactivatedState which is an extension for this for InputText()
struct ImGuiDeactivatedItemData
{
ImGuiID ID;
@@ -3214,7 +3222,7 @@ namespace ImGui
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
// Fonts, drawing
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL: DO NOT USE YET.
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL.
IMGUI_API void UnregisterUserTexture(ImTextureData* tex);
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
@@ -3435,7 +3443,7 @@ namespace ImGui
IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key);
IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0);
IMGUI_API void SetKeyOwnersForKeyChord(ImGuiKeyChord key, ImGuiID owner_id, ImGuiInputFlags flags = 0);
IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
IMGUI_API bool SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags);
IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id'
inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiContext* ctx, ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(key); IM_ASSERT(IsNamedKey(key)); return &ctx->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; }
@@ -3493,7 +3501,7 @@ namespace ImGui
IMGUI_API void ClearDragDrop();
IMGUI_API bool IsDragDropPayloadBeingAccepted();
IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);
IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb);
IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding);
// Typing-Select API
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
@@ -3976,6 +3984,7 @@ IMGUI_API void ImFontAtlasTextureBlockFill(ImTextureData* dst_tex,
IMGUI_API void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h);
IMGUI_API void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h);
IMGUI_API void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h);
IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format);
IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status);
IMGUI_API const char* ImTextureDataGetFormatName(ImTextureFormat format);

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (tables and columns code)
/*
@@ -2074,11 +2074,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
// Draw top border
if (top_border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y)
window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y1), ImVec2(table->BorderX2, bg_y1), top_border_col, border_size);
window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y1, top_border_col, border_size);
// Draw bottom border at the row unfreezing mark (always strong)
if (draw_strong_bottom_border && bg_y2 >= table->BgClipRect.Min.y && bg_y2 < table->BgClipRect.Max.y)
window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size);
window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y2, table->BorderColorStrong, border_size);
}
// End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle)
@@ -2855,7 +2855,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0)
draw_y2 = draw_y2_body;
if (draw_y2 > draw_y1)
inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size);
inner_drawlist->AddLineV(column->MaxX, draw_y1, draw_y2, TableGetColumnBorderCol(table, order_n, column_n), border_size);
}
}
@@ -2872,17 +2872,17 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
const ImU32 outer_col = table->BorderColorStrong;
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
{
inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size);
inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, border_size);
}
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
{
inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size);
inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size);
inner_drawlist->AddLineV(outer_border.Min.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
inner_drawlist->AddLineV(outer_border.Max.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
}
else if (table->Flags & ImGuiTableFlags_BordersOuterH)
{
inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size);
inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size);
inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Min.y, outer_col, border_size);
inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Max.y, outer_col, border_size);
}
}
if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y)
@@ -2890,7 +2890,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
// Draw bottom-most row border between it is above outer border.
const float border_y = table->RowPosY2;
if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y)
inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size);
inner_drawlist->AddLineH(table->BorderX1, table->BorderX2, border_y, table->BorderColorLight, border_size);
}
inner_drawlist->PopClipRect();
@@ -4618,7 +4618,7 @@ void ImGui::EndColumns()
// Draw column
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
const float xi = IM_TRUNC(x);
window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col);
window->DrawList->AddLineV(xi, y1 + 1.0f, y2, col);
}
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.8 WIP
// dear imgui, v1.92.8
// (widgets code)
/*
@@ -1151,7 +1151,7 @@ void ImGui::ImageWithBg(ImTextureRef tex_ref, const ImVec2& image_size, const Im
else
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
if (g.Style.ImageBorderSize > 0.0f)
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, ImDrawFlags_None, g.Style.ImageBorderSize);
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, g.Style.ImageBorderSize);
}
void ImGui::Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
@@ -1288,8 +1288,9 @@ bool ImGui::Checkbox(const char* label, bool* v)
if (is_visible)
{
RenderNavCursor(total_bb, id);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : (mixed_value || checked) ? ImGuiCol_CheckboxSelectedBg : ImGuiCol_FrameBg);
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
RenderFrame(check_bb.Min, check_bb.Max, bg_col, true, style.FrameRounding);
if (mixed_value)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
@@ -1556,7 +1557,7 @@ bool ImGui::TextLink(const char* label)
}
float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontBakedScale * 0.20f);
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI
window->DrawList->AddLineH(bb.Min.x, bb.Max.x, line_y, GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
RenderText(bb.Min, label, label_end, false);
@@ -1766,9 +1767,9 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
const float sep1_x2 = label_pos.x - style.ItemSpacing.x;
const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x;
if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), separator_col, separator_thickness);
window->DrawList->AddLineH(sep1_x1, sep1_x2, seps_y, separator_col, separator_thickness);
if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness);
window->DrawList->AddLineH(sep2_x1, sep2_x2, seps_y, separator_col, separator_thickness);
if (g.LogEnabled)
LogSetNextTextDecoration("---", NULL);
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, label_end, &label_size);
@@ -1778,7 +1779,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
if (g.LogEnabled)
LogText("---");
if (separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness);
window->DrawList->AddLineH(sep1_x1, sep2_x2, seps_y, separator_col, separator_thickness);
}
}
@@ -2375,12 +2376,17 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void
// Sanitize format
// - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf
// - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %.
char format_sanitized[32];
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
{
format = type_info->ScanFmt;
}
else
{
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized));
if (format[0] == '\0')
format = type_info->ScanFmt; // Format doesn't want us to show the number currently, but we still need to parse the resulting input
}
// Small types need a 32-bit buffer to receive the result from scanf()
int v32 = 0;
@@ -3566,7 +3572,8 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min,
// - ImParseFormatSanitizeForPrinting() [Internal]
// - ImParseFormatSanitizeForScanning() [Internal]
// - ImParseFormatPrecision() [Internal]
// - TempInputTextScalar() [Internal]
// - TempInputText() [Internal]
// - TempInputScalar() [Internal]
// - InputScalar()
// - InputScalarN()
// - InputFloat()
@@ -3795,7 +3802,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;
IM_ASSERT((flags & ImGuiInputTextFlags_EnterReturnsTrue) == 0); // Not supported by InputScalar(). Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit()!
//IM_ASSERT((flags & ImGuiInputTextFlags_EnterReturnsTrue) == 0); // Not supported by InputScalar(). Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit()!
if (format == NULL)
format = DataTypeGetInfo(data_type)->PrintFmt;
@@ -3832,7 +3839,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
}
// Apply
bool value_changed = ret ? DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL) : false;
bool input_edited = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_EditedInternal) != 0; // We would be using 'ret' if ImGuiInputTextFlags_EnterReturnsTrue was not involved.
bool value_changed = input_edited ? DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL) : false;
// Step buttons
if (has_step_buttons)
@@ -3846,13 +3854,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
if (ButtonEx("-", ImVec2(button_size, button_size)))
{
DataTypeApplyOp(data_type, '-', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
value_changed = true;
value_changed = ret = true;
}
SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("+", ImVec2(button_size, button_size)))
{
DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
value_changed = true;
value_changed = ret = true;
}
PopItemFlag();
if (flags & ImGuiInputTextFlags_ReadOnly)
@@ -3874,6 +3882,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
if (value_changed)
MarkItemEdited(g.LastItemData.ID);
if (flags & ImGuiInputTextFlags_EnterReturnsTrue)
return ret;
return value_changed;
}
@@ -4574,6 +4584,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
ImGuiInputTextState* state = &g.InputTextState;
if (id == 0 || state->ID != id)
return;
//IMGUI_DEBUG_LOG_ACTIVEID("InputTextDeactivateHook() id = 0x%08X\n", id);
g.InputTextDeactivatedState.ID = state->ID;
if (state->Flags & ImGuiInputTextFlags_ReadOnly)
{
@@ -4889,7 +4900,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
const bool is_osx = io.ConfigMacOSXBehaviors;
if (g.ActiveId != id && init_make_active)
if (init_make_active && g.ActiveId != id)
{
IM_ASSERT(state && state->ID == id);
SetActiveID(id, window);
@@ -5630,7 +5641,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll);
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_InputTextCursor), 1.0f * (float)(int)style._MainScale); // FIXME-DPI: Cursor thickness (#7031)
draw_window->DrawList->AddLineV(cursor_screen_rect.Min.x, cursor_screen_rect.Min.y, cursor_screen_rect.Max.y, GetColorU32(ImGuiCol_InputTextCursor), 1.0f * (float)(int)style._MainScale); // FIXME-DPI: Cursor thickness (#7031)
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
// This is required for some backends (SDL3) to start emitting character/text inputs.
@@ -6344,7 +6355,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps;
const int vert_start_idx = draw_list->VtxBuffer.Size;
draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc);
draw_list->PathStroke(col_white, 0, wheel_thickness);
draw_list->PathStroke(col_white, wheel_thickness);
const int vert_end_idx = draw_list->VtxBuffer.Size;
// Paint colors over existing vertices
@@ -6488,7 +6499,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
if (g.Style.FrameBorderSize > 0.0f)
RenderFrameBorder(bb.Min, bb.Max, rounding);
else
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding, 0, 1.0f * (float)(int)g.Style._MainScale); // Color buttons are often in need of some sort of border // FIXME-DPI
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding, 1.0f * (float)(int)g.Style._MainScale); // Color buttons are often in need of some sort of border // FIXME-DPI
}
// Drag and Drop Source
@@ -7161,11 +7172,11 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3);
if (x1 < x2)
window->DrawList->PathLineTo(ImVec2(x2, y));
window->DrawList->PathStroke(GetColorU32(ImGuiCol_TreeLines), ImDrawFlags_None, g.Style.TreeLinesSize);
window->DrawList->PathStroke(GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
}
else
{
window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
window->DrawList->AddLineH(x1, x2, y, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
}
}
@@ -7191,7 +7202,7 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data)
float x = ImTrunc(data->DrawLinesX1);
if (data->DrawLinesTableColumn != -1)
TablePushColumnChannel(data->DrawLinesTableColumn);
window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
window->DrawList->AddLineV(x, y1, y2, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
if (data->DrawLinesTableColumn != -1)
TablePopColumnChannel();
}
@@ -8364,11 +8375,23 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
if (ImGuiTable* table = g.CurrentTable)
if (table->CurrentColumn != -1)
{
// FIXME: We cannot use current ClipRect as it includes HostClipRect.
// A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994)
// FIXME: We cannot solely use current ClipRect as it includes HostClipRect.
// However we account for ClipRect being larger than current column (e.g. when using SpanAllColumns)
// A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994, #9383)
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX);
item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX);
float clip_min_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Min.x : window->ClipRect.Min.x;
float clip_max_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Max.x : window->ClipRect.Max.x;
if (clip_min_x != clip_max_x) // When zero sized we expect that bounds have been clamped and thus are unreliable
{
item_rect.Min.x = ImMax(item_rect.Min.x, ImMin(column->MinX, clip_min_x));
item_rect.Max.x = ImMin(item_rect.Max.x, ImMax(column->MaxX, clip_max_x));
}
else
{
item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX);
item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX);
}
//GetForegroundDrawList()->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255, 0, 255, 255));
}
const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(item_rect);
const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect);
@@ -9245,10 +9268,14 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
}
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
// Create window
PushStyleColor(ImGuiCol_WindowShadow, ImVec4(0, 0, 0, 0));
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint
bool is_open = Begin(name, NULL, window_flags);
PopStyleVar(2);
PopStyleColor();
return is_open;
}
@@ -9370,8 +9397,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
bool pressed;
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups;
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoAutoClosePopups | (ImGuiSelectableFlags)ImGuiSelectableFlags_SelectOnClick;
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{
@@ -9409,6 +9435,14 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
if (!enabled)
EndDisabled();
// Once dragged, release ActiveId + key ownership. This is to allow the idiom of mouse down a menu, dragging elsewhere, up on some other MenuItem(). (#8233, #9394)
// Could move logic into lower-level ImGuiButtonFlags_AutoReleaseActiveId + ImGuiButtonFlags_AutoReleaseKeyOwner? Easier once we get rid of the Selectable() middle-man here.
if (g.ActiveId == id && g.HoveredId != id && g.ActiveIdSource == ImGuiInputSource_Mouse && IsMouseDragging(0))
{
ClearActiveID();
SetKeyOwner(ImGuiKey_MouseLeft, ImGuiKeyOwner_NoOwner);
}
const bool hovered = (g.HoveredId == id) && enabled && !g.NavHighlightItemUnderNav;
if (menuset_is_open)
PopItemFlag();
@@ -9489,6 +9523,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
PopID();
if (g.ActiveId == id && want_open)
g.ActiveIdNoClearOnFocusLoss = true;
if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
{
// Don't reopen/recycle same menu level in the same frame if it is a different menu ID, first close the other menu and yield for a frame.
@@ -9581,7 +9618,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
BeginDisabled();
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SetNavIdOnHover;
const ImGuiSelectableFlags selectable_flags = (ImGuiSelectableFlags)ImGuiSelectableFlags_SelectOnRelease | (ImGuiSelectableFlags)ImGuiSelectableFlags_SetNavIdOnHover;
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{
@@ -9624,6 +9661,17 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
RenderCheckMark(window->DrawList, text_pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
}
}
// Once dragged, release ActiveId + key ownership. This is to allow the idiom of mouse down a menu, dragging elsewhere, up on some other MenuItem(). (#8233, #9394)
// Could move logic into lower-level ImGuiButtonFlags_AutoReleaseActiveId + ImGuiButtonFlags_AutoReleaseKeyOwner? Easier once we get rid of the Selectable() middle-man here.
const ImGuiID id = g.LastItemData.ID;
if (g.ActiveId == id && g.HoveredId != id && g.ActiveIdSource == ImGuiInputSource_Mouse && IsMouseDragging(0))
{
ClearActiveID();
SetKeyOwner(ImGuiKey_MouseLeft, ImGuiKeyOwner_NoOwner);
}
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
if (!enabled)
EndDisabled();
@@ -10736,7 +10784,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
float rounding = style.TabRounding;
display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
display_draw_list->PathStroke(overline_col, style.TabBarOverlineSize);
}
else
{
@@ -10840,7 +10888,7 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9);
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding - 0.5f, y1 + rounding + 0.5f), rounding, 9, 12);
draw_list->PathLineTo(ImVec2(bb.Max.x - 0.5f, y2));
draw_list->PathStroke(GetColorU32(ImGuiCol_Border), 0, g.Style.TabBorderSize);
draw_list->PathStroke(GetColorU32(ImGuiCol_Border), g.Style.TabBorderSize);
}
}