Merge remote-tracking branch 'upstream/master' into HEAD
build / Build - Windows (push) Has been cancelled
build / Build - Linux (push) Has been cancelled
build / Build - MacOS (push) Has been cancelled
build / Build - iOS (push) Has been cancelled
build / Build - Emscripten (push) Has been cancelled
build / Build - Android (push) Has been cancelled
build / Test - Windows (push) Has been cancelled
build / Test - Linux (push) Has been cancelled
scheduled / scheduled (push) Successful in 14s
build / Build - Windows (push) Has been cancelled
build / Build - Linux (push) Has been cancelled
build / Build - MacOS (push) Has been cancelled
build / Build - iOS (push) Has been cancelled
build / Build - Emscripten (push) Has been cancelled
build / Build - Android (push) Has been cancelled
build / Test - Windows (push) Has been cancelled
build / Test - Linux (push) Has been cancelled
scheduled / scheduled (push) Successful in 14s
This commit is contained in:
@@ -5,8 +5,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [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: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [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: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// 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.
|
// 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.
|
// 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
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (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-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-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)
|
// 2026-04-03: Metal: avoid redundant vertex buffer bind in SetupRenderState. (#9343)
|
||||||
@@ -79,6 +78,8 @@
|
|||||||
@interface MetalContext : NSObject
|
@interface MetalContext : NSObject
|
||||||
@property (nonatomic, strong) id<MTLDevice> device;
|
@property (nonatomic, strong) id<MTLDevice> device;
|
||||||
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
@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) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
||||||
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
||||||
@property (nonatomic, strong) NSMutableArray<MetalBuffer*>* bufferCache;
|
@property (nonatomic, strong) NSMutableArray<MetalBuffer*>* bufferCache;
|
||||||
@@ -91,6 +92,7 @@
|
|||||||
struct ImGui_ImplMetal_Data
|
struct ImGui_ImplMetal_Data
|
||||||
{
|
{
|
||||||
MetalContext* SharedMetalContext;
|
MetalContext* SharedMetalContext;
|
||||||
|
id<MTLRenderCommandEncoder> RenderCommandEncoder;
|
||||||
|
|
||||||
ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
|
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 setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1];
|
||||||
|
|
||||||
[commandEncoder setRenderPipelineState:renderPipelineState];
|
[commandEncoder setRenderPipelineState:renderPipelineState];
|
||||||
|
[commandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateLinear atIndex:0];
|
||||||
|
|
||||||
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:vertexBufferOffset atIndex:0];
|
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:vertexBufferOffset atIndex:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw callbacks
|
// 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.
|
// Metal Render function.
|
||||||
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
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* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
|
||||||
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
||||||
|
|
||||||
|
bd->RenderCommandEncoder = commandEncoder;
|
||||||
ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// 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];
|
[sharedMetalContext.bufferCache addObject:indexBuffer];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
bd->RenderCommandEncoder = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex)
|
static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex)
|
||||||
@@ -382,7 +389,17 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
depthStencilDescriptor.depthWriteEnabled = NO;
|
depthStencilDescriptor.depthWriteEnabled = NO;
|
||||||
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||||
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
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
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
|
[samplerDescriptor release];
|
||||||
[depthStencilDescriptor release];
|
[depthStencilDescriptor release];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -399,6 +416,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
ImGui_ImplMetal_DestroyTexture(tex);
|
ImGui_ImplMetal_DestroyTexture(tex);
|
||||||
|
|
||||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
||||||
|
bd->SharedMetalContext.samplerStateLinear = nil;
|
||||||
|
bd->SharedMetalContext.samplerStateNearest = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||||
@@ -415,6 +434,8 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState;
|
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 = [[MetalContext alloc] init];
|
||||||
bd->SharedMetalContext.device = device;
|
bd->SharedMetalContext.device = device;
|
||||||
@@ -599,9 +620,9 @@ void ImGui_ImplMetal_Shutdown()
|
|||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"fragment half4 fragment_main(VertexOut in [[stage_in]],\n"
|
"fragment half4 fragment_main(VertexOut in [[stage_in]],\n"
|
||||||
" texture2d<half, access::sample> texture [[texture(0)]]) {\n"
|
" texture2d<half, access::sample> texture [[texture(0)]],\n"
|
||||||
" constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n"
|
" sampler textureSampler [[sampler(0)]]) {\n"
|
||||||
" half4 texColor = texture.sample(linearSampler, in.texCoords);\n"
|
" half4 texColor = texture.sample(textureSampler, in.texCoords);\n"
|
||||||
" return half4(in.color) * texColor;\n"
|
" return half4(in.color) * texColor;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|||||||
@@ -255,7 +255,9 @@ struct ImGui_ImplOpenGL3_Data
|
|||||||
bool UseBufferSubData;
|
bool UseBufferSubData;
|
||||||
bool UseTexParameterToSetSampler;
|
bool UseTexParameterToSetSampler;
|
||||||
GLuint NextSampler; // Used if !HasBindSampler && 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;
|
ImVector<char> TempBuffer;
|
||||||
|
|
||||||
@@ -404,8 +406,13 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
|||||||
|
|
||||||
// Draw callbacks
|
// 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.
|
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_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; } }
|
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.
|
// OpenGL3 Render function.
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
// 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_InitLoader();
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
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; }
|
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->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
|
||||||
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
|
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
|
||||||
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
||||||
|
|||||||
@@ -328,11 +328,31 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
|
|||||||
WGPUShaderModuleDescriptor desc = {};
|
WGPUShaderModuleDescriptor desc = {};
|
||||||
desc.nextInChain = (WGPUChainedStruct*)&wgsl_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 = {};
|
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
if (module && !validation_error)
|
||||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
{
|
||||||
|
stage_desc.module = module;
|
||||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||||
#endif
|
}
|
||||||
|
else if (module)
|
||||||
|
{
|
||||||
|
wgpuShaderModuleRelease(module);
|
||||||
|
}
|
||||||
return stage_desc;
|
return stage_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-05-19: DPI: ImGui_ImplWin32_EnableDpiAwareness() helper uses SetProcessDpiAwarenessContext() instead of SetThreadDpiAwarenessContext(), fixes DPI scaling issues with e.g. OpenGL. (#9403)
|
||||||
// 2026-01-28: Inputs: Minor optimization not submitting gamepad input if packet number has not changed (reworked from 2025-09-23 attempt). (#9202, #8556)
|
// 2026-01-28: Inputs: Minor optimization not submitting gamepad input if packet number has not changed (reworked from 2025-09-23 attempt). (#9202, #8556)
|
||||||
// 2025-12-03: Inputs: handle WM_IME_CHAR/WM_IME_COMPOSITION messages to support Unicode inputs on MBCS (non-Unicode) Windows. (#9099, #3653, #5961)
|
// 2025-12-03: Inputs: handle WM_IME_CHAR/WM_IME_COMPOSITION messages to support Unicode inputs on MBCS (non-Unicode) Windows. (#9099, #3653, #5961)
|
||||||
// 2025-10-19: Inputs: Revert previous change to allow for io.ClearInputKeys() on focus-out not losing gamepad state.
|
// 2025-10-19: Inputs: Revert previous change to allow for io.ClearInputKeys() on focus-out not losing gamepad state.
|
||||||
@@ -886,6 +887,7 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
|||||||
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
||||||
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
||||||
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
||||||
|
typedef BOOL(WINAPI* PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1703+ (Creators Update)
|
||||||
|
|
||||||
// Helper function to enable DPI awareness without setting up a manifest
|
// Helper function to enable DPI awareness without setting up a manifest
|
||||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||||
@@ -893,7 +895,12 @@ void ImGui_ImplWin32_EnableDpiAwareness()
|
|||||||
if (_IsWindows10OrGreater())
|
if (_IsWindows10OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||||
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
if (PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContextFn = (PFN_SetProcessDpiAwarenessContext)::GetProcAddress(user32_dll, "SetProcessDpiAwarenessContext")) // Windows 10 v1703+
|
||||||
|
{
|
||||||
|
SetProcessDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) // Windows 10 v1607+
|
||||||
{
|
{
|
||||||
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+146
-32
@@ -36,34 +36,103 @@ HOW TO UPDATE?
|
|||||||
- Please report any issue!
|
- Please report any issue!
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
VERSION 1.92.8 WIP (In Progress)
|
VERSION 1.92.9 WIP (In Progress)
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
Breaking Changes:
|
Breaking Changes:
|
||||||
|
|
||||||
|
- TreeNode: commented out legacy name `ImGuiTreeNodeFlags_SpanTextWidth` which
|
||||||
|
was obsoleted in 1.90.7 (May 2024). Use `ImGuiTreeNodeFlags_SpanLabelWidth`.
|
||||||
|
|
||||||
|
Other Changes:
|
||||||
|
|
||||||
|
- Windows:
|
||||||
|
- Clicking on a window's empty-space to move/focus a window checks
|
||||||
|
for lack of mouse button ownership. This gives an additional opportunity
|
||||||
|
for user code to bypass it without using a clickable item. (#9382)
|
||||||
|
- Clicking on a window's empty-space to move/focus a window checks
|
||||||
|
for lack of queued focus request. (#9382)
|
||||||
|
- InputText:
|
||||||
|
- Added `style.InputTextCursorSize` to configure cursor/caret thickness. (#7031, #9409)
|
||||||
|
This is automatically scaled by `style.ScaleAllSizes()`.
|
||||||
|
- Fonts:
|
||||||
|
- Added `IMGUI_DISABLE_DEFAULT_FONT_BITMAP`/`IMGUI_DISABLE_DEFAULT_FONT_VECTOR` to
|
||||||
|
disable embedding either fonts separately. (#9407)
|
||||||
|
- Tweak `CalcTextSize()` awkward width rounding/ceiling code to reduce floating-point
|
||||||
|
imprecisions altering the result by 1 even at relatively small width. (#791)
|
||||||
|
- Fixed an issue where passing a manually created ImFontAtlas to CreateContext() would
|
||||||
|
incorrectly destroy it in DestroyContext() when ref-count gets back to zero. (#9426)
|
||||||
- DrawList:
|
- DrawList:
|
||||||
- Obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`,
|
- Minor optimization to `AddLine()`, `AddLineH()`, `AddLineV()` functions. (#4091)
|
||||||
|
- Added `ImDrawListFlags_TextNoPixelSnap` to disable snapping of AddText()
|
||||||
|
coordinates for a given scope. (#3437, #9417, #2291)
|
||||||
|
- ColorButton:
|
||||||
|
- Small rendering tweak/optimization for the alpha checkerboard.
|
||||||
|
- Demo:
|
||||||
|
- Extract 'Widgets->Tree Nodes->Selectable Nodes' out of the 'Advanced'
|
||||||
|
demo for clarity (manual reimplementation of basic selection).
|
||||||
|
- Backends:
|
||||||
|
- Win32:
|
||||||
|
- Uses `SetProcessDpiAwarenessContext()` instead of `SetThreadDpiAwarenessContext()`
|
||||||
|
when available, fixing OpenGL DPI scaling issues as e.g. NVIDIA drivers tends
|
||||||
|
to spawn multiple-thread to manage OpenGL. (#9403)
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
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: 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.
|
||||||
|
- Reminder: you do NOT need to specify `ImDrawFlags_RoundCornersAll` for rounding, it is already the default!
|
||||||
|
- DrawList: obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`,
|
||||||
which is part of our new standard draw callbacks. (#9378)
|
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.
|
Redirecting the earlier value into the later one when set, so both old and new code should work.
|
||||||
|
- DrawList: changed value of `ImDrawFlags_Closed`. It was previously advertised as "always == 1" when introduced
|
||||||
|
in 1.82 (2021/02), in order to facilitate backward compatibility with the legacy `bool closed` flag. This
|
||||||
|
guarantee has been removed. The bit is reserved, and `AddPolyline()`, `PathStroke()` will assert when it is used.
|
||||||
- Backends:
|
- Backends:
|
||||||
- Vulkan: redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. (#914)
|
- 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]
|
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):
|
- 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.
|
- 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.
|
- 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.
|
+ `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.
|
- When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler.
|
||||||
- Before: ImGui_ImplVulkan_AddTexture(VkSampler, VkImageView, VkImageLayout)
|
- Before: `ImGui_ImplVulkan_AddTexture(VkSampler, VkImageView, VkImageLayout)`
|
||||||
- After: ImGui_ImplVulkan_AddTexture(VkImageView, VkImageLayout)
|
- After: `ImGui_ImplVulkan_AddTexture(VkImageView, VkImageLayout)`
|
||||||
- Kept inline redirection function that ignores the sampler (will obsolete).
|
- 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)
|
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.
|
If there is a legit need/request for them or any render state we can always add them back.
|
||||||
|
|
||||||
Other Changes:
|
Other Changes:
|
||||||
|
|
||||||
- DrawList:
|
- 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.
|
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
|
They allow backend-agnostic code from e.g. switching to a Nearest/Point sampler without
|
||||||
messing with custom Renderer-specific callbacks.
|
messing with custom Renderer-specific callbacks.
|
||||||
@@ -73,12 +142,22 @@ Other Changes:
|
|||||||
Note that some backends might not support all callbacks.
|
Note that some backends might not support all callbacks.
|
||||||
(#9378, #9371, #3590, #8926, #2973, #7485, #7468, #6969, #5118, #7616, #9173, #8322, #7230,
|
(#9378, #9371, #3590, #8926, #2973, #7485, #7468, #6969, #5118, #7616, #9173, #8322, #7230,
|
||||||
#5999, #6452, #5156, #7342, #7592, #7511)
|
#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]
|
||||||
|
The new functions are more optimal and will be part of a larger effort in 1.93 to fix
|
||||||
|
inconsistencies and improve the DrawList API. In the current API, `AddLine()` adds a "magic" +0.5f
|
||||||
|
offset and then center the line, whereas AddLineH()/AddLineV() use the right side of the line to expand.
|
||||||
|
For thickness=1.0f lines this is equivalent:
|
||||||
|
`AddLine({10,3}, {20,3}, ...)` --> `AddLineH(x1=10, x2=20, y=3, ...)`.
|
||||||
|
`AddLine({3,10}, {3,20}, ...)` --> `AddLineV(x=3, y1=10, y2=20, ...)`.
|
||||||
|
For larger integer thickness, AddLine() will center but may be blurry, AddLineH()/AddLineV()
|
||||||
|
will expand "inside" (to the right side) and will always be sharp.
|
||||||
|
A subsequent release will expand on those concepts and add new options.
|
||||||
- InputText:
|
- InputText:
|
||||||
- InputTextMultiline: fixed an issue processing deactivation logic when an active
|
- InputTextMultiline: fixed an issue processing deactivation logic when an active
|
||||||
multi-line edit is clipped due to being out of view.
|
multi-line edit is clipped due to being out of view.
|
||||||
- Fixed a crash when toggling ReadOnly while active. (#9354)
|
- 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:
|
- Tables:
|
||||||
- Fixed issues reporting ideal size to parent window/container: (#9352, #7651)
|
- 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.
|
- When both scrollbars are visible but only one of ScrollX/ScrollY was explicitly requested.
|
||||||
@@ -87,38 +166,70 @@ Other Changes:
|
|||||||
- Fixed a single-axis auto-resizing feedback loop issue with nested containers
|
- Fixed a single-axis auto-resizing feedback loop issue with nested containers
|
||||||
and varying scrollbar visibility. (#9352)
|
and varying scrollbar visibility. (#9352)
|
||||||
- Detect and report error when calling End() instead of EndPopup() on a popup. (#9351)
|
- 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
|
- Child windows with only `ImGuiChildFlags_AutoResizeY` flag keep using the proportional
|
||||||
default ItemWidth. (#9355)
|
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:
|
- Multi-Select:
|
||||||
- Fixed an issue using Multi-Select within a Table causing column width measurement to
|
- 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)
|
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,
|
- 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)
|
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
|
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)
|
edges from not being correctly unselected. (#7994, #8250, #7821, #7850, #7970)
|
||||||
- Box-Select: improved dirty/unclip rectangle logic for ImGuiMultiSelectFlags_BoxSelect2d.
|
- Improved dirty/unclip rectangle logic for `ImGuiMultiSelectFlags_BoxSelect2d`.
|
||||||
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode, where
|
- Fixed an issue using `ImGuiMultiSelectFlags_BoxSelect2d` mode, where
|
||||||
items out of view wouldn't be properly selected while scrolling while mouse cursor
|
items out of view wouldn't be properly selected while scrolling while mouse cursor
|
||||||
is hovering outside of selection scope. (#7994, #1861, #6518)
|
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
|
to incorrect merging of sequential selection requests while also scrolling fast
|
||||||
enough to overlap multiple rows during a frame. (#7994, #1861, #6518)
|
enough to overlap multiple rows during a frame. (#7994, #1861, #6518)
|
||||||
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode in a Table
|
- Fixed an issue using `ImGuiMultiSelectFlags_BoxSelect2d` mode in a Table
|
||||||
while relying on the TableNextColumn() return value to perform coarse clipping. (#7994)
|
while relying on the `TableNextColumn()` return value to perform coarse clipping. (#7994)
|
||||||
- Box-Select: disabled merging consecutive selection requests as we have no reliable
|
- Disabled merging consecutive selection requests as we have no reliable
|
||||||
way of detecting if user has submitted all consecutives items without clipping gaps,
|
way of detecting if user has submitted all consecutive items without clipping gaps,
|
||||||
and ImGuiSelectionUserData is technically opaque storage. (#7994, #1861)
|
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
|
(we will probably bring this back as a minor optimization if we have a way to for
|
||||||
user to tell us ImGuiSelectionUserData are indices)
|
user to tell us `ImGuiSelectionUserData` are indices)
|
||||||
- Box-Select: fixes for using accross nested child windows. (#8364)
|
- Fixes for using across nested child windows. (#8364)
|
||||||
- Box-Select + Clipper: fixed an issue selecting items while scrolling while a clipper
|
- Box-Select + Clipper: fixed an issue selecting items while scrolling while a clipper
|
||||||
active. (#7994, #8250, #7821, #7850, #7970)
|
active. (#7994, #8250, #7821, #7850, #7970)
|
||||||
- Box-Select + Tables: fixed an issue using box-selection in a tables with
|
- Box-Select + Tables: fixed an issue using box-selection in a tables with
|
||||||
items straying out of columns boundaries. (#7994, #2221)
|
items straying out of columns boundaries. (#7994, #2221)
|
||||||
- Box-Select + Tables: fixed an issue when calling `BeginMultiSelect()` in a table
|
- Box-Select + Tables: fixed an issue when calling `BeginMultiSelect()` in a table
|
||||||
before layout has been locked (first row or headers row submitted). (#8250)
|
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:
|
- 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
|
- Fixed vertical scrollbar top coordinates when using thick borders on windows
|
||||||
with no title bar and no menu bar. (#9366)
|
with no title bar and no menu bar. (#9366)
|
||||||
- Fonts:
|
- Fonts:
|
||||||
@@ -131,8 +242,12 @@ Other Changes:
|
|||||||
- Tweaked assert triggering when first item height measurement fails, and made it
|
- Tweaked assert triggering when first item height measurement fails, and made it
|
||||||
a better recoverable error. (#9350)
|
a better recoverable error. (#9350)
|
||||||
- Misc:
|
- Misc:
|
||||||
- Minor optimization: reduce redudant label scanning in common widgets.
|
- Minor optimization: reduce redundant label scanning in common widgets.
|
||||||
- Added missing Test Engine hooks for PlotXXX(), VSliderXXX(), TableHeader().
|
- 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:
|
- Backends:
|
||||||
- Added support for new standardized draw callbacks in most backends: (#9378)
|
- Added support for new standardized draw callbacks in most backends: (#9378)
|
||||||
- Allegro5: Reset n/a n/a
|
- Allegro5: Reset n/a n/a
|
||||||
@@ -140,7 +255,7 @@ Other Changes:
|
|||||||
- DX10: Reset SetSamplerLinear SetSamplerNearest
|
- DX10: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- DX11: Reset SetSamplerLinear SetSamplerNearest
|
- DX11: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- DX12: Reset SetSamplerLinear SetSamplerNearest
|
- DX12: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- Metal: Reset *missing* *missing*
|
- Metal: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- OpenGL2: Reset SetSamplerLinear SetSamplerNearest
|
- OpenGL2: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- OpenGL3+: Reset SetSamplerLinear SetSamplerNearest
|
- OpenGL3+: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- SDLGPU3: Reset SetSamplerLinear SetSamplerNearest
|
- SDLGPU3: Reset SetSamplerLinear SetSamplerNearest
|
||||||
@@ -148,7 +263,7 @@ Other Changes:
|
|||||||
- SDLRenderer3: Reset SetSamplerLinear SetSamplerNearest
|
- SDLRenderer3: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- Vulkan: Reset SetSamplerLinear SetSamplerNearest
|
- Vulkan: Reset SetSamplerLinear SetSamplerNearest
|
||||||
- WebGPU: 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`
|
- GLFW: added a Win32-specific implementation of `ImGui_ImplGlfw_GetContentScaleXXXX`
|
||||||
functions for legacy GLFW 3.2. (#9003)
|
functions for legacy GLFW 3.2. (#9003)
|
||||||
- Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads
|
- Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads
|
||||||
@@ -158,14 +273,13 @@ Other Changes:
|
|||||||
- SDL2: made `ImGui_ImplSDL2_GetContentScaleForWindow()`/`ImGui_ImplSDL2_GetContentScaleForDisplay()`
|
- 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
|
helpers return a minimum of 1.0f, as some Linux setup seems to report <1.0f value
|
||||||
and this breaks scaling border size. (#9369)
|
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:
|
- Examples:
|
||||||
- Update VS toolset in all .vcxproj from VS2015 (v140) to VS2017 (v141). The later is the
|
- 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.
|
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:
|
- 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_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_SAMPLER_POOL_SIZE` descriptors of type `VK_DESCRIPTOR_TYPE_SAMPLER`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|||||||
@@ -77,6 +77,17 @@ Some solutions:
|
|||||||
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
|
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
|
||||||
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
|
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
|
||||||
|
|
||||||
|
### (5) Reduce texture resizes/copy on startup
|
||||||
|
|
||||||
|
🆕 Since 1.92, the ImFontAtlas is initially created using a 512x128 texture, then grows as glyphs and fonts are used. Atlas growth leads to alloc+copy, and both the old and new sized textures are present in memory for a short time (typically one frame). If you use known fonts and want to reduce initial growth, you may set `TexMinWidth` and `TexMinHeight` during initializaton.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
ImFontAtlas* atlas = io.Fonts;
|
||||||
|
atlas->TexMinWidth = 1024;
|
||||||
|
atlas->TexMinHeight = 1024;
|
||||||
|
atlas->AddFont(...);
|
||||||
|
```
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ Dear ImGui is particularly suited to integration in game engines (for tooling),
|
|||||||
|
|
||||||
**Backends for a variety of graphics API and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui.
|
**Backends for a variety of graphics API and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui.
|
||||||
|
|
||||||
C++20 users wishing to use a module may the use [stripe2933/imgui-module](https://github.com/stripe2933/imgui-module) third-party extension.
|
C++20 users wishing to use a module may use the [stripe2933/imgui-module](https://github.com/stripe2933/imgui-module) third-party extension.
|
||||||
|
|
||||||
See the [Getting Started & Integration](#getting-started--integration) section of this document for more details.
|
See the [Getting Started & Integration](#getting-started--integration) section of this document for more details.
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -146,6 +146,28 @@ else() # Native/Desktop build
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(IMGUI_WGVK_DIR)
|
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()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -187,6 +209,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
|
|||||||
if(IMGUI_WGVK_DIR)
|
if(IMGUI_WGVK_DIR)
|
||||||
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
|
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} 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)
|
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
||||||
|
|||||||
@@ -141,6 +141,28 @@ else() # Native/Desktop build
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(IMGUI_WGVK_DIR)
|
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()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
@@ -183,6 +205,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
|
|||||||
if(IMGUI_WGVK_DIR)
|
if(IMGUI_WGVK_DIR)
|
||||||
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
|
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} 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)
|
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
||||||
|
|||||||
@@ -141,6 +141,28 @@ else() # Native/Desktop build
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(IMGUI_WGVK_DIR)
|
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()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -182,6 +204,7 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
|
|||||||
if(IMGUI_WGVK_DIR)
|
if(IMGUI_WGVK_DIR)
|
||||||
target_sources(${IMGUI_EXECUTABLE} PRIVATE ${IMGUI_WGVK_DIR}/src/wgvk.c)
|
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} 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)
|
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGVK_DIR}/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /std:clatest /experimental:c11atomics)
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.2.32616.157
|
VisualStudioVersion = 17.2.32616.157
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx9", "example_win32_directx9\example_win32_directx9.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "example_win32_directx10\example_win32_directx10.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "example_win32_directx10\example_win32_directx10.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}"
|
||||||
EndProject
|
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}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
|
||||||
|
|||||||
+3
-1
@@ -49,7 +49,9 @@
|
|||||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean/ProggyForever), remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert.
|
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean + ProggyForever). Remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert.
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FONT_BITMAP // Disable default embedded bitmap font (ProggyClean). Remove ~9 KB from output binary. AddFontDefaultBitmap() will assert.
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FONT_VECTOR // Disable default embedded vector font (ProggyForever), Remove ~14 KB from output binary. AddFontDefaultVector() will assert.
|
||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
//---- Enable Test Engine / Automation features.
|
//---- Enable Test Engine / Automation features.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (main code and documentation)
|
// (main code and documentation)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@@ -395,7 +395,31 @@ 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.
|
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.
|
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/06/02 (1.92.9) - TreeNode: commented out legacy name ImGuiTreeNodeFlags_SpanTextWidth which was obsoleted in 1.90.7 (May 2024). Use ImGuiTreeNodeFlags_SpanLabelWidth instead.
|
||||||
|
- 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/05/07 (1.92.8) - DrawList: changed value of `ImDrawFlags_Closed`. It was previously advertised as "always == 1" when introduced in 1.82 (2021/02), in order to facilitate backward compatibility with the legacy `bool closed` flag.
|
||||||
|
This guarantee has been removed. The bit is reserved and `AddPolyline()`, `PathStroke()` will assert when it is used.
|
||||||
|
- 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.
|
- 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 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.
|
- 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.
|
||||||
@@ -1516,6 +1540,7 @@ ImGuiStyle::ImGuiStyle()
|
|||||||
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||||
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
|
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
|
||||||
SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
||||||
|
InputTextCursorSize = 1.0f; // Thickness of cursor/caret in InputText().
|
||||||
SeparatorSize = 1.0f; // Thickness of border in Separator().
|
SeparatorSize = 1.0f; // Thickness of border in Separator().
|
||||||
SeparatorTextBorderSize = 3.0f; // Thickness of border in SeparatorText().
|
SeparatorTextBorderSize = 3.0f; // Thickness of border in SeparatorText().
|
||||||
SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
|
SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
|
||||||
@@ -1591,6 +1616,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor)
|
|||||||
DragDropTargetBorderSize = ImTrunc(DragDropTargetBorderSize * scale_factor);
|
DragDropTargetBorderSize = ImTrunc(DragDropTargetBorderSize * scale_factor);
|
||||||
DragDropTargetPadding = ImTrunc(DragDropTargetPadding * scale_factor);
|
DragDropTargetPadding = ImTrunc(DragDropTargetPadding * scale_factor);
|
||||||
ColorMarkerSize = ImTrunc(ColorMarkerSize * scale_factor);
|
ColorMarkerSize = ImTrunc(ColorMarkerSize * scale_factor);
|
||||||
|
InputTextCursorSize = ImTrunc(InputTextCursorSize * scale_factor);
|
||||||
SeparatorSize = ImTrunc(SeparatorSize * scale_factor);
|
SeparatorSize = ImTrunc(SeparatorSize * scale_factor);
|
||||||
SeparatorTextBorderSize = ImTrunc(SeparatorTextBorderSize * scale_factor);
|
SeparatorTextBorderSize = ImTrunc(SeparatorTextBorderSize * scale_factor);
|
||||||
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
|
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
|
||||||
@@ -3659,6 +3685,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] =
|
|||||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
|
||||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize
|
||||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding
|
{ 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, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize
|
||||||
@@ -3759,6 +3786,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
|||||||
case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
|
case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
|
||||||
case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
|
case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
|
||||||
case ImGuiCol_CheckMark: return "CheckMark";
|
case ImGuiCol_CheckMark: return "CheckMark";
|
||||||
|
case ImGuiCol_CheckboxSelectedBg: return "CheckboxSelectedBg";
|
||||||
case ImGuiCol_SliderGrab: return "SliderGrab";
|
case ImGuiCol_SliderGrab: return "SliderGrab";
|
||||||
case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
|
case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
|
||||||
case ImGuiCol_Button: return "Button";
|
case ImGuiCol_Button: return "Button";
|
||||||
@@ -3926,8 +3954,8 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
|
|||||||
text_end_full = FindRenderedTextEnd(text);
|
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);
|
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->AddLineV(pos_max.x, pos_min.y - 4, 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(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.
|
// 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)
|
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;
|
const float border_size = g.Style.FrameBorderSize;
|
||||||
if (borders && border_size > 0.0f)
|
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 + 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, 0, 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;
|
const float border_size = g.Style.FrameBorderSize;
|
||||||
if (border_size > 0.0f)
|
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 + 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, 0, 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;
|
const float thickness = 2.0f;
|
||||||
if (flags & ImGuiNavRenderCursorFlags_Compact)
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -4029,7 +4057,7 @@ void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFl
|
|||||||
bool fully_visible = window->ClipRect.Contains(display_rect);
|
bool fully_visible = window->ClipRect.Contains(display_rect);
|
||||||
if (!fully_visible)
|
if (!fully_visible)
|
||||||
window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
|
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)
|
if (!fully_visible)
|
||||||
window->DrawList->PopClipRect();
|
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_min = ImFmod((float)g.Time * 5.0f, 2.0f * IM_PI);
|
||||||
float a_max = a_min + IM_PI * 1.65f;
|
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->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();
|
draw_list->PopTexture();
|
||||||
}
|
}
|
||||||
@@ -4448,7 +4476,7 @@ void ImGui::Shutdown()
|
|||||||
for (ImFontAtlas* atlas : g.FontAtlases)
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
{
|
{
|
||||||
UnregisterFontAtlas(atlas);
|
UnregisterFontAtlas(atlas);
|
||||||
if (atlas->RefCount == 0)
|
if (atlas->RefCount == 0 && atlas->OwnerContext == &g)
|
||||||
{
|
{
|
||||||
atlas->Locked = false;
|
atlas->Locked = false;
|
||||||
IM_DELETE(atlas);
|
IM_DELETE(atlas);
|
||||||
@@ -4697,7 +4725,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
|||||||
g.ActiveIdIsJustActivated = (g.ActiveId != id);
|
g.ActiveIdIsJustActivated = (g.ActiveId != id);
|
||||||
if (g.ActiveIdIsJustActivated)
|
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.ActiveIdTimer = 0.0f;
|
||||||
g.ActiveIdHasBeenPressedBefore = false;
|
g.ActiveIdHasBeenPressedBefore = false;
|
||||||
g.ActiveIdHasBeenEditedBefore = false;
|
g.ActiveIdHasBeenEditedBefore = false;
|
||||||
@@ -4753,8 +4782,12 @@ void ImGui::MarkItemEdited(ImGuiID id)
|
|||||||
// This marking is to be able to provide info for IsItemDeactivatedAfterEdit().
|
// 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.
|
// 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;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_EditedInternal;
|
||||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_NoMarkEdited)
|
if (g.LastItemData.ItemFlags & ImGuiItemFlags_NoMarkEdited)
|
||||||
return;
|
return;
|
||||||
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||||
|
|
||||||
if (g.ActiveId == id || g.ActiveId == 0)
|
if (g.ActiveId == id || g.ActiveId == 0)
|
||||||
{
|
{
|
||||||
// FIXME: Can't we fully rely on LastItemData yet?
|
// 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)
|
// 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.
|
// 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.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)
|
bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
|
||||||
@@ -4935,7 +4965,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
|
|||||||
{
|
{
|
||||||
g.HoveredIdPreviousFrameItemCount++;
|
g.HoveredIdPreviousFrameItemCount++;
|
||||||
if (g.DebugDrawIdConflictsId == id)
|
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
|
#endif
|
||||||
|
|
||||||
@@ -5332,14 +5362,15 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
|||||||
|
|
||||||
// Click on empty space to focus window and start moving
|
// Click on empty space to focus window and start moving
|
||||||
// (after we're done with all our widgets)
|
// (after we're done with all our widgets)
|
||||||
if (g.IO.MouseClicked[0])
|
if (IsMouseClicked(0, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner))
|
||||||
{
|
{
|
||||||
// Handle the edge case of a popup being closed while clicking in its empty space.
|
// Handle the edge case of a popup being closed while clicking in its empty space.
|
||||||
// If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more.
|
// If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more.
|
||||||
ImGuiWindow* hovered_root = hovered_window ? hovered_window->RootWindow : NULL;
|
ImGuiWindow* hovered_root = hovered_window ? hovered_window->RootWindow : NULL;
|
||||||
const bool is_closed_popup = hovered_root && (hovered_root->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(hovered_root->PopupId, ImGuiPopupFlags_AnyPopupLevel);
|
const bool is_closed_popup = hovered_root && (hovered_root->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(hovered_root->PopupId, ImGuiPopupFlags_AnyPopupLevel);
|
||||||
|
const bool is_queued_focus_request = g.NavMoveSubmitted && (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi);
|
||||||
|
|
||||||
if (hovered_window != NULL && !is_closed_popup)
|
if (hovered_window != NULL && !is_closed_popup && !is_queued_focus_request)
|
||||||
{
|
{
|
||||||
StartMouseMovingWindow(hovered_window); //-V595
|
StartMouseMovingWindow(hovered_window); //-V595
|
||||||
|
|
||||||
@@ -5370,7 +5401,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
|||||||
// With right mouse button we close popups without changing focus based on where the mouse is aimed
|
// With right mouse button we close popups without changing focus based on where the mouse is aimed
|
||||||
// Instead, focus will be restored to the window under the bottom-most closed popup.
|
// Instead, focus will be restored to the window under the bottom-most closed popup.
|
||||||
// (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
// (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
||||||
if (g.IO.MouseClicked[1] && g.HoveredId == 0)
|
if (g.HoveredId == 0 && IsMouseClicked(1, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner))
|
||||||
{
|
{
|
||||||
// Find the top-most window between HoveredWindow and the top-most Modal Window.
|
// Find the top-most window between HoveredWindow and the top-most Modal Window.
|
||||||
// This is where we can trim the popup stack.
|
// This is where we can trim the popup stack.
|
||||||
@@ -5732,7 +5763,7 @@ void ImGui::NewFrame()
|
|||||||
g.CurrentWindowStack.resize(0);
|
g.CurrentWindowStack.resize(0);
|
||||||
g.BeginPopupStack.resize(0);
|
g.BeginPopupStack.resize(0);
|
||||||
g.ItemFlagsStack.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.CurrentItemFlags = g.ItemFlagsStack.back();
|
||||||
g.GroupStack.resize(0);
|
g.GroupStack.resize(0);
|
||||||
|
|
||||||
@@ -5967,7 +5998,7 @@ static void ImGui::RenderDimmedBackgrounds()
|
|||||||
if (window->DrawList->CmdBuffer.Size == 0)
|
if (window->DrawList->CmdBuffer.Size == 0)
|
||||||
window->DrawList->AddDrawCmd();
|
window->DrawList->AddDrawCmd();
|
||||||
window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size);
|
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();
|
window->DrawList->PopClipRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6169,11 +6200,9 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
|
|||||||
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
||||||
|
|
||||||
// Round
|
// Round
|
||||||
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
// (see 7b0bf230, 4622fa4b6, #791 for details about this.)
|
||||||
// FIXME: Investigate using ceilf or e.g.
|
// FIXME: Add a way to disable this.
|
||||||
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
text_size.x = ImCeilFast(text_size.x);
|
||||||
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
|
|
||||||
text_size.x = IM_TRUNC(text_size.x + 0.99999f);
|
|
||||||
|
|
||||||
return text_size;
|
return text_size;
|
||||||
}
|
}
|
||||||
@@ -6292,11 +6321,12 @@ bool ImGui::IsItemToggledOpen()
|
|||||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
|
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call after a Selectable() or TreeNode() involved in multi-selection.
|
// Call after a Selectable() or TreeNode() items inside a BeginMultiSelect()/EndMultiSelect() scope.
|
||||||
// Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose.
|
// - Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose.
|
||||||
// This is only meant to be called inside a BeginMultiSelect()/EndMultiSelect() block.
|
// Outside of a multi-select block:
|
||||||
// (Outside of multi-select, it would be misleading/ambiguous to report this signal, as widgets
|
// - It would be misleading/ambiguous to report this signal, as widgets return e.g. a pressed event,
|
||||||
// return e.g. a pressed event and user code is in charge of altering selection in ways we cannot predict.)
|
// and user code is in charge of altering selection in ways we cannot predict.
|
||||||
|
// Prefer using 'if (IsItemClicked() && !IsItemToggledOpen())' for a manual reimplementation of selection.
|
||||||
bool ImGui::IsItemToggledSelection()
|
bool ImGui::IsItemToggledSelection()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@@ -7127,7 +7157,7 @@ static void RenderWindowOuterSingleBorder(ImGuiWindow* window, int border_n, ImU
|
|||||||
const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f);
|
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.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->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)
|
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||||
@@ -7136,7 +7166,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|||||||
const float border_size = window->WindowBorderSize;
|
const float border_size = window->WindowBorderSize;
|
||||||
const ImU32 border_col = GetColorU32(ImGuiCol_Border);
|
const ImU32 border_col = GetColorU32(ImGuiCol_Border);
|
||||||
if (border_size > 0.0f && (window->Flags & ImGuiWindowFlags_NoBackground) == 0)
|
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)
|
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.
|
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))
|
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||||
{
|
{
|
||||||
float y = window->Pos.y + window->TitleBarHeight - 1;
|
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,7 +7231,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
|||||||
if (bg_col & IM_COL32_A_MASK)
|
if (bg_col & IM_COL32_A_MASK)
|
||||||
{
|
{
|
||||||
ImRect bg_rect(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size);
|
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;
|
ImDrawList* bg_draw_list = window->DrawList;
|
||||||
bg_draw_list->AddRectFilled(bg_rect.Min, bg_rect.Max, bg_col, window_rounding, bg_rounding_flags);
|
bg_draw_list->AddRectFilled(bg_rect.Min, bg_rect.Max, bg_col, window_rounding, bg_rounding_flags);
|
||||||
}
|
}
|
||||||
@@ -7221,7 +7251,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.
|
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);
|
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)
|
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
|
// Scrollbars
|
||||||
@@ -8950,6 +8980,8 @@ static void ImGui::UpdateTexturesNewFrame()
|
|||||||
IM_ASSERT(atlas->RendererHasTextures == has_textures);
|
IM_ASSERT(atlas->RendererHasTextures == has_textures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (ImTextureData* tex : g.UserTextures)
|
||||||
|
ImTextureDataUpdateNewFrame(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a single texture list
|
// Build a single texture list
|
||||||
@@ -9011,7 +9043,7 @@ ImFont* ImGui::GetDefaultFont()
|
|||||||
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
|
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXPERIMENTAL: DO NOT USE YET.
|
// EXPERIMENTAL. Use ImTextureDataQueueUpload() to queue updates. Textures logic will be automatically be updated in NewFrame().
|
||||||
void ImGui::RegisterUserTexture(ImTextureData* tex)
|
void ImGui::RegisterUserTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@@ -10341,15 +10373,21 @@ void ImGui::UpdateMouseWheel()
|
|||||||
LockWheelingWindow(NULL, 0.0f);
|
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;
|
ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
|
||||||
if (!mouse_window || mouse_window->Collapsed)
|
if (!mouse_window || mouse_window->Collapsed)
|
||||||
return;
|
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
|
// 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.
|
// 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)
|
if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
|
||||||
@@ -10653,6 +10691,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id)
|
|||||||
// - SetKeyOwner(..., None) : clears owner
|
// - SetKeyOwner(..., None) : clears owner
|
||||||
// - SetKeyOwner(..., Any, !Lock) : illegal (assert)
|
// - SetKeyOwner(..., Any, !Lock) : illegal (assert)
|
||||||
// - SetKeyOwner(..., Any or None, Lock) : set lock
|
// - 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)
|
void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@@ -10679,30 +10718,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); }
|
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())
|
// if (IsItemHovered() || IsItemActive())
|
||||||
// SetKeyOwner(key, GetItemID());
|
// 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.
|
// 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.
|
// 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.
|
// 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;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiID id = g.LastItemData.ID;
|
ImGuiID id = g.LastItemData.ID;
|
||||||
if (id == 0 || (g.HoveredId != id && g.ActiveId != id))
|
if (id == 0 || (g.HoveredId != id && g.ActiveId != id))
|
||||||
return;
|
return false;
|
||||||
if ((flags & ImGuiInputFlags_CondMask_) == 0)
|
if ((flags & ImGuiInputFlags_CondMask_) == 0)
|
||||||
flags |= ImGuiInputFlags_CondDefault_;
|
flags |= ImGuiInputFlags_CondDefault_;
|
||||||
if ((g.HoveredId == id && (flags & ImGuiInputFlags_CondHovered)) || (g.ActiveId == id && (flags & ImGuiInputFlags_CondActive)))
|
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!
|
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_);
|
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.
|
// This is the only public API until we expose owner_id versions of the API as replacements.
|
||||||
@@ -12453,6 +12496,17 @@ bool ImGui::BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags ext
|
|||||||
return false;
|
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];
|
char name[128];
|
||||||
IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu);
|
IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu);
|
||||||
ImFormatString(name, IM_COUNTOF(name), "%s###Menu_%02d", label, g.BeginMenuDepth); // Recycle windows based on depth
|
ImFormatString(name, IM_COUNTOF(name), "%s###Menu_%02d", label, g.BeginMenuDepth); // Recycle windows based on depth
|
||||||
@@ -13750,13 +13804,13 @@ static void ImGui::NavUpdate()
|
|||||||
// FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource?
|
// FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource?
|
||||||
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
||||||
const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown };
|
const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown };
|
||||||
if (nav_gamepad_active)
|
if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad)
|
||||||
for (ImGuiKey key : nav_gamepad_keys_to_change_source)
|
for (ImGuiKey key : nav_gamepad_keys_to_change_source)
|
||||||
if (IsKeyDown(key))
|
if (IsKeyDown(key))
|
||||||
g.NavInputSource = ImGuiInputSource_Gamepad;
|
g.NavInputSource = ImGuiInputSource_Gamepad;
|
||||||
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
||||||
const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow };
|
const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow };
|
||||||
if (nav_keyboard_active)
|
if (nav_keyboard_active && g.NavInputSource != ImGuiInputSource_Keyboard)
|
||||||
for (ImGuiKey key : nav_keyboard_keys_to_change_source)
|
for (ImGuiKey key : nav_keyboard_keys_to_change_source)
|
||||||
if (IsKeyDown(key))
|
if (IsKeyDown(key))
|
||||||
g.NavInputSource = ImGuiInputSource_Keyboard;
|
g.NavInputSource = ImGuiInputSource_Keyboard;
|
||||||
@@ -15117,7 +15171,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|||||||
{
|
{
|
||||||
ImRect bb = g.DragDropTargetRect;
|
ImRect bb = g.DragDropTargetRect;
|
||||||
bb.Expand(-3.5f);
|
bb.Expand(-3.5f);
|
||||||
RenderDragDropTargetRectEx(GetForegroundDrawList(), bb);
|
RenderDragDropTargetRectEx(GetForegroundDrawList(), bb, g.Style.DragDropTargetRounding);
|
||||||
}
|
}
|
||||||
else if (draw_target_rect)
|
else if (draw_target_rect)
|
||||||
{
|
{
|
||||||
@@ -15148,16 +15202,16 @@ void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb)
|
|||||||
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
|
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
|
||||||
if (push_clip_rect)
|
if (push_clip_rect)
|
||||||
window->DrawList->PushClipRectFullScreen();
|
window->DrawList->PushClipRectFullScreen();
|
||||||
RenderDragDropTargetRectEx(window->DrawList, bb_display);
|
RenderDragDropTargetRectEx(window->DrawList, bb_display, g.Style.DragDropTargetRounding);
|
||||||
if (push_clip_rect)
|
if (push_clip_rect)
|
||||||
window->DrawList->PopClipRect();
|
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;
|
ImGuiContext& g = *GImGui;
|
||||||
draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), g.Style.DragDropTargetRounding, 0);
|
draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), rounding, 0);
|
||||||
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), g.Style.DragDropTargetRounding, 0, g.Style.DragDropTargetBorderSize);
|
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), rounding, g.Style.DragDropTargetBorderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImGuiPayload* ImGui::GetDragDropPayload()
|
const ImGuiPayload* ImGui::GetDragDropPayload()
|
||||||
@@ -16259,7 +16313,7 @@ void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list)
|
|||||||
draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding);
|
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_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);
|
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);
|
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);
|
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);
|
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
|
||||||
@@ -16682,7 +16736,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
|
|
||||||
BulletText("Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name);
|
BulletText("Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name);
|
||||||
if (IsItemHovered())
|
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();
|
Indent();
|
||||||
char buf[128];
|
char buf[128];
|
||||||
for (int rect_n = 0; rect_n < TRT_Count; rect_n++)
|
for (int rect_n = 0; rect_n < TRT_Count; rect_n++)
|
||||||
@@ -16697,7 +16751,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]);
|
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);
|
Selectable(buf);
|
||||||
if (IsItemHovered())
|
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
|
else
|
||||||
@@ -16706,7 +16760,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]);
|
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);
|
Selectable(buf);
|
||||||
if (IsItemHovered())
|
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();
|
Unindent();
|
||||||
@@ -17114,7 +17168,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
ImRect r = Funcs::GetTableRect(table, cfg->ShowTablesRectsType, column_n);
|
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);
|
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;
|
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
|
else
|
||||||
@@ -17291,7 +17345,7 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con
|
|||||||
{
|
{
|
||||||
ImDrawListFlags backup_flags = fg_draw_list->Flags;
|
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->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;
|
fg_draw_list->Flags = backup_flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17319,7 +17373,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
|
|||||||
for (int n = 0; n < 3; n++, idx_n++)
|
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));
|
vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos));
|
||||||
if (show_mesh)
|
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
|
// Draw bounding boxes
|
||||||
if (show_aabb)
|
if (show_aabb)
|
||||||
@@ -17600,8 +17654,8 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label)
|
|||||||
{
|
{
|
||||||
ImDrawList* draw_list = GetForegroundDrawList(tab_bar->Window);
|
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->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->AddLineV(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y, 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->ScrollingRectMaxX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255));
|
||||||
}
|
}
|
||||||
if (open)
|
if (open)
|
||||||
{
|
{
|
||||||
@@ -17930,8 +17984,8 @@ void ImGui::DebugDrawCursorPos(ImU32 col)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImVec2 pos = window->DC.CursorPos;
|
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->AddLineV(pos.x, pos.y - 3.0f, 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->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
|
// Draw a 10px wide rectangle around CurposPos.x using Line Y1/Y2 in current window's DrawList
|
||||||
@@ -17942,9 +17996,9 @@ void ImGui::DebugDrawLineExtents(ImU32 col)
|
|||||||
float curr_x = window->DC.CursorPos.x;
|
float curr_x = window->DC.CursorPos.x;
|
||||||
float line_y1 = (window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y);
|
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);
|
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->AddLineH(curr_x - 5.0f, 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->AddLineV(curr_x - 0.5f, line_y1, 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_y2, col, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw last item rect in ForegroundDrawList (so it is always visible)
|
// Draw last item rect in ForegroundDrawList (so it is always visible)
|
||||||
@@ -18314,7 +18368,7 @@ void ImGui::ShowFontSelector(const char* label)
|
|||||||
"- Load additional fonts with io.Fonts->AddFontXXX() functions.\n"
|
"- Load additional fonts with io.Fonts->AddFontXXX() functions.\n"
|
||||||
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\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"
|
"- 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)
|
#endif // #if !defined(IMGUI_DISABLE_DEMO_WINDOWS) || !defined(IMGUI_DISABLE_DEBUG_TOOLS)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (headers)
|
// (headers)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.92.8 WIP"
|
#define IMGUI_VERSION "1.92.9 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19274
|
#define IMGUI_VERSION_NUM 19282
|
||||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||||
|
|
||||||
@@ -613,7 +613,8 @@ namespace ImGui
|
|||||||
IMGUI_API ImGuiID GetID(int int_id);
|
IMGUI_API ImGuiID GetID(int int_id);
|
||||||
|
|
||||||
// Widgets: Text
|
// Widgets: Text
|
||||||
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text.
|
// - Note that all functions taking format strings in the API may be passed ("%s", text) or ("%.*s", text_len, text): which will automatically bypass the formatter.
|
||||||
|
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Practically equivalent to 'Text("%s", text)' but doesn't require null terminated string if 'text_end' is specified.
|
||||||
IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text
|
IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text
|
||||||
IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1);
|
IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||||
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
||||||
@@ -837,7 +838,7 @@ namespace ImGui
|
|||||||
|
|
||||||
// Popups, Modals
|
// Popups, Modals
|
||||||
// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
|
// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
|
||||||
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
|
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing Escape (call 'Shortcut(ImGuiKey_Escape)' to claim a higher-priority shortcut).
|
||||||
// - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls.
|
// - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls.
|
||||||
// - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time.
|
// - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time.
|
||||||
// - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().
|
// - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().
|
||||||
@@ -1092,10 +1093,11 @@ namespace ImGui
|
|||||||
// Inputs Utilities: Key/Input Ownership [BETA]
|
// Inputs Utilities: Key/Input Ownership [BETA]
|
||||||
// - One common use case would be to allow your items to disable standard inputs behaviors such
|
// - 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.
|
// 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.
|
// - 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.
|
// - 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
|
// Inputs Utilities: Mouse
|
||||||
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
|
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
|
||||||
@@ -1329,7 +1331,7 @@ enum ImGuiTreeNodeFlags_
|
|||||||
|
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_NavLeftJumpsToParent, // Renamed in 1.92.0
|
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_NavLeftJumpsToParent, // Renamed in 1.92.0
|
||||||
ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7
|
//ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7
|
||||||
//ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
//ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -1755,6 +1757,7 @@ enum ImGuiCol_
|
|||||||
ImGuiCol_ScrollbarGrabHovered,
|
ImGuiCol_ScrollbarGrabHovered,
|
||||||
ImGuiCol_ScrollbarGrabActive,
|
ImGuiCol_ScrollbarGrabActive,
|
||||||
ImGuiCol_CheckMark, // Checkbox tick and RadioButton circle
|
ImGuiCol_CheckMark, // Checkbox tick and RadioButton circle
|
||||||
|
ImGuiCol_CheckboxSelectedBg, // Checkbox background when Selected, otherwise use FrameBg
|
||||||
ImGuiCol_SliderGrab,
|
ImGuiCol_SliderGrab,
|
||||||
ImGuiCol_SliderGrabActive,
|
ImGuiCol_SliderGrabActive,
|
||||||
ImGuiCol_Button,
|
ImGuiCol_Button,
|
||||||
@@ -1852,6 +1855,7 @@ enum ImGuiStyleVar_
|
|||||||
ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign
|
ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign
|
||||||
ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize
|
ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize
|
||||||
ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding
|
ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding
|
||||||
|
ImGuiStyleVar_DragDropTargetRounding, // float DragDropTargetRounding
|
||||||
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
|
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
|
||||||
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
|
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
|
||||||
ImGuiStyleVar_SeparatorSize, // float SeparatorSize
|
ImGuiStyleVar_SeparatorSize, // float SeparatorSize
|
||||||
@@ -2328,13 +2332,14 @@ struct ImGuiStyle
|
|||||||
ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes.
|
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 TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
|
||||||
float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line.
|
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 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 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.
|
float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers.
|
||||||
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
||||||
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
||||||
|
float InputTextCursorSize; // Thickness of cursor/caret in InputText().
|
||||||
float SeparatorSize; // Thickness of border in Separator(). Must be >= 1.0f.
|
float SeparatorSize; // Thickness of border in Separator(). Must be >= 1.0f.
|
||||||
float SeparatorTextBorderSize; // Thickness of border in SeparatorText()
|
float SeparatorTextBorderSize; // Thickness of border in SeparatorText()
|
||||||
ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
|
ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
|
||||||
@@ -2609,7 +2614,7 @@ struct ImGuiIO
|
|||||||
//void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
|
//void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
float FontGlobalScale; // Moved io.FontGlobalScale to style.FontScaleMain in 1.92 (June 2025)
|
float FontGlobalScale; // Moved io.FontGlobalScale to style.FontScaleMain in 1.92.0 (June 2025)
|
||||||
|
|
||||||
// Legacy: before 1.91.1, clipboard functions were stored in ImGuiIO instead of ImGuiPlatformIO.
|
// Legacy: before 1.91.1, clipboard functions were stored in ImGuiIO instead of ImGuiPlatformIO.
|
||||||
// As this is will affect all users of custom engines/backends, we are providing proper legacy redirection (will obsolete).
|
// As this is will affect all users of custom engines/backends, we are providing proper legacy redirection (will obsolete).
|
||||||
@@ -3239,23 +3244,30 @@ struct ImDrawListSplitter
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Flags for ImDrawList functions
|
// 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_
|
enum ImDrawFlags_
|
||||||
{
|
{
|
||||||
ImDrawFlags_None = 0,
|
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.
|
// Rounding for AddRect(), AddRectFilled(), PathRect()
|
||||||
ImDrawFlags_RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02.
|
// - When not specified, we defaults to ImDrawFlags_RoundCornersAll! So you only need to use those flags if you want another configuration.
|
||||||
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_RoundCornersTopLeft = 1 << 4, // Round top-left corner only (when rounding > 0.0f, we default to all corners).
|
||||||
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_RoundCornersTopRight = 1 << 5, // Round top-right corner only (when rounding > 0.0f, we default to all corners).
|
||||||
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_RoundCornersBottomLeft = 1 << 6, // Round bottom-left corner only (when rounding > 0.0f, we default to all corners).
|
||||||
|
ImDrawFlags_RoundCornersBottomRight = 1 << 7, // Round bottom-right corner only (when rounding > 0.0f, we default to all corners).
|
||||||
|
ImDrawFlags_RoundCornersNone = 1 << 8, // Disable rounding even if `float rounding > 0.0f`. This is NOT zero, NOT an implicit flag!
|
||||||
|
ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, // (Default!!)
|
||||||
|
ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified!
|
||||||
ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight,
|
ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight,
|
||||||
ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight,
|
ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight,
|
||||||
ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft,
|
ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft,
|
||||||
ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight,
|
ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight,
|
||||||
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_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone,
|
||||||
|
|
||||||
|
// Stroke options
|
||||||
|
ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed.
|
||||||
|
//ImDrawFlags_Closed = 1 << 0, // Prior to 1.92.8 (May 2026), ImDrawFlags_Closed was guaranteed to be == 1<<0 == 1 for legacy compatibility reason. Hardcoded use of 1 or true should be replaced.
|
||||||
|
|
||||||
|
ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // == 0x8000000F,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
|
// Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
|
||||||
@@ -3267,6 +3279,7 @@ enum ImDrawListFlags_
|
|||||||
ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering (NOT point/nearest filtering).
|
ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering (NOT point/nearest filtering).
|
||||||
ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
|
ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
|
||||||
ImDrawListFlags_AllowVtxOffset = 1 << 3, // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
|
ImDrawListFlags_AllowVtxOffset = 1 << 3, // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
|
||||||
|
ImDrawListFlags_TextNoPixelSnap = 1 << 4, // Disable automatically snapping AddText() calls to pixel boundaries.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw command list
|
// Draw command list
|
||||||
@@ -3321,7 +3334,9 @@ struct ImDrawList
|
|||||||
// In future versions we will use textures to provide cheaper and higher-quality circles.
|
// 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.
|
// 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 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 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 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);
|
IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f);
|
||||||
@@ -3342,7 +3357,7 @@ struct ImDrawList
|
|||||||
// General polygon
|
// General polygon
|
||||||
// - Only simple polygons are supported by filling functions (no self-intersections, no holes).
|
// - 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.
|
// - 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 AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||||
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||||
|
|
||||||
@@ -3362,7 +3377,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 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 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 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 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 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
|
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 +3425,15 @@ struct ImDrawList
|
|||||||
|
|
||||||
// Obsolete names
|
// Obsolete names
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#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 PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.0
|
||||||
inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.0
|
inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.0
|
||||||
|
#else
|
||||||
|
void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding /*= 0.0f*/, ImDrawFlags flags /*= 0*/, float thickness /*= 1.0f*/) = delete;
|
||||||
|
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
|
#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 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)
|
//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 +3545,7 @@ struct ImTextureData
|
|||||||
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
||||||
|
|
||||||
// Functions
|
// 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() { memset((void*)this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||||
~ImTextureData() { DestroyPixels(); }
|
~ImTextureData() { DestroyPixels(); }
|
||||||
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
||||||
@@ -3678,13 +3701,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 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 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 CompactCache(); // Compact cached glyphs and texture.
|
||||||
IMGUI_API void SetFontLoader(const ImFontLoader* font_loader); // Change font loader at runtime.
|
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:
|
// 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 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.
|
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
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
@@ -3902,7 +3925,7 @@ struct ImFont
|
|||||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL);
|
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL);
|
||||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0);
|
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0);
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); }
|
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); } // Obsoleted old name in 1.92.0. Note how `scale` was to `size`.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// [Internal] Don't use!
|
// [Internal] Don't use!
|
||||||
@@ -4017,11 +4040,11 @@ struct ImGuiPlatformIO
|
|||||||
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
|
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
|
||||||
void* Renderer_RenderState;
|
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_ResetRenderState; // Request to reset the graphics/render state.
|
||||||
ImDrawCallback DrawCallback_SetSamplerLinear; // Request to set current texture sampling to Linear
|
ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear.
|
||||||
ImDrawCallback DrawCallback_SetSamplerNearest; // Request to set current texture sampling to Nearest/Point
|
ImDrawCallback DrawCallback_SetSamplerNearest; // Request backend to set texture sampling to Nearest/Point.
|
||||||
//ImDrawCallback DrawCallback_SetSamplerCustom; // Request to set current texture sampling using Backend Specific data.
|
//ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data.
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Output
|
// Output
|
||||||
|
|||||||
+199
-84
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (demo code)
|
// (demo code)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@@ -73,6 +73,7 @@ Index of this file:
|
|||||||
// [SECTION] Demo Window / ShowDemoWindow()
|
// [SECTION] Demo Window / ShowDemoWindow()
|
||||||
// [SECTION] DemoWindowMenuBar()
|
// [SECTION] DemoWindowMenuBar()
|
||||||
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
|
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
|
||||||
|
// [SECTION] Helpers: ExampleImageViewer
|
||||||
// [SECTION] DemoWindowWidgetsBasic()
|
// [SECTION] DemoWindowWidgetsBasic()
|
||||||
// [SECTION] DemoWindowWidgetsBullets()
|
// [SECTION] DemoWindowWidgetsBullets()
|
||||||
// [SECTION] DemoWindowWidgetsCollapsingHeaders()
|
// [SECTION] DemoWindowWidgetsCollapsingHeaders()
|
||||||
@@ -108,6 +109,7 @@ Index of this file:
|
|||||||
// [SECTION] User Guide / ShowUserGuide()
|
// [SECTION] User Guide / ShowUserGuide()
|
||||||
// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
|
// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
|
||||||
// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
|
// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
|
||||||
|
// [SECTION] Example App: Image Viewer / ShowExampleAppImageViewer()
|
||||||
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
|
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
|
||||||
// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
|
// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
|
||||||
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
|
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
|
||||||
@@ -238,6 +240,7 @@ static void ShowExampleAppAssetsBrowser(bool* p_open);
|
|||||||
static void ShowExampleAppConsole(bool* p_open);
|
static void ShowExampleAppConsole(bool* p_open);
|
||||||
static void ShowExampleAppCustomRendering(bool* p_open);
|
static void ShowExampleAppCustomRendering(bool* p_open);
|
||||||
static void ShowExampleAppDocuments(bool* p_open);
|
static void ShowExampleAppDocuments(bool* p_open);
|
||||||
|
static void ShowExampleAppImageViewer(bool* p_open);
|
||||||
static void ShowExampleAppLog(bool* p_open);
|
static void ShowExampleAppLog(bool* p_open);
|
||||||
static void ShowExampleAppLayout(bool* p_open);
|
static void ShowExampleAppLayout(bool* p_open);
|
||||||
static void ShowExampleAppPropertyEditor(bool* p_open, ImGuiDemoWindowData* demo_data);
|
static void ShowExampleAppPropertyEditor(bool* p_open, ImGuiDemoWindowData* demo_data);
|
||||||
@@ -308,6 +311,7 @@ struct ImGuiDemoWindowData
|
|||||||
bool ShowAppConsole = false;
|
bool ShowAppConsole = false;
|
||||||
bool ShowAppCustomRendering = false;
|
bool ShowAppCustomRendering = false;
|
||||||
bool ShowAppDocuments = false;
|
bool ShowAppDocuments = false;
|
||||||
|
bool ShowAppImageViewer = false;
|
||||||
bool ShowAppLog = false;
|
bool ShowAppLog = false;
|
||||||
bool ShowAppLayout = false;
|
bool ShowAppLayout = false;
|
||||||
bool ShowAppPropertyEditor = 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.ShowAppAssetsBrowser) { ShowExampleAppAssetsBrowser(&demo_data.ShowAppAssetsBrowser); }
|
||||||
if (demo_data.ShowAppConsole) { ShowExampleAppConsole(&demo_data.ShowAppConsole); }
|
if (demo_data.ShowAppConsole) { ShowExampleAppConsole(&demo_data.ShowAppConsole); }
|
||||||
if (demo_data.ShowAppCustomRendering) { ShowExampleAppCustomRendering(&demo_data.ShowAppCustomRendering); }
|
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.ShowAppLog) { ShowExampleAppLog(&demo_data.ShowAppLog); }
|
||||||
if (demo_data.ShowAppLayout) { ShowExampleAppLayout(&demo_data.ShowAppLayout); }
|
if (demo_data.ShowAppLayout) { ShowExampleAppLayout(&demo_data.ShowAppLayout); }
|
||||||
if (demo_data.ShowAppPropertyEditor) { ShowExampleAppPropertyEditor(&demo_data.ShowAppPropertyEditor, &demo_data); }
|
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("Console", NULL, &demo_data->ShowAppConsole);
|
||||||
ImGui::MenuItem("Custom rendering", NULL, &demo_data->ShowAppCustomRendering);
|
ImGui::MenuItem("Custom rendering", NULL, &demo_data->ShowAppCustomRendering);
|
||||||
ImGui::MenuItem("Documents", NULL, &demo_data->ShowAppDocuments);
|
ImGui::MenuItem("Documents", NULL, &demo_data->ShowAppDocuments);
|
||||||
|
ImGui::MenuItem("Image Viewer", NULL, &demo_data->ShowAppImageViewer);
|
||||||
ImGui::MenuItem("Log", NULL, &demo_data->ShowAppLog);
|
ImGui::MenuItem("Log", NULL, &demo_data->ShowAppLog);
|
||||||
ImGui::MenuItem("Property editor", NULL, &demo_data->ShowAppPropertyEditor);
|
ImGui::MenuItem("Property editor", NULL, &demo_data->ShowAppPropertyEditor);
|
||||||
ImGui::MenuItem("Simple layout", NULL, &demo_data->ShowAppLayout);
|
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::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
|
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::EndMenu();
|
||||||
}
|
}
|
||||||
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
||||||
@@ -825,6 +831,87 @@ static ExampleTreeNode* ExampleTree_CreateDemoTree()
|
|||||||
return node_L0;
|
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()
|
// [SECTION] DemoWindowWidgetsBasic()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1802,40 +1889,29 @@ static void DemoWindowWidgetsImages()
|
|||||||
// - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
// - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||||||
|
|
||||||
// Grab the current texture identifier used by the font atlas.
|
// 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;
|
||||||
// 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)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_w = (float)io.Fonts->TexData->Width;
|
float my_tex_h = (float)atlas->TexData->Height;
|
||||||
float my_tex_h = (float)io.Fonts->TexData->Height;
|
|
||||||
|
|
||||||
{
|
|
||||||
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
|
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
|
||||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
|
||||||
|
// Basic drawing
|
||||||
|
ImGui::SeparatorText("Image()/ImageWithBg() function");
|
||||||
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
|
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
|
||||||
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
|
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize));
|
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::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();
|
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_DEMO_MARKER("Widgets/Images/Textured buttons");
|
||||||
|
ImGui::SeparatorText("Textured Buttons");
|
||||||
ImGui::TextWrapped("And now some textured buttons..");
|
ImGui::TextWrapped("And now some textured buttons..");
|
||||||
static int pressed_count = 0;
|
static int pressed_count = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
@@ -4045,7 +4121,7 @@ static void DemoWindowWidgetsTooltips()
|
|||||||
ImGui::BeginDisabled();
|
ImGui::BeginDisabled();
|
||||||
ImGui::Button("Disabled item", sz);
|
ImGui::Button("Disabled item", sz);
|
||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||||
ImGui::SetTooltip("I am a a tooltip for a disabled item.");
|
ImGui::SetTooltip("I am a tooltip for a disabled item.");
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
@@ -4062,9 +4138,9 @@ static void DemoWindowWidgetsTreeNodes()
|
|||||||
{
|
{
|
||||||
IMGUI_DEMO_MARKER("Widgets/Tree Nodes");
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes");
|
||||||
// See see "Examples -> Property Editor" (ShowExampleAppPropertyEditor() function) for a fancier, data-driven tree.
|
// See see "Examples -> Property Editor" (ShowExampleAppPropertyEditor() function) for a fancier, data-driven tree.
|
||||||
if (ImGui::TreeNode("Basic trees"))
|
if (ImGui::TreeNode("Basic Trees"))
|
||||||
{
|
{
|
||||||
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Basic trees");
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Basic Trees");
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
// Use SetNextItemOpen() so set the default state of a node to be open. We could
|
// Use SetNextItemOpen() so set the default state of a node to be open. We could
|
||||||
@@ -4088,9 +4164,9 @@ static void DemoWindowWidgetsTreeNodes()
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TreeNode("Hierarchy lines"))
|
if (ImGui::TreeNode("Hierarchy Lines"))
|
||||||
{
|
{
|
||||||
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Hierarchy lines");
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Hierarchy Lines");
|
||||||
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DefaultOpen;
|
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DefaultOpen;
|
||||||
HelpMarker("Default option for DrawLinesXXX is stored in style.TreeLinesFlags");
|
HelpMarker("Default option for DrawLinesXXX is stored in style.TreeLinesFlags");
|
||||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesNone", &base_flags, ImGuiTreeNodeFlags_DrawLinesNone);
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesNone", &base_flags, ImGuiTreeNodeFlags_DrawLinesNone);
|
||||||
@@ -4127,15 +4203,57 @@ static void DemoWindowWidgetsTreeNodes()
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TreeNode("Advanced, with Selectable nodes"))
|
if (ImGui::TreeNode("Selectable Nodes"))
|
||||||
{
|
{
|
||||||
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Advanced, with Selectable nodes");
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Selectable Nodes");
|
||||||
HelpMarker(
|
HelpMarker(
|
||||||
"This is a more typical looking tree with selectable nodes.\n"
|
"Manually implemented selectable nodes.\n"
|
||||||
"Click to select, Ctrl+Click to toggle, click on arrows or double-click to open.");
|
"Click to select, Ctrl+Click to toggle, click on arrows or double-click to open.\n\n"
|
||||||
|
"You may also use the multi-select API (see 'Demo->Widgets->Selection State & Multi-Select') for more advanced multi-selection features.");
|
||||||
|
|
||||||
|
// Hold in 'selection_mask' a simple representation of what may be user-side selection state.
|
||||||
|
// - You may retain selection state inside or outside your objects in whatever format you see fit.
|
||||||
|
// You may use ImGuiSelectionBasicStorage which is conceptually close to a set<> of identifiers.
|
||||||
|
// - We record which node was clicked and then apply selection at the end of the loop.
|
||||||
|
// - This is a manual and simplified reimplementation of multi-selection, which the full
|
||||||
|
// BeginMultiSelect() API implements better, but which is not trivial to wire for trees.
|
||||||
|
static int selection_mask = 0x00;
|
||||||
|
int node_clicked_idx = -1;
|
||||||
|
for (int node_n = 0; node_n < 6; node_n++)
|
||||||
|
{
|
||||||
|
// Disable the default "open on single-click behavior" + set Selected flag according to our selection.
|
||||||
|
// To alter selection we use if 'IsItemClicked() && !IsItemToggledOpen()', so clicking on an arrow doesn't alter selection.
|
||||||
|
// In a BeginMultiSelect()/EndMultiSelect() we could use IsItemToggledSelection() but here we reimplement and use our own logic.
|
||||||
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||||
|
if (selection_mask & (1 << node_n))
|
||||||
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
|
||||||
|
bool is_open = ImGui::TreeNodeEx((void*)(intptr_t)node_n, flags, "Selectable Node %d", node_n);
|
||||||
|
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen())
|
||||||
|
node_clicked_idx = node_n;
|
||||||
|
if (is_open)
|
||||||
|
{
|
||||||
|
ImGui::BulletText("<Node contents here>");
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node_clicked_idx != -1)
|
||||||
|
{
|
||||||
|
// Update selection state (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
|
||||||
|
if (ImGui::GetIO().KeyCtrl)
|
||||||
|
selection_mask ^= (1 << node_clicked_idx); // Ctrl+Click to toggle
|
||||||
|
else //if (!(selection_mask & (1 << node_clicked_idx))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
|
||||||
|
selection_mask = (1 << node_clicked_idx); // Click to single-select
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::TreeNode("Advanced"))
|
||||||
|
{
|
||||||
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Advanced");
|
||||||
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||||
static bool align_label_with_current_x_position = false;
|
static bool align_label_with_current_x_position = false;
|
||||||
static bool test_drag_and_drop = false;
|
static bool use_drag_and_drop = false;
|
||||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
||||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
||||||
@@ -4153,44 +4271,30 @@ static void DemoWindowWidgetsTreeNodes()
|
|||||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesToNodes", &base_flags, ImGuiTreeNodeFlags_DrawLinesToNodes);
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesToNodes", &base_flags, ImGuiTreeNodeFlags_DrawLinesToNodes);
|
||||||
|
|
||||||
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
|
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
|
||||||
ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop);
|
ImGui::Checkbox("Make Tree Nodes as drag & drop sources", &use_drag_and_drop);
|
||||||
ImGui::Text("Hello!");
|
|
||||||
if (align_label_with_current_x_position)
|
if (align_label_with_current_x_position)
|
||||||
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
|
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
|
||||||
|
|
||||||
// 'selection_mask' is dumb representation of what may be user-side selection state.
|
for (int node_n = 0; node_n < 6; node_n++)
|
||||||
// You may retain selection state inside or outside your objects in whatever format you see fit.
|
|
||||||
// 'node_clicked' is temporary storage of what node we have clicked to process selection at the end
|
|
||||||
/// of the loop. May be a pointer to your own node type, etc.
|
|
||||||
static int selection_mask = (1 << 2);
|
|
||||||
int node_clicked = -1;
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
{
|
||||||
// Disable the default "open on single-click behavior" + set Selected flag according to our selection.
|
|
||||||
// To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection.
|
|
||||||
ImGuiTreeNodeFlags node_flags = base_flags;
|
ImGuiTreeNodeFlags node_flags = base_flags;
|
||||||
const bool is_selected = (selection_mask & (1 << i)) != 0;
|
if (node_n < 3)
|
||||||
if (is_selected)
|
|
||||||
node_flags |= ImGuiTreeNodeFlags_Selected;
|
|
||||||
if (i < 3)
|
|
||||||
{
|
{
|
||||||
// Items 0..2 are Tree Node
|
// Items 0..2 are Tree Node
|
||||||
bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i);
|
bool is_open = ImGui::TreeNodeEx((void*)(intptr_t)node_n, node_flags, "Selectable Node %d", node_n);
|
||||||
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen())
|
if (use_drag_and_drop && ImGui::BeginDragDropSource())
|
||||||
node_clicked = i;
|
|
||||||
if (test_drag_and_drop && ImGui::BeginDragDropSource())
|
|
||||||
{
|
{
|
||||||
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
|
ImGui::SetDragDropPayload("MY_TREENODE_PAYLOAD_TYPE", NULL, 0);
|
||||||
ImGui::Text("This is a drag and drop source");
|
ImGui::Text("This is a drag and drop source");
|
||||||
ImGui::EndDragDropSource();
|
ImGui::EndDragDropSource();
|
||||||
}
|
}
|
||||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth))
|
if (node_n == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth))
|
||||||
{
|
{
|
||||||
// Item 2 has an additional inline button to help demonstrate SpanLabelWidth.
|
// Item 2 has an additional inline button to help demonstrate SpanLabelWidth.
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton("button")) {}
|
if (ImGui::SmallButton("button")) {}
|
||||||
}
|
}
|
||||||
if (node_open)
|
if (is_open)
|
||||||
{
|
{
|
||||||
ImGui::BulletText("Blah blah\nBlah Blah");
|
ImGui::BulletText("Blah blah\nBlah Blah");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@@ -4204,26 +4308,15 @@ static void DemoWindowWidgetsTreeNodes()
|
|||||||
// The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can
|
// The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can
|
||||||
// use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text().
|
// use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text().
|
||||||
node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
|
node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
|
||||||
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i);
|
ImGui::TreeNodeEx((void*)(intptr_t)node_n, node_flags, "Selectable Leaf %d", node_n);
|
||||||
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen())
|
if (use_drag_and_drop && ImGui::BeginDragDropSource())
|
||||||
node_clicked = i;
|
|
||||||
if (test_drag_and_drop && ImGui::BeginDragDropSource())
|
|
||||||
{
|
{
|
||||||
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
|
ImGui::SetDragDropPayload("MY_TREENODE_PAYLOAD_TYPE", NULL, 0);
|
||||||
ImGui::Text("This is a drag and drop source");
|
ImGui::Text("This is a drag and drop source");
|
||||||
ImGui::EndDragDropSource();
|
ImGui::EndDragDropSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node_clicked != -1)
|
|
||||||
{
|
|
||||||
// Update selection state
|
|
||||||
// (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
|
|
||||||
if (ImGui::GetIO().KeyCtrl)
|
|
||||||
selection_mask ^= (1 << node_clicked); // Ctrl+Click to toggle
|
|
||||||
else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
|
|
||||||
selection_mask = (1 << node_clicked); // Click to single-select
|
|
||||||
}
|
|
||||||
if (align_label_with_current_x_position)
|
if (align_label_with_current_x_position)
|
||||||
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
|
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
@@ -8827,7 +8920,7 @@ static void ShowExampleMenuFile()
|
|||||||
IMGUI_DEMO_MARKER("Examples/Menu/Options");
|
IMGUI_DEMO_MARKER("Examples/Menu/Options");
|
||||||
static bool enabled = true;
|
static bool enabled = true;
|
||||||
ImGui::MenuItem("Enabled", "", &enabled);
|
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++)
|
for (int i = 0; i < 10; i++)
|
||||||
ImGui::Text("Scrolling Text %d", i);
|
ImGui::Text("Scrolling Text %d", i);
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
@@ -9239,6 +9332,28 @@ static void ShowExampleAppConsole(bool* p_open)
|
|||||||
console.Draw("Example: Console", 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()
|
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -10131,20 +10246,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->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->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->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, 0.0f, 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, 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, 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.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
|
//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->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->AddLineH(x, 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->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
|
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||||
|
|
||||||
// Path
|
// Path
|
||||||
draw_list->PathArcTo(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, 3.141592f, 3.141592f * -0.5f);
|
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;
|
x += sz + spacing;
|
||||||
|
|
||||||
// Quadratic Bezier Curve (3 control points)
|
// Quadratic Bezier Curve (3 control points)
|
||||||
@@ -10278,9 +10393,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
|||||||
{
|
{
|
||||||
const float GRID_STEP = 64.0f;
|
const float GRID_STEP = 64.0f;
|
||||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
|
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)
|
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)
|
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);
|
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);
|
||||||
|
|||||||
+154
-95
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (drawing and font code)
|
// (drawing and font code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -208,6 +208,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
|||||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f);
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f);
|
||||||
colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||||
|
colors[ImGuiCol_CheckboxSelectedBg] = ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_FrameBgHovered], 0.65f);
|
||||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f);
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f);
|
||||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||||
colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
|
colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
|
||||||
@@ -275,6 +276,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
|||||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f);
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f);
|
||||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f);
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f);
|
||||||
colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f);
|
colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f);
|
||||||
|
colors[ImGuiCol_CheckboxSelectedBg] = ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_FrameBgActive], 0.65f);
|
||||||
colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
|
colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
|
||||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f);
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f);
|
||||||
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f);
|
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f);
|
||||||
@@ -343,6 +345,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
|||||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f);
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f);
|
||||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f);
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f);
|
||||||
colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||||
|
colors[ImGuiCol_CheckboxSelectedBg] = ImVec4(0.95f, 0.97f, 1.00f, 1.00f);
|
||||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
|
||||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f);
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f);
|
||||||
colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
|
colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
|
||||||
@@ -653,7 +656,7 @@ void ImDrawList::_OnChangedVtxOffset()
|
|||||||
int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
|
int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
|
||||||
{
|
{
|
||||||
// Automatic segment count
|
// Automatic segment count
|
||||||
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
|
const int radius_idx = (int)(radius + 0.999f); // ceil to never reduce accuracy
|
||||||
if (radius_idx >= 0 && radius_idx < IM_COUNTOF(_Data->CircleSegmentCounts))
|
if (radius_idx >= 0 && radius_idx < IM_COUNTOF(_Data->CircleSegmentCounts))
|
||||||
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||||
else
|
else
|
||||||
@@ -811,7 +814,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
|
|||||||
|
|
||||||
// TODO: Thickness anti-aliased lines cap are missing their AA fringe.
|
// TODO: Thickness anti-aliased lines cap are missing their AA fringe.
|
||||||
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
|
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
|
||||||
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness)
|
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, float thickness, ImDrawFlags flags)
|
||||||
{
|
{
|
||||||
if (points_count < 2 || (col & IM_COL32_A_MASK) == 0)
|
if (points_count < 2 || (col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
@@ -821,6 +824,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
|||||||
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
|
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
|
||||||
const bool thick_line = (thickness > _FringeScale);
|
const bool thick_line = (thickness > _FringeScale);
|
||||||
|
|
||||||
|
// If this assert triggers on legacy code:
|
||||||
|
// - 1.92.8 (2025/05): swapped two last parameters order: flags, thickness --> thickness, flags. This should normally be caught by compile-time type-checking.
|
||||||
|
// - 1.92.8 (2025/05): changed value of ImDrawList_Closed which was previously guaranteed to be == 1. Hardcoded use of 1 or true should be replaced.
|
||||||
|
// Read more details near AddRect() + see "API BREAKING CHANGES" section for 1.82, 1.90 and 1.92.8.
|
||||||
|
IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?");
|
||||||
|
|
||||||
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
||||||
{
|
{
|
||||||
// Anti-aliased stroke
|
// Anti-aliased stroke
|
||||||
@@ -1441,14 +1450,6 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDr
|
|||||||
{
|
{
|
||||||
if (rounding >= 0.5f)
|
if (rounding >= 0.5f)
|
||||||
{
|
{
|
||||||
// If this assert triggers on legacy code, please update your code replacing hardcoded values with ImDrawFlags_RoundCorners* values.
|
|
||||||
// - See details in 1.82 Changelog as well as 2021/03/12 and 2023/09/08 entries in "API BREAKING CHANGES" section.
|
|
||||||
// - Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc. anyway.
|
|
||||||
// - Marked obsolete in 1.82 and completely removed in 1.90:
|
|
||||||
// - Hard coded support for ~0 == ImDrawFlags_RoundCornersAll.
|
|
||||||
// - Hard coded support for values 0x01 to 0x0F (matching 15 out of 16 old flags combinations) --> see FixRectCornerFlags() in <1.90 code.
|
|
||||||
// - Hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'
|
|
||||||
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
|
|
||||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||||
flags |= ImDrawFlags_RoundCornersAll;
|
flags |= ImDrawFlags_RoundCornersAll;
|
||||||
|
|
||||||
@@ -1479,22 +1480,48 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th
|
|||||||
{
|
{
|
||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
PathLineTo(p1 + ImVec2(0.5f, 0.5f));
|
const ImVec2 points[2] = { ImVec2(p1.x + 0.5f, p1.y + 0.5f), ImVec2(p2.x + 0.5f, p2.y + 0.5f) };
|
||||||
PathLineTo(p2 + ImVec2(0.5f, 0.5f));
|
AddPolyline(points, 2, col, thickness);
|
||||||
PathStroke(col, 0, thickness);
|
}
|
||||||
|
|
||||||
|
void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness)
|
||||||
|
{
|
||||||
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
|
return;
|
||||||
|
const ImVec2 points[2] = { ImVec2(min_x + 0.5f, y + 0.5f), ImVec2(max_x + 0.5f, y + 0.5f) }; // Same as AddLine() above.
|
||||||
|
AddPolyline(points, 2, col, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness)
|
||||||
|
{
|
||||||
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
|
return;
|
||||||
|
const ImVec2 points[2] = { ImVec2(x + 0.5f, min_y + 0.5f), ImVec2(x + 0.5f, max_y + 0.5f) }; // Same as AddLine() above.
|
||||||
|
AddPolyline(points, 2, col, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// p_min = upper-left, p_max = lower-right
|
// p_min = upper-left, p_max = lower-right
|
||||||
// Note we don't render 1 pixels sized rectangles properly.
|
// Note we don't render 1 pixels sized rectangles properly.
|
||||||
void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness)
|
void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, float thickness, ImDrawFlags flags)
|
||||||
{
|
{
|
||||||
|
// If this assert triggers on legacy code:
|
||||||
|
// - 1.92.8 (2025/05): swapped two last parameters order: flags, thickness --> thickness, flags. This should normally be caught by compile-time type-checking.
|
||||||
|
// - 1.92.8 (2025/05): changed value of ImDrawList_Closed which was previously guaranteed to be == 1. Hardcoded use of 1 or true should be replaced.
|
||||||
|
// - 1.82.0 (2021/03): changed ImDrawCornerFlags to ImDrawFlags_RoundCornersXXX values.
|
||||||
|
// If you used hard-coded 1 to 15 or ~0 in flags to configure corner rounding use the new flags!
|
||||||
|
// - Hard coded support for ~0 == ImDrawFlags_RoundCornersAll.
|
||||||
|
// - Hard coded support for values 0x01 to 0x0F (matching 15 out of 16 old flags combinations) --> see FixRectCornerFlags() in <1.90 code.
|
||||||
|
// - Hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'.
|
||||||
|
// See "API BREAKING CHANGES" section for 1.82, 1.90 and 1.92.8.
|
||||||
|
IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); // Or misuse of legacy hard-coded ImDrawCornerFlags values
|
||||||
|
|
||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
||||||
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags);
|
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags);
|
||||||
else
|
else
|
||||||
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags); // Better looking lower-right corner and rounded non-AA shapes.
|
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags); // Better looking lower-right corner and rounded non-AA shapes.
|
||||||
PathStroke(col, ImDrawFlags_Closed, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags)
|
void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags)
|
||||||
@@ -1538,7 +1565,7 @@ void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, c
|
|||||||
PathLineTo(p2);
|
PathLineTo(p2);
|
||||||
PathLineTo(p3);
|
PathLineTo(p3);
|
||||||
PathLineTo(p4);
|
PathLineTo(p4);
|
||||||
PathStroke(col, ImDrawFlags_Closed, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col)
|
void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col)
|
||||||
@@ -1561,7 +1588,7 @@ void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p
|
|||||||
PathLineTo(p1);
|
PathLineTo(p1);
|
||||||
PathLineTo(p2);
|
PathLineTo(p2);
|
||||||
PathLineTo(p3);
|
PathLineTo(p3);
|
||||||
PathStroke(col, ImDrawFlags_Closed, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col)
|
void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col)
|
||||||
@@ -1596,7 +1623,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
|
|||||||
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathStroke(col, ImDrawFlags_Closed, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments)
|
void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments)
|
||||||
@@ -1632,7 +1659,7 @@ void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_
|
|||||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||||
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
||||||
PathStroke(col, ImDrawFlags_Closed, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guaranteed to honor 'num_segments'
|
// Guaranteed to honor 'num_segments'
|
||||||
@@ -1659,7 +1686,7 @@ void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 co
|
|||||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||||
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||||
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
|
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
|
||||||
PathStroke(col, true, thickness);
|
PathStroke(col, thickness, ImDrawFlags_Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments)
|
void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments)
|
||||||
@@ -1684,7 +1711,7 @@ void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2
|
|||||||
|
|
||||||
PathLineTo(p1);
|
PathLineTo(p1);
|
||||||
PathBezierCubicCurveTo(p2, p3, p4, num_segments);
|
PathBezierCubicCurveTo(p2, p3, p4, num_segments);
|
||||||
PathStroke(col, 0, thickness);
|
PathStroke(col, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quadratic Bezier takes 3 controls points
|
// Quadratic Bezier takes 3 controls points
|
||||||
@@ -1695,7 +1722,7 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
|
|||||||
|
|
||||||
PathLineTo(p1);
|
PathLineTo(p1);
|
||||||
PathBezierQuadraticCurveTo(p2, p3, num_segments);
|
PathBezierQuadraticCurveTo(p2, p3, num_segments);
|
||||||
PathStroke(col, 0, thickness);
|
PathStroke(col, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
||||||
@@ -2495,10 +2522,11 @@ void ImTextureData::DestroyPixels()
|
|||||||
// - Default texture data encoded in ASCII
|
// - Default texture data encoded in ASCII
|
||||||
// - ImFontAtlas()
|
// - ImFontAtlas()
|
||||||
// - ImFontAtlas::Clear()
|
// - ImFontAtlas::Clear()
|
||||||
// - ImFontAtlas::CompactCache()
|
// - ImFontAtlas::ClearFonts()
|
||||||
// - ImFontAtlas::ClearInputData()
|
// - ImFontAtlas::ClearInputData()
|
||||||
// - ImFontAtlas::ClearTexData()
|
// - ImFontAtlas::ClearTexData()
|
||||||
// - ImFontAtlas::ClearFonts()
|
// - ImFontAtlas::CompactCache()
|
||||||
|
// - ImFontAtlas::SetFontLoader()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// - ImFontAtlasUpdateNewFrame()
|
// - ImFontAtlasUpdateNewFrame()
|
||||||
// - ImFontAtlasTextureBlockConvert()
|
// - ImFontAtlasTextureBlockConvert()
|
||||||
@@ -2535,8 +2563,6 @@ void ImTextureData::DestroyPixels()
|
|||||||
// - ImFontAtlasBuildPreloadAllGlyphRanges()
|
// - ImFontAtlasBuildPreloadAllGlyphRanges()
|
||||||
// - ImFontAtlasBuildUpdatePointers()
|
// - ImFontAtlasBuildUpdatePointers()
|
||||||
// - ImFontAtlasBuildRenderBitmapFromString()
|
// - ImFontAtlasBuildRenderBitmapFromString()
|
||||||
// - ImFontAtlasBuildUpdateBasicTexData()
|
|
||||||
// - ImFontAtlasBuildUpdateLinesTexData()
|
|
||||||
// - ImFontAtlasBuildAddFont()
|
// - ImFontAtlasBuildAddFont()
|
||||||
// - ImFontAtlasBuildSetupFontBakedEllipsis()
|
// - ImFontAtlasBuildSetupFontBakedEllipsis()
|
||||||
// - ImFontAtlasBuildSetupFontBakedBlanks()
|
// - ImFontAtlasBuildSetupFontBakedBlanks()
|
||||||
@@ -2553,13 +2579,14 @@ void ImTextureData::DestroyPixels()
|
|||||||
// - ImFontAtlasUpdateDrawListsSharedData()
|
// - ImFontAtlasUpdateDrawListsSharedData()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// - ImFontAtlasBuildSetTexture()
|
// - ImFontAtlasBuildSetTexture()
|
||||||
// - ImFontAtlasBuildAddTexture()
|
// - ImFontAtlasBuildUpdateTexData()
|
||||||
// - ImFontAtlasBuildMakeSpace()
|
// - ImFontAtlasTextureAdd()
|
||||||
// - ImFontAtlasBuildRepackTexture()
|
// - ImFontAtlasTextureRepack()
|
||||||
// - ImFontAtlasBuildGrowTexture()
|
// - ImFontAtlasTextureGrow()
|
||||||
// - ImFontAtlasBuildRepackOrGrowTexture()
|
// - ImFontAtlasTextureMakeSpace()
|
||||||
// - ImFontAtlasBuildGetTextureSizeEstimate()
|
// - ImFontAtlasTextureGetSizeEstimate()
|
||||||
// - ImFontAtlasBuildCompactTexture()
|
// - ImFontAtlasBuildClear()
|
||||||
|
// - ImFontAtlasTextureCompact()
|
||||||
// - ImFontAtlasBuildInit()
|
// - ImFontAtlasBuildInit()
|
||||||
// - ImFontAtlasBuildDestroy()
|
// - ImFontAtlasBuildDestroy()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -2659,7 +2686,9 @@ ImFontAtlas::~ImFontAtlas()
|
|||||||
TexData = NULL;
|
TexData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you call this mid-frame, you would need to add new font and bind them!
|
// You probably should not call this directly. It is not well specified.
|
||||||
|
// If you want to replace all your fonts mid-frame, most likely you should instead call ClearFonts() then load the new fonts.
|
||||||
|
// Calling this mid-frame will discard the CPU-side copy of the texture data which is generally unreliable as you may have textures queued for creation or updates.
|
||||||
void ImFontAtlas::Clear()
|
void ImFontAtlas::Clear()
|
||||||
{
|
{
|
||||||
bool backup_renderer_has_textures = RendererHasTextures;
|
bool backup_renderer_has_textures = RendererHasTextures;
|
||||||
@@ -2669,20 +2698,27 @@ void ImFontAtlas::Clear()
|
|||||||
RendererHasTextures = backup_renderer_has_textures;
|
RendererHasTextures = backup_renderer_has_textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlas::CompactCache()
|
void ImFontAtlas::ClearFonts()
|
||||||
{
|
{
|
||||||
ImFontAtlasTextureCompact(this);
|
// FIXME-NEWATLAS: Illegal to remove currently bound font.
|
||||||
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||||
|
for (ImFont* font : Fonts)
|
||||||
|
ImFontAtlasBuildNotifySetFont(this, font, NULL);
|
||||||
|
ImFontAtlasBuildDestroy(this);
|
||||||
|
ClearInputData();
|
||||||
|
Fonts.clear_delete();
|
||||||
|
TexIsBuilt = false;
|
||||||
|
for (ImDrawListSharedData* shared_data : DrawListSharedDatas)
|
||||||
|
if (shared_data->FontAtlas == this)
|
||||||
|
{
|
||||||
|
shared_data->Font = NULL;
|
||||||
|
shared_data->FontScale = shared_data->FontSize = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlas::SetFontLoader(const ImFontLoader* font_loader)
|
|
||||||
{
|
|
||||||
ImFontAtlasBuildSetupFontLoader(this, font_loader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlas::ClearInputData()
|
void ImFontAtlas::ClearInputData()
|
||||||
{
|
{
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||||
|
|
||||||
for (ImFont* font : Fonts)
|
for (ImFont* font : Fonts)
|
||||||
ImFontAtlasFontDestroyOutput(this, font);
|
ImFontAtlasFontDestroyOutput(this, font);
|
||||||
for (ImFontConfig& font_cfg : Sources)
|
for (ImFontConfig& font_cfg : Sources)
|
||||||
@@ -2706,22 +2742,14 @@ void ImFontAtlas::ClearTexData()
|
|||||||
//Locked = true; // Hoped to be able to lock this down but some reload patterns may not be happy with it.
|
//Locked = true; // Hoped to be able to lock this down but some reload patterns may not be happy with it.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlas::ClearFonts()
|
void ImFontAtlas::CompactCache()
|
||||||
{
|
{
|
||||||
// FIXME-NEWATLAS: Illegal to remove currently bound font.
|
ImFontAtlasTextureCompact(this);
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
|
||||||
for (ImFont* font : Fonts)
|
|
||||||
ImFontAtlasBuildNotifySetFont(this, font, NULL);
|
|
||||||
ImFontAtlasBuildDestroy(this);
|
|
||||||
ClearInputData();
|
|
||||||
Fonts.clear_delete();
|
|
||||||
TexIsBuilt = false;
|
|
||||||
for (ImDrawListSharedData* shared_data : DrawListSharedDatas)
|
|
||||||
if (shared_data->FontAtlas == this)
|
|
||||||
{
|
|
||||||
shared_data->Font = NULL;
|
|
||||||
shared_data->FontScale = shared_data->FontSize = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImFontAtlas::SetFontLoader(const ImFontLoader* font_loader)
|
||||||
|
{
|
||||||
|
ImFontAtlasBuildSetupFontLoader(this, font_loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas)
|
static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas)
|
||||||
@@ -2791,7 +2819,25 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
|||||||
// Update texture status
|
// Update texture status
|
||||||
for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
|
for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
|
||||||
{
|
{
|
||||||
|
// Update and remove if requested
|
||||||
ImTextureData* tex = atlas->TexList[tex_n];
|
ImTextureData* tex = atlas->TexList[tex_n];
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
|
||||||
|
|
||||||
|
bool remove_from_list = ImTextureDataUpdateNewFrame(tex);
|
||||||
|
if (remove_from_list)
|
||||||
|
{
|
||||||
|
IM_ASSERT(atlas->TexData != tex);
|
||||||
|
tex->DestroyPixels();
|
||||||
|
IM_DELETE(tex);
|
||||||
|
atlas->TexList.erase(atlas->TexList.begin() + tex_n);
|
||||||
|
tex_n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImTextureDataUpdateNewFrame(ImTextureData* tex)
|
||||||
|
{
|
||||||
bool remove_from_list = false;
|
bool remove_from_list = false;
|
||||||
if (tex->Status == ImTextureStatus_OK)
|
if (tex->Status == ImTextureStatus_OK)
|
||||||
{
|
{
|
||||||
@@ -2799,8 +2845,6 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
|||||||
tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0;
|
tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0;
|
||||||
tex->UpdateRect.w = tex->UpdateRect.h = 0;
|
tex->UpdateRect.w = tex->UpdateRect.h = 0;
|
||||||
}
|
}
|
||||||
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
|
|
||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
|
|
||||||
|
|
||||||
// Request destroy
|
// Request destroy
|
||||||
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
||||||
@@ -2832,16 +2876,7 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
|||||||
if (tex->Status == ImTextureStatus_WantDestroy)
|
if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
tex->UnusedFrames++;
|
tex->UnusedFrames++;
|
||||||
|
|
||||||
// Destroy and remove
|
return remove_from_list;
|
||||||
if (remove_from_list)
|
|
||||||
{
|
|
||||||
IM_ASSERT(atlas->TexData != tex);
|
|
||||||
tex->DestroyPixels();
|
|
||||||
IM_DELETE(tex);
|
|
||||||
atlas->TexList.erase(atlas->TexList.begin() + tex_n);
|
|
||||||
tex_n--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h)
|
void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h)
|
||||||
@@ -2955,12 +2990,17 @@ void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, I
|
|||||||
memcpy(dst_tex->GetPixelsAt(dst_x, dst_y + y), src_tex->GetPixelsAt(src_x, src_y + y), w * dst_tex->BytesPerPixel);
|
memcpy(dst_tex->GetPixelsAt(dst_x, dst_y + y), src_tex->GetPixelsAt(src_x, src_y + y), w * dst_tex->BytesPerPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue texture block update for renderer backend
|
|
||||||
void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h)
|
void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
ImTextureDataQueueUpload(tex, x, y, w, h);
|
||||||
|
atlas->TexIsBuilt = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue texture block update for renderer backend
|
||||||
|
void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
IM_ASSERT(tex->Status != ImTextureStatus_WantDestroy && tex->Status != ImTextureStatus_Destroyed);
|
IM_ASSERT(tex->Status != ImTextureStatus_WantDestroy && tex->Status != ImTextureStatus_Destroyed);
|
||||||
IM_ASSERT(x >= 0 && x <= 0xFFFF && y >= 0 && y <= 0xFFFF && w >= 0 && x + w <= 0x10000 && h >= 0 && y + h <= 0x10000);
|
IM_ASSERT(x >= 0 && x <= 0xFFFF && y >= 0 && y <= 0xFFFF && w >= 0 && x + w <= 0x10000 && h >= 0 && y + h <= 0x10000);
|
||||||
IM_UNUSED(atlas);
|
|
||||||
|
|
||||||
ImTextureRect req = { (unsigned short)x, (unsigned short)y, (unsigned short)w, (unsigned short)h };
|
ImTextureRect req = { (unsigned short)x, (unsigned short)y, (unsigned short)w, (unsigned short)h };
|
||||||
int new_x1 = ImMax(tex->UpdateRect.w == 0 ? 0 : tex->UpdateRect.x + tex->UpdateRect.w, req.x + req.w);
|
int new_x1 = ImMax(tex->UpdateRect.w == 0 ? 0 : tex->UpdateRect.x + tex->UpdateRect.w, req.x + req.w);
|
||||||
@@ -2973,7 +3013,6 @@ void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex,
|
|||||||
tex->UsedRect.y = ImMin(tex->UsedRect.y, req.y);
|
tex->UsedRect.y = ImMin(tex->UsedRect.y, req.y);
|
||||||
tex->UsedRect.w = (unsigned short)(ImMax(tex->UsedRect.x + tex->UsedRect.w, req.x + req.w) - tex->UsedRect.x);
|
tex->UsedRect.w = (unsigned short)(ImMax(tex->UsedRect.x + tex->UsedRect.w, req.x + req.w) - tex->UsedRect.x);
|
||||||
tex->UsedRect.h = (unsigned short)(ImMax(tex->UsedRect.y + tex->UsedRect.h, req.y + req.h) - tex->UsedRect.y);
|
tex->UsedRect.h = (unsigned short)(ImMax(tex->UsedRect.y + tex->UsedRect.h, req.y + req.h) - tex->UsedRect.y);
|
||||||
atlas->TexIsBuilt = false;
|
|
||||||
|
|
||||||
// No need to queue if status is == ImTextureStatus_WantCreate
|
// No need to queue if status is == ImTextureStatus_WantCreate
|
||||||
if (tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantUpdates)
|
if (tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantUpdates)
|
||||||
@@ -3113,8 +3152,10 @@ static void Decode85(const unsigned char* src, unsigned char* dst)
|
|||||||
dst += 4;
|
dst += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP)
|
||||||
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size);
|
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size);
|
||||||
|
#endif
|
||||||
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR)
|
||||||
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size);
|
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3139,7 +3180,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg)
|
|||||||
// If you want a similar font which may be better scaled, consider using AddFontDefaultVector().
|
// If you want a similar font which may be better scaled, consider using AddFontDefaultVector().
|
||||||
ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template)
|
ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template)
|
||||||
{
|
{
|
||||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP)
|
||||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||||
if (!font_cfg_template)
|
if (!font_cfg_template)
|
||||||
font_cfg.PixelSnapH = true; // Prevents sub-integer scaling factors at lower-level layers.
|
font_cfg.PixelSnapH = true; // Prevents sub-integer scaling factors at lower-level layers.
|
||||||
@@ -3160,14 +3201,14 @@ ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template)
|
|||||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||||
IM_UNUSED(font_cfg_template);
|
IM_UNUSED(font_cfg_template);
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a minimal version of ProggyForever, designed to match our good old ProggyClean, but nicely scalable.
|
// Load a minimal version of ProggyForever, designed to match our good old ProggyClean, but nicely scalable.
|
||||||
// (See build script in https://github.com/ocornut/proggyforever for details)
|
// (See build script in https://github.com/ocornut/proggyforever for details)
|
||||||
ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template)
|
ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template)
|
||||||
{
|
{
|
||||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR)
|
||||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||||
if (!font_cfg_template)
|
if (!font_cfg_template)
|
||||||
font_cfg.PixelSnapH = true; // Precisely match ProggyClean, but prevents sub-integer scaling factors at lower-level layers.
|
font_cfg.PixelSnapH = true; // Precisely match ProggyClean, but prevents sub-integer scaling factors at lower-level layers.
|
||||||
@@ -3188,7 +3229,7 @@ ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template)
|
|||||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||||
IM_UNUSED(font_cfg_template);
|
IM_UNUSED(font_cfg_template);
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
|
ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
|
||||||
@@ -3544,7 +3585,7 @@ void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImFontAtlasBuildUpdateBasicTexData(ImFontAtlas* atlas)
|
static void ImFontAtlasBuildUpdateTexDataBasic(ImFontAtlas* atlas)
|
||||||
{
|
{
|
||||||
// Pack and store identifier so we can refresh UV coordinates on texture resize.
|
// Pack and store identifier so we can refresh UV coordinates on texture resize.
|
||||||
// FIXME-NEWATLAS: User/custom rects where user code wants to store UV coordinates will need to do the same thing.
|
// FIXME-NEWATLAS: User/custom rects where user code wants to store UV coordinates will need to do the same thing.
|
||||||
@@ -3578,7 +3619,7 @@ static void ImFontAtlasBuildUpdateBasicTexData(ImFontAtlas* atlas)
|
|||||||
atlas->TexUvWhitePixel = ImVec2((r.x + 0.5f) * atlas->TexUvScale.x, (r.y + 0.5f) * atlas->TexUvScale.y);
|
atlas->TexUvWhitePixel = ImVec2((r.x + 0.5f) * atlas->TexUvScale.x, (r.y + 0.5f) * atlas->TexUvScale.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas)
|
static void ImFontAtlasBuildUpdateTexDataLines(ImFontAtlas* atlas)
|
||||||
{
|
{
|
||||||
if (atlas->Flags & ImFontAtlasFlags_NoBakedLines)
|
if (atlas->Flags & ImFontAtlasFlags_NoBakedLines)
|
||||||
return;
|
return;
|
||||||
@@ -4027,6 +4068,12 @@ static void ImFontAtlasBuildSetTexture(ImFontAtlas* atlas, ImTextureData* tex)
|
|||||||
ImFontAtlasUpdateDrawListsTextures(atlas, old_tex_ref, atlas->TexRef);
|
ImFontAtlasUpdateDrawListsTextures(atlas, old_tex_ref, atlas->TexRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImFontAtlasBuildUpdateTexData(ImFontAtlas* atlas)
|
||||||
|
{
|
||||||
|
ImFontAtlasBuildUpdateTexDataBasic(atlas);
|
||||||
|
ImFontAtlasBuildUpdateTexDataLines(atlas);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new texture, discard previous one
|
// Create a new texture, discard previous one
|
||||||
ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h)
|
ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h)
|
||||||
{
|
{
|
||||||
@@ -4141,8 +4188,7 @@ void ImFontAtlasTextureRepack(ImFontAtlas* atlas, int w, int h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update other cached UV
|
// Update other cached UV
|
||||||
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
ImFontAtlasBuildUpdateTexData(atlas);
|
||||||
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
|
||||||
|
|
||||||
builder->LockDisableResize = false;
|
builder->LockDisableResize = false;
|
||||||
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
||||||
@@ -4291,8 +4337,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
|||||||
ImFontAtlasPackInit(atlas);
|
ImFontAtlasPackInit(atlas);
|
||||||
|
|
||||||
// Add required texture data
|
// Add required texture data
|
||||||
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
ImFontAtlasBuildUpdateTexData(atlas);
|
||||||
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
|
||||||
|
|
||||||
// Register fonts
|
// Register fonts
|
||||||
ImFontAtlasBuildUpdatePointers(atlas);
|
ImFontAtlasBuildUpdatePointers(atlas);
|
||||||
@@ -4321,6 +4366,8 @@ void ImFontAtlasBuildDestroy(ImFontAtlas* atlas)
|
|||||||
atlas->Builder = NULL;
|
atlas->Builder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImFontAtlasPackInit(ImFontAtlas * atlas)
|
void ImFontAtlasPackInit(ImFontAtlas * atlas)
|
||||||
{
|
{
|
||||||
ImTextureData* tex = atlas->TexData;
|
ImTextureData* tex = atlas->TexData;
|
||||||
@@ -5717,8 +5764,13 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
|||||||
if (glyph->Colored)
|
if (glyph->Colored)
|
||||||
col |= ~IM_COL32_A_MASK;
|
col |= ~IM_COL32_A_MASK;
|
||||||
float scale = (size >= 0.0f) ? (size / baked->Size) : 1.0f;
|
float scale = (size >= 0.0f) ? (size / baked->Size) : 1.0f;
|
||||||
float x = IM_TRUNC(pos.x);
|
float x = pos.x;
|
||||||
float y = IM_TRUNC(pos.y);
|
float y = pos.y;
|
||||||
|
if ((draw_list->Flags & ImDrawListFlags_TextNoPixelSnap) == 0)
|
||||||
|
{
|
||||||
|
x = IM_TRUNC(x);
|
||||||
|
y = IM_TRUNC(y);
|
||||||
|
}
|
||||||
|
|
||||||
float x1 = x + glyph->X0 * scale;
|
float x1 = x + glyph->X0 * scale;
|
||||||
float x2 = x + glyph->X1 * scale;
|
float x2 = x + glyph->X1 * scale;
|
||||||
@@ -5750,12 +5802,17 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
|||||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText().
|
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText().
|
||||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||||
{
|
{
|
||||||
// Align to be pixel perfect
|
|
||||||
begin:
|
begin:
|
||||||
float x = IM_TRUNC(pos.x);
|
// Align to be pixel perfect
|
||||||
float y = IM_TRUNC(pos.y);
|
float x = pos.x;
|
||||||
|
float y = pos.y;
|
||||||
if (y > clip_rect.w)
|
if (y > clip_rect.w)
|
||||||
return;
|
return;
|
||||||
|
if ((draw_list->Flags & ImDrawListFlags_TextNoPixelSnap) == 0)
|
||||||
|
{
|
||||||
|
x = IM_TRUNC(x);
|
||||||
|
y = IM_TRUNC(y);
|
||||||
|
}
|
||||||
|
|
||||||
if (!text_end)
|
if (!text_end)
|
||||||
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||||
@@ -6019,7 +6076,7 @@ void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float
|
|||||||
draw_list->PathLineTo(ImVec2(bx - third, by - third));
|
draw_list->PathLineTo(ImVec2(bx - third, by - third));
|
||||||
draw_list->PathLineTo(ImVec2(bx, by));
|
draw_list->PathLineTo(ImVec2(bx, by));
|
||||||
draw_list->PathLineTo(ImVec2(bx + third * 2.0f, by - third * 2.0f));
|
draw_list->PathLineTo(ImVec2(bx + third * 2.0f, by - third * 2.0f));
|
||||||
draw_list->PathStroke(col, 0, thickness);
|
draw_list->PathStroke(col, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
|
// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
|
||||||
@@ -6141,8 +6198,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p
|
|||||||
flags = ImDrawFlags_RoundCornersDefault_;
|
flags = ImDrawFlags_RoundCornersDefault_;
|
||||||
if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF)
|
if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF)
|
||||||
{
|
{
|
||||||
ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col));
|
ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col));
|
||||||
ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col));
|
ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col));
|
||||||
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
|
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
|
||||||
|
|
||||||
int yi = 0;
|
int yi = 0;
|
||||||
@@ -6151,12 +6208,12 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p
|
|||||||
float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y);
|
float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y);
|
||||||
if (y2 <= y1)
|
if (y2 <= y1)
|
||||||
continue;
|
continue;
|
||||||
for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f)
|
for (float x = p_min.x + grid_off.x + ((yi ^ 1) & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f)
|
||||||
{
|
{
|
||||||
float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x);
|
float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x);
|
||||||
if (x2 <= x1)
|
if (x2 <= x1)
|
||||||
continue;
|
continue;
|
||||||
ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone;
|
ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; // FIXME: Could use CalcRoundingFlagsForRectInRect()
|
||||||
if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; }
|
if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; }
|
||||||
if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; }
|
if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; }
|
||||||
|
|
||||||
@@ -6298,7 +6355,7 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
|||||||
// Download and more information at https://github.com/bluescan/proggyfonts
|
// Download and more information at https://github.com/bluescan/proggyfonts
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP)
|
||||||
|
|
||||||
// File: 'ProggyClean.ttf' (41208 bytes)
|
// File: 'ProggyClean.ttf' (41208 bytes)
|
||||||
// Exported using binary_to_compressed_c.exe -u8 "ProggyClean.ttf" proggy_clean_ttf
|
// Exported using binary_to_compressed_c.exe -u8 "ProggyClean.ttf" proggy_clean_ttf
|
||||||
@@ -6478,6 +6535,7 @@ static const char* GetDefaultCompressedFontDataProggyClean(int* out_size)
|
|||||||
*out_size = proggy_clean_ttf_compressed_size;
|
*out_size = proggy_clean_ttf_compressed_size;
|
||||||
return (const char*)proggy_clean_ttf_compressed_data;
|
return (const char*)proggy_clean_ttf_compressed_data;
|
||||||
}
|
}
|
||||||
|
#endif // #if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Default font data (ProggyForever-Regular-minimal.ttf)
|
// [SECTION] Default font data (ProggyForever-Regular-minimal.ttf)
|
||||||
@@ -6486,6 +6544,8 @@ static const char* GetDefaultCompressedFontDataProggyClean(int* out_size)
|
|||||||
// MIT license / Copyright (c) 2026 Disco Hello, Copyright (c) 2019,2023 Tristan Grimmer
|
// MIT license / Copyright (c) 2026 Disco Hello, Copyright (c) 2019,2023 Tristan Grimmer
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR)
|
||||||
|
|
||||||
// File: 'output/ProggyForever-Regular-minimal.ttf' (18556 bytes)
|
// File: 'output/ProggyForever-Regular-minimal.ttf' (18556 bytes)
|
||||||
// Exported using binary_to_compressed_c.exe -u8 "output/ProggyForever-Regular-minimal.ttf" proggy_forever_minimal_ttf
|
// Exported using binary_to_compressed_c.exe -u8 "output/ProggyForever-Regular-minimal.ttf" proggy_forever_minimal_ttf
|
||||||
static const unsigned int proggy_forever_minimal_ttf_compressed_size = 14562;
|
static const unsigned int proggy_forever_minimal_ttf_compressed_size = 14562;
|
||||||
@@ -6740,7 +6800,6 @@ static const char* GetDefaultCompressedFontDataProggyForever(int* out_size)
|
|||||||
*out_size = proggy_forever_minimal_ttf_compressed_size;
|
*out_size = proggy_forever_minimal_ttf_compressed_size;
|
||||||
return (const char*)proggy_forever_minimal_ttf_compressed_data;
|
return (const char*)proggy_forever_minimal_ttf_compressed_data;
|
||||||
}
|
}
|
||||||
|
#endif // #if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR)
|
||||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
+11
-4
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (internal structures/api)
|
// (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.
|
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||||
@@ -531,6 +531,7 @@ inline float ImFloor(float f) { return
|
|||||||
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||||
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only.
|
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only.
|
||||||
|
inline float ImCeilFast(float f) { int i = (int)f; return (float)(i + (f > (float)i)); } // Consider using the the bit-hack version (search for "0x1p120f").
|
||||||
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||||
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||||
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||||
@@ -1005,6 +1006,7 @@ enum ImGuiItemStatusFlags_
|
|||||||
ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid.
|
ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid.
|
||||||
ImGuiItemStatusFlags_HasShortcut = 1 << 10, // g.LastItemData.Shortcut valid. Set by SetNextItemShortcut() -> ItemAdd().
|
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_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
|
// Additional status + semantic for ImGuiTestEngine
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
@@ -1210,6 +1212,7 @@ struct IMGUI_API ImGuiMenuColumns
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Internal temporary state for deactivating InputText() instances.
|
// Internal temporary state for deactivating InputText() instances.
|
||||||
|
// Store as part of ImGuiDeactivatedItemData?
|
||||||
struct IMGUI_API ImGuiInputTextDeactivatedState
|
struct IMGUI_API ImGuiInputTextDeactivatedState
|
||||||
{
|
{
|
||||||
ImGuiID ID; // widget id owning the text state (which just got deactivated)
|
ImGuiID ID; // widget id owning the text state (which just got deactivated)
|
||||||
@@ -1455,6 +1458,7 @@ struct ImGuiPtrOrIndex
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
|
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
|
||||||
|
// Also see ImGuiInputTextDeactivatedState which is an extension for this for InputText()
|
||||||
struct ImGuiDeactivatedItemData
|
struct ImGuiDeactivatedItemData
|
||||||
{
|
{
|
||||||
ImGuiID ID;
|
ImGuiID ID;
|
||||||
@@ -1699,6 +1703,7 @@ enum ImGuiActivateFlags_
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Early work-in-progress API for ScrollToItem()
|
// Early work-in-progress API for ScrollToItem()
|
||||||
|
// FIXME: Missing flags to request making both edges visible when possible.
|
||||||
enum ImGuiScrollFlags_
|
enum ImGuiScrollFlags_
|
||||||
{
|
{
|
||||||
ImGuiScrollFlags_None = 0,
|
ImGuiScrollFlags_None = 0,
|
||||||
@@ -3214,7 +3219,7 @@ namespace ImGui
|
|||||||
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
||||||
|
|
||||||
// Fonts, drawing
|
// 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 UnregisterUserTexture(ImTextureData* tex);
|
||||||
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
|
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
|
||||||
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
|
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
|
||||||
@@ -3435,7 +3440,7 @@ namespace ImGui
|
|||||||
IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key);
|
IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key);
|
||||||
IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0);
|
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 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'
|
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]; }
|
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 +3498,7 @@ namespace ImGui
|
|||||||
IMGUI_API void ClearDragDrop();
|
IMGUI_API void ClearDragDrop();
|
||||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||||
IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);
|
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
|
// Typing-Select API
|
||||||
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
|
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
|
||||||
@@ -3976,6 +3981,8 @@ 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 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 ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
IMGUI_API bool ImTextureDataUpdateNewFrame(ImTextureData* tex);
|
||||||
|
IMGUI_API void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h);
|
||||||
IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format);
|
IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format);
|
||||||
IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status);
|
IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status);
|
||||||
IMGUI_API const char* ImTextureDataGetFormatName(ImTextureFormat format);
|
IMGUI_API const char* ImTextureDataGetFormatName(ImTextureFormat format);
|
||||||
|
|||||||
+11
-11
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (tables and columns code)
|
// (tables and columns code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2074,11 +2074,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
|
|
||||||
// Draw top border
|
// Draw top border
|
||||||
if (top_border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y)
|
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)
|
// 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)
|
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)
|
// 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)
|
else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0)
|
||||||
draw_y2 = draw_y2_body;
|
draw_y2 = draw_y2_body;
|
||||||
if (draw_y2 > draw_y1)
|
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;
|
const ImU32 outer_col = table->BorderColorStrong;
|
||||||
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
|
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)
|
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->AddLineV(outer_border.Min.x, outer_border.Min.y, 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.Max.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
|
||||||
}
|
}
|
||||||
else if (table->Flags & ImGuiTableFlags_BordersOuterH)
|
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->AddLineH(outer_border.Min.x, 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.Max.y, outer_col, border_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y)
|
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.
|
// Draw bottom-most row border between it is above outer border.
|
||||||
const float border_y = table->RowPosY2;
|
const float border_y = table->RowPosY2;
|
||||||
if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y)
|
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();
|
inner_drawlist->PopClipRect();
|
||||||
@@ -4618,7 +4618,7 @@ void ImGui::EndColumns()
|
|||||||
// Draw column
|
// Draw column
|
||||||
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
|
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
|
||||||
const float xi = IM_TRUNC(x);
|
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.
|
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.
|
||||||
|
|||||||
+78
-36
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.92.8 WIP
|
// dear imgui, v1.92.9 WIP
|
||||||
// (widgets code)
|
// (widgets code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -266,6 +266,8 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that all functions taking format strings in the API may be passed ("%s", text) or ("%.*s", text_len, text),
|
||||||
|
// which will automatically bypass the formatter.
|
||||||
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
||||||
{
|
{
|
||||||
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||||
@@ -1151,7 +1153,7 @@ void ImGui::ImageWithBg(ImTextureRef tex_ref, const ImVec2& image_size, const Im
|
|||||||
else
|
else
|
||||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||||
if (g.Style.ImageBorderSize > 0.0f)
|
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)
|
void ImGui::Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
|
||||||
@@ -1288,8 +1290,9 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
|||||||
if (is_visible)
|
if (is_visible)
|
||||||
{
|
{
|
||||||
RenderNavCursor(total_bb, id);
|
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);
|
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
RenderFrame(check_bb.Min, check_bb.Max, bg_col, true, style.FrameRounding);
|
||||||
if (mixed_value)
|
if (mixed_value)
|
||||||
{
|
{
|
||||||
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
||||||
@@ -1556,7 +1559,7 @@ bool ImGui::TextLink(const char* label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontBakedScale * 0.20f);
|
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));
|
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
|
||||||
RenderText(bb.Min, label, label_end, false);
|
RenderText(bb.Min, label, label_end, false);
|
||||||
@@ -1745,14 +1748,14 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
|||||||
const float separator_thickness = style.SeparatorTextBorderSize;
|
const float separator_thickness = style.SeparatorTextBorderSize;
|
||||||
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
|
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
|
||||||
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
|
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
|
||||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
|
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||||
ItemSize(min_size, text_baseline_y);
|
ItemSize(min_size, text_baseline_y);
|
||||||
if (!ItemAdd(bb, id))
|
if (!ItemAdd(bb, id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const float sep1_x1 = pos.x;
|
const float sep1_x1 = pos.x;
|
||||||
const float sep2_x2 = bb.Max.x;
|
const float sep2_x2 = bb.Max.x;
|
||||||
const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f);
|
const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.999f);
|
||||||
|
|
||||||
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f);
|
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f);
|
||||||
const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN
|
const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN
|
||||||
@@ -1766,9 +1769,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 sep1_x2 = label_pos.x - style.ItemSpacing.x;
|
||||||
const float sep2_x1 = label_pos.x + label_size.x + extra_w + 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)
|
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)
|
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)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("---", NULL);
|
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);
|
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 +1781,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
|||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogText("---");
|
LogText("---");
|
||||||
if (separator_thickness > 0.0f)
|
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 +2378,17 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void
|
|||||||
|
|
||||||
// Sanitize format
|
// 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
|
// - 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];
|
char format_sanitized[32];
|
||||||
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
|
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
|
||||||
|
{
|
||||||
format = type_info->ScanFmt;
|
format = type_info->ScanFmt;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized));
|
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()
|
// Small types need a 32-bit buffer to receive the result from scanf()
|
||||||
int v32 = 0;
|
int v32 = 0;
|
||||||
@@ -3566,7 +3574,8 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min,
|
|||||||
// - ImParseFormatSanitizeForPrinting() [Internal]
|
// - ImParseFormatSanitizeForPrinting() [Internal]
|
||||||
// - ImParseFormatSanitizeForScanning() [Internal]
|
// - ImParseFormatSanitizeForScanning() [Internal]
|
||||||
// - ImParseFormatPrecision() [Internal]
|
// - ImParseFormatPrecision() [Internal]
|
||||||
// - TempInputTextScalar() [Internal]
|
// - TempInputText() [Internal]
|
||||||
|
// - TempInputScalar() [Internal]
|
||||||
// - InputScalar()
|
// - InputScalar()
|
||||||
// - InputScalarN()
|
// - InputScalarN()
|
||||||
// - InputFloat()
|
// - InputFloat()
|
||||||
@@ -3795,7 +3804,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiStyle& style = g.Style;
|
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)
|
if (format == NULL)
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||||
@@ -3832,7 +3841,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply
|
// 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
|
// Step buttons
|
||||||
if (has_step_buttons)
|
if (has_step_buttons)
|
||||||
@@ -3846,13 +3856,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|||||||
if (ButtonEx("-", ImVec2(button_size, button_size)))
|
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);
|
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);
|
SameLine(0, style.ItemInnerSpacing.x);
|
||||||
if (ButtonEx("+", ImVec2(button_size, button_size)))
|
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);
|
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();
|
PopItemFlag();
|
||||||
if (flags & ImGuiInputTextFlags_ReadOnly)
|
if (flags & ImGuiInputTextFlags_ReadOnly)
|
||||||
@@ -3874,6 +3884,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|||||||
if (value_changed)
|
if (value_changed)
|
||||||
MarkItemEdited(g.LastItemData.ID);
|
MarkItemEdited(g.LastItemData.ID);
|
||||||
|
|
||||||
|
if (flags & ImGuiInputTextFlags_EnterReturnsTrue)
|
||||||
|
return ret;
|
||||||
return value_changed;
|
return value_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4574,6 +4586,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
|
|||||||
ImGuiInputTextState* state = &g.InputTextState;
|
ImGuiInputTextState* state = &g.InputTextState;
|
||||||
if (id == 0 || state->ID != id)
|
if (id == 0 || state->ID != id)
|
||||||
return;
|
return;
|
||||||
|
//IMGUI_DEBUG_LOG_ACTIVEID("InputTextDeactivateHook() id = 0x%08X\n", id);
|
||||||
g.InputTextDeactivatedState.ID = state->ID;
|
g.InputTextDeactivatedState.ID = state->ID;
|
||||||
if (state->Flags & ImGuiInputTextFlags_ReadOnly)
|
if (state->Flags & ImGuiInputTextFlags_ReadOnly)
|
||||||
{
|
{
|
||||||
@@ -4889,7 +4902,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool is_osx = io.ConfigMacOSXBehaviors;
|
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);
|
IM_ASSERT(state && state->ID == id);
|
||||||
SetActiveID(id, window);
|
SetActiveID(id, window);
|
||||||
@@ -5630,7 +5643,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);
|
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);
|
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))
|
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), style.InputTextCursorSize);
|
||||||
|
|
||||||
// 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.)
|
// 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.
|
// This is required for some backends (SDL3) to start emitting character/text inputs.
|
||||||
@@ -6344,7 +6357,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 float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps;
|
||||||
const int vert_start_idx = draw_list->VtxBuffer.Size;
|
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->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;
|
const int vert_end_idx = draw_list->VtxBuffer.Size;
|
||||||
|
|
||||||
// Paint colors over existing vertices
|
// Paint colors over existing vertices
|
||||||
@@ -6488,7 +6501,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||||||
if (g.Style.FrameBorderSize > 0.0f)
|
if (g.Style.FrameBorderSize > 0.0f)
|
||||||
RenderFrameBorder(bb.Min, bb.Max, rounding);
|
RenderFrameBorder(bb.Min, bb.Max, rounding);
|
||||||
else
|
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
|
// Drag and Drop Source
|
||||||
@@ -7161,11 +7174,11 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
|
|||||||
window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3);
|
window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3);
|
||||||
if (x1 < x2)
|
if (x1 < x2)
|
||||||
window->DrawList->PathLineTo(ImVec2(x2, y));
|
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
|
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 +7204,7 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data)
|
|||||||
float x = ImTrunc(data->DrawLinesX1);
|
float x = ImTrunc(data->DrawLinesX1);
|
||||||
if (data->DrawLinesTableColumn != -1)
|
if (data->DrawLinesTableColumn != -1)
|
||||||
TablePushColumnChannel(data->DrawLinesTableColumn);
|
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)
|
if (data->DrawLinesTableColumn != -1)
|
||||||
TablePopColumnChannel();
|
TablePopColumnChannel();
|
||||||
}
|
}
|
||||||
@@ -8364,12 +8377,24 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
if (ImGuiTable* table = g.CurrentTable)
|
if (ImGuiTable* table = g.CurrentTable)
|
||||||
if (table->CurrentColumn != -1)
|
if (table->CurrentColumn != -1)
|
||||||
{
|
{
|
||||||
// FIXME: We cannot use current ClipRect as it includes HostClipRect.
|
// FIXME: We cannot solely use current ClipRect as it includes HostClipRect.
|
||||||
// A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994)
|
// 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];
|
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
||||||
|
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.Min.x = ImMax(item_rect.Min.x, column->MinX);
|
||||||
item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX);
|
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_curr = bs->BoxSelectRectCurr.Overlaps(item_rect);
|
||||||
const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect);
|
const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect);
|
||||||
if ((rect_overlap_curr && !rect_overlap_prev && !selected) || (rect_overlap_prev && !rect_overlap_curr))
|
if ((rect_overlap_curr && !rect_overlap_prev && !selected) || (rect_overlap_prev && !rect_overlap_curr))
|
||||||
@@ -8927,7 +8952,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
|||||||
// Tooltip on hover
|
// Tooltip on hover
|
||||||
if (hovered && inner_bb.Contains(g.IO.MousePos))
|
if (hovered && inner_bb.Contains(g.IO.MousePos))
|
||||||
{
|
{
|
||||||
const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f);
|
const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.999f);
|
||||||
const int v_idx = (int)(t * item_count);
|
const int v_idx = (int)(t * item_count);
|
||||||
IM_ASSERT(v_idx >= 0 && v_idx < values_count);
|
IM_ASSERT(v_idx >= 0 && v_idx < values_count);
|
||||||
|
|
||||||
@@ -9370,8 +9395,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
|||||||
|
|
||||||
bool pressed;
|
bool pressed;
|
||||||
|
|
||||||
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
|
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoAutoClosePopups | (ImGuiSelectableFlags)ImGuiSelectableFlags_SelectOnClick;
|
||||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups;
|
|
||||||
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||||
{
|
{
|
||||||
@@ -9409,6 +9433,14 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
|||||||
if (!enabled)
|
if (!enabled)
|
||||||
EndDisabled();
|
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;
|
const bool hovered = (g.HoveredId == id) && enabled && !g.NavHighlightItemUnderNav;
|
||||||
if (menuset_is_open)
|
if (menuset_is_open)
|
||||||
PopItemFlag();
|
PopItemFlag();
|
||||||
@@ -9489,6 +9521,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));
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
|
if (g.ActiveId == id && want_open)
|
||||||
|
g.ActiveIdNoClearOnFocusLoss = true;
|
||||||
|
|
||||||
if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
|
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.
|
// 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 +9616,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
|||||||
BeginDisabled();
|
BeginDisabled();
|
||||||
|
|
||||||
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
|
// 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;
|
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||||
{
|
{
|
||||||
@@ -9624,6 +9659,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);
|
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));
|
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
EndDisabled();
|
EndDisabled();
|
||||||
@@ -10736,7 +10782,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
float rounding = style.TabRounding;
|
float rounding = style.TabRounding;
|
||||||
display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
|
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->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
|
else
|
||||||
{
|
{
|
||||||
@@ -10827,20 +10873,16 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
|
|||||||
IM_UNUSED(flags);
|
IM_UNUSED(flags);
|
||||||
IM_ASSERT(width > 0.0f);
|
IM_ASSERT(width > 0.0f);
|
||||||
const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f));
|
const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f));
|
||||||
const float y1 = bb.Min.y + 1.0f;
|
const float y1 = bb.Min.y + 1.0f; // Leave a bit of room in title bars.
|
||||||
const float y2 = bb.Max.y - g.Style.TabBarBorderSize;
|
const float y2 = bb.Max.y - g.Style.TabBarBorderSize;
|
||||||
draw_list->PathLineTo(ImVec2(bb.Min.x, y2));
|
draw_list->AddRectFilled(bb.Min, ImVec2(bb.Max.x, y2), col, rounding, ImDrawFlags_RoundCornersTop);
|
||||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9);
|
|
||||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12);
|
|
||||||
draw_list->PathLineTo(ImVec2(bb.Max.x, y2));
|
|
||||||
draw_list->PathFillConvex(col);
|
|
||||||
if (g.Style.TabBorderSize > 0.0f)
|
if (g.Style.TabBorderSize > 0.0f)
|
||||||
{
|
{
|
||||||
draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2));
|
draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2));
|
||||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9);
|
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->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->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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user