mirror of
https://github.com/ocornut/imgui.git
synced 2026-03-23 17:10:53 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_vulkan.cpp # imgui.cpp # imgui_demo.cpp
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-03-11: Vulkan: Added ImGui_ImplVulkan_PipelineInfo::ExtraDynamicStates[] to allow specifying extra dynamic states to add when creating the VkPipeline. (#9211)
|
||||
// 2025-09-26: [Helpers] *BREAKING CHANGE*: Vulkan: Helper ImGui_ImplVulkanH_DestroyWindow() does not call vkDestroySurfaceKHR(): as surface is created by caller of ImGui_ImplVulkanH_CreateOrResizeWindow(), it is more consistent that we don't destroy it. (#9163)
|
||||
// 2026-01-05: [Helpers] *BREAKING CHANGE*: Vulkan: Helper for creating render pass uses ImGui_ImplVulkanH_Window::AttachmentDesc to create render pass. Removed ClearEnabled. (#9152)
|
||||
// 2025-11-24: [Helpers] Vulkan: Helper for creating a swap-chain (used by examples and multi-viewports) selects VkSwapchainCreateInfoKHR's compositeAlpha based on cap.supportedCompositeAlpha. (#8784)
|
||||
@@ -1040,11 +1041,13 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
|
||||
blend_info.attachmentCount = 1;
|
||||
blend_info.pAttachments = color_attachment;
|
||||
|
||||
VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
ImVector<VkDynamicState> dynamic_states = info->ExtraDynamicStates;
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
VkPipelineDynamicStateCreateInfo dynamic_state = {};
|
||||
dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamic_state.dynamicStateCount = (uint32_t)IM_COUNTOF(dynamic_states);
|
||||
dynamic_state.pDynamicStates = dynamic_states;
|
||||
dynamic_state.dynamicStateCount = dynamic_states.Size;
|
||||
dynamic_state.pDynamicStates = dynamic_states.Data;
|
||||
|
||||
VkGraphicsPipelineCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
|
||||
@@ -90,6 +90,7 @@ struct ImGui_ImplVulkan_PipelineInfo
|
||||
// For Main and Secondary viewports
|
||||
uint32_t Subpass; //
|
||||
VkSampleCountFlagBits MSAASamples = {}; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
ImVector<VkDynamicState> ExtraDynamicStates; // Optional, allows to insert more dynamic states into our VkPipeline
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-03-09: Removed support for Emscripten < 4.0.10. (#9281)
|
||||
// 2025-10-16: Update to compile with Dawn and Emscripten's 4.0.10+ '--use-port=emdawnwebgpu' ports. (#8381, #8898)
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. (#8465)
|
||||
@@ -60,11 +61,8 @@
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#error Exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined!
|
||||
#endif
|
||||
|
||||
// This condition is true when it's built with EMSCRIPTEN using -sUSE_WEBGPU=1 flag (deprecated from 4.0.10)
|
||||
// This condition is false for all other 3 cases: WGPU-Native, DAWN-Native or DAWN-EMSCRIPTEN (using --use-port=emdawnwebgpu flag)
|
||||
#if defined(__EMSCRIPTEN__) && defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN
|
||||
#error Emscripten <4.0.10 with '-sUSE_WEBGPU=1' is not supported anymore.
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
@@ -263,15 +261,9 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||
#else
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
#endif
|
||||
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
desc.nextInChain = (WGPUChainedStruct*)&wgsl_desc;
|
||||
@@ -279,11 +271,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||
#else
|
||||
stage_desc.entryPoint = "main";
|
||||
#endif
|
||||
return stage_desc;
|
||||
}
|
||||
|
||||
@@ -402,11 +390,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
WGPUBufferDescriptor vb_desc =
|
||||
{
|
||||
nullptr,
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
{ "Dear ImGui Vertex buffer", WGPU_STRLEN, },
|
||||
#else
|
||||
"Dear ImGui Vertex buffer",
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
|
||||
false
|
||||
@@ -430,11 +414,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
WGPUBufferDescriptor ib_desc =
|
||||
{
|
||||
nullptr,
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
{ "Dear ImGui Index buffer", WGPU_STRLEN, },
|
||||
#else
|
||||
"Dear ImGui Index buffer",
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
|
||||
false
|
||||
@@ -566,11 +546,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
// Create texture
|
||||
WGPUTextureDescriptor tex_desc = {};
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
tex_desc.label = { "Dear ImGui Texture", WGPU_STRLEN };
|
||||
#else
|
||||
tex_desc.label = "Dear ImGui Texture";
|
||||
#endif
|
||||
tex_desc.dimension = WGPUTextureDimension_2D;
|
||||
tex_desc.size.width = tex->Width;
|
||||
tex_desc.size.height = tex->Height;
|
||||
@@ -611,20 +587,12 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
|
||||
// This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions.
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
WGPUTexelCopyTextureInfo dst_view = {};
|
||||
#else
|
||||
WGPUImageCopyTexture dst_view = {};
|
||||
#endif
|
||||
dst_view.texture = backend_tex->Texture;
|
||||
dst_view.mipLevel = 0;
|
||||
dst_view.origin = { (uint32_t)upload_x, (uint32_t)upload_y, 0 };
|
||||
dst_view.aspect = WGPUTextureAspect_All;
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
WGPUTexelCopyBufferLayout layout = {};
|
||||
#else
|
||||
WGPUTextureDataLayout layout = {};
|
||||
#endif
|
||||
layout.offset = 0;
|
||||
layout.bytesPerRow = tex->Width * tex->BytesPerPixel;
|
||||
layout.rowsPerImage = upload_h;
|
||||
@@ -642,11 +610,7 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
|
||||
WGPUBufferDescriptor ub_desc =
|
||||
{
|
||||
nullptr,
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
{ "Dear ImGui Uniform buffer", WGPU_STRLEN, },
|
||||
#else
|
||||
"Dear ImGui Uniform buffer",
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
||||
MEMALIGN(sizeof(Uniforms), 16),
|
||||
false
|
||||
@@ -758,11 +722,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
// Create depth-stencil State
|
||||
WGPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.format = bd->depthStencilFormat;
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
|
||||
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
||||
#else
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
#endif
|
||||
depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
|
||||
@@ -847,11 +807,7 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
||||
io.BackendRendererName = "imgui_impl_wgpu (Dawn, Native)";
|
||||
#endif
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
io.BackendRendererName = "imgui_impl_wgpu (WGPU, Emscripten)"; // linked using EMSCRIPTEN with "-sUSE_WEBGPU=1" flag, deprecated from EMSCRIPTEN 4.0.10
|
||||
#else
|
||||
io.BackendRendererName = "imgui_impl_wgpu (WGPU, Native)";
|
||||
#endif
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
// When targeting native platforms:
|
||||
// - One of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU *must* be provided.
|
||||
// When targeting Emscripten:
|
||||
// - We now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN is Emscripten version is 4.0.10+, which correspond to using Emscripten '--use-port=emdawnwebgpu'.
|
||||
// - We now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN and requires Emscripten 4.0.10+, which correspond to using Emscripten '--use-port=emdawnwebgpu'.
|
||||
// - Emscripten < 4.0.10 is not supported anymore (old '-sUSE_WEBGPU=1' option).
|
||||
// - We can still define IMGUI_IMPL_WEBGPU_BACKEND_WGPU to use Emscripten '-s USE_WEBGPU=1' which is marked as obsolete by Emscripten.
|
||||
// Add #define to your imconfig.h file, or as a compilation flag in your build system.
|
||||
// This requirement may be removed once WebGPU stabilizes and backends converge on a unified interface.
|
||||
@@ -35,20 +36,7 @@
|
||||
// Setup Emscripten default if not specified.
|
||||
#if defined(__EMSCRIPTEN__) && !defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#include <emscripten/version.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN_MAJOR__
|
||||
#if (__EMSCRIPTEN_MAJOR__ >= 5) || ((__EMSCRIPTEN_MAJOR__ >= 4) && (__EMSCRIPTEN_MINOR__ >= 0) && (__EMSCRIPTEN_TINY__ >= 10))
|
||||
#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#else
|
||||
#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
#endif
|
||||
#else
|
||||
#if (__EMSCRIPTEN_major__ >= 4) && (__EMSCRIPTEN_minor__ >= 0) && (__EMSCRIPTEN_tiny__ >= 10)
|
||||
#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#else
|
||||
#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
@@ -111,7 +99,7 @@ const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type);
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||
const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type);
|
||||
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type);
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -41,6 +41,18 @@ HOW TO UPDATE?
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Separator(): fixed a legacy quirk where Separator() was submitting a zero-height
|
||||
item for layout purpose, even though it draws a 1-pixel separator.
|
||||
The fix could affect code e.g. computing height from multiple widgets in order to
|
||||
allocate vertical space for a footer or multi-line status bar. (#2657, #9263)
|
||||
The "Console" example had such a bug:
|
||||
float footer_height = style.ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
BeginChild("ScrollingRegion", { 0, -footer_height });
|
||||
Should be:
|
||||
float footer_height = style.ItemSpacing.y + style.SeparatorSize + ImGui::GetFrameHeightWithSpacing();
|
||||
BeginChild("ScrollingRegion", { 0, -footer_height });
|
||||
When such idiom was used and assuming zero-height Separator, it is likely that
|
||||
in 1.92.7 the resulting window will have unexpected 1 pixel scrolling range.
|
||||
- Combo(), ListBox(): commented out legacy signatures which were obsoleted in 1.90
|
||||
(Nov 2023), when the getter callback type was changed from:
|
||||
getter type: bool (*getter)(void* user_data, int idx, const char** out_text)
|
||||
@@ -60,22 +72,44 @@ Other Changes:
|
||||
- InputText:
|
||||
- Shift+Enter in multi-line editor always adds a new line, regardless of
|
||||
ImGuiInputTextFlags_CtrlEnterForNewLine being set or not. (#9239)
|
||||
- Style: border sizes are now scaled (and rounded) by ScaleAllSizes().
|
||||
- Demo: fixed IMGUI_DEMO_MARKER locations for examples applets. (#9261, #3689) [@pthom]
|
||||
- Reworked io.ConfigInputTextEnterKeepActive mode so that pressing Enter will
|
||||
deactivate/reactivate the item in order for e.g. IsItemDeactivatedAfterEdit()
|
||||
signals to be emitted the same way regardless of that setting. (#9001, #9115)
|
||||
- Style:
|
||||
- Border sizes are now scaled (and rounded) by ScaleAllSizes().
|
||||
- When using large values with ScallAllSizes(), the following items thickness
|
||||
are scaled to integer amounts:
|
||||
- InputText Caret/cursor thickness. (#7031)
|
||||
- CloseButton() thickness.
|
||||
- TextLink() underline thickness.
|
||||
- ColorButton() border thickness.
|
||||
- Separator() thickness, via scaling newly added style.SeparatorSize. (#2657, #9263)
|
||||
- Clipper:
|
||||
- Clear `DisplayStart`/`DisplayEnd` fields when `Step()` returns false.
|
||||
- Added `UserIndex` helper storage. This is solely a convenience for cases where
|
||||
you may want to carry an index around.
|
||||
- Scrollbar:
|
||||
- Implemented a custom tweak to extend hit-testing bounding box when window is sitting
|
||||
at the edge of a viewport (e.g. fullscreen or docked window), so that e.g. mouse the
|
||||
mouse at the extreme of the screen will reach the scrollbar. (#9276)
|
||||
- Demo: fixed IMGUI_DEMO_MARKER locations for examples applets. (#9261, #3689) [@pthom]
|
||||
- Backends:
|
||||
- SDLGPU3: removed unnecessary call to SDL_WaitForGPUIdle when releasing
|
||||
vertex/index buffers. (#9262) [@jaenis]
|
||||
- WebGPU: fixed version check for Emscripten 5.0.0+.
|
||||
- WebGPU: removed support for Emscripten <4.0.10. (#9281) [@ypujante]
|
||||
- Examples:
|
||||
- Emscripten: added `tabindex=-1` to canvas in our shell_minimal.htm. Without it,
|
||||
the canvas was not focusable in the DOM, which in turn make some backends
|
||||
(e.g. pongasoft/emscripten-glfw) not receive focus loss events. (#9259) [@pthom]
|
||||
- WGPU: fixed undefined behaviors in example code for requesting adapter
|
||||
- Emscripten: fixed minor rendering issues with our HTML shell. (#9281) [@ypujante]
|
||||
- hidden small blue outline when canvas is focused on Chrome.
|
||||
- hidden scrollbar in Firefox.
|
||||
- Vulkan: added ImGui_ImplVulkan_PipelineInfo::ExtraDynamicStates[] to allow specifying
|
||||
extra dynamic states to add when creating the VkPipeline. (#9211) [@DziubanMaciej]
|
||||
- WebGPU: fixed undefined behaviors in example code for requesting adapter
|
||||
and device. (#9246, #9256) [@r-lyeh]
|
||||
- GLFW/SDL2/SDL3+WebGPU: removed suport for Emscripten <4.0.10. (#9281) [@ypujante]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ or view this file with any Markdown viewer.
|
||||
- Handy [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide to integrate Dear ImGui in an existing application.
|
||||
- 20+ standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them.
|
||||
- See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function. The demo covers most features of Dear ImGui, so you can read the code and see its output.
|
||||
- See pthom's online [imgui_explorer](https://pthom.github.io/imgui_explorer) which is a web version of the demo with a source code browser.
|
||||
- See documentation: [Backends](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md), [Examples](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md), [Fonts](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
|
||||
- See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h).
|
||||
- The [Glossary](https://github.com/ocornut/imgui/wiki/Glossary) page may be useful.
|
||||
|
||||
@@ -110,11 +110,10 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
|
||||
### Demo
|
||||
|
||||
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`.
|
||||
- [Web version of the demo](https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html) courtesy of [@pthom](https://github.com/pthom).
|
||||
- [Screenshot of the demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
||||
- [imgui_explorer](https://pthom.github.io/imgui_explorer): Web version of the demo w/ source code browser, courtesy of [@pthom](https://github.com/pthom).
|
||||
|
||||
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
|
||||
- [imgui-demo-binaries-20250625.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20250625.zip) (Windows, 1.92.0, built 2025/06/25, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||
- [imgui-demo-binaries-20260225.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20260225.zip) (Windows, 1.92.6, built 2026/02/25, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||
|
||||
### Gallery
|
||||
|
||||
|
||||
@@ -52,23 +52,15 @@ set(IMGUI_EXAMPLE_SOURCE_FILES
|
||||
)
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
if(NOT IMGUI_EMSCRIPTEN_WEBGPU_FLAG) # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG not used, set by current EMSCRIPTEN version
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Choose between --use-port=emdawnwebgpu (Dawn implementation of EMSCRIPTEN) and -sUSE_WEBGPU=1 (WGPU implementation of EMSCRIPTEN, deprecated in 4.0.10): default to --use-port=emdawnwebgpu for EMSCRIPTEN >= 4.0.10")
|
||||
else()
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "-sUSE_WEBGPU=1" CACHE STRING "Use -sUSE_WEBGPU=1 for EMSCRIPTEN WGPU implementation")
|
||||
endif()
|
||||
else() # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG used, check correct version
|
||||
if(EMSCRIPTEN_VERSION VERSION_LESS "4.0.10" AND "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
# it's necessary EMSCRIPTEN >= v4.0.10 (although "--use-port=path/to/emdawnwebgpu.port.py" is supported/tested from v4.0.8)
|
||||
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
|
||||
endif()
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Default to --use-port=emdawnwebgpu. You can override to provide your own local port.")
|
||||
else()
|
||||
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
|
||||
endif()
|
||||
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "3.1.57")
|
||||
if(NOT IMGUI_EMSCRIPTEN_GLFW3)
|
||||
# Defaults to contrib.glfw3 because Emscripten version is > 3.1.57
|
||||
set(IMGUI_EMSCRIPTEN_GLFW3 "--use-port=contrib.glfw3" CACHE STRING "Choose between --use-port=contrib.glfw3 and -sUSE_GLFW=3 for GLFW implementation (default to --use-port=contrib.glfw3)")
|
||||
else() # cannot use contrib.glfw3 prior to 3.1.57
|
||||
set(IMGUI_EMSCRIPTEN_GLFW3 "-sUSE_GLFW=3" CACHE STRING "Use -sUSE_GLFW=3 for GLFW implementation" FORCE)
|
||||
endif()
|
||||
|
||||
set(LIBRARIES glfw)
|
||||
@@ -165,7 +157,6 @@ endif()
|
||||
# In this example IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU internal define is set according to:
|
||||
# EMSCRIPTEN: by used FLAG
|
||||
# --use-port=emdawnwebgpu --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN defined
|
||||
# -sUSE_WEBGPU=1 --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU defined
|
||||
# NATIVE: by used SDK installation directory
|
||||
# if IMGUI_DAWN_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN defined
|
||||
# if IMGUI_WGPU_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU defined
|
||||
@@ -191,12 +182,8 @@ else() # Emscripten settings
|
||||
endif()
|
||||
message(STATUS "Using ${IMGUI_EMSCRIPTEN_GLFW3} GLFW implementation")
|
||||
|
||||
if("${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
else()
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGPU")
|
||||
endif()
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
message(STATUS "Using ${IMGUI_EMSCRIPTEN_WEBGPU_FLAG} WebGPU implementation")
|
||||
|
||||
target_link_options(${IMGUI_EXECUTABLE} PRIVATE
|
||||
|
||||
@@ -19,8 +19,8 @@ WEB_DIR = web
|
||||
EXE = $(WEB_DIR)/index.html
|
||||
IMGUI_DIR = ../..
|
||||
SOURCES = main.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
CPPFLAGS =
|
||||
@@ -40,11 +40,7 @@ LDFLAGS += -s ASYNCIFY=1
|
||||
LDFLAGS += -s NO_EXIT_RUNTIME=0
|
||||
LDFLAGS += -s ASSERTIONS=1
|
||||
|
||||
# (1) Using legacy WebGPU implementation (Emscripten < 4.0.10)
|
||||
#EMS += -DIMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
#LDFLAGS += -s USE_WEBGPU=1
|
||||
|
||||
# or (2) Using newer Dawn-based WebGPU port (Emscripten >= 4.0.10)
|
||||
# Using Dawn-based WebGPU port (requires Emscripten >= 4.0.10)
|
||||
EMS += --use-port=emdawnwebgpu
|
||||
LDFLAGS += --use-port=emdawnwebgpu
|
||||
|
||||
|
||||
@@ -60,14 +60,10 @@ For the WASM code produced by Emscripten to work correctly, it will also be nece
|
||||
CMake checks the EMSCRIPEN version then:
|
||||
- if EMS >= 4.0.10 uses `--use-port=emdawnwebgpu` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- if EMS < 4.0.10 uses `-sUSE_WEBGPU=1` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
|
||||
#### Generate Emscripten forcing `-sUSE_WEBGPU=1` deprecated flag even with EMS >= 4.0.10
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="-sUSE_WEBGPU=1" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
- if EMS < 4.0.10 the build aborts (`-sUSE_WEBGPU=1` is no longer supported by our examples and our WGPU backend)
|
||||
|
||||
#### Generate Emscripten using external WebGPU library (emdawnwebgpu_pkg)
|
||||
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="--use-port=path_to_emdawnwebgpu_pkg" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- *To use external WebGPU library it's necessary to have EMS >= 4.0.10 or the minimum requirements specified by the package:*
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#include <emscripten/html5_webgpu.h>
|
||||
#endif
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
@@ -345,17 +342,6 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
return acquired_device.MoveToCHandle();
|
||||
}
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Adapter and device initialization via JS
|
||||
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
||||
{
|
||||
if (!navigator.gpu)
|
||||
throw Error("WebGPU not supported.");
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const device = await adapter.requestDevice();
|
||||
Module.preinitializedWebGPUDevice = device;
|
||||
} );
|
||||
#else // __EMSCRIPTEN__
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
@@ -412,7 +398,6 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
bool InitWGPU(GLFWwindow* window)
|
||||
@@ -462,23 +447,6 @@ bool InitWGPU(GLFWwindow* window)
|
||||
instanceDesc.requiredFeatures = &timedWaitAny;
|
||||
wgpu_instance = wgpuCreateInstance(&instanceDesc);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
getAdapterAndDeviceViaJS();
|
||||
|
||||
wgpu_device = emscripten_webgpu_get_device();
|
||||
IM_ASSERT(wgpu_device != nullptr && "Error creating the Device");
|
||||
|
||||
WGPUSurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
||||
html_surface_desc.selector = "#canvas";
|
||||
|
||||
WGPUSurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc.chain;
|
||||
|
||||
// Create the surface.
|
||||
wgpu_surface = wgpuInstanceCreateSurface(wgpu_instance, &surface_desc);
|
||||
preferred_fmt = wgpuSurfaceGetPreferredFormat(wgpu_surface, {} /* adapter */);
|
||||
#else // __EMSCRIPTEN__
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
@@ -498,7 +466,6 @@ bool InitWGPU(GLFWwindow* window)
|
||||
wgpuSurfaceGetCapabilities(wgpu_surface, adapter, &surface_capabilities);
|
||||
|
||||
preferred_fmt = surface_capabilities.formats[0];
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
wgpu_surface_configuration.presentMode = WGPUPresentMode_Fifo;
|
||||
|
||||
@@ -52,17 +52,10 @@ set(IMGUI_EXAMPLE_SOURCE_FILES
|
||||
)
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
if(NOT IMGUI_EMSCRIPTEN_WEBGPU_FLAG) # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG not used, set by current EMSCRIPTEN version
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Choose between --use-port=emdawnwebgpu (Dawn implementation of EMSCRIPTEN) and -sUSE_WEBGPU=1 (WGPU implementation of EMSCRIPTEN, deprecated in 4.0.10): default to --use-port=emdawnwebgpu for EMSCRIPTEN >= 4.0.10")
|
||||
else()
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "-sUSE_WEBGPU=1" CACHE STRING "Use -sUSE_WEBGPU=1 for EMSCRIPTEN WGPU implementation")
|
||||
endif()
|
||||
else() # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG used, check correct version
|
||||
if(EMSCRIPTEN_VERSION VERSION_LESS "4.0.10" AND "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
# it's necessary EMSCRIPTEN >= v4.0.10 (although "--use-port=path/to/emdawnwebgpu.port.py" is supported/tested from v4.0.8)
|
||||
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
|
||||
endif()
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Default to --use-port=emdawnwebgpu. You can override to provide your own local port.")
|
||||
else()
|
||||
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
|
||||
endif()
|
||||
|
||||
add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1)
|
||||
@@ -160,7 +153,6 @@ endif()
|
||||
# IMGUI_IMPL_WEBGPU_BACKEND_DAWN/WGPU internal define is set according to:
|
||||
# EMSCRIPTEN: by used FLAG
|
||||
# --use-port=emdawnwebgpu --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled (+EMSCRIPTEN)
|
||||
# -sUSE_WEBGPU=1 --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled (+EMSCRIPTEN)
|
||||
# NATIVE: by used SDK installation directory
|
||||
# if IMGUI_DAWN_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled
|
||||
# if IMGUI_WGPU_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled
|
||||
@@ -180,12 +172,8 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
|
||||
else() # Emscripten settings
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||
|
||||
if("${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
else()
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGPU")
|
||||
endif()
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
message(STATUS "Using ${IMGUI_EMSCRIPTEN_WEBGPU_FLAG} WebGPU implementation")
|
||||
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "-sUSE_SDL=2")
|
||||
|
||||
@@ -19,8 +19,8 @@ WEB_DIR = web
|
||||
EXE = $(WEB_DIR)/index.html
|
||||
IMGUI_DIR = ../..
|
||||
SOURCES = main.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
CPPFLAGS =
|
||||
@@ -40,11 +40,7 @@ LDFLAGS += -s ASYNCIFY=1
|
||||
LDFLAGS += -s NO_EXIT_RUNTIME=0
|
||||
LDFLAGS += -s ASSERTIONS=1
|
||||
|
||||
# (1) Using legacy WebGPU implementation (Emscripten < 4.0.10)
|
||||
#EMS += -DIMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
#LDFLAGS += -s USE_WEBGPU=1
|
||||
|
||||
# or (2) Using newer Dawn-based WebGPU port (Emscripten >= 4.0.10)
|
||||
# Using Dawn-based WebGPU port (requires Emscripten >= 4.0.10)
|
||||
EMS += --use-port=emdawnwebgpu
|
||||
LDFLAGS += --use-port=emdawnwebgpu
|
||||
|
||||
|
||||
@@ -60,14 +60,10 @@ For the WASM code produced by Emscripten to work correctly, it will also be nece
|
||||
CMake checks the EMSCRIPEN version then:
|
||||
- if EMS >= 4.0.10 uses `--use-port=emdawnwebgpu` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- if EMS < 4.0.10 uses `-sUSE_WEBGPU=1` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
|
||||
#### Generate Emscripten forcing `-sUSE_WEBGPU=1` deprecated flag even with EMS >= 4.0.10
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="-sUSE_WEBGPU=1" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
- if EMS < 4.0.10 the build aborts (`-sUSE_WEBGPU=1` is no longer supported by our examples and our WGPU backend)
|
||||
|
||||
#### Generate Emscripten using external WebGPU library (emdawnwebgpu_pkg)
|
||||
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="--use-port=path_to_emdawnwebgpu_pkg" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- *To use external WebGPU library it's necessary to have EMS >= 4.0.10 or the minimum requirements specified by the package:*
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#include <emscripten/html5_webgpu.h>
|
||||
#endif
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
@@ -328,17 +325,6 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
return acquired_device.MoveToCHandle();
|
||||
}
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Adapter and device initialization via JS
|
||||
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
||||
{
|
||||
if (!navigator.gpu)
|
||||
throw Error("WebGPU not supported.");
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const device = await adapter.requestDevice();
|
||||
Module.preinitializedWebGPUDevice = device;
|
||||
} );
|
||||
#else // __EMSCRIPTEN__
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
@@ -395,7 +381,6 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
static bool InitWGPU(SDL_Window* window)
|
||||
@@ -446,23 +431,6 @@ static bool InitWGPU(SDL_Window* window)
|
||||
instanceDesc.requiredFeatures = &timedWaitAny;
|
||||
wgpu_instance = wgpuCreateInstance(&instanceDesc);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
getAdapterAndDeviceViaJS();
|
||||
|
||||
wgpu_device = emscripten_webgpu_get_device();
|
||||
assert(wgpu_device != nullptr && "Error creating the Device");
|
||||
|
||||
WGPUSurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
||||
html_surface_desc.selector = "#canvas";
|
||||
|
||||
WGPUSurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc.chain;
|
||||
|
||||
// Create the surface.
|
||||
wgpu_surface = wgpuInstanceCreateSurface(wgpu_instance, &surface_desc);
|
||||
preferred_fmt = wgpuSurfaceGetPreferredFormat(wgpu_surface, {} /* adapter */);
|
||||
#else // __EMSCRIPTEN__
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
@@ -482,7 +450,6 @@ static bool InitWGPU(SDL_Window* window)
|
||||
wgpuSurfaceGetCapabilities(wgpu_surface, adapter, &surface_capabilities);
|
||||
|
||||
preferred_fmt = surface_capabilities.formats[0];
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
wgpu_surface_configuration.presentMode = WGPUPresentMode_Fifo;
|
||||
|
||||
@@ -55,18 +55,8 @@ if(EMSCRIPTEN)
|
||||
if(EMSCRIPTEN_VERSION VERSION_LESS "4.0.15")
|
||||
message(FATAL_ERROR "Using Emscripten with SDL3 needs Emscripten version >= 4.0.15")
|
||||
endif()
|
||||
if(NOT IMGUI_EMSCRIPTEN_WEBGPU_FLAG) # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG not used, set by current EMSCRIPTEN version
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Choose between --use-port=emdawnwebgpu (Dawn implementation of EMSCRIPTEN) and -sUSE_WEBGPU=1 (WGPU implementation of EMSCRIPTEN, deprecated in 4.0.10): default to --use-port=emdawnwebgpu for EMSCRIPTEN >= 4.0.10")
|
||||
else()
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "-sUSE_WEBGPU=1" CACHE STRING "Use -sUSE_WEBGPU=1 for EMSCRIPTEN WGPU implementation")
|
||||
endif()
|
||||
else() # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG used, check correct version
|
||||
if(EMSCRIPTEN_VERSION VERSION_LESS "4.0.10" AND "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
# it's necessary EMSCRIPTEN >= v4.0.10 (although "--use-port=path/to/emdawnwebgpu.port.py" is supported/tested from v4.0.8)
|
||||
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
|
||||
endif()
|
||||
endif()
|
||||
# emdawnwebgpu was introduced in 4.0.10 so, due to the prior requirement, this will work
|
||||
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Default to --use-port=emdawnwebgpu. You can override to provide your own local port.")
|
||||
|
||||
add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1)
|
||||
else() # Native/Desktop build
|
||||
@@ -162,7 +152,6 @@ endif()
|
||||
# IMGUI_IMPL_WEBGPU_BACKEND_DAWN/WGPU internal define is set according to:
|
||||
# EMSCRIPTEN: by used FLAG
|
||||
# --use-port=emdawnwebgpu --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled (+EMSCRIPTEN)
|
||||
# -sUSE_WEBGPU=1 --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled (+EMSCRIPTEN)
|
||||
# NATIVE: by used SDK installation directory
|
||||
# if IMGUI_DAWN_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled
|
||||
# if IMGUI_WGPU_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled
|
||||
@@ -182,12 +171,8 @@ if(NOT EMSCRIPTEN) # WegGPU-Native settings
|
||||
else() # Emscripten settings
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||
|
||||
if("${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
else()
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGPU")
|
||||
endif()
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
|
||||
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
|
||||
message(STATUS "Using ${IMGUI_EMSCRIPTEN_WEBGPU_FLAG} WebGPU implementation")
|
||||
|
||||
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "-sUSE_SDL=3")
|
||||
|
||||
@@ -19,8 +19,8 @@ WEB_DIR = web
|
||||
EXE = $(WEB_DIR)/index.html
|
||||
IMGUI_DIR = ../..
|
||||
SOURCES = main.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
CPPFLAGS =
|
||||
@@ -40,11 +40,7 @@ LDFLAGS += -s ASYNCIFY=1
|
||||
LDFLAGS += -s NO_EXIT_RUNTIME=0
|
||||
LDFLAGS += -s ASSERTIONS=1
|
||||
|
||||
# (1) Using legacy WebGPU implementation (Emscripten < 4.0.10)
|
||||
#EMS += -DIMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
#LDFLAGS += -s USE_WEBGPU=1
|
||||
|
||||
# or (2) Using newer Dawn-based WebGPU port (Emscripten >= 4.0.10)
|
||||
# Using Dawn-based WebGPU port (requires Emscripten >= 4.0.10)
|
||||
EMS += --use-port=emdawnwebgpu
|
||||
LDFLAGS += --use-port=emdawnwebgpu
|
||||
|
||||
|
||||
@@ -60,14 +60,10 @@ For the WASM code produced by Emscripten to work correctly, it will also be nece
|
||||
CMake checks the EMSCRIPEN version then:
|
||||
- if EMS >= 4.0.10 uses `--use-port=emdawnwebgpu` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- if EMS < 4.0.10 uses `-sUSE_WEBGPU=1` flag to build
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
|
||||
#### Generate Emscripten forcing `-sUSE_WEBGPU=1` deprecated flag even with EMS >= 4.0.10
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="-sUSE_WEBGPU=1" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_WGPU` compiler define
|
||||
- if EMS < 4.0.10 the build aborts (`-sUSE_WEBGPU=1` is no longer supported by our examples and our WGPU backend
|
||||
|
||||
#### Generate Emscripten using external WebGPU library (emdawnwebgpu_pkg)
|
||||
|
||||
- `emcmake cmake -G Ninja -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="--use-port=path_to_emdawnwebgpu_pkg" -B where_to_build_dir`
|
||||
- it set `IMGUI_IMPL_WEBGPU_BACKEND_DAWN` compiler define
|
||||
- *To use external WebGPU library it's necessary to have EMS >= 4.0.10 or the minimum requirements specified by the package:*
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#include <emscripten/html5_webgpu.h>
|
||||
#endif
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
@@ -339,17 +336,6 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
return acquired_device.MoveToCHandle();
|
||||
}
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Adapter and device initialization via JS
|
||||
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
||||
{
|
||||
if (!navigator.gpu)
|
||||
throw Error("WebGPU not supported.");
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const device = await adapter.requestDevice();
|
||||
Module.preinitializedWebGPUDevice = device;
|
||||
} );
|
||||
#else // __EMSCRIPTEN__
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
@@ -406,7 +392,6 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
static bool InitWGPU(SDL_Window* window)
|
||||
@@ -457,23 +442,6 @@ static bool InitWGPU(SDL_Window* window)
|
||||
instanceDesc.requiredFeatures = &timedWaitAny;
|
||||
wgpu_instance = wgpuCreateInstance(&instanceDesc);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
getAdapterAndDeviceViaJS();
|
||||
|
||||
wgpu_device = emscripten_webgpu_get_device();
|
||||
IM_ASSERT(wgpu_device != nullptr && "Error creating the Device");
|
||||
|
||||
WGPUSurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
||||
html_surface_desc.selector = "#canvas";
|
||||
|
||||
WGPUSurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc.chain;
|
||||
|
||||
// Create the surface.
|
||||
wgpu_surface = wgpuInstanceCreateSurface(wgpu_instance, &surface_desc);
|
||||
preferred_fmt = wgpuSurfaceGetPreferredFormat(wgpu_surface, {} /* adapter */);
|
||||
#else // __EMSCRIPTEN__
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
@@ -493,7 +461,6 @@ static bool InitWGPU(SDL_Window* window)
|
||||
wgpuSurfaceGetCapabilities(wgpu_surface, adapter, &surface_capabilities);
|
||||
|
||||
preferred_fmt = surface_capabilities.formats[0];
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
wgpu_surface_configuration.presentMode = WGPUPresentMode_Fifo;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
|
||||
<title>Dear ImGui Emscripten example</title>
|
||||
<style>
|
||||
body { margin: 0; background-color: black }
|
||||
body { margin: 0; background-color: black; overflow: hidden; }
|
||||
/* FIXME: with our GLFW example this block seems to break resizing and io.DisplaySize gets stuck */
|
||||
.emscripten {
|
||||
position: absolute;
|
||||
@@ -26,6 +26,9 @@
|
||||
image-rendering: pixelated;
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
#canvas:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
46
imgui.cpp
46
imgui.cpp
@@ -20,7 +20,7 @@
|
||||
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
|
||||
// - Issues & support ........... https://github.com/ocornut/imgui/issues
|
||||
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
|
||||
// - Web version of the Demo .... https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html (w/ source code browser)
|
||||
// - Web version of the Demo .... https://pthom.github.io/imgui_explorer (w/ source code browser)
|
||||
|
||||
// For FIRST-TIME users having issues compiling/linking/running:
|
||||
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
||||
@@ -208,7 +208,7 @@ CODE
|
||||
The UI can be highly dynamic, there are no construction or destruction steps, less superfluous
|
||||
data retention on your side, less state duplication, less state synchronization, fewer bugs.
|
||||
- Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features.
|
||||
Or browse https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html for interactive web version.
|
||||
Or browse pthom's online imgui_explorer: https://pthom.github.io/imgui_explorer for a web version w/ source code browser.
|
||||
- The library is designed to be built from sources. Avoid pre-compiled binaries and packaged versions. See imconfig.h to configure your build.
|
||||
- Dear ImGui is an implementation of the IMGUI paradigm (immediate-mode graphical user interface, a term coined by Casey Muratori).
|
||||
You can learn about IMGUI principles at http://www.johno.se/book/imgui.html, http://mollyrocket.com/861 & more links in Wiki.
|
||||
@@ -402,7 +402,17 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
|
||||
- 2026/02/27 (1.92.7) - Commented out legacy signature for Combo(), ListBox(), signatures which were obsoleted in 1.90 (Nov 2023), when the getter callback type was changed.
|
||||
- 2026/02/26 (1.92.7) - Separator: fixed a legacy quirk where Separator() was submitting a zero-height item for layout purpose, even though it draws a 1-pixel separator.
|
||||
The fix could affect code e.g. computing height from multiple widgets in order to allocate vertical space for a footer or multi-line status bar. (#2657, #9263)
|
||||
The "Console" example had such a bug:
|
||||
float footer_height = style.ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
BeginChild("ScrollingRegion", { 0, -footer_height });
|
||||
Should be:
|
||||
float footer_height = style.ItemSpacing.y + style.SeparatorSize + ImGui::GetFrameHeightWithSpacing();
|
||||
BeginChild("ScrollingRegion", { 0, -footer_height });
|
||||
When such idiom was used and assuming zero-height Separator, it is likely that
|
||||
in 1.92.7 the resulting window will have unexpected 1 pixel scrolling range.
|
||||
- 2026/02/23 (1.92.7) - Commented out legacy signature for Combo(), ListBox(), signatures which were obsoleted in 1.90 (Nov 2023), when the getter callback type was changed.
|
||||
- Old getter type: bool (*getter)(void* user_data, int idx, const char** out_text) // Set label + return bool. False replaced label with placeholder.
|
||||
- New getter type: const char* (*getter)(void* user_data, int idx) // Return label or NULL/empty label if missing
|
||||
- 2026/01/08 (1.92.6) - Commented out legacy names obsoleted in 1.90 (Sept 2023): 'BeginChildFrame()' --> 'BeginChild()' with 'ImGuiChildFlags_FrameStyle'. 'EndChildFrame()' --> 'EndChild()'. 'ShowStackToolWindow()' --> 'ShowIDStackToolWindow()'. 'IM_OFFSETOF()' --> 'offsetof()'.
|
||||
@@ -1116,6 +1126,8 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
||||
- Run the examples/ applications and explore them.
|
||||
- Read Getting Started (https://github.com/ocornut/imgui/wiki/Getting-Started) guide.
|
||||
- See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function.
|
||||
- See pthom's online imgui_explorer (https://pthom.github.io/imgui_explorer) which is a web
|
||||
version of the demo with a source code browser.
|
||||
- The demo covers most features of Dear ImGui, so you can read the code and see its output.
|
||||
- See documentation and comments at the top of imgui.cpp + effectively imgui.h.
|
||||
- 20+ standalone example applications using e.g. OpenGL/DirectX are provided in the
|
||||
@@ -1526,7 +1538,8 @@ ImGuiStyle::ImGuiStyle()
|
||||
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.
|
||||
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.
|
||||
SeparatorTextBorderSize = 3.0f; // Thickness of border in SeparatorText()
|
||||
SeparatorSize = 1.0f; // Thickness of border in Separator().
|
||||
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).
|
||||
SeparatorTextPadding = ImVec2(20.0f,3.f);// Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
|
||||
DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
|
||||
@@ -1601,8 +1614,9 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor)
|
||||
DragDropTargetBorderSize = ImTrunc(DragDropTargetBorderSize * scale_factor);
|
||||
DragDropTargetPadding = ImTrunc(DragDropTargetPadding * scale_factor);
|
||||
ColorMarkerSize = ImTrunc(ColorMarkerSize * scale_factor);
|
||||
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
|
||||
SeparatorSize = ImTrunc(SeparatorSize * scale_factor);
|
||||
SeparatorTextBorderSize = ImTrunc(SeparatorTextBorderSize * scale_factor);
|
||||
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
|
||||
DockingSeparatorSize = ImTrunc(DockingSeparatorSize * scale_factor);
|
||||
DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
|
||||
DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
|
||||
@@ -3572,7 +3586,7 @@ bool ImGuiListClipper::Step()
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Generic helper, equivalent to old ImGui::CalcListClipping() but statelesss
|
||||
// Generic helper, equivalent to old ImGui::CalcListClipping() but stateless
|
||||
void ImGui::CalcClipRectVisibleItemsY(const ImRect& clip_rect, const ImVec2& pos, float items_height, int* out_visible_start, int* out_visible_end)
|
||||
{
|
||||
*out_visible_start = ImMax((int)((clip_rect.Min.y - pos.y) / items_height), 0);
|
||||
@@ -3706,6 +3720,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] =
|
||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding
|
||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize
|
||||
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize
|
||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign
|
||||
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding
|
||||
@@ -4351,6 +4366,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
MouseStationaryTimer = 0.0f;
|
||||
|
||||
InputTextPasswordFontBackupFlags = ImFontFlags_None;
|
||||
InputTextReactivateId = 0;
|
||||
TempInputId = 0;
|
||||
memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue));
|
||||
BeginMenuDepth = BeginComboDepth = 0;
|
||||
@@ -5752,6 +5768,8 @@ void ImGui::NewFrame()
|
||||
g.ActiveIdIsJustActivated = false;
|
||||
if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
|
||||
g.TempInputId = 0;
|
||||
if (g.InputTextReactivateId != 0 && g.InputTextReactivateId != g.DeactivatedItemData.ID)
|
||||
g.InputTextReactivateId = 0;
|
||||
if (g.ActiveId == 0)
|
||||
{
|
||||
g.ActiveIdUsingNavDirMask = 0x00;
|
||||
@@ -6090,7 +6108,7 @@ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32
|
||||
draw_list->ChannelsMerge();
|
||||
if (draw_list->CmdBuffer.Size == 0)
|
||||
draw_list->AddDrawCmd();
|
||||
draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // FIXME: Need to stricty ensure ImDrawCmd are not merged (ElemCount==6 checks below will verify that)
|
||||
draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // FIXME: Need to strictly ensure ImDrawCmd are not merged (ElemCount==6 checks below will verify that)
|
||||
ImDrawCmd cmd = draw_list->CmdBuffer.back();
|
||||
IM_ASSERT(cmd.ElemCount == 0);
|
||||
draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col);
|
||||
@@ -12950,16 +12968,16 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
|
||||
// - Each popups may contain child windows, which is why we compare ->RootWindowDockTree!
|
||||
// Window -> Popup1 -> Popup1_Child -> Popup2 -> Popup2_Child
|
||||
// We step through every popup from bottom to top to validate their position relative to reference window.
|
||||
bool ref_window_is_descendent_of_popup = false;
|
||||
bool ref_window_is_descendant_of_popup = false;
|
||||
for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++)
|
||||
if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window)
|
||||
//if (popup_window->RootWindowDockTree == ref_window->RootWindowDockTree) // FIXME-MERGE
|
||||
if (IsWindowWithinBeginStackOf(ref_window, popup_window))
|
||||
{
|
||||
ref_window_is_descendent_of_popup = true;
|
||||
ref_window_is_descendant_of_popup = true;
|
||||
break;
|
||||
}
|
||||
if (!ref_window_is_descendent_of_popup)
|
||||
if (!ref_window_is_descendant_of_popup)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -15467,7 +15485,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
|
||||
// Magic fallback to handle items with no assigned ID, e.g. Text(), Image()
|
||||
// We build a throwaway ID based on current ID stack + relative AABB of items in window.
|
||||
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING/RESIZINGG OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
|
||||
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING/RESIZING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
|
||||
// We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
|
||||
// Rely on keeping other window->LastItemXXX fields intact.
|
||||
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
|
||||
@@ -23297,7 +23315,7 @@ void ImGui::DebugNodeFont(ImFont* font)
|
||||
src_n, src->Name, src->OversampleH, oversample_h, src->OversampleV, oversample_v, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y);
|
||||
}
|
||||
|
||||
DebugNodeFontGlyphesForSrcMask(font, baked, ~0);
|
||||
DebugNodeFontGlyphsForSrcMask(font, baked, ~0);
|
||||
TreePop();
|
||||
}
|
||||
PopID();
|
||||
@@ -23306,7 +23324,7 @@ void ImGui::DebugNodeFont(ImFont* font)
|
||||
Unindent();
|
||||
}
|
||||
|
||||
void ImGui::DebugNodeFontGlyphesForSrcMask(ImFont* font, ImFontBaked* baked, int src_mask)
|
||||
void ImGui::DebugNodeFontGlyphsForSrcMask(ImFont* font, ImFontBaked* baked, int src_mask)
|
||||
{
|
||||
ImDrawList* draw_list = GetWindowDrawList();
|
||||
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
|
||||
@@ -24110,7 +24128,7 @@ void ImGui::DebugNodeColumns(ImGuiOldColumns*) {}
|
||||
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
|
||||
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
|
||||
void ImGui::DebugNodeFont(ImFont*) {}
|
||||
void ImGui::DebugNodeFontGlyphesForSrcMask(ImFont*, ImFontBaked*, int) {}
|
||||
void ImGui::DebugNodeFontGlyphsForSrcMask(ImFont*, ImFontBaked*, int) {}
|
||||
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
|
||||
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}
|
||||
void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {}
|
||||
|
||||
10
imgui.h
10
imgui.h
@@ -20,7 +20,7 @@
|
||||
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
|
||||
// - Issues & support ........... https://github.com/ocornut/imgui/issues
|
||||
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
|
||||
// - Web version of the Demo .... https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html (w/ source code browser)
|
||||
// - Web version of the Demo .... https://pthom.github.io/imgui_manual (w/ source code browser)
|
||||
|
||||
// For FIRST-TIME users having issues compiling/linking/running:
|
||||
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
||||
@@ -30,7 +30,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.92.7 WIP"
|
||||
#define IMGUI_VERSION_NUM 19263
|
||||
#define IMGUI_VERSION_NUM 19264
|
||||
#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_VIEWPORT // In 'docking' WIP branch.
|
||||
@@ -1937,6 +1937,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding
|
||||
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
|
||||
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
|
||||
ImGuiStyleVar_SeparatorSize, // float SeparatorSize
|
||||
ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize
|
||||
ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign
|
||||
ImGuiStyleVar_SeparatorTextPadding, // ImVec2 SeparatorTextPadding
|
||||
@@ -2417,6 +2418,7 @@ struct ImGuiStyle
|
||||
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 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 SeparatorSize; // Thickness of border in Separator()
|
||||
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 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
|
||||
@@ -2533,7 +2535,7 @@ struct ImGuiIO
|
||||
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
|
||||
bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.
|
||||
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
|
||||
bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only).
|
||||
bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will reactivate item and select all text (single-line only).
|
||||
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
|
||||
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
|
||||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
|
||||
@@ -3774,7 +3776,7 @@ enum ImFontAtlasFlags_
|
||||
// - Call Build() + GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data.
|
||||
// - Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture in a format natural to your graphics API.
|
||||
// Common pitfalls:
|
||||
// - If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the
|
||||
// - If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persists up until the
|
||||
// atlas is build (when calling GetTexData*** or Build()). We only copy the pointer, not the data.
|
||||
// - Important: By default, AddFontFromMemoryTTF() takes ownership of the data. Even though we are not writing to it, we will free the pointer on destruction.
|
||||
// You can set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
// How to easily locate code?
|
||||
// - Use Tools->Item Picker to debug break in code by clicking any widgets: https://github.com/ocornut/imgui/wiki/Debug-Tools
|
||||
// - Browse an online version the demo with code linked to hovered widgets: https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html
|
||||
// - Browse pthom's online imgui_explorer: web version the demo w/ source code browser: https://pthom.github.io/imgui_explorer
|
||||
// - Find a visible string and search for it in the code!
|
||||
|
||||
//---------------------------------------------------
|
||||
@@ -294,9 +294,9 @@ static void ShowDockingDisabledMessage()
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
}
|
||||
|
||||
// Helper to wire demo markers located in code to an interactive browser (e.g. imgui_manual)
|
||||
// Helper to wire demo markers located in code to an interactive browser (e.g. https://pthom.github.io/imgui_explorer)
|
||||
#if IMGUI_VERSION_NUM >= 19263
|
||||
namespace ImGui { extern IMGUI_API void DemoMarker(const char* file, int line, const char* section); };
|
||||
namespace ImGui { extern IMGUI_API void DemoMarker(const char* file, int line, const char* section); }
|
||||
#define IMGUI_DEMO_MARKER(section) do { ImGui::DemoMarker("imgui_demo.cpp", __LINE__, section); } while (0)
|
||||
#endif
|
||||
|
||||
@@ -459,6 +459,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::BulletText("The \"Examples\" menu above leads to more demo contents.");
|
||||
ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n"
|
||||
"and Metrics/Debugger (general purpose Dear ImGui debugging tool).");
|
||||
ImGui::BulletText("Web demo (w/ source code browser): ");
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGui::TextLinkOpenURL("https://pthom.github.io/imgui_explorer");
|
||||
|
||||
ImGui::SeparatorText("PROGRAMMER GUIDE:");
|
||||
ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!");
|
||||
@@ -587,7 +590,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
|
||||
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
|
||||
ImGui::Checkbox("io.ConfigInputTextEnterKeepActive", &io.ConfigInputTextEnterKeepActive);
|
||||
ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only).");
|
||||
ImGui::SameLine(); HelpMarker("Pressing Enter will reactivate item and select all text (single-line only).");
|
||||
ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
|
||||
ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
|
||||
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);
|
||||
@@ -1794,7 +1797,6 @@ static void DemoWindowWidgetsDragsAndSliders()
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround);
|
||||
ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_ColorMarkers", &flags, ImGuiSliderFlags_ColorMarkers);
|
||||
//ImGui::CheckboxFlags("ImGuiSliderFlags_ColorMarkersG", &flags, 1 << ImGuiSliderFlags_ColorMarkersIndexShift_); // Not explicitly documented but possible.
|
||||
|
||||
// Drags
|
||||
static float drag_f = 0.5f;
|
||||
@@ -2010,29 +2012,32 @@ static void DemoWindowWidgetsMultiComponents()
|
||||
static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
|
||||
static int vec4i[4] = { 1, 5, 100, 255 };
|
||||
|
||||
static ImGuiSliderFlags flags = 0;
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_ColorMarkers", &flags, ImGuiSliderFlags_ColorMarkers); // Only passing this to Drag/Sliders
|
||||
|
||||
ImGui::SeparatorText("2-wide");
|
||||
ImGui::InputFloat2("input float2", vec4f);
|
||||
ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f);
|
||||
ImGui::InputInt2("input int2", vec4i);
|
||||
ImGui::DragInt2("drag int2", vec4i, 1, 0, 255);
|
||||
ImGui::SliderInt2("slider int2", vec4i, 0, 255);
|
||||
ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::DragInt2("drag int2", vec4i, 1, 0, 255, NULL, flags);
|
||||
ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::SliderInt2("slider int2", vec4i, 0, 255, NULL, flags);
|
||||
|
||||
ImGui::SeparatorText("3-wide");
|
||||
ImGui::InputFloat3("input float3", vec4f);
|
||||
ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f);
|
||||
ImGui::InputInt3("input int3", vec4i);
|
||||
ImGui::DragInt3("drag int3", vec4i, 1, 0, 255);
|
||||
ImGui::SliderInt3("slider int3", vec4i, 0, 255);
|
||||
ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::DragInt3("drag int3", vec4i, 1, 0, 255, NULL, flags);
|
||||
ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::SliderInt3("slider int3", vec4i, 0, 255, NULL, flags);
|
||||
|
||||
ImGui::SeparatorText("4-wide");
|
||||
ImGui::InputFloat4("input float4", vec4f);
|
||||
ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f);
|
||||
ImGui::InputInt4("input int4", vec4i);
|
||||
ImGui::DragInt4("drag int4", vec4i, 1, 0, 255);
|
||||
ImGui::SliderInt4("slider int4", vec4i, 0, 255);
|
||||
ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::DragInt4("drag int4", vec4i, 1, 0, 255, NULL, flags);
|
||||
ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f, NULL, flags);
|
||||
ImGui::SliderInt4("slider int4", vec4i, 0, 255, NULL, flags);
|
||||
|
||||
ImGui::SeparatorText("Ranges");
|
||||
static float begin = 10, end = 90;
|
||||
@@ -8613,6 +8618,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");
|
||||
SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f");
|
||||
SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.");
|
||||
SliderFloat("SeparatorSize", &style.SeparatorSize, 0.0f, 10.0f, "%.0f");
|
||||
SliderFloat("SeparatorTextBorderSize", &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
|
||||
SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f");
|
||||
SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%.0f");
|
||||
@@ -9086,7 +9092,8 @@ struct ExampleAppConsole
|
||||
ImGui::Separator();
|
||||
|
||||
// Reserve enough left-over height for 1 separator + 1 input text
|
||||
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
const float footer_height_to_reserve = style.SeparatorSize + style.ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
{
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
@@ -10115,7 +10122,7 @@ static void ShowExampleAppWindowTitles(bool*)
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 200), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Same title as another window##2");
|
||||
IMGUI_DEMO_MARKER("Examples/Manipulating window titles##2");;
|
||||
IMGUI_DEMO_MARKER("Examples/Manipulating window titles##2");
|
||||
ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique.");
|
||||
ImGui::End();
|
||||
|
||||
|
||||
@@ -3209,7 +3209,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
|
||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
{
|
||||
// Store a short copy of filename into into the font name for convenience
|
||||
// Store a short copy of filename into the font name for convenience
|
||||
const char* p;
|
||||
for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "%s", p);
|
||||
@@ -3217,7 +3217,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
|
||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||
}
|
||||
|
||||
// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
|
||||
// NB: Transfer ownership of 'font_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
|
||||
ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
|
||||
{
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||
|
||||
@@ -545,7 +545,7 @@ inline float ImLinearSweep(float current, float target, float speed) { if (cu
|
||||
inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
|
||||
inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
inline float ImExponentialMovingAverage(float avg, float sample, int n){ avg -= avg / n; avg += sample / n; return avg; }
|
||||
inline float ImExponentialMovingAverage(float avg, float sample, int n){ avg -= avg / (float)n; avg += sample / (float)n; return avg; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Geometry
|
||||
@@ -2667,6 +2667,7 @@ struct ImGuiContext
|
||||
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
|
||||
ImFontBaked InputTextPasswordFontBackupBaked;
|
||||
ImFontFlags InputTextPasswordFontBackupFlags;
|
||||
ImGuiID InputTextReactivateId; // ID of InputText to reactivate on next frame (for io.ConfigInputTextEnterKeepActive behavior)
|
||||
ImGuiID TempInputId; // Temporary text input when using Ctrl+Click on a slider, etc.
|
||||
ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types
|
||||
int BeginMenuDepth;
|
||||
@@ -3938,6 +3939,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
|
||||
IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners
|
||||
IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir);
|
||||
IMGUI_API void ExtendHitBoxWhenNearViewportEdge(ImGuiWindow* window, ImRect* bb, float threshold, ImGuiAxis axis);
|
||||
|
||||
// Widgets low-level behaviors
|
||||
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
|
||||
@@ -3956,8 +3958,8 @@ namespace ImGui
|
||||
// Template functions are instantiated in imgui_widgets.cpp for a finite number of types.
|
||||
// To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036).
|
||||
// e.g. " extern template IMGUI_API float RoundScalarWithFormatT<float, float>(const char* format, ImGuiDataType data_type, float v); "
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API float ScaleRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API float ScaleRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||
template<typename T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
|
||||
@@ -4011,7 +4013,7 @@ namespace ImGui
|
||||
IMGUI_API bool BeginErrorTooltip();
|
||||
IMGUI_API void EndErrorTooltip();
|
||||
|
||||
// Demo Doc Marker for e.g. imgui_manual
|
||||
// Demo Doc Marker for e.g. imgui_explorer
|
||||
IMGUI_API void DemoMarker(const char* file, int line, const char* section);
|
||||
|
||||
// Debug Tools
|
||||
@@ -4034,7 +4036,7 @@ namespace ImGui
|
||||
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);
|
||||
IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);
|
||||
IMGUI_API void DebugNodeFont(ImFont* font);
|
||||
IMGUI_API void DebugNodeFontGlyphesForSrcMask(ImFont* font, ImFontBaked* baked, int src_mask);
|
||||
IMGUI_API void DebugNodeFontGlyphsForSrcMask(ImFont* font, ImFontBaked* baked, int src_mask);
|
||||
IMGUI_API void DebugNodeFontGlyph(ImFont* font, const ImFontGlyph* glyph);
|
||||
IMGUI_API void DebugNodeTexture(ImTextureData* tex, int int_id, const ImFontAtlasRect* highlight_rect = NULL); // ID used to facilitate persisting the "current" texture.
|
||||
IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label);
|
||||
|
||||
@@ -919,7 +919,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
|
||||
const ImU32 cross_col = GetColorU32(ImGuiCol_Text);
|
||||
const ImVec2 cross_center = bb.GetCenter() - ImVec2(0.5f, 0.5f);
|
||||
const float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f;
|
||||
const float cross_thickness = 1.0f; // FIXME-DPI
|
||||
const float cross_thickness = 1.0f * (float)(int)g.Style._MainScale; // FIXME-DPI
|
||||
window->DrawList->AddLine(cross_center + ImVec2(+cross_extent, +cross_extent), cross_center + ImVec2(-cross_extent, -cross_extent), cross_col, cross_thickness);
|
||||
window->DrawList->AddLine(cross_center + ImVec2(+cross_extent, -cross_extent), cross_center + ImVec2(-cross_extent, +cross_extent), cross_col, cross_thickness);
|
||||
|
||||
@@ -980,6 +980,16 @@ ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
|
||||
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y + border_top, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
|
||||
}
|
||||
|
||||
void ImGui::ExtendHitBoxWhenNearViewportEdge(ImGuiWindow* window, ImRect* bb, float threshold, ImGuiAxis axis)
|
||||
{
|
||||
ImRect window_rect = window->RootWindow->Rect();
|
||||
ImRect viewport_rect = window->Viewport->GetMainRect();
|
||||
if (window_rect.Min[axis] == viewport_rect.Min[axis] && bb->Min[axis] > window_rect.Min[axis] && bb->Min[axis] - threshold <= window_rect.Min[axis])
|
||||
bb->Min[axis] = window_rect.Min[axis];
|
||||
if (window_rect.Max[axis] == viewport_rect.Max[axis] && bb->Max[axis] < window_rect.Max[axis] && bb->Max[axis] + threshold >= window_rect.Max[axis])
|
||||
bb->Max[axis] = window_rect.Max[axis];
|
||||
}
|
||||
|
||||
void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -1042,11 +1052,15 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), grab_h_minsize, scrollbar_size_v);
|
||||
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
|
||||
|
||||
// As a special thing, we allow scrollbar near the edge of a screen/viewport to be reachable with mouse at the extreme edge (#9276)
|
||||
ImRect bb_hit = bb_frame;
|
||||
ExtendHitBoxWhenNearViewportEdge(window, &bb_hit, g.Style.WindowBorderSize, (ImGuiAxis)(axis ^ 1));
|
||||
|
||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||
bool held = false;
|
||||
bool hovered = false;
|
||||
ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||
ButtonBehavior(bb_hit, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_visible_v);
|
||||
float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max);
|
||||
@@ -1536,7 +1550,7 @@ bool ImGui::TextLink(const char* label)
|
||||
}
|
||||
|
||||
float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontBakedScale * 0.20f);
|
||||
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf)); // FIXME-TEXT: Underline mode // FIXME-DPI
|
||||
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
|
||||
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
|
||||
RenderText(bb.Min, label, label_end);
|
||||
@@ -1671,9 +1685,13 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags, float thickness)
|
||||
|
||||
// We don't provide our width to the layout so that it doesn't get feed back into AutoFit
|
||||
// FIXME: This prevents ->CursorMaxPos based bounding box evaluation from working (e.g. TableEndCell)
|
||||
const float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change.
|
||||
|
||||
// Between 1.71 and 1.92.7, we maintained a hack where a 1.0f thin Separator() would not impact layout.
|
||||
// This was mostly chosen to allow backward compatibility with user's code assuming zero-height when calculating height for layout (e.g. bottom alignment of a status bar).
|
||||
// In order to handle scaling we need to scale separator thickness and it would not makes sense to have a disparity depending on height.
|
||||
////float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change.
|
||||
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness));
|
||||
ItemSize(ImVec2(0.0f, thickness_for_layout));
|
||||
ItemSize(ImVec2(0.0f, thickness));
|
||||
|
||||
if (ItemAdd(bb, 0))
|
||||
{
|
||||
@@ -1699,14 +1717,13 @@ void ImGui::Separator()
|
||||
return;
|
||||
|
||||
// Those flags should eventually be configurable by the user
|
||||
// FIXME: We cannot g.Style.SeparatorTextBorderSize for thickness as it relates to SeparatorText() which is a decorated separator, not defaulting to 1.0f.
|
||||
ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
|
||||
|
||||
// Only applies to legacy Columns() api as they relied on Separator() a lot.
|
||||
if (window->DC.CurrentColumns)
|
||||
flags |= ImGuiSeparatorFlags_SpanAllColumns;
|
||||
|
||||
SeparatorEx(flags, 1.0f);
|
||||
SeparatorEx(flags, g.Style.SeparatorSize);
|
||||
}
|
||||
|
||||
void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w)
|
||||
@@ -2568,9 +2585,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);
|
||||
|
||||
// Convert to parametric space, apply delta, convert back
|
||||
float v_old_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float v_old_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float v_new_parametric = v_old_parametric + g.DragCurrentAccum;
|
||||
v_cur = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new_parametric, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
v_cur = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new_parametric, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
v_old_ref_for_accum_remainder = v_old_parametric;
|
||||
}
|
||||
else
|
||||
@@ -2587,7 +2604,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
if (is_logarithmic)
|
||||
{
|
||||
// Convert to parametric space, apply delta, convert back
|
||||
float v_new_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float v_new_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
g.DragCurrentAccum -= (float)(v_new_parametric - v_old_ref_for_accum_remainder);
|
||||
}
|
||||
else
|
||||
@@ -2663,6 +2680,20 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only clamp Ctrl+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
|
||||
static bool TempInputIsClampEnabled(ImGuiSliderFlags flags, ImGuiDataType data_type, const void* p_min, const void* p_max)
|
||||
{
|
||||
if ((flags & ImGuiSliderFlags_ClampOnInput) && (p_min != NULL || p_max != NULL))
|
||||
{
|
||||
const int clamp_range_dir = (p_min != NULL && p_max != NULL) ? ImGui::DataTypeCompare(data_type, p_min, p_max) : 0; // -1 when *p_min < *p_max, == 0 when *p_min == *p_max
|
||||
if (p_min == NULL || p_max == NULL || clamp_range_dir < 0)
|
||||
return true;
|
||||
if (clamp_range_dir == 0)
|
||||
return ImGui::DataTypeIsZero(data_type, p_min) ? ((flags & ImGuiSliderFlags_ClampZeroRange) != 0) : true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
|
||||
// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags)
|
||||
@@ -2728,16 +2759,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
|
||||
if (temp_input_is_active)
|
||||
{
|
||||
// Only clamp Ctrl+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
|
||||
bool clamp_enabled = false;
|
||||
if ((flags & ImGuiSliderFlags_ClampOnInput) && (p_min != NULL || p_max != NULL))
|
||||
{
|
||||
const int clamp_range_dir = (p_min != NULL && p_max != NULL) ? DataTypeCompare(data_type, p_min, p_max) : 0; // -1 when *p_min < *p_max, == 0 when *p_min == *p_max
|
||||
if (p_min == NULL || p_max == NULL || clamp_range_dir < 0)
|
||||
clamp_enabled = true;
|
||||
else if (clamp_range_dir == 0)
|
||||
clamp_enabled = DataTypeIsZero(data_type, p_min) ? ((flags & ImGuiSliderFlags_ClampZeroRange) != 0) : true;
|
||||
}
|
||||
const bool clamp_enabled = TempInputIsClampEnabled(flags, data_type, p_min, p_max);
|
||||
return TempInputScalar(frame_bb, id, label, data_type, p_data, format, clamp_enabled ? p_min : NULL, clamp_enabled ? p_max : NULL);
|
||||
}
|
||||
|
||||
@@ -2937,14 +2959,14 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
|
||||
|
||||
// Convert a value v in the output space of a slider into a parametric position on the slider itself (the logical opposite of ScaleValueFromRatioT)
|
||||
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
||||
float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
||||
float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, TYPE v_max, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
||||
{
|
||||
if (v_min == v_max)
|
||||
return 0.0f;
|
||||
IM_UNUSED(data_type);
|
||||
|
||||
const TYPE v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min);
|
||||
if (is_logarithmic)
|
||||
if (logarithmic_zero_epsilon > 0.0f) // == is_logarithmic from caller
|
||||
{
|
||||
bool flipped = v_max < v_min;
|
||||
|
||||
@@ -2994,7 +3016,7 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T
|
||||
|
||||
// Convert a parametric position on a slider into a value v in the output space (the logical opposite of ScaleRatioFromValueT)
|
||||
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
||||
TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
||||
TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
||||
{
|
||||
// We special-case the extents because otherwise our logarithmic fudging can lead to "mathematically correct"
|
||||
// but non-intuitive behaviors like a fully-left slider not actually reaching the minimum value. Also generally simpler.
|
||||
@@ -3004,7 +3026,7 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
|
||||
return v_max;
|
||||
|
||||
TYPE result = (TYPE)0;
|
||||
if (is_logarithmic)
|
||||
if (logarithmic_zero_epsilon > 0.0f) // == is_logarithmic from caller
|
||||
{
|
||||
// Fudge min/max to avoid getting silly results close to zero
|
||||
FLOATTYPE v_min_fudged = (ImAbs((FLOATTYPE)v_min) < logarithmic_zero_epsilon) ? ((v_min < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_min;
|
||||
@@ -3109,7 +3131,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
const float mouse_abs_pos = g.IO.MousePos[axis];
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
@@ -3164,7 +3186,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
}
|
||||
else if (g.SliderCurrentAccumDirty)
|
||||
{
|
||||
clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f)) // This is to avoid applying the saturation when already past the limits
|
||||
{
|
||||
@@ -3178,10 +3200,10 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
clicked_t = ImSaturate(clicked_t + delta);
|
||||
|
||||
// Calculate what our "new" clicked_t will be, and thus how far we actually moved the slider, and subtract this from the accumulator
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat))
|
||||
v_new = RoundScalarWithFormatT<TYPE>(format, data_type, v_new);
|
||||
float new_clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float new_clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
if (delta > 0)
|
||||
g.SliderCurrentAccum -= ImMin(new_clicked_t - old_clicked_t, delta);
|
||||
@@ -3199,7 +3221,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
|
||||
if (set_new_value)
|
||||
{
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
// Round to user desired precision based on format string
|
||||
if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat))
|
||||
@@ -3221,7 +3243,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
else
|
||||
{
|
||||
// Output grab position so it can be displayed by the caller
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
@@ -3329,7 +3351,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
if (temp_input_is_active)
|
||||
{
|
||||
// Only clamp Ctrl+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
|
||||
const bool clamp_enabled = (flags & ImGuiSliderFlags_ClampOnInput) != 0;
|
||||
const bool clamp_enabled = (flags & ImGuiSliderFlags_ClampOnInput) != 0; // Don't use TempInputIsClampEnabled()
|
||||
return TempInputScalar(frame_bb, id, label, data_type, p_data, format, clamp_enabled ? p_min : NULL, clamp_enabled ? p_max : NULL);
|
||||
}
|
||||
|
||||
@@ -3714,29 +3736,28 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
g.LastItemData.ItemFlags |= ImGuiItemFlags_NoMarkEdited; // Because TempInputText() uses ImGuiInputTextFlags_MergedItem it doesn't submit a new item, so we poke LastItemData.
|
||||
bool value_changed = false;
|
||||
if (TempInputText(bb, id, label, data_buf, IM_COUNTOF(data_buf), flags))
|
||||
if (!TempInputText(bb, id, label, data_buf, IM_COUNTOF(data_buf), flags))
|
||||
return false;
|
||||
|
||||
// Backup old value
|
||||
size_t data_type_size = type_info->Size;
|
||||
ImGuiDataTypeStorage data_backup;
|
||||
memcpy(&data_backup, p_data, data_type_size);
|
||||
|
||||
// Apply new value (or operations) then clamp
|
||||
DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL);
|
||||
if (p_clamp_min || p_clamp_max)
|
||||
{
|
||||
// Backup old value
|
||||
size_t data_type_size = type_info->Size;
|
||||
ImGuiDataTypeStorage data_backup;
|
||||
memcpy(&data_backup, p_data, data_type_size);
|
||||
|
||||
// Apply new value (or operations) then clamp
|
||||
DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL);
|
||||
if (p_clamp_min || p_clamp_max)
|
||||
{
|
||||
if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0)
|
||||
ImSwap(p_clamp_min, p_clamp_max);
|
||||
DataTypeClamp(data_type, p_data, p_clamp_min, p_clamp_max);
|
||||
}
|
||||
|
||||
// Only mark as edited if new value is different
|
||||
g.LastItemData.ItemFlags &= ~ImGuiItemFlags_NoMarkEdited;
|
||||
value_changed = memcmp(&data_backup, p_data, data_type_size) != 0;
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0)
|
||||
ImSwap(p_clamp_min, p_clamp_max);
|
||||
DataTypeClamp(data_type, p_data, p_clamp_min, p_clamp_max);
|
||||
}
|
||||
|
||||
// Only mark as edited if new value is different
|
||||
g.LastItemData.ItemFlags &= ~ImGuiItemFlags_NoMarkEdited;
|
||||
bool value_changed = memcmp(&data_backup, p_data, data_type_size) != 0;
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@@ -4747,7 +4768,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
wrap_width = ImMax(1.0f, GetContentRegionAvail().x + (draw_window->ScrollbarY ? 0.0f : -g.Style.ScrollbarSize));
|
||||
|
||||
const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateId == id) && ((g.NavActivateFlags & ImGuiActivateFlags_PreferInput) || (g.NavInputSource == ImGuiInputSource_Keyboard)));
|
||||
|
||||
const bool input_requested_by_reactivate = (g.InputTextReactivateId == id); // for io.ConfigInputTextEnterKeepActive
|
||||
const bool user_clicked = hovered && io.MouseClicked[0];
|
||||
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
|
||||
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
|
||||
@@ -4758,7 +4779,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->WantReloadUserBuf);
|
||||
const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_reactivate);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
@@ -5095,11 +5116,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
bool is_new_line = is_multiline && !is_gamepad_validate && (is_shift_enter || (is_enter && !ctrl_enter_for_new_line) || (is_ctrl_enter && ctrl_enter_for_new_line));
|
||||
if (!is_new_line)
|
||||
{
|
||||
validated = true;
|
||||
validated = clear_active_id = true;
|
||||
if (io.ConfigInputTextEnterKeepActive && !is_multiline)
|
||||
{
|
||||
// Queue reactivation, so that e.g. IsItemDeactivatedAfterEdit() will work. (#9001)
|
||||
state->SelectAll(); // No need to scroll
|
||||
else
|
||||
clear_active_id = true;
|
||||
g.InputTextReactivateId = id; // Mark for reactivation on next frame
|
||||
}
|
||||
}
|
||||
else if (!is_readonly)
|
||||
{
|
||||
@@ -5573,7 +5596,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll);
|
||||
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
|
||||
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
|
||||
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_InputTextCursor), 1.0f); // FIXME-DPI: Cursor thickness (#7031)
|
||||
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)
|
||||
|
||||
// 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.
|
||||
@@ -6431,7 +6454,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
if (g.Style.FrameBorderSize > 0.0f)
|
||||
RenderFrameBorder(bb.Min, bb.Max, rounding);
|
||||
else
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color buttons are often in need of some sort of border // FIXME-DPI
|
||||
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
|
||||
}
|
||||
|
||||
// Drag and Drop Source
|
||||
|
||||
@@ -315,7 +315,7 @@ static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
// but we'll now add more waste for everything we've visited
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
@@ -470,7 +470,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
// stitched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
|
||||
@@ -886,7 +886,7 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl
|
||||
// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
|
||||
|
||||
STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
|
||||
// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
|
||||
// the same as stbtt_GetCodepointBitmap, but you can specify a subpixel
|
||||
// shift for the character
|
||||
|
||||
STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
|
||||
|
||||
Reference in New Issue
Block a user