Squashed 'external/imgui/imgui/' changes from 5c1d2d1e4c..f5befd2d29
f5befd2d29 Version 1.91.9b cfed7a3a54 Tables: fixed assert/issues loading settings. (#8496, #7934) 93b446a962 Backtrack of version tagging 1.92.0 > 1.91.9b for publishing a hotfix (#8496) a7dc184772 Moved ImDrawIdx definition lower in imgui.h. Moved ImTextureID slightly below in its own section. bfaef8ca17 Version 1.92.0 WIP 2737dbb1e1 Docs: Fixed typo. Very oops. (#8495) 4d4f1fd364 Docs: retroactively document ConfigData->Sources renaming. (#8495) d6493aab02 Fix typo in comment (#8494) 97428e8ac9 Version 1.91.9 ea2a12112d Misc: Various zealous warning fixes for newer version of Clang. b758b8223f InputText: Pasting a multi-line buffer into a single-line edit replaces carriage return by spaces. (#8459) 79bba34c5f Revert "Added ImGuiKey_AbntC1, ImGuiKey_AbntC2 + Backends: GLFW, Win32: added support. (#8468)" d9dad2f4a1 Scrollbar: stabilize visibility of ScrollbarX when detecting a feedback loop. (#8488, #3285, #4539) 6e30c42101 Tables: fixed an issue with TableSetupColumn() overriding ini data. (#7934) de4f77b0ac Backends: DX12: comment about using SrvDescriptorAllocFn/SrvDescriptorFreeFn. 09654f4e8c Revert "Examples: Updated all .vcxproj from VS2015 to VS2019 (toolset v140 to v142), Windows SDK 8.1 to 10." 557c77e455 Added ImGuiKey_AbntC1, ImGuiKey_AbntC2 + Backends: GLFW, Win32: added support. (#8468) 6da230636b Examples: Updated all .vcxproj from VS2015 to VS2019 (toolset v140 to v142), Windows SDK 8.1 to 10. 51e4cba909 Backends: Fixed zealous warnings. 39585aa90d Amend Changelog to talk about OEM keys. (#7136, #7201, #7206, #7306, #7670, #7672, #8468) a9e53829d2 Backends: Win32, SDL2, SDL3, GLFW: prioritize scancodes instead of translated keycodes when dealing with OEM keys + Added ImGuiKey_Oem102. (#7136, #7201, #7206, #7306, #7670, #7672, #8468) 88d4827b64 Update FAQ.md for SDL3 (#8480) 3c3d943fb1 Docs: Fix some typos (#8473) 806731e37a Set IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS on 3DS sdk (#8477, #8476) 1ec99f4fd3 Internals: added ImStrlen/ImMemchr #define to facilitate experimenting with variations. (#8421) 377a387a42 Add proper ImGuiTextBuffer::resize() support other than 0. 9f49292b35 Internals: Menus: reworked mangling of menu windows to use "###Menu_00" etc. instead of "##Menu_00". 119dfbc627 Debug Tools: Tweaked layout of ID Stack Tool and always display full path. (#4631) fcec08f7ae Demo: (Refactor) Moved ExampleTreeNode contents below ShowDemoWindow() so main entry point is more visible to casual reader. 324172fb1f Demo: (Refactor) Moved DemoWindowWidgets() below the functions it calls, reducing amount of forward declarations. a7657f2ed4 Examples: SDL3: Added comments to clarify setup for users of the unfortunate SDL_MAIN_USE_CALLBACKS feature. (#8455) df31774327 Disabled: Fixed an issue restoring Alpha in EndDisabled() when using nested BeginDisabled() calls with PushStyleVar(ImGuiStyleVar_DisabledAlpha) within. (#8454, #7640) 71b160cdbb Demo: (Refactor) Moved code into DemoWindowWidgetsDisableBlocks() section. 7a919e80c9 Demo: (Refactor) Moved code into DemoWindowWidgetsQueryingStatuses() section. 0758594bd2 Demo: (Refactor) Moved code into DemoWindowWidgetsDragAndDrop() section. 9b486e47fe Demo: (Refactor) Moved code into DemoWindowWidgetsDragsAndSliders(), DemoWindowWidgetsMultiComponents(), DemoWindowWidgetsVerticalSliders() sections. caf3faa054 Demo: (Refactor) Moved code into DemoWindowWidgetsColorAndPickers() section. 510a9a77d6 Demo: (Refactor) Moved code into DemoWindowWidgetsDataTypes() section. 4d0c776a80 Demo: (Refactor) Moved code into DemoWindowWidgetsPlotting(), DemoWindowWidgetsProgressBars(), DemoWindowWidgetsTabs() sections. 4450d61ac2 Demo: (Refactor) Moved code into DemoWindowWidgetsSelectables(), DemoWindowWidgetsTextFilter(), DemoWindowWidgetsTextInputs() sections. 22baec494b Demo: (Refactor) Moved code into DemoWindowWidgetsComboBoxes(), DemoWindowWidgetsImages(), DemoWindowWidgetsListBoxes() sections. 94877a137d Demo: (Refactor) Moved code into DemoWindowWidgetsBullets(), DemoWindowWidgetsCollapsingHeaders(), DemoWindowWidgetsCollapsingText() sections. de3f68a233 Demo: (Refactor) Moved code into DemoWindowWidgetsTooltips(), DemoWindowWidgetsTreeNodes() sections. b2c55c9db5 Demo: (Refactor) Moved code into DemoWindowWidgetsBasic() section. eefd2da0f6 Demo: (Refactor) Added new empty sections.. Renamed existing helper functions. ce13f6b73e Backends: GLFW: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled with asserts enabled. (#8452) 4819eae867 Clipper: Fixed an issue where passing an out of bound index to IncludeItemByIndex() could incorrectly offset the final cursor. c5ade6591e TextLink(), TextLinkOpenURL(): fixed honoring text baseline alignment. (#8451, #7660) 9c2876b9f8 ShowFontAtlas() uses ImageWithBg(). (#8131, #8238) 1aab00da85 Misc shallow tweaks/tidying up. (#8446) 482a1f50b6 Internals: rename ImGuiDataVarInfo to ImGuiStyleVarInfo. Move ImGuiStyleMod, ImGuiColorMod to own section. 494ea57b65 Image: removed 'tint_col', 'border_col' parameters from Image(). Added ImageWithBg(). Added style.ImageBorderSize, ImGuiStyleVar_ImageBorderSize. (#8131, #8238) cdafefd4be Backends: WebGPU: Add nextInChain field for VertexAttributes under Dawn (#8438) 8bd3e20c86 Backends: WebGPU: include imgui.h before backend check (#8437) aa83d5d455 Backends: SDL2, SDL3: Only start SDL_CaptureMouse() when mouse is being dragged. (#6410, #3650) aaacb01b8d Backends: WebGPU: Recreate image bind groups during render. (#8426, #8046, #7765, #8027) 9996a2d51b Backends: WebGPU: update code for latest webgpu-native changes. Fix for Emscripten. (#8426) 6aa0810de5 Backends: WebGPU: update code for latest webgpu-native changes. Amend. (#8426) 4f4fb1d220 Backends: WebGPU: update code for latest webgpu-native changes. (#8426) 242d856ede Examples: SDL3+SDL_Renderer: removed reference to OpenGL to remove confusion. (#8434) a86fcbd947 Examples: SDL3+SDL_Renderer: removed reference to OpenGL to remove confusion. (#8434) 4c0604ec2e Font: shallow refactor, rename ConfigData[] fields to Sources[], ConfigDataCount to SourcesCount. 6e29450f76 Internals: added IsItemActiveAsInputText() helper. 030746faff Debug Tools: Added io.ConfigDebugHighlightIdConflictsShowItemPicker. (#7961, #7669) dac40d0487 Backends: SDL2, SDL3: don't call SDL_GetGlobalMouseState() when mouse position is in relative mode. (#8425, #8407) ef969a53f5 Tabs: fixed Unsaved Marker not being visible when Close Button is. (#8430, #8387) 5dce79e941 Backends: DirectX12: Fixed an issue where pre-1.91.5 legacy ImGui_ImplDX12_Init() signature started breaking in 1.91.8 due to missing command queue. (#8429) 74afea04d6 Fix typos in docs (#8427) edc66d79c7 Nav: extract code into a NavUpdateWindowingApplyFocus() so it may be reused elsewhere. 434b7710f3 Internals: packing ImGuiDataVarInfo + misc renaming + value of ImGuiDataType_Pointer doesn't need to be Count+1 1e18a6cf60 Examples: GLFW+Vulkan: make GLFW_DIR overridable in cmake bit. (#8419) a6bcbb173b Examples: Android: Update kotlin version (#8409) 6dc376f676 ImFontAtlas: added software/drawlist version of ImGuiMouseCursor_Wait/ImGuiMouseCursor_Progress + moved GetMouseCursorTexData() to internals. 85c488ee12 Hot-fix for broken MouseDrawCursor support for ImGuiMouseCursor_Wait/ImGuiMouseCursor_Progress/ImGuiMouseCursor_NotAllowed. 05742f9b6f Tables: share code between TableSetupColumn() and TableLoadSettings(). (#7934) 8b7b3ce03e Tables: fixed an issue where Columns Width state wouldn't be correctly restored when hot-reloading .ini state. (#7934) eec097fe35 Added ImGuiMouseCursor_Progress mouse cursor 8a35386+ support in SDL2,SDL3,Win32,Allegro5 backends. 8a35386ba7 Added ImGuiMouseCursor_Wait mouse cursor (busy/wait/hourglass shape) + support in SDL2,SDL3,Win32,Allegro5 backends. 8f0411ff03 Backends: OpenGL3: Lazily reinitialize embedded GL loader for when calling backend from e.g. other DLL boundaries. (#8406) c4a32a129d Tabs: fixed middle-button to close not checking hovering, only close button visibility. (#8399, #8387) 78ec1272e9 ImDrawList: added InitialFringeScale in ImDrawListSharedData. Default to 1.0f. 2860d7ba05 Selectable: Fixed horizontal label alignment with SelectableTextAlign.x > 0 and specifying a selectable size. (#8338) 474305c476 ImFont: simpler constructor. ec4cd2cb8c Backends: Vulkan: Fixed crash with using no prototypes + *BREAKING* Added ApiVersion to ImGui_ImplVulkan_LoadFunctions(). (#8326, #8365, #8400) 98c2f6b0c4 Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651) e1ae7db4cc Backends: Vulkan: Fixed building with older headers not supporting VK_HEADER_VERSION_COMPLETE. (#8326, #8365) 12963f5231 Examples: Vulkan: make ApiVersion a little more visible in examples. (#8326, #8365) 890ead6a71 Backends: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" without -KHR on API 1.3. (#8326, #8365) f94a5f0e8c Docs: Update doc about plutosvg (#8395) b78cc37891 Backends: SDL2: Fixed build for versions older than 2.0.14. (#7660) a931fb7f51 Fixed static analyzer warning. 7cd31c3557 Tables: tamed some .ini settings optimizations to more accurately allow overwriting/hot-reloading settings. (#7934) 7221f5e739 Styles, Tabs: Fixed ef7ffaf. (#8387) ef7ffaff74 Styles, Tabs: (Breaking) Renamed TabMinWidthForCloseButton to TabCloseButtonMinWidthUnselected. Added TabCloseButtonMinWidthSelected. (#8387) 3d900edba7 Examples: Win32+DirectX12: Fixed ExampleDescriptorHeapAllocator overflow free index. 6916f935eb InputText: Allow CTRL+Shift+Z to redo even outside of OSX. (#8389) 3b2f2602b4 Windows: Fixed an issue where BeginChild() inside a collapsed Begin() wouldn't inherit the SkipItems flag. 4dc9df6aae Tables: fixed an issue where Columns Visible/Hidden state wouldn't be correctly overridden when hot-reloading .ini state. (#7934) 88cda0cab6 Fixed minor warning. Added comment. a431e1277e Backends: SDL2, SDL3: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler. (#7660) a18622c369 TextLinkOpenURL(): fixed default Win32 io.PlatformOpenInShellFn handler to handle UTF-8 regardless of system regional settings. (#7660) 2206e31e54 Demo: Combos: demonstrate a very simple way to add a filter to a combo. (#718) e8ad60cc4f Fix typo (#8382) 50dbb086f2 Tables: sneakily honor ImGuiNextWindowDataFlags_HasChildFlags/ImGuiNextWindowDataFlags_HasWindowFlags as a way to facilitate various hacks/workarounds. e368015d79 Tables: a clipped scrolling table correctly clears SetNextWindowXXX flags. (#8196) e5668b8c73 Internals: rename ImGuiNextWindowData::Flags to HasFlags for consistency and to reduce mistakes. 4982602f6f Windows, Style: Added style.WindowBorderHoverPadding setting to configure inner/outer padding applied to hit-testing of windows borders. 914fbcf2e5 Fonts: removed unnecessary const qualifier from ImFont::FindGlyph() 4f1d3809c3 Fixed tabs and spaces (#8377) 0625b37760 Scrollbar: Rework logic that fades-out scrollbar when it becomes too small. cfed18afc7 Add ImFontConfig::GlyphExtraAdvanceX as a replacement for GlyphExtraSpacing.x (#242) 2d20e13746 Backends: GLFW: Added comment about io.AddMouseSourceEvent() not being properly called. (#8374) 1a31e31ae9 (Breaking) Fonts: removed ImFontConfig::GlyphExtraSpacing option which seems largely obsolete and unused. (#242) de962e83d0 ImFont: remove SetGlyphVisible() da0ba9e2fe Backends: WebGPU: add type alias for dawn WGPUProgrammableStageDescriptor -> WGPUComputeState. (#8369) 5dd84082ab InputTextWithHint(): Fixed buffer overflow when user callback modifies the buffer contents in a way that alters hint visibility. (#8368) 204cebc8fc Backends: Metal: Fixed a crash on application resources. (#8367, #7419) [@anszom] 6265339995 Fixed IsItemDeactivatedAfterEdit() signal being broken for Checkbox(), RadioButton(), Selectable(). (#8370) f820bf7cd4 Version 1.91.9 WIP e4db4e423d Internals: renamed GetIOEx() to GetIO(). Added GetPlatformIO() explicit context variant. - OOPS e2a99b5760 Internals: renamed GetIOEx() to GetIO(). Added GetPlatformIO() explicit context variant. dbb5eeaadf Version 1.91.8 e6c5296f30 Examples: SDL3: Fix for Emscripten platform (#8363) ae6cfd32a0 Tables, Menus: Fixed tables or child windows submitted inside BeginMainMenuBar() being unable to save their settings. (#8356) fa178f4235 Error Handling: Recovery from missing EndMenuBar() call. (#1651) c0308da665 Fixed zealous GCC warning. (#8355) dabc990189 Rename internal id for standardizing naming convention. "##menubar" -> "##MenuBar", "###NavWindowingList" -> "###NavWindowingOverlay" a71191515a EndMainMenuBar doesn't attempt to restore focus when there's an active id. (#8355) dfd1bc3c5b Tables, Menus: Fixed using BeginTable() in menu layer (any menu bar). (#8355) 4230e98720 Error Handling, Debug Log: IMGUI_DEBUG_LOG_ERROR() doesn't need the extra variable. ea0da0bf47 Extracted PushPasswordFont() out of InputText code. 9c4948a4d1 TabBar: Internals: added TabItemSpacing(). (#8349, #3291) a05d547ae8 Windows: separating WindowItemStatusFlags from ChildItemStatusFlag, because IsItemXXX _after_ BeginChild()>Begin() shouldn't return last status emitted by e.g. EndChild() 134fbe1245 Windows: Fixed IsItemXXXX() functions not working on append-version of EndChild(). (#8350) 5a28f188ff Fixed parameter names to SetLastItemData() to align with current names. 96e3b147f0 Fixed build with IMGUI_ENABLE_FREETYPE (#8346) afb6e9a879 Fonts: OversampleH auto-selection uses 36 as heuristic for now. 8a1613a382 Fonts: OversampleH/OversampleV value defaults to 0 for automatic selection. 4211fdc70b ImFont: compact comments in header section. 9eafb7bbfb ImFont: IndexLookup[] table hold 16-bit values even in ImWchar32 mode. 53244aaac7 Amend 9bc5b04 with a shadowed variable warning fix. ed7551c1d4 Selectable: Fixed horizontal label alignment when combined with using ImGuiSelectableFlags_SpanAllColumns. (#8338) bbf957875b Amend 9bc5b04 to avoid using GImGui mid-function. 9bc5b0406d Windows, Style: Fixed small rendering issues with menu bar, resize grip and scrollbar when using thick border sizes. (#8267, #7887) 10199341b1 ImFontAtlas: made calling ClearFonts() call ClearInputData(). (#8174, #6556, #6336, #4723) 71da34c48c Debug Tools: Tweaked font preview + indent "Glyphs" block. 6906ac979e ColorEdit, ColorPicker: (Breaking) redesigned how alpha is displayed in the preview square. (#8335, #1578, #346) fdca6c08ad Inputs: added IsMouseReleasedWithDelay() helper. (#8337, #8320) d17e9fc107 Backends: SDL_GPU: shallow tweaks + disable anisotropy in sampler. Examples: SDL+Vulkan: Fixed incorrect defines. 3e6bdc2242 Examples: SDL3+SDL_GPU: use SDL_GPU_PRESENTMODE_MAILBOX swapchain parameters. bf13442c7c Moved ImGuiColorEditFlags_AlphaPreview/ImGuiColorEditFlags_AlphaPreviewHalf flags. Demo: reorganized some of color edit/picker demo section. 2af26b75d1 ColorEdit, ColorPicker: Fixed alpha preview broken in 1.91.7. (#8336, #8241). [@PathogenDavid] 7ae7c90790 Tabs, Style: reworked selected overline rendering to better accommodate for rounded tabs. (#8334) e8779a67b1 Font: direct AddText()/RenderText() calls don't need to call strlen() if below clipping region. 4c2e7bb035 Backends: SDL2,SDL3: removed assert preventing using ImGui_ImplSDL2_SetGamepadMode()/ImGui_ImplSDL3_SetGamepadMode() with ImGui_ImplSDL2_GamepadMode_Manual/ImGui_ImplSDL3_GamepadMode_Manual and an empty array. (#8329) 8b0af7fddc Backends: SDL: update comments regarding API stability, regarding SDL_GPU and SDL_Renderer. aa1b4ea861 Backends: OSX: Remove notification observer when shutting down. (#8331) aa23f3801b Backends: SDL_Renderer2/3: Use endian-dependent RGBA32 texture format, to match SDL_Color. (#8327) 80c9cd1f6e Font: reduce unnecessary padding in ImFontConfig struct too. d7454de80a Font: minor tweak to struct alignment. dd89a3741b Backends: Vulkan: sharing duplicate code. (#5446, #8326) 487d7f9a29 Font: Internals: make used page maps smaller. Since it's extremely rarely used and for iterations only. ~34->16 bytes with ImWchar32. f2262eb81a Windows: latch FontRefSize at time of Begin(), consistent with e.g. TitleBarHeight, and to avoid calling CalcFontSize() on non-current window. b7c27c5333 Windows: legacy SetWindowFontScale() is properly inherited by nested child windows. (#2701, #8138, #1018) 4c64ba16c5 imgui_freetype: fixed issue where glyph advances would incorrectly be snapped to pixels. 007735737a Ignore vscode artifacts (#8324) b4a5d1dc53 Backends: SDLGPU3: Rename GpuDevice->Device. Expose ImGui_ImplSDLGPU3_CreateDeviceObjects(), ImGui_ImplSDLGPU3_DestroyDeviceObjects(). Misc renaming. (#8163, #7998, #7988) 0f33d7185f Examples: Vulkan: vkAcquireNextImageKHR() and vkQueuePresentKHR() returning VK_SUBOPTIMAL_KHR keeps moving forward. (#7825, #7831) 8ebf22d3c1 Backends: Vulkan: use ImVector<> for simplicity. 6684984c49 Examples: DirectX12: Reduced number of frame in flight from 3 to 2 in provided example, to reduce latency. 0e21bde77b Misc shallow merge to reduce diff in other branches. 8a9de84cd0 FontAtlas: reduced baked IM_DRAWLIST_TEX_LINES_WIDTH_MAX from 63 to 32. (#3245) 100075f2be Backends: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own. c59a2267d0 Version 1.91.8 WIP git-subtree-dir: external/imgui/imgui git-subtree-split: f5befd2d29e66809cd1110a152e375a7f1981f06
This commit is contained in:
parent
b8ca49f7dc
commit
86042dc522
2
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
2
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@ -8,7 +8,7 @@ body:
|
||||
For anything else: **we are happy to use 'GitHub Issues' for many types of open-ended questions**. We are encouraging 'Issues' becoming a large, centralized, tagged, cross-referenced database of Dear ImGui contents.
|
||||
|
||||
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
|
||||
|
||||
|
||||
**If you are using Dear ImGui as part of a job that you are being well-paid for** and your company is not a sponsor. Please be mindful that this is a Free Software and you might be about to ask volunteers to help you doing your job. Please put extra effort describing your issue or question properly. If your company is wealthy, please read [Funding](https://github.com/ocornut/imgui/wiki/Funding) and consider getting in touch.
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -49,6 +49,9 @@ examples/example_sdl2_opengl3/web/*
|
||||
.idea
|
||||
cmake-build-*
|
||||
|
||||
## VS code artifacts
|
||||
.vscode
|
||||
|
||||
## Unix executables from our example Makefiles
|
||||
examples/example_glfw_metal/example_glfw_metal
|
||||
examples/example_glfw_opengl2/example_glfw_opengl2
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
@ -594,6 +595,8 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
||||
case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break;
|
||||
case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break;
|
||||
case ImGuiMouseCursor_Wait: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY; break;
|
||||
case ImGuiMouseCursor_Progress: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS; break;
|
||||
case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break;
|
||||
}
|
||||
al_set_system_mouse_cursor(bd->Display, cursor_id);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
// DirectX10 data
|
||||
struct ImGui_ImplDX10_Data
|
||||
{
|
||||
ID3D10Device* pd3dDevice;
|
||||
@ -87,8 +87,7 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
|
||||
// Setup viewport
|
||||
D3D10_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
|
||||
D3D10_VIEWPORT vp = {};
|
||||
vp.Width = (UINT)draw_data->DisplaySize.x;
|
||||
vp.Height = (UINT)draw_data->DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
@ -152,8 +151,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
D3D10_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
@ -167,8 +165,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
D3D10_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
@ -431,7 +428,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D10_BUFFER_DESC desc;
|
||||
D3D10_BUFFER_DESC desc = {};
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX10);
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
|
||||
|
@ -90,8 +90,7 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
// Setup viewport
|
||||
D3D11_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||
D3D11_VIEWPORT vp = {};
|
||||
vp.Width = draw_data->DisplaySize.x;
|
||||
vp.Height = draw_data->DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
@ -158,8 +157,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
@ -172,8 +170,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
@ -447,7 +444,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-24: DirectX12: Fixed an issue where ImGui_ImplDX12_Init() signature change from 2024-11-15 combined with change from 2025-01-15 made legacy ImGui_ImplDX12_Init() crash. (#8429)
|
||||
// 2025-01-15: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own.
|
||||
// 2024-12-09: DirectX12: Let user specifies the DepthStencilView format by setting ImGui_ImplDX12_InitInfo::DSVFormat.
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* Changed ImGui_ImplDX12_Init() signature to take a ImGui_ImplDX12_InitInfo struct. Legacy ImGui_ImplDX12_Init() signature is still supported (will obsolete).
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* User is now required to pass function pointers to allocate/free SRV Descriptors. We provide convenience legacy fields to pass a single descriptor, matching the old API, but upcoming features will want multiple.
|
||||
@ -64,6 +66,8 @@ struct ImGui_ImplDX12_Texture
|
||||
ID3D12Resource* pTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
|
||||
ImGui_ImplDX12_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplDX12_Data
|
||||
@ -72,6 +76,8 @@ struct ImGui_ImplDX12_Data
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
ID3D12CommandQueue* pCommandQueue;
|
||||
bool commandQueueOwned;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
DXGI_FORMAT DSVFormat;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
@ -131,8 +137,7 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
D3D12_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D12_VIEWPORT));
|
||||
D3D12_VIEWPORT vp = {};
|
||||
vp.Width = draw_data->DisplaySize.x;
|
||||
vp.Height = draw_data->DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
@ -143,14 +148,12 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv;
|
||||
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = {};
|
||||
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
||||
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
||||
vbv.StrideInBytes = stride;
|
||||
command_list->IASetVertexBuffers(0, 1, &vbv);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = {};
|
||||
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
||||
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||
@ -180,8 +183,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// FIXME: I'm assuming that this only gets called once per frame!
|
||||
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
||||
// FIXME: We are assuming that this only gets called once per frame!
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->frameIndex = bd->frameIndex + 1;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||
@ -191,13 +193,11 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
{
|
||||
SafeRelease(fr->VertexBuffer);
|
||||
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
D3D12_HEAP_PROPERTIES props = {};
|
||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.Height = 1;
|
||||
@ -214,13 +214,11 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
{
|
||||
SafeRelease(fr->IndexBuffer);
|
||||
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
D3D12_HEAP_PROPERTIES props = {};
|
||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.Height = 1;
|
||||
@ -328,8 +326,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
// Upload texture to graphics system
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
D3D12_HEAP_PROPERTIES props = {};
|
||||
props.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
@ -352,11 +349,11 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
||||
|
||||
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT uploadSize = height * uploadPitch;
|
||||
UINT upload_pitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT upload_size = height * upload_pitch;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = uploadSize;
|
||||
desc.Width = upload_size;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
@ -376,26 +373,28 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
void* mapped = nullptr;
|
||||
D3D12_RANGE range = { 0, uploadSize };
|
||||
D3D12_RANGE range = { 0, upload_size };
|
||||
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4);
|
||||
memcpy((void*) ((uintptr_t) mapped + y * upload_pitch), pixels + y * width * 4, width * 4);
|
||||
uploadBuffer->Unmap(0, &range);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||
srcLocation.pResource = uploadBuffer;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = width;
|
||||
srcLocation.PlacedFootprint.Footprint.Height = height;
|
||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||
dstLocation.pResource = pTexture;
|
||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstLocation.SubresourceIndex = 0;
|
||||
{
|
||||
srcLocation.pResource = uploadBuffer;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = width;
|
||||
srcLocation.PlacedFootprint.Footprint.Height = height;
|
||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.RowPitch = upload_pitch;
|
||||
|
||||
dstLocation.pResource = pTexture;
|
||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstLocation.SubresourceIndex = 0;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
@ -412,15 +411,6 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
HANDLE event = ::CreateEvent(0, 0, 0, 0);
|
||||
IM_ASSERT(event != nullptr);
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
@ -435,6 +425,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
hr = cmdList->Close();
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = bd->pCommandQueue;
|
||||
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
||||
hr = cmdQueue->Signal(fence, 1);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
@ -444,7 +435,6 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
cmdQueue->Release();
|
||||
::CloseHandle(event);
|
||||
fence->Release();
|
||||
uploadBuffer->Release();
|
||||
@ -563,8 +553,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
|
||||
memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||
psoDesc.NodeMask = 1;
|
||||
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
psoDesc.pRootSignature = bd->pRootSignature;
|
||||
@ -707,11 +696,14 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (bd->commandQueueOwned)
|
||||
SafeRelease(bd->pCommandQueue);
|
||||
bd->commandQueueOwned = false;
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
|
||||
// Free SRV descriptor used by texture
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, font_tex->hFontSrvCpuDescHandle, font_tex->hFontSrvGpuDescHandle);
|
||||
SafeRelease(font_tex->pTextureResource);
|
||||
@ -737,6 +729,8 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
init_info = &bd->InitInfo;
|
||||
|
||||
bd->pd3dDevice = init_info->Device;
|
||||
IM_ASSERT(init_info->CommandQueue != NULL);
|
||||
bd->pCommandQueue = init_info->CommandQueue;
|
||||
bd->RTVFormat = init_info->RTVFormat;
|
||||
bd->DSVFormat = init_info->DSVFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
@ -754,7 +748,7 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
init_info->SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == false);
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == false && "Only 1 simultaneous texture allowed with legacy ImGui_ImplDX12_Init() signature!");
|
||||
*out_cpu_handle = bd->InitInfo.LegacySingleSrvCpuDescriptor;
|
||||
*out_gpu_handle = bd->InitInfo.LegacySingleSrvGpuDescriptor;
|
||||
bd->LegacySingleDescriptorUsed = true;
|
||||
@ -798,8 +792,19 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
||||
init_info.RTVFormat = rtv_format;
|
||||
init_info.SrvDescriptorHeap = srv_descriptor_heap;
|
||||
init_info.LegacySingleSrvCpuDescriptor = font_srv_cpu_desc_handle;
|
||||
init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;;
|
||||
return ImGui_ImplDX12_Init(&init_info);
|
||||
init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
HRESULT hr = device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&init_info.CommandQueue));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
bool ret = ImGui_ImplDX12_Init(&init_info);
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->commandQueueOwned = true;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -27,14 +27,14 @@
|
||||
struct ImGui_ImplDX12_InitInfo
|
||||
{
|
||||
ID3D12Device* Device;
|
||||
ID3D12CommandQueue* CommandQueue;
|
||||
ID3D12CommandQueue* CommandQueue; // Command queue used for queuing texture uploads.
|
||||
int NumFramesInFlight;
|
||||
DXGI_FORMAT RTVFormat; // RenderTarget format.
|
||||
DXGI_FORMAT DSVFormat; // DepthStencilView format.
|
||||
void* UserData;
|
||||
|
||||
// Allocating SRV descriptors for textures is up to the application, so we provide callbacks.
|
||||
// (current version of the backend will only allocate one descriptor, future versions will need to allocate more)
|
||||
// (current version of the backend will only allocate one descriptor, from 1.92 the backend will need to allocate more)
|
||||
ID3D12DescriptorHeap* SrvDescriptorHeap;
|
||||
void (*SrvDescriptorAllocFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle);
|
||||
void (*SrvDescriptorFreeFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_desc_handle);
|
||||
@ -54,7 +54,8 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
// - font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
// - When we introduced the ImGui_ImplDX12_InitInfo struct we also added a 'ID3D12CommandQueue* CommandQueue' field.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||
#endif
|
||||
|
||||
|
@ -9,6 +9,9 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@ -25,7 +28,9 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// 2025-03-10: Map GLFW_KEY_WORLD_1 and GLFW_KEY_WORLD_2 into ImGuiKey_Oem102.
|
||||
// 2025-03-03: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled with asserts enabled.
|
||||
// 2024-08-22: Moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
||||
@ -217,6 +222,8 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
||||
case GLFW_KEY_EQUAL: return ImGuiKey_Equal;
|
||||
case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||
case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case GLFW_KEY_WORLD_1: return ImGuiKey_Oem102;
|
||||
case GLFW_KEY_WORLD_2: return ImGuiKey_Oem102;
|
||||
case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||
case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
|
||||
case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||
@ -467,7 +474,7 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
||||
|
||||
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||
{
|
||||
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||
}
|
||||
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
@ -595,8 +602,14 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
bd->Time = 0.0;
|
||||
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
#if GLFW_VERSION_COMBINED < 3300
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window, text); };
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window); };
|
||||
#else
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); };
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); };
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; };
|
||||
#endif
|
||||
|
@ -8,6 +8,9 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
static int g_Time = 0; // Current time, in milliseconds
|
||||
|
||||
// Glut has 1 function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above.
|
||||
// Glut has one function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above.
|
||||
static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
|
||||
{
|
||||
switch (key)
|
||||
|
@ -13,6 +13,7 @@
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-03: Metal: Crash fix. (#8367)
|
||||
// 2024-01-08: Metal: Fixed memory leaks when using metal-cpp (#8276, #8166) or when using multiple contexts (#7419).
|
||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||
@ -311,11 +312,11 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
indexBufferOffset += (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
}
|
||||
|
||||
__block MetalContext* sharedMetalContext = bd->SharedMetalContext;
|
||||
MetalContext* sharedMetalContext = bd->SharedMetalContext;
|
||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
||||
@synchronized(sharedMetalContext.bufferCache)
|
||||
{
|
||||
[sharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[sharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
|
@ -69,6 +69,16 @@
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
#include <stdio.h>
|
||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
||||
#else
|
||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
||||
#endif
|
||||
|
||||
// OpenGL data
|
||||
struct ImGui_ImplOpenGL2_Data
|
||||
{
|
||||
GLuint FontTexture;
|
||||
@ -155,7 +165,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-18: OpenGL: Lazily reinitialize embedded GL loader for when calling backend from e.g. other DLL boundaries. (#8406)
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
|
||||
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
|
||||
@ -53,7 +54,7 @@
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
|
||||
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
|
||||
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
|
||||
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
|
||||
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre-3.3 context which have the defines set by a loader.
|
||||
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
||||
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
||||
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
||||
@ -169,6 +170,7 @@
|
||||
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
||||
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
||||
#define IMGL3W_IMPL
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||
#include "imgui_impl_opengl3_loader.h"
|
||||
#endif
|
||||
|
||||
@ -276,6 +278,21 @@ struct ImGui_ImplOpenGL3_VtxAttribState
|
||||
};
|
||||
#endif
|
||||
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
bool ImGui_ImplOpenGL3_InitLoader();
|
||||
bool ImGui_ImplOpenGL3_InitLoader()
|
||||
{
|
||||
// Initialize our loader
|
||||
#ifdef IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||
if (glGetIntegerv == nullptr && imgl3wInit() != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
{
|
||||
@ -283,14 +300,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Initialize our loader
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||
if (imgl3wInit() != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
||||
// Initialize loader
|
||||
if (!ImGui_ImplOpenGL3_InitLoader())
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
|
||||
@ -303,6 +315,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
// GLES 2
|
||||
bd->GlVersion = 200;
|
||||
bd->GlProfileIsES2 = true;
|
||||
IM_UNUSED(gl_version_str);
|
||||
#else
|
||||
// Desktop or GLES 3
|
||||
GLint major = 0;
|
||||
@ -405,6 +418,8 @@ void ImGui_ImplOpenGL3_NewFrame()
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL3_Init()?");
|
||||
|
||||
ImGui_ImplOpenGL3_InitLoader(); // Lazily init loader if not already done for e.g. DLL boundaries.
|
||||
|
||||
if (!bd->ShaderHandle)
|
||||
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
@ -496,6 +511,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplOpenGL3_InitLoader(); // Lazily init loader if not already done for e.g. DLL boundaries.
|
||||
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
|
||||
// Backup GL state
|
||||
|
@ -10,6 +10,8 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
// Missing features or Issues:
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@ -19,6 +21,7 @@
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
// Missing features or Issues:
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@ -29,6 +31,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-20: Removed notification observer when shutting down. (#8331)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
@ -36,7 +39,7 @@
|
||||
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
||||
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mice).
|
||||
// 2022-11-02: Fixed mouse coordinates before clicking the host window.
|
||||
// 2022-10-06: Fixed mouse inputs on flipped views.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
@ -421,12 +424,12 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
||||
|
||||
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
||||
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
||||
@ -497,6 +500,7 @@ void ImGui_ImplOSX_Shutdown()
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:bd->Observer];
|
||||
bd->Observer = nullptr;
|
||||
if (bd->Monitor != nullptr)
|
||||
{
|
||||
|
@ -21,6 +21,12 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g.Linux debuggers not claiming capture back. (#6410, #3650)
|
||||
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
||||
// 2025-01-20: Made ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode_Manual) accept an empty array.
|
||||
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
|
||||
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
@ -114,6 +120,7 @@
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||
#endif
|
||||
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
||||
#define SDL_HAS_OPEN_URL SDL_VERSION_ATLEAST(2,0,14)
|
||||
#if SDL_HAS_VULKAN
|
||||
#include <SDL_vulkan.h>
|
||||
#endif
|
||||
@ -185,7 +192,6 @@ static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImG
|
||||
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
|
||||
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
||||
{
|
||||
IM_UNUSED(scancode);
|
||||
switch (keycode)
|
||||
{
|
||||
case SDLK_TAB: return ImGuiKey_Tab;
|
||||
@ -203,17 +209,17 @@ ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
||||
case SDLK_SPACE: return ImGuiKey_Space;
|
||||
case SDLK_RETURN: return ImGuiKey_Enter;
|
||||
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
||||
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
|
||||
//case SDLK_QUOTE: return ImGuiKey_Apostrophe;
|
||||
case SDLK_COMMA: return ImGuiKey_Comma;
|
||||
case SDLK_MINUS: return ImGuiKey_Minus;
|
||||
//case SDLK_MINUS: return ImGuiKey_Minus;
|
||||
case SDLK_PERIOD: return ImGuiKey_Period;
|
||||
case SDLK_SLASH: return ImGuiKey_Slash;
|
||||
//case SDLK_SLASH: return ImGuiKey_Slash;
|
||||
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
|
||||
//case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||
//case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
//case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||
//case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
//case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
|
||||
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||
@ -309,6 +315,24 @@ ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Fallback to scancode
|
||||
switch (scancode)
|
||||
{
|
||||
case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||
case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
|
||||
case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
|
||||
case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
case SDL_SCANCODE_NONUSBACKSLASH: return ImGuiKey_Oem102;
|
||||
case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
|
||||
case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
|
||||
case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
|
||||
default: break;
|
||||
}
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
||||
@ -479,6 +503,8 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
|
||||
#elif SDL_HAS_OPEN_URL
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
||||
#endif
|
||||
|
||||
// Gamepad handling
|
||||
@ -494,6 +520,8 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Wait] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Progress] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
@ -600,8 +628,14 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
|
||||
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
||||
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
|
||||
// - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
||||
// - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to migitate the issue we wait until mouse has moved to begin capture.
|
||||
bool want_capture = false;
|
||||
for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++)
|
||||
if (ImGui::IsMouseDragging(button_n, 1.0f))
|
||||
want_capture = true;
|
||||
SDL_CaptureMouse(want_capture ? SDL_TRUE : SDL_FALSE);
|
||||
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (bd->Window == focused_window);
|
||||
#else
|
||||
@ -614,8 +648,10 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
||||
const bool is_relative_mouse_mode = SDL_GetRelativeMouseMode() != 0;
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
int window_x, window_y, mouse_x_global, mouse_y_global;
|
||||
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
|
||||
SDL_GetWindowPosition(bd->Window, &window_x, &window_y);
|
||||
@ -665,7 +701,7 @@ void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_
|
||||
ImGui_ImplSDL2_CloseGamepads();
|
||||
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
|
||||
{
|
||||
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
|
||||
IM_ASSERT(manual_gamepads_array != nullptr || manual_gamepads_count <= 0);
|
||||
for (int n = 0; n < manual_gamepads_count; n++)
|
||||
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// dear imgui: Platform Backend for SDL3
|
||||
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
@ -22,6 +20,12 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g.Linux debuggers not claiming capture back. (#6410, #3650)
|
||||
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
||||
// 2025-01-20: Made ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode_Manual) accept an empty array.
|
||||
// 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten.
|
||||
// 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
@ -204,17 +208,17 @@ ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
||||
case SDLK_SPACE: return ImGuiKey_Space;
|
||||
case SDLK_RETURN: return ImGuiKey_Enter;
|
||||
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
||||
case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
//case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case SDLK_COMMA: return ImGuiKey_Comma;
|
||||
case SDLK_MINUS: return ImGuiKey_Minus;
|
||||
//case SDLK_MINUS: return ImGuiKey_Minus;
|
||||
case SDLK_PERIOD: return ImGuiKey_Period;
|
||||
case SDLK_SLASH: return ImGuiKey_Slash;
|
||||
//case SDLK_SLASH: return ImGuiKey_Slash;
|
||||
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
case SDLK_GRAVE: return ImGuiKey_GraveAccent;
|
||||
//case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||
//case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
//case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||
//case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
//case SDLK_GRAVE: return ImGuiKey_GraveAccent;
|
||||
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||
@ -293,6 +297,24 @@ ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Fallback to scancode
|
||||
switch (scancode)
|
||||
{
|
||||
case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||
case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
|
||||
case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
|
||||
case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
case SDL_SCANCODE_NONUSBACKSLASH: return ImGuiKey_Oem102;
|
||||
case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
|
||||
case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
|
||||
case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
|
||||
default: break;
|
||||
}
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
||||
@ -465,6 +487,7 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
||||
|
||||
// Gamepad handling
|
||||
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
|
||||
@ -479,6 +502,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Wait] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Progress] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_PROGRESS);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
@ -569,8 +594,14 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
|
||||
// We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
||||
SDL_CaptureMouse(bd->MouseButtonsDown != 0);
|
||||
// - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
||||
// - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to migitate the issue we wait until mouse has moved to begin capture.
|
||||
bool want_capture = false;
|
||||
for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++)
|
||||
if (ImGui::IsMouseDragging(button_n, 1.0f))
|
||||
want_capture = true;
|
||||
SDL_CaptureMouse(want_capture);
|
||||
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (bd->Window == focused_window);
|
||||
#else
|
||||
@ -584,7 +615,8 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
||||
const bool is_relative_mouse_mode = SDL_GetWindowRelativeMouseMode(bd->Window);
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
float mouse_x_global, mouse_y_global;
|
||||
@ -637,7 +669,7 @@ void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad*
|
||||
ImGui_ImplSDL3_CloseGamepads();
|
||||
if (mode == ImGui_ImplSDL3_GamepadMode_Manual)
|
||||
{
|
||||
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
|
||||
IM_ASSERT(manual_gamepads_array != nullptr || manual_gamepads_count <= 0);
|
||||
for (int n = 0; n < manual_gamepads_count; n++)
|
||||
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// dear imgui: Platform Backend for SDL3
|
||||
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
|
@ -21,13 +21,16 @@
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-09: SDL_Gpu: Added the SDL_GPU3 backend.
|
||||
// 2025-01-16: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device.
|
||||
// 2025-01-09: SDL_GPU: Added the SDL_GPU3 backend.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_sdlgpu3.h"
|
||||
#include "imgui_impl_sdlgpu3_shaders.h"
|
||||
|
||||
// SDL_GPU Data
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
|
||||
struct ImGui_ImplSDLGPU3_FrameData
|
||||
{
|
||||
@ -37,10 +40,9 @@ struct ImGui_ImplSDLGPU3_FrameData
|
||||
uint32_t IndexBufferSize = 0;
|
||||
};
|
||||
|
||||
// SDL_GPU Data
|
||||
struct ImGui_ImplSDLGPU3_Data
|
||||
{
|
||||
ImGui_ImplSDLGPU3_InitInfo GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo InitInfo;
|
||||
|
||||
// Graphics pipeline & shaders
|
||||
SDL_GPUShader* VertexShader = nullptr;
|
||||
@ -57,8 +59,6 @@ struct ImGui_ImplSDLGPU3_Data
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static bool ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
static void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
static void ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -89,8 +89,8 @@ static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGra
|
||||
SDL_GPUBufferBinding index_buffer_binding = {};
|
||||
index_buffer_binding.buffer = fd->IndexBuffer;
|
||||
index_buffer_binding.offset = 0;
|
||||
SDL_BindGPUVertexBuffers(render_pass,0,&vertex_buffer_binding,1);
|
||||
SDL_BindGPUIndexBuffer(render_pass,&index_buffer_binding,sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
SDL_BindGPUVertexBuffers(render_pass,0, &vertex_buffer_binding, 1);
|
||||
SDL_BindGPUIndexBuffer(render_pass, &index_buffer_binding, sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
@ -101,7 +101,7 @@ static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGra
|
||||
viewport.h = (float)fb_height;
|
||||
viewport.min_depth = 0.0f;
|
||||
viewport.max_depth = 1.0f;
|
||||
SDL_SetGPUViewport(render_pass,&viewport);
|
||||
SDL_SetGPUViewport(render_pass, &viewport);
|
||||
|
||||
// Setup scale and translation
|
||||
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
@ -116,16 +116,17 @@ static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGra
|
||||
static void CreateOrResizeBuffer(SDL_GPUBuffer** buffer, uint32_t* old_size, uint32_t new_size, SDL_GPUBufferUsageFlags usage)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
SDL_WaitForGPUIdle(v->GpuDevice);
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, *buffer);
|
||||
// Even though this is fairly rarely called.
|
||||
SDL_WaitForGPUIdle(v->Device);
|
||||
SDL_ReleaseGPUBuffer(v->Device, *buffer);
|
||||
|
||||
SDL_GPUBufferCreateInfo buffer_info = {};
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.size = new_size;
|
||||
buffer_info.props = 0;
|
||||
*buffer = SDL_CreateGPUBuffer(v->GpuDevice, &buffer_info);
|
||||
*buffer = SDL_CreateGPUBuffer(v->Device, &buffer_info);
|
||||
*old_size = new_size;
|
||||
IM_ASSERT(*buffer != nullptr && "Failed to create GPU Buffer, call SDL_GetError() for more information");
|
||||
}
|
||||
@ -142,7 +143,7 @@ void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||
|
||||
uint32_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||
@ -160,13 +161,13 @@ void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
index_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
index_transferbuffer_info.size = index_size;
|
||||
|
||||
SDL_GPUTransferBuffer* vertex_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &vertex_transferbuffer_info);
|
||||
SDL_GPUTransferBuffer* vertex_transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &vertex_transferbuffer_info);
|
||||
IM_ASSERT(vertex_transferbuffer != nullptr && "Failed to create the vertex transfer buffer, call SDL_GetError() for more information");
|
||||
SDL_GPUTransferBuffer* index_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &index_transferbuffer_info);
|
||||
SDL_GPUTransferBuffer* index_transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &index_transferbuffer_info);
|
||||
IM_ASSERT(index_transferbuffer != nullptr && "Failed to create the index transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->GpuDevice, index_transferbuffer, true);
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->Device, vertex_transferbuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->Device, index_transferbuffer, true);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
@ -175,8 +176,8 @@ void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, index_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, vertex_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, index_transferbuffer);
|
||||
|
||||
SDL_GPUTransferBufferLocation vertex_buffer_location = {};
|
||||
vertex_buffer_location.offset = 0;
|
||||
@ -196,11 +197,11 @@ void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
index_buffer_region.size = index_size;
|
||||
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region,true);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region,true);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region, true);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region, true);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, index_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, index_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, vertex_transferbuffer);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
||||
@ -278,16 +279,16 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
SDL_SetGPUScissor(render_pass, &scissor_rect);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
void ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
// Destroy existing texture (if any)
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_WaitForGPUIdle(v->GpuDevice);
|
||||
SDL_WaitForGPUIdle(v->Device);
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
@ -308,7 +309,7 @@ bool ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
texture_info.num_levels = 1;
|
||||
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
|
||||
bd->FontTexture = SDL_CreateGPUTexture(v->GpuDevice, &texture_info);
|
||||
bd->FontTexture = SDL_CreateGPUTexture(v->Device, &texture_info);
|
||||
IM_ASSERT(bd->FontTexture && "Failed to create font texture, call SDL_GetError() for more info");
|
||||
}
|
||||
|
||||
@ -317,39 +318,37 @@ bool ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
|
||||
// Create all the upload structures and upload:
|
||||
{
|
||||
SDL_GPUTransferBufferCreateInfo font_transferbuffer_info = {};
|
||||
font_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
font_transferbuffer_info.size = upload_size;
|
||||
SDL_GPUTransferBufferCreateInfo transferbuffer_info = {};
|
||||
transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
transferbuffer_info.size = upload_size;
|
||||
|
||||
SDL_GPUTransferBuffer* font_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &font_transferbuffer_info);
|
||||
IM_ASSERT(font_transferbuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||
SDL_GPUTransferBuffer* transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &transferbuffer_info);
|
||||
IM_ASSERT(transferbuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
void* texture_ptr = SDL_MapGPUTransferBuffer(v->GpuDevice, font_transferbuffer, false);
|
||||
void* texture_ptr = SDL_MapGPUTransferBuffer(v->Device, transferbuffer, false);
|
||||
memcpy(texture_ptr, pixels, upload_size);
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, font_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, transferbuffer);
|
||||
|
||||
SDL_GPUTextureTransferInfo font_transfer_info = {};
|
||||
font_transfer_info.offset = 0;
|
||||
font_transfer_info.transfer_buffer = font_transferbuffer;
|
||||
SDL_GPUTextureTransferInfo transfer_info = {};
|
||||
transfer_info.offset = 0;
|
||||
transfer_info.transfer_buffer = transferbuffer;
|
||||
|
||||
SDL_GPUTextureRegion font_texture_region = {};
|
||||
font_texture_region.texture = bd->FontTexture;
|
||||
font_texture_region.w = width;
|
||||
font_texture_region.h = height;
|
||||
font_texture_region.d = 1;
|
||||
SDL_GPUTextureRegion texture_region = {};
|
||||
texture_region.texture = bd->FontTexture;
|
||||
texture_region.w = width;
|
||||
texture_region.h = height;
|
||||
texture_region.d = 1;
|
||||
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->GpuDevice);
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->Device);
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
SDL_UploadToGPUTexture(copy_pass, &font_transfer_info, &font_texture_region, false);
|
||||
SDL_UploadToGPUTexture(copy_pass, &transfer_info, &texture_region, false);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_SubmitGPUCommandBuffer(cmd);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, font_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, transferbuffer);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)&bd->FontBinding);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// You probably never need to call this, as it is called by ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_Shutdown().
|
||||
@ -357,10 +356,10 @@ void ImGui_ImplSDLGPU3_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_ReleaseGPUTexture(v->GpuDevice, bd->FontTexture);
|
||||
SDL_ReleaseGPUTexture(v->Device, bd->FontTexture);
|
||||
bd->FontBinding.texture = nullptr;
|
||||
bd->FontTexture = nullptr;
|
||||
}
|
||||
@ -371,9 +370,9 @@ static void Imgui_ImplSDLGPU3_CreateShaders()
|
||||
{
|
||||
// Create the shader modules
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
const char* driver = SDL_GetGPUDeviceDriver(v->GpuDevice);
|
||||
const char* driver = SDL_GetGPUDeviceDriver(v->Device);
|
||||
|
||||
SDL_GPUShaderCreateInfo vertex_shader_info = {};
|
||||
vertex_shader_info.entrypoint = "main";
|
||||
@ -422,8 +421,8 @@ static void Imgui_ImplSDLGPU3_CreateShaders()
|
||||
fragment_shader_info.code_size = sizeof(metallib_fragment);
|
||||
}
|
||||
#endif
|
||||
bd->VertexShader = SDL_CreateGPUShader(v->GpuDevice, &vertex_shader_info);
|
||||
bd->FragmentShader = SDL_CreateGPUShader(v->GpuDevice, &fragment_shader_info);
|
||||
bd->VertexShader = SDL_CreateGPUShader(v->Device, &vertex_shader_info);
|
||||
bd->FragmentShader = SDL_CreateGPUShader(v->Device, &fragment_shader_info);
|
||||
IM_ASSERT(bd->VertexShader != nullptr && "Failed to create vertex shader, call SDL_GetError() for more information");
|
||||
IM_ASSERT(bd->FragmentShader != nullptr && "Failed to create fragment shader, call SDL_GetError() for more information");
|
||||
}
|
||||
@ -431,7 +430,7 @@ static void Imgui_ImplSDLGPU3_CreateShaders()
|
||||
static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
Imgui_ImplSDLGPU3_CreateShaders();
|
||||
|
||||
SDL_GPUVertexBufferDescription vertex_buffer_desc[1];
|
||||
@ -507,14 +506,14 @@ static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline()
|
||||
pipeline_info.depth_stencil_state = depth_stencil_state;
|
||||
pipeline_info.target_info = target_info;
|
||||
|
||||
bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->GpuDevice, &pipeline_info);
|
||||
bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->Device, &pipeline_info);
|
||||
IM_ASSERT(bd->Pipeline != nullptr && "Failed to create graphics pipeline, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
if (!bd->FontSampler)
|
||||
{
|
||||
@ -529,27 +528,26 @@ bool ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
sampler_info.mip_lod_bias = 0.0f;
|
||||
sampler_info.min_lod = -1000.0f;
|
||||
sampler_info.max_lod = 1000.0f;
|
||||
sampler_info.enable_anisotropy = true;
|
||||
sampler_info.enable_anisotropy = false;
|
||||
sampler_info.max_anisotropy = 1.0f;
|
||||
sampler_info.enable_compare = false;
|
||||
|
||||
bd->FontSampler = SDL_CreateGPUSampler(v->GpuDevice, &sampler_info);
|
||||
bd->FontSampler = SDL_CreateGPUSampler(v->Device, &sampler_info);
|
||||
bd->FontBinding.sampler = bd->FontSampler;
|
||||
IM_ASSERT(bd->FontSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateGraphicsPipeline();
|
||||
|
||||
return true;
|
||||
ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_DestroyFrameData()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.VertexBuffer);
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.IndexBuffer);
|
||||
SDL_ReleaseGPUBuffer(v->Device, bd->MainWindowFrameData.VertexBuffer);
|
||||
SDL_ReleaseGPUBuffer(v->Device, bd->MainWindowFrameData.IndexBuffer);
|
||||
bd->MainWindowFrameData.VertexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.IndexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.VertexBufferSize = 0;
|
||||
@ -559,15 +557,15 @@ void ImGui_ImplSDLGPU3_DestroyFrameData()
|
||||
void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->VertexShader); bd->VertexShader = nullptr;}
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->FragmentShader); bd->FragmentShader = nullptr;}
|
||||
if (bd->FontSampler) { SDL_ReleaseGPUSampler(v->GpuDevice, bd->FontSampler); bd->FontSampler = nullptr;}
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->GpuDevice, bd->Pipeline); bd->Pipeline = nullptr;}
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->Device, bd->VertexShader); bd->VertexShader = nullptr;}
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->Device, bd->FragmentShader); bd->FragmentShader = nullptr;}
|
||||
if (bd->FontSampler) { SDL_ReleaseGPUSampler(v->Device, bd->FontSampler); bd->FontSampler = nullptr;}
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr;}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
||||
@ -582,10 +580,10 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
||||
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
IM_ASSERT(info->GpuDevice != nullptr);
|
||||
IM_ASSERT(info->Device != nullptr);
|
||||
IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
|
||||
|
||||
bd->GPUInitInfo = *info;
|
||||
bd->InitInfo = *info;
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
|
||||
|
@ -29,18 +29,21 @@
|
||||
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
|
||||
struct ImGui_ImplSDLGPU3_InitInfo
|
||||
{
|
||||
SDL_GPUDevice* GpuDevice = nullptr;
|
||||
SDL_GPUDevice* Device = nullptr;
|
||||
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
|
||||
IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
|
||||
IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
|
||||
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
@ -1,11 +1,13 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL2.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
||||
// it might be difficult to step out of those boundaries.
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
@ -21,6 +23,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
|
||||
@ -97,10 +100,10 @@ void ImGui_ImplSDLRenderer2_Shutdown()
|
||||
|
||||
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||
SDL_RenderSetViewport(renderer, nullptr);
|
||||
SDL_RenderSetClipRect(renderer, nullptr);
|
||||
SDL_RenderSetViewport(renderer, nullptr);
|
||||
SDL_RenderSetClipRect(renderer, nullptr);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_NewFrame()
|
||||
@ -114,21 +117,21 @@ void ImGui_ImplSDLRenderer2_NewFrame()
|
||||
|
||||
void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||
{
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||
float rsx = 1.0f;
|
||||
float rsy = 1.0f;
|
||||
SDL_RenderGetScale(renderer, &rsx, &rsy);
|
||||
float rsy = 1.0f;
|
||||
SDL_RenderGetScale(renderer, &rsx, &rsy);
|
||||
ImVec2 render_scale;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||
struct BackupSDLRendererState
|
||||
@ -151,9 +154,9 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
@ -198,7 +201,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
#endif
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw(renderer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
@ -228,7 +231,7 @@ bool ImGui_ImplSDLRenderer2_CreateFontsTexture()
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (bd->FontTexture == nullptr)
|
||||
{
|
||||
SDL_Log("error creating texture");
|
||||
|
@ -1,11 +1,13 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL2.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
||||
// it might be difficult to step out of those boundaries.
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
@ -1,13 +1,13 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.0.0+)
|
||||
// (Requires: SDL 3.1.8+)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
||||
// it might be difficult to step out of those boundaries.
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
@ -23,6 +23,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
@ -98,10 +99,10 @@ void ImGui_ImplSDLRenderer3_Shutdown()
|
||||
|
||||
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||
SDL_SetRenderViewport(renderer, nullptr);
|
||||
SDL_SetRenderClipRect(renderer, nullptr);
|
||||
SDL_SetRenderViewport(renderer, nullptr);
|
||||
SDL_SetRenderClipRect(renderer, nullptr);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_NewFrame()
|
||||
@ -135,21 +136,21 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||
float rsx = 1.0f;
|
||||
float rsy = 1.0f;
|
||||
SDL_GetRenderScale(renderer, &rsx, &rsy);
|
||||
float rsy = 1.0f;
|
||||
SDL_GetRenderScale(renderer, &rsx, &rsy);
|
||||
ImVec2 render_scale;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||
struct BackupSDLRendererState
|
||||
@ -174,9 +175,9 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
@ -217,7 +218,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
@ -247,7 +248,7 @@ bool ImGui_ImplSDLRenderer3_CreateFontsTexture()
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (bd->FontTexture == nullptr)
|
||||
{
|
||||
SDL_Log("error creating texture");
|
||||
|
@ -1,13 +1,13 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.0.0+)
|
||||
// (Requires: SDL 3.1.8+)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
||||
// it might be difficult to step out of those boundaries.
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-14: *BREAKING CHANGE*: Added uint32_t api_version to ImGui_ImplVulkan_LoadFunctions().
|
||||
// 2025-02-13: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. Default to header version if unspecified. Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" (without -KHR suffix) on API 1.3. (#8326)
|
||||
// 2025-01-09: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify how many image sampler descriptors are expected to be available in descriptor pool. (#6642)
|
||||
// 2025-01-06: Vulkan: Added more ImGui_ImplVulkanH_XXXX helper functions to simplify our examples.
|
||||
// 2024-12-11: Vulkan: Fixed setting VkSwapchainCreateInfoKHR::preTransform for platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222)
|
||||
@ -51,7 +53,7 @@
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symmetry. (#914, #5738).
|
||||
// 2022-01-20: Vulkan: Added support for ImTextureID as VkDescriptorSet. User need to call ImGui_ImplVulkan_AddTexture(). Building for 32-bit targets requires '#define ImTextureID ImU64'. (#914).
|
||||
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
|
||||
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likelihood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.
|
||||
// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer.
|
||||
@ -216,7 +218,7 @@ struct ImGui_ImplVulkan_WindowRenderBuffers
|
||||
{
|
||||
uint32_t Index;
|
||||
uint32_t Count;
|
||||
ImGui_ImplVulkan_FrameRenderBuffers* FrameRenderBuffers;
|
||||
ImVector<ImGui_ImplVulkan_FrameRenderBuffers> FrameRenderBuffers;
|
||||
};
|
||||
|
||||
struct ImGui_ImplVulkan_Texture
|
||||
@ -501,12 +503,12 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
|
||||
// Allocate array to store enough vertex/index buffers
|
||||
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == nullptr)
|
||||
if (wrb->FrameRenderBuffers.Size == 0)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
wrb->Count = v->ImageCount;
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
memset((void*)wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
wrb->FrameRenderBuffers.resize(wrb->Count);
|
||||
memset((void*)wrb->FrameRenderBuffers.Data, 0, wrb->FrameRenderBuffers.size_in_bytes());
|
||||
}
|
||||
IM_ASSERT(wrb->Count == v->ImageCount);
|
||||
wrb->Index = (wrb->Index + 1) % wrb->Count;
|
||||
@ -1079,12 +1081,35 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
if (bd->DescriptorPool) { vkDestroyDescriptorPool(v->Device, bd->DescriptorPool, v->Allocator); bd->DescriptorPool = VK_NULL_HANDLE; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data)
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
static void ImGui_ImplVulkan_LoadDynamicRenderingFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data)
|
||||
{
|
||||
// Manually load those two (see #5446, #8326, #8365)
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func(api_version < VK_API_VERSION_1_3 ? "vkCmdBeginRenderingKHR" : "vkCmdBeginRendering", user_data));
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func(api_version < VK_API_VERSION_1_3 ? "vkCmdEndRenderingKHR" : "vkCmdEndRendering", user_data));
|
||||
}
|
||||
#endif
|
||||
|
||||
// If unspecified by user, assume that ApiVersion == HeaderVersion
|
||||
// We don't care about other versions than 1.3 for our checks, so don't need to make this exhaustive (e.g. with all #ifdef VK_VERSION_1_X checks)
|
||||
static uint32_t ImGui_ImplVulkan_GetDefaultApiVersion()
|
||||
{
|
||||
#ifdef VK_HEADER_VERSION_COMPLETE
|
||||
return VK_HEADER_VERSION_COMPLETE;
|
||||
#else
|
||||
return VK_API_VERSION_1_0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data)
|
||||
{
|
||||
// Load function pointers
|
||||
// You can use the default Vulkan loader using:
|
||||
// ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); });
|
||||
// ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_3, [](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); });
|
||||
// But this would be roughly equivalent to not setting VK_NO_PROTOTYPES.
|
||||
if (api_version == 0)
|
||||
api_version = ImGui_ImplVulkan_GetDefaultApiVersion();
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
||||
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
|
||||
@ -1094,9 +1119,7 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
|
||||
#undef IMGUI_VULKAN_FUNC_LOAD
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
// Manually load those two (see #5446)
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func("vkCmdBeginRenderingKHR", user_data));
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func("vkCmdEndRenderingKHR", user_data));
|
||||
ImGui_ImplVulkan_LoadDynamicRenderingFunctions(api_version, loader_func, user_data);
|
||||
#endif
|
||||
#else
|
||||
IM_UNUSED(loader_func);
|
||||
@ -1111,12 +1134,14 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
||||
{
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
|
||||
if (info->ApiVersion == 0)
|
||||
info->ApiVersion = ImGui_ImplVulkan_GetDefaultApiVersion();
|
||||
|
||||
if (info->UseDynamicRendering)
|
||||
{
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#ifndef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
|
||||
ImGui_ImplVulkan_LoadDynamicRenderingFunctions(info->ApiVersion, [](const char* function_name, void* user_data) { return vkGetInstanceProcAddr((VkInstance)user_data, function_name); }, (void*)info->Instance);
|
||||
#endif
|
||||
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR != nullptr);
|
||||
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR != nullptr);
|
||||
@ -1250,8 +1275,7 @@ void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulk
|
||||
{
|
||||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkan_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->FrameRenderBuffers.clear();
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
@ -1460,10 +1484,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
|
||||
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
|
||||
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = nullptr;
|
||||
wd->FrameSemaphores = nullptr;
|
||||
wd->Frames.clear();
|
||||
wd->FrameSemaphores.clear();
|
||||
wd->ImageCount = 0;
|
||||
if (wd->RenderPass)
|
||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||
@ -1518,12 +1540,11 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
|
||||
check_vk_result(err);
|
||||
|
||||
IM_ASSERT(wd->Frames == nullptr && wd->FrameSemaphores == nullptr);
|
||||
wd->SemaphoreCount = wd->ImageCount + 1;
|
||||
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
|
||||
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->SemaphoreCount);
|
||||
memset((void*)wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
|
||||
memset((void*)wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount);
|
||||
wd->Frames.resize(wd->ImageCount);
|
||||
wd->FrameSemaphores.resize(wd->SemaphoreCount);
|
||||
memset(wd->Frames.Data, 0, wd->Frames.size_in_bytes());
|
||||
memset(wd->FrameSemaphores.Data, 0, wd->FrameSemaphores.size_in_bytes());
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
wd->Frames[i].Backbuffer = backbuffers[i];
|
||||
}
|
||||
@ -1633,10 +1654,8 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
|
||||
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
|
||||
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
|
||||
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = nullptr;
|
||||
wd->FrameSemaphores = nullptr;
|
||||
wd->Frames.clear();
|
||||
wd->FrameSemaphores.clear();
|
||||
vkDestroyPipeline(device, wd->Pipeline, allocator);
|
||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
||||
|
@ -75,16 +75,17 @@
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3 or your value of VkApplicationInfo::apiVersion. May be lower than header version (VK_HEADER_VERSION_COMPLETE)
|
||||
VkInstance Instance;
|
||||
VkPhysicalDevice PhysicalDevice;
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
@ -103,7 +104,7 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
@ -123,7 +124,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet d
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||
@ -207,8 +208,8 @@ struct ImGui_ImplVulkanH_Window
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
ImVector<ImGui_ImplVulkanH_Frame> Frames;
|
||||
ImVector<ImGui_ImplVulkanH_FrameSemaphores> FrameSemaphores;
|
||||
|
||||
ImGui_ImplVulkanH_Window()
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-02-26: Recreate image bind groups during render. (#8426, #8046, #7765, #8027) + Update for latest webgpu-native changes.
|
||||
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
|
||||
// 2024-10-07: Expose selected render state in ImGui_ImplWGPU_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
@ -40,6 +41,8 @@
|
||||
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-28: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
||||
#ifndef __EMSCRIPTEN__
|
||||
@ -52,14 +55,19 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_wgpu.h"
|
||||
#include <limits.h>
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// Dawn renamed WGPUProgrammableStageDescriptor to WGPUComputeState (see: https://github.com/webgpu-native/webgpu-headers/pull/413)
|
||||
// Using type alias until WGPU adopts the same naming convention (#8369)
|
||||
using WGPUProgrammableStageDescriptor = WGPUComputeState;
|
||||
#endif
|
||||
|
||||
// Dear ImGui prototypes from imgui_internal.h
|
||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
|
||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed);
|
||||
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
|
||||
|
||||
// WebGPU data
|
||||
@ -71,7 +79,6 @@ struct RenderResources
|
||||
WGPUBuffer Uniforms = nullptr; // Shader uniforms
|
||||
WGPUBindGroup CommonBindGroup = nullptr; // Resources bind-group to bind the common resources to pipeline
|
||||
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
||||
WGPUBindGroup ImageBindGroup = nullptr; // Default font-resource of Dear ImGui
|
||||
WGPUBindGroupLayout ImageBindGroupLayout = nullptr; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
|
||||
};
|
||||
|
||||
@ -245,7 +252,6 @@ static void SafeRelease(RenderResources& res)
|
||||
SafeRelease(res.Sampler);
|
||||
SafeRelease(res.Uniforms);
|
||||
SafeRelease(res.CommonBindGroup);
|
||||
SafeRelease(res.ImageBindGroup);
|
||||
SafeRelease(res.ImageBindGroupLayout);
|
||||
};
|
||||
|
||||
@ -261,14 +267,14 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||
#else
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
#endif
|
||||
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
@ -276,7 +282,8 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||
#else
|
||||
stage_desc.entryPoint = "main";
|
||||
@ -393,7 +400,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Vertex buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
@ -420,7 +427,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Index buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
@ -485,18 +492,14 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
{
|
||||
// Bind custom texture
|
||||
ImTextureID tex_id = pcmd->GetTexID();
|
||||
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id));
|
||||
auto bind_group = bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash);
|
||||
if (bind_group)
|
||||
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id), 0);
|
||||
WGPUBindGroup bind_group = (WGPUBindGroup)bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash);
|
||||
if (!bind_group)
|
||||
{
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
|
||||
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group);
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, nullptr);
|
||||
bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
|
||||
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, bind_group);
|
||||
}
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
|
||||
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
@ -518,6 +521,16 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Remove all ImageBindGroups
|
||||
ImGuiStorage& image_bind_groups = bd->renderResources.ImageBindGroups;
|
||||
for (int i = 0; i < image_bind_groups.Data.Size; i++)
|
||||
{
|
||||
WGPUBindGroup bind_group = (WGPUBindGroup)image_bind_groups.Data[i].val_p;
|
||||
SafeRelease(bind_group);
|
||||
}
|
||||
image_bind_groups.Data.resize(0);
|
||||
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
}
|
||||
|
||||
@ -533,7 +546,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||
// Upload texture to graphics system
|
||||
{
|
||||
WGPUTextureDescriptor tex_desc = {};
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
tex_desc.label = { "Dear ImGui Font Texture", WGPU_STRLEN };
|
||||
#else
|
||||
tex_desc.label = "Dear ImGui Font Texture";
|
||||
@ -561,12 +574,20 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||
|
||||
// Upload texture data
|
||||
{
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUTexelCopyTextureInfo dst_view = {};
|
||||
#else
|
||||
WGPUImageCopyTexture dst_view = {};
|
||||
#endif
|
||||
dst_view.texture = bd->renderResources.FontTexture;
|
||||
dst_view.mipLevel = 0;
|
||||
dst_view.origin = { 0, 0, 0 };
|
||||
dst_view.aspect = WGPUTextureAspect_All;
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUTexelCopyBufferLayout layout = {};
|
||||
#else
|
||||
WGPUTextureDataLayout layout = {};
|
||||
#endif
|
||||
layout.offset = 0;
|
||||
layout.bytesPerRow = width * size_pp;
|
||||
layout.rowsPerImage = height;
|
||||
@ -600,7 +621,7 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Uniform buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
||||
@ -666,9 +687,15 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
// Vertex input configuration
|
||||
WGPUVertexAttribute attribute_desc[] =
|
||||
{
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||
{ nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||
#else
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||
#endif
|
||||
};
|
||||
|
||||
WGPUVertexBufferLayout buffer_layouts[1];
|
||||
@ -708,7 +735,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
// Create depth-stencil State
|
||||
WGPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.format = bd->depthStencilFormat;
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
||||
#else
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
@ -743,11 +770,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
||||
common_bg_descriptor.entries = common_bg_entries;
|
||||
bd->renderResources.CommonBindGroup = wgpuDeviceCreateBindGroup(bd->wgpuDevice, &common_bg_descriptor);
|
||||
|
||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], bd->renderResources.FontTextureView);
|
||||
bd->renderResources.ImageBindGroup = image_bind_group;
|
||||
bd->renderResources.ImageBindGroupLayout = bg_layouts[1];
|
||||
bd->renderResources.ImageBindGroups.SetVoidPtr(ImHashData(&bd->renderResources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
|
||||
|
||||
SafeRelease(vertex_shader_desc.module);
|
||||
SafeRelease(pixel_shader_desc.module);
|
||||
@ -807,7 +830,6 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
||||
bd->renderResources.Uniforms = nullptr;
|
||||
bd->renderResources.CommonBindGroup = nullptr;
|
||||
bd->renderResources.ImageBindGroups.Data.reserve(100);
|
||||
bd->renderResources.ImageBindGroup = nullptr;
|
||||
bd->renderResources.ImageBindGroupLayout = nullptr;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||
@ -256,6 +258,8 @@ static bool ImGui_ImplWin32_UpdateMouseCursor(ImGuiIO& io, ImGuiMouseCursor imgu
|
||||
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||
case ImGuiMouseCursor_Wait: win32_cursor = IDC_WAIT; break;
|
||||
case ImGuiMouseCursor_Progress: win32_cursor = IDC_APPSTARTING; break;
|
||||
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||
}
|
||||
::SetCursor(::LoadCursor(nullptr, win32_cursor));
|
||||
@ -428,6 +432,8 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
return ImGuiKey_KeypadEnter;
|
||||
|
||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||
//IMGUI_DEBUG_LOG("scancode %3d, keycode = 0x%02X\n", scancode, wParam);
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_TAB: return ImGuiKey_Tab;
|
||||
@ -445,17 +451,17 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||
case VK_SPACE: return ImGuiKey_Space;
|
||||
case VK_RETURN: return ImGuiKey_Enter;
|
||||
case VK_ESCAPE: return ImGuiKey_Escape;
|
||||
case VK_OEM_7: return ImGuiKey_Apostrophe;
|
||||
//case VK_OEM_7: return ImGuiKey_Apostrophe;
|
||||
case VK_OEM_COMMA: return ImGuiKey_Comma;
|
||||
case VK_OEM_MINUS: return ImGuiKey_Minus;
|
||||
//case VK_OEM_MINUS: return ImGuiKey_Minus;
|
||||
case VK_OEM_PERIOD: return ImGuiKey_Period;
|
||||
case VK_OEM_2: return ImGuiKey_Slash;
|
||||
case VK_OEM_1: return ImGuiKey_Semicolon;
|
||||
case VK_OEM_PLUS: return ImGuiKey_Equal;
|
||||
case VK_OEM_4: return ImGuiKey_LeftBracket;
|
||||
case VK_OEM_5: return ImGuiKey_Backslash;
|
||||
case VK_OEM_6: return ImGuiKey_RightBracket;
|
||||
case VK_OEM_3: return ImGuiKey_GraveAccent;
|
||||
//case VK_OEM_2: return ImGuiKey_Slash;
|
||||
//case VK_OEM_1: return ImGuiKey_Semicolon;
|
||||
//case VK_OEM_PLUS: return ImGuiKey_Equal;
|
||||
//case VK_OEM_4: return ImGuiKey_LeftBracket;
|
||||
//case VK_OEM_5: return ImGuiKey_Backslash;
|
||||
//case VK_OEM_6: return ImGuiKey_RightBracket;
|
||||
//case VK_OEM_3: return ImGuiKey_GraveAccent;
|
||||
case VK_CAPITAL: return ImGuiKey_CapsLock;
|
||||
case VK_SCROLL: return ImGuiKey_ScrollLock;
|
||||
case VK_NUMLOCK: return ImGuiKey_NumLock;
|
||||
@ -547,8 +553,28 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||
case VK_F24: return ImGuiKey_F24;
|
||||
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
||||
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
||||
default: return ImGuiKey_None;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Fallback to scancode
|
||||
// https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
|
||||
switch (scancode)
|
||||
{
|
||||
case 41: return ImGuiKey_GraveAccent; // VK_OEM_8 in EN-UK, VK_OEM_3 in EN-US, VK_OEM_7 in FR, VK_OEM_5 in DE, etc.
|
||||
case 12: return ImGuiKey_Minus;
|
||||
case 13: return ImGuiKey_Equal;
|
||||
case 26: return ImGuiKey_LeftBracket;
|
||||
case 27: return ImGuiKey_RightBracket;
|
||||
case 86: return ImGuiKey_Oem102;
|
||||
case 43: return ImGuiKey_Backslash;
|
||||
case 39: return ImGuiKey_Semicolon;
|
||||
case 40: return ImGuiKey_Apostrophe;
|
||||
case 51: return ImGuiKey_Comma;
|
||||
case 52: return ImGuiKey_Period;
|
||||
case 53: return ImGuiKey_Slash;
|
||||
}
|
||||
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
||||
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||
@ -790,9 +816,9 @@ static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||
{
|
||||
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
|
||||
if (RtlVerifyVersionInfoFn == nullptr)
|
||||
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||
if (RtlVerifyVersionInfoFn == nullptr)
|
||||
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||
if (RtlVerifyVersionInfoFn == nullptr)
|
||||
return FALSE;
|
||||
|
||||
@ -800,10 +826,10 @@ static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||
ULONGLONG conditionMask = 0;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||
versionInfo.dwMajorVersion = major;
|
||||
versionInfo.dwMinorVersion = minor;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||
versionInfo.dwMinorVersion = minor;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
||||
@ -861,16 +887,16 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
||||
UINT xdpi = 96, ydpi = 96;
|
||||
if (_IsWindows8Point1OrGreater())
|
||||
{
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
||||
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
||||
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
||||
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||
if (GetDpiForMonitorFn != nullptr)
|
||||
{
|
||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
if (GetDpiForMonitorFn != nullptr)
|
||||
{
|
||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||
return xdpi / 96.0f;
|
||||
}
|
||||
return xdpi / 96.0f;
|
||||
}
|
||||
}
|
||||
#ifndef NOGDI
|
||||
const HDC dc = ::GetDC(nullptr);
|
||||
|
@ -35,6 +35,235 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.91.9b (Released 2025-03-17)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.91.9b
|
||||
|
||||
- Tables: Fixed assert when loading .ini settings with reordered columns. (#8496, #7934)
|
||||
- Tables: Fixed issues when loading .ini settings for a table with columns using
|
||||
ImGuiTableColumnFlags_DefaultHide or ImGuiTableColumnFlags_DefaultSort. (#8496, #7934)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.91.9 (Released 2025-03-14)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.91.9
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Image: removed 'tint_col' and 'border_col' parameter from Image() function. (#8131, #8238)
|
||||
- Old function signature:
|
||||
void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 tint_col = (1,1,1,1), ImVec4 border_col = (0,0,0,0));
|
||||
- New function signatures:
|
||||
void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1));
|
||||
void ImageWithBg(ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 bg_col = (0,0,0,0), ImVec4 tint_col = (1,1,1,1));
|
||||
- TL;DR: 'border_col' had misleading side-effect on layout, 'bg_col' was missing, parameter order couldn't be consistent with ImageButton().
|
||||
- New behavior always use ImGuiCol_Border color + style.ImageBorderSize / ImGuiStyleVar_ImageBorderSize.
|
||||
- Old behavior altered border size (and therefore layout) based on border color's
|
||||
alpha, which caused variety of problems.
|
||||
- Old behavior used a fixed value of 1.0f for border size which was not tweakable.
|
||||
- Kept legacy signature (will obsolete), which mimics the old behavior,
|
||||
but uses Max(1.0f, style.ImageBorderSize) when border_col is specified.
|
||||
- Added ImageWithBg() function which has both 'bg_col' (which was missing) and 'tint_col'.
|
||||
It was impossible to add 'bg_col' to Image() with a parameter order consistent with
|
||||
other functions, so we decided to remove 'tint_col' and introduce ImageWithBg().
|
||||
- Renamed ImFontConfig::GlyphExtraSpacing.x option to GlyphExtraAdvanceX. (#242)
|
||||
- Renamed style.TabMinWidthForCloseButton to style.TabCloseButtonMinWidthUnselected.
|
||||
- Backends: Vulkan: Added 'uint32_t api_version' argument to ImGui_ImplVulkan_LoadFunctions().
|
||||
Note that it was also added to ImGui_ImplVulkan_InitInfo but for the later it is optional.
|
||||
(#8326, #8365, #8400)
|
||||
- Internals: Fonts: ImFontAtlas::ConfigData[] has been renamed to ImFontAtlas::Sources[],
|
||||
- Internals: Fonts: ImFont::ConfigData[], ConfigDataCount has been renamed to Sources[], SourcesCount.
|
||||
- Internals: Menus: reworked mangling of menu windows to use "###Menu_00" etc. instead
|
||||
of "##Menu_00", allowing them to also store the menu name before it. This shouldn't
|
||||
affect code unless directly accessing menu window from their mangled name.
|
||||
|
||||
Other changes:
|
||||
|
||||
- Fixed IsItemDeactivatedAfterEdit() signal being broken for Checkbox(),
|
||||
RadioButton(), Selectable(). Regression from 2025/01/13. (#8370)
|
||||
- Windows: Fixed an issue where BeginChild() inside a collapsed Begin()
|
||||
wouldn't inherit the SkipItems flag, resulting in missing coarse clipping
|
||||
opportunities for code not checking the BeginChild() return value.
|
||||
- Windows, Style: Added style.WindowBorderHoverPadding setting to configure
|
||||
inner/outer padding applied to hit-testing of windows borders and detection
|
||||
of hovered window.
|
||||
- InputText: Allow CTRL+Shift+Z to redo even outside of OSX. (#8389) [@tanksdude]
|
||||
- InputText: Pasting a multi-line buffer into a single-line edit replaces
|
||||
carriage return by spaces. (#8459)
|
||||
- InputTextWithHint(): Fixed buffer-overflow (luckily often with no visible effect)
|
||||
when a user callback modified the buffer contents in a way that altered the
|
||||
visibility of the preview/hint buffer. (#8368) [@m9710797, @ocornut]
|
||||
- Scrollbar: Rework logic that fades-out scrollbar when it becomes too small,
|
||||
which amusingly made it disappear when using very big font/frame size.
|
||||
- Scrollbar: Automatically stabilize ScrollbarX visibility when detecting a
|
||||
feedback loop manifesting with ScrollbarX visibility toggling on and off
|
||||
repeatedly. (#8488, #3285, #4539)
|
||||
(feedback loops of this sort can manifest in various situations, but combining
|
||||
horizontal + vertical scrollbar + using a clipper with varying width items is
|
||||
one frequent cause. The better solution is to, either: (1) enforce visibility
|
||||
by using ImGuiWindowFlags_AlwaysHorizontalScrollbar or (2) declare stable
|
||||
contents width with SetNextWindowContentSize(), if you can compute it.)
|
||||
- Tables: fixed calling SetNextWindowScroll() on clipped scrolling table
|
||||
to not leak the value into a subsequent window. (#8196)
|
||||
- Tables: fixed an issue where Columns Visible/Width state wouldn't be correctly
|
||||
restored when hot-reloading .ini state. (#7934)
|
||||
- Tables: tamed some .ini settings optimizations to more accurately allow
|
||||
overwriting/hot-reloading settings in more situations. (#7934)
|
||||
- Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651)
|
||||
- Image: Added ImageWithBg() variant with bg color and tint color. (#8131, #8238)
|
||||
- Image, Style: Added style.ImageBorderSize, ImGuiStyleVar_ImageBorderSize. (#8131, #8238)
|
||||
- Selectable: Fixed horizontal label alignment with SelectableTextAlign.x > 0 and
|
||||
specifying a selectable size. (#8338)
|
||||
- Tabs, Style: made the Close Button of selected tabs always visible by default,
|
||||
without requiring to hover the tab. (#8387)
|
||||
- Added style.TabCloseButtonMinWidthSelected/TabCloseButtonMinWidthUnselected settings
|
||||
to configure visibility of the Close Button for selected and unselected tabs.
|
||||
(-1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width)
|
||||
- Default for selected tabs: TabCloseButtonMinWidthSelected = -1.0f (always visible)
|
||||
- Default for unselected tabs: TabCloseButtonMinWidthUnselected = 0.0f (visible when hovered)
|
||||
- Tabs: fixed middle-mouse-button to close tab not checking that close button
|
||||
is hovered, merely its visibility. (#8399, #8387) [@nicovanbentum]
|
||||
- TextLink(), TextLinkOpenURL(): fixed honoring text baseline alignment.
|
||||
(#8451, #7660) [@achabense]
|
||||
- TextLinkOpenURL(): fixed default Win32 io.PlatformOpenInShellFn handler to
|
||||
handle UTF-8 regardless of system regional settings. (#7660) [@achabense]
|
||||
- Disabled: Fixed an issue restoring Alpha in EndDisabled() when using nested
|
||||
BeginDisabled() calls with PushStyleVar(ImGuiStyleVar_DisabledAlpha) within. (#8454, #7640)
|
||||
- Clipper: Fixed an issue where passing an out of bound index to IncludeItemByIndex()
|
||||
could incorrectly offset the final cursor, even if that index was not iterated through.
|
||||
One case where it would manifest was calling Combo() with an out of range index. (#8450)
|
||||
- Debug Tools: Added io.ConfigDebugHighlightIdConflictsShowItemPicker (defaults to true)
|
||||
to allow disabled Item Picker suggestion in user facing builds. (#7961, #7669)
|
||||
- Debug Tools: Tweaked layout of ID Stack Tool and always display full path. (#4631)
|
||||
- Misc: Various zealous warning fixes for newer version of Clang.
|
||||
- Misc: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursors
|
||||
(busy/wait/hourglass shape, with or without an arrow cursor).
|
||||
- Demo: Reorganized "Widgets" section to be alphabetically ordered and split in more functions.
|
||||
- Demo: Combos: demonstrate a very simple way to add a filter to a combo,
|
||||
by showing the filter inside the combo contents. (#718)
|
||||
- Examples: SDL3: Added comments to clarify setup for users of the unfortunate
|
||||
SDL_MAIN_USE_CALLBACKS feature. (#8455)
|
||||
- IO: Added ImGuiKey_Oem102 to ImGuiKey enum. (#7136, #7201, #7206, #7306, #8468)
|
||||
- Backends: reworked key handlers to use/prioritize untranslated scancodes instead of
|
||||
translated keycodes when dealing with OEM keys which are too difficult to find a reliable
|
||||
translated mapping on all systems, backends and keyboard layout.
|
||||
(#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||
- The affected keys are: ImGuiKey_Apostrophe, ImGuiKey_Comma, ImGuiKey_Minus, ImGuiKey_Period,
|
||||
ImGuiKey_Slash, ImGuiKey_Semicolon, ImGuiKey_Equal, ImGuiKey_LeftBracket, ImGuiKey_RightBracket,
|
||||
ImGuiKey_Backslash, ImGuiKey_GraveAccent, and newly introduced ImGuiKey_Oem102.
|
||||
- This is NOT affecting characters used the text inputs.
|
||||
- Fixes many cases of keys not emitting a ImGuiKey value with certain keyboard layouts.
|
||||
- Makes emitted ImGuiKey values more consistent regardless of keyboard mapping,
|
||||
but you may be getting different values as before.
|
||||
- Win32, SDL2, SDL3: Use scancodes for OEM keys.
|
||||
- GLFW: GLFW_KEY_WORLD_1 and GLFW_KEY_WORLD_2 are emitting ImGuiKey_Oem102.
|
||||
- Backends: GLFW: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled
|
||||
with asserts enabled. (#8452)
|
||||
- Backends: SDL2, SDL3: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn
|
||||
handler. (#7660) [@achabense]
|
||||
- Backends: SDL2, SDL3, Win32, Allegro5: Added support for ImGuiMouseCursor_Wait
|
||||
and ImGuiMouseCursor_Progress cursors.
|
||||
- Backends: SDL2, SDL3: Avoid calling SDL_GetGlobalMouseState() when mouse is in
|
||||
relative mode. (#8425, #8407) [@TheMode]
|
||||
- Backends: SDL2, SDL3: Only start SDL_CaptureMouse() when mouse is being dragged,
|
||||
to mitigate issues with e.g. Linux debuggers not claiming capture back on debug
|
||||
break. (#6410, #3650)
|
||||
- Backends: OpenGL3: Lazily reinitialize embedded GL loader for when calling backend
|
||||
from e.g. other DLL boundaries. (#8406)
|
||||
- Backends: DirectX12: Fixed an issue where pre-1.91.5 legacy ImGui_ImplDX12_Init()
|
||||
signature started breaking in 1.91.8 due to missing command queue. (#8429)
|
||||
- Backends: Metal: Fixed a crash on application resources. (#8367, #7419) [@anszom]
|
||||
- Backends: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo.
|
||||
Default to header version if unspecified. (#8326, #8365) [@mklefrancois]
|
||||
- Backends: Vulkan: Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering"
|
||||
(without -KHR suffix) on API 1.3. (#8326, #8365) [@mklefrancois]
|
||||
- Backends: WebGPU: Recreate image bind groups during render to allow reuse of
|
||||
WGPUTextureView pointers. (#8426, #8046, #7765, #8027) [@pplux, @Jairard]
|
||||
- Backends: WebGPU: Fix for DAWN API change WGPUProgrammableStageDescriptor -> WGPUComputeState.
|
||||
[@PhantomCloak] (#8369)
|
||||
- Backends: WebGPU: Fix for webgpu-native API changes. (#8426) [@pplux]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.91.8 (Released 2025-01-31)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.91.8
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- ColorEdit, ColorPicker: redesigned how alpha is displayed in the preview
|
||||
square. (#8335, #1578, #346)
|
||||
- Removed ImGuiColorEditFlags_AlphaPreview (made value 0): it is now the default behavior.
|
||||
- Prior to 1.91.8: alpha was made opaque in the preview by default _unless_ using ImGuiColorEditFlags_AlphaPreview.
|
||||
- We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||
- The new flags may be combined better and allow finer controls:
|
||||
- ImGuiColorEditFlags_AlphaOpaque: disable alpha in the preview, but alpha value still editable.
|
||||
- ImGuiColorEditFlags_AlphaNoBg: disable rendering a checkerboard background behind transparent color.
|
||||
- ImGuiColorEditFlags_AlphaPreviewHalf: display half opaque / half transparent preview.
|
||||
- Backends: SDLGPU3: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device
|
||||
for consistency. (#8163, #7998, #7988)
|
||||
|
||||
Other changes:
|
||||
|
||||
- imgui_freetype: fixed issue where glyph advances would incorrectly be
|
||||
snapped to pixels. Effectively it would only be noticeable when hinting
|
||||
is disabled with ImGuiFreeTypeBuilderFlags_NoHinting, as hinting itself
|
||||
snaps glyph advances.
|
||||
- Inputs: added IsMouseReleasedWithDelay() helper. (#8337, #8320)
|
||||
Use if you absolutely need to distinguish single-click from double-clicks
|
||||
by introducing a delay. This is a very rarely used UI idiom, but some apps
|
||||
use this: e.g. MS Explorer single-click on an icon triggers a rename.
|
||||
Generally use with 'delay >= io.MouseDoubleClickTime' + combine with a
|
||||
'GetMouseClickedCount() == 1' check.
|
||||
- Windows: legacy SetWindowFontScale() is properly inherited by nested child
|
||||
windows. Note that an upcoming major release should make this obsolete,
|
||||
but in the meanwhile it works better now. (#2701, #8138, #1018)
|
||||
- Windows, Style: Fixed small rendering issues with menu bar, resize grip and
|
||||
scrollbar when using thick border sizes. (#8267, #7887)
|
||||
- Windows: Fixed IsItemXXXX() functions not working on append-version of EndChild(). (#8350)
|
||||
Also made some of the fields accessible after BeginChild() to match Begin() logic.
|
||||
- Error Handling: Recovery from missing EndMenuBar() call. (#1651)
|
||||
- Tables, Menus: Fixed using BeginTable() in menu layer (any menu bar). (#8355)
|
||||
It previously overrode the current layer back to main layer, which caused an issue
|
||||
with MainMenuBar attempted to release focus when leaving the menu layer.
|
||||
- Tables, Menus: Fixed tables or child windows submitted inside BeginMainMenuBar()
|
||||
being unable to save their settings, as the main menu bar uses _NoSavedSettings. (#8356)
|
||||
- ColorEdit, ColorPicker: Fixed alpha preview broken in 1.91.7. (#8336, #8241). [@PathogenDavid]
|
||||
- Tabs, Style: reworked selected overline rendering to better accommodate
|
||||
for rounded tabs. Reduced default thickness (style.TabBarOverlineSize),
|
||||
increased default rounding (style.TabRounding). (#8334) [@Kian738, @ocornut]
|
||||
- Debug Tools: Tweaked font preview.
|
||||
- ImDrawList: texture baked storage for thick line reduced from ~64x64 to ~32x32. (#3245)
|
||||
- Fonts: IndexLookup[] table hold 16-bit values even in ImWchar32 mode,
|
||||
as it accounts for number of glyphs in same font. This is favorable to
|
||||
CalcTextSize() calls touching less memory.
|
||||
- Fonts: OversampleH/OversampleV defaults to 0 for automatic selection.
|
||||
- OversampleH == 0 --> use 1 or 2 depending on font size and use of PixelSnapH.
|
||||
- OversampleV == 0 --> always use 1.
|
||||
- ImFontAtlas: made calling ClearFonts() call ClearInputData(), as calling
|
||||
one without the other is never correct. (#8174, #6556, #6336, #4723)
|
||||
- Examples: DirectX12: Reduced number of frame in flight from 3 to 2 in
|
||||
provided example, to reduce latency.
|
||||
- Examples: Vulkan: better handle VK_SUBOPTIMAL_KHR being returned by
|
||||
vkAcquireNextImageKHR() or vkQueuePresentKHR(). (#7825, #7831) [@NostraMagister]
|
||||
- Backends: SDL2: removed assert preventing using ImGui_ImplSDL2_SetGamepadMode()
|
||||
with ImGui_ImplSDL2_GamepadMode_Manual and an empty array. (#8329)
|
||||
- Backends: SDL3: removed assert preventing using ImGui_ImplSDL3_SetGamepadMode()
|
||||
with ImGui_ImplSDL3_GamepadMode_Manual and an empty array. (#8329)
|
||||
- Backends: SDLGPU3: Exposed ImGui_ImplSDLGPU3_CreateDeviceObjects()/_DestroyDeviceObjects().
|
||||
Removed return value from ImGui_ImplSDLGPU3_CreateFontsTexture(). (#8163, #7998, #7988)
|
||||
- Backends: SDL_Renderer2/3: Use endian-dependent RGBA32 texture format, to match
|
||||
SDL_Color. (#8327) [@dkosmari]
|
||||
- Backends: DirectX12: Texture upload use the command queue provided in
|
||||
ImGui_ImplDX12_InitInfo instead of creating its own.
|
||||
- Backends: OSX: Removed notification observer when shutting down. (#8331) [@jrachele]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.91.7 (Released 2025-01-14)
|
||||
-----------------------------------------------------------------------
|
||||
@ -79,6 +308,8 @@ Other changes:
|
||||
the label (not only the highlight/frame) also spans all columns. This is
|
||||
useful for table rows where you know nothing else is submitted. (#8318, #3565)
|
||||
Obviously best used with ImGuiTableFlags_NoBordersInBodyUntilResize.
|
||||
- Selectable: Fixed horizontal label alignment when combined with using
|
||||
ImGuiSelectableFlags_SpanAllColumns. (#8338)
|
||||
- Drags: Added ImGuiSliderFlags_NoSpeedTweaks flag to disable keyboard
|
||||
modifiers altering the tweak speed. Useful if you want to alter tweak speed
|
||||
yourself based on your own logic. (#8223)
|
||||
@ -93,7 +324,7 @@ Other changes:
|
||||
- Demo: Added label edition to Property Editor demo + fix an ID issue. (#8266) [@moritz-h]
|
||||
- Misc: Fixed misc/cpp/imgui_stdlib.h/.cpp not supporting IMGUI_DISABLE. (#8294) [@juur]
|
||||
- Misc: Fixed MinGW builds not using UTF-8 friendly _wfopen(). (#8300)
|
||||
- Backends: SDL_GPU for SDL3: Added backend for SDL_GPU! (#8163, #7998, #7988) [@DeltaW0x].
|
||||
- Backends: SDLGPU3 for SDL3: Added backend for SDL_GPU! (#8163, #7998, #7988) [@DeltaW0x].
|
||||
- Backends: SDL3: Added ImGui_ImplSDL3_InitForSDLGPU() for consistency, even
|
||||
though it is currently not doing anything particular. (#8163, #7998, #7988)
|
||||
- Backends: Allegro5: Avoid calling al_set_mouse_cursor() repeatedly since it appears
|
||||
@ -201,7 +432,7 @@ Other changes:
|
||||
initial mouse down event.
|
||||
- Note that it may reveal incorrect usage if you were using InputInt/InputFloat
|
||||
without persistent storage by relying solely on e.g. IsItemDeactivatedAfterEdit():
|
||||
this was never supported and didn't work consistantly (see #8149).
|
||||
this was never supported and didn't work consistently (see #8149).
|
||||
- InputText: fixed a bug (regression in 1.91.2) where modifying text buffer within
|
||||
a callback would sometimes prevents further appending to the buffer.
|
||||
- Tabs, Style: made ImGuiCol_TabDimmedSelectedOverline alpha 0 (not visible) in default
|
||||
@ -305,7 +536,7 @@ Other changes:
|
||||
supported by InputFloat, InputInt, InputScalar etc. widgets. It actually never was. (#8065, #3946)
|
||||
- imgui_freetype: Added support for plutosvg (as an alternative to lunasvg) to render
|
||||
OpenType SVG fonts. Requires defining IMGUI_ENABLE_FREETYPE_PLUTOSVG along with IMGUI_ENABLE_FREETYPE.
|
||||
Providing headers/librairies for plutosvg + plutovg is up to you (see #7927 for help).
|
||||
Providing headers/libraries for plutosvg + plutovg is up to you (see #7927 for help).
|
||||
(#7927, #7187, #6591, #6607) [@pthom]
|
||||
- Backends: DX11, DX12, SDLRenderer2/3. Vulkan, WGPU: expose selected state in
|
||||
ImGui_ImplXXXX_RenderState structures during render loop user draw callbacks.
|
||||
@ -488,7 +719,7 @@ Other changes:
|
||||
by an extra pixel + rework the change so that contents doesn't overlap the bottom and
|
||||
right border in a scrolling table. (#6765, #3752, #7428)
|
||||
- Tables: fixed an issue resizing columns or querying hovered column/row when using multiple
|
||||
synched instances that are layed out at different X positions. (#7933)
|
||||
synced instances that are laid out at different X positions. (#7933)
|
||||
- Tabs: avoid queuing a refocus when tab is already focused, which would have the
|
||||
side-effect of e.g. closing popup on a mouse release. (#7914)
|
||||
- InputText: allow callback to update buffer while in read-only mode. (imgui_club/#46)
|
||||
@ -721,7 +952,7 @@ Other changes:
|
||||
- Windows: BeginChild(): fixed a glitch when during a resize of a child window which is
|
||||
tightly close to the boundaries of its parent (e.g. with zero WindowPadding), the child
|
||||
position could have temporarily be moved around by erroneous padding application. (#7706)
|
||||
- TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal
|
||||
- TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw a horizontal
|
||||
line over selected tabs to increase visibility. This is used by docking.
|
||||
Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors.
|
||||
- Tables: added TableGetHoveredColumn() to public API, as an alternative to testing for
|
||||
@ -784,7 +1015,7 @@ Other changes:
|
||||
- Scrollbar: made scrolling logic more standard: clicking above or below the
|
||||
grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150)
|
||||
- Scrollbar: fixed miscalculation of vertical scrollbar visibility when required
|
||||
solely by the presence of an horizontal scrollbar. (#1574)
|
||||
solely by the presence of a horizontal scrollbar. (#1574)
|
||||
- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal
|
||||
to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut]
|
||||
- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal
|
||||
@ -918,7 +1149,7 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- TreeNode: Fixed a layout inconsistency when using a empty/hidden label followed
|
||||
- TreeNode: Fixed a layout inconsistency when using an empty/hidden label followed
|
||||
by a SameLine() call. (#7505, #282)
|
||||
Before: TreeNode("##Hidden"); SameLine(); Text("Hello");
|
||||
// This was actually incorrect! BUT appeared to look ok with the default style
|
||||
@ -1017,7 +1248,7 @@ Other changes:
|
||||
Note that only simple polygons (no self-intersections, no holes) are supported.
|
||||
- DrawList: Allow AddText() to accept null ranges. (#3615, 7391)
|
||||
- Docs: added more wiki links to headers of imgui.h/imgui.cpp to facilitate discovery
|
||||
of interesting resources, because github doesn't allow Wiki to be crawled by search engines.
|
||||
of interesting resources, because GitHub doesn't allow Wiki to be crawled by search engines.
|
||||
- This is the main wiki: https://github.com/ocornut/imgui/wiki
|
||||
- This is the crawlable version: https://github-wiki-see.page/m/ocornut/imgui/wiki
|
||||
Adding a link to the crawlable version, even though it is not intended for humans,
|
||||
@ -1169,7 +1400,7 @@ Other changes:
|
||||
- BeginChild(): Resize borders rendered even when ImGuiWindowFlags_NoBackground
|
||||
is specified. (#1710, #7194)
|
||||
- Fixed some auto-resizing path using style.WindowMinSize.x (instead of x/y)
|
||||
for both axises since 1.90. (#7106) [@n0bodysec]
|
||||
for both axes since 1.90. (#7106) [@n0bodysec]
|
||||
- Scrolling: internal scrolling value is rounded instead of truncated, as a way to reduce
|
||||
speed asymmetry when (incorrectly) attempting to scroll by non-integer amount. (#6677)
|
||||
- Navigation (Keyboard/gamepad):
|
||||
@ -1327,7 +1558,7 @@ Other changes:
|
||||
- Combining this with also specifying ImGuiChildFlags_AlwaysAutoResize disables
|
||||
this optimization, meaning child contents will never be clipped (not recommended).
|
||||
- Please be considerate that child are full windows and carry significant overhead:
|
||||
combining auto-resizing for both axises to create a non-scrolling child to merely draw
|
||||
combining auto-resizing for both axes to create a non-scrolling child to merely draw
|
||||
a border would be better more optimally using BeginGroup(). (see #1496)
|
||||
(until we come up with new helpers for framed groups and work-rect adjustments).
|
||||
- BeginChild(): made it possible to use SetNextWindowSizeConstraints() rectangle, often
|
||||
@ -1389,7 +1620,7 @@ Other changes:
|
||||
parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
|
||||
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
|
||||
register contents size in a way that would affect the scrolling layer.
|
||||
Was most often noticeable when using an horizontal scrollbar. (#6789)
|
||||
Was most often noticeable when using a horizontal scrollbar. (#6789)
|
||||
- InputText:
|
||||
- InputTextMultiline: Fixed a crash pressing Down on last empty line of a multi-line buffer.
|
||||
(regression from 1.89.2, only happened in some states). (#6783, #6000)
|
||||
@ -1595,7 +1826,7 @@ Breaking changes:
|
||||
|
||||
- Moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal.
|
||||
As the fields were added in 1.89 and expected to be left unchanged by most users, or only
|
||||
tweaked once during app initialisation, we are exceptionally accepting the breakage.
|
||||
tweaked once during app initialization, we are exceptionally accepting the breakage.
|
||||
Majority of users should not even notice.
|
||||
- Overlapping items: (#6512, #3909, #517)
|
||||
- Added 'SetNextItemAllowOverlap()' (called before an item) as a replacement for using
|
||||
@ -1695,7 +1926,7 @@ Breaking changes:
|
||||
- Commented out obsolete/redirecting functions that were marked obsolete more than two years ago:
|
||||
- ListBoxHeader() -> use BeginListBox()
|
||||
- ListBoxFooter() -> use EndListBox()
|
||||
- Note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for refeence.
|
||||
- Note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for reference.
|
||||
- Backends: SDL_Renderer: Renamed 'imgui_impl_sdlrenderer.h/cpp' to 'imgui_impl_sdlrenderer2.h/cpp',
|
||||
in order to accommodate for upcoming SDL3 and change in its SDL_Renderer API. (#6286)
|
||||
- Backends: GLUT: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame().
|
||||
@ -1859,7 +2090,7 @@ Other changes:
|
||||
- Public API: PushTabStop(false) / PopTabStop()
|
||||
- Internal: PushItemFlag(ImGuiItemFlags_NoTabStop, true);
|
||||
- Internal: Directly pass ImGuiItemFlags_NoTabStop to ItemAdd() for custom widgets.
|
||||
- Nav: Tabbing/Shift-Tabbing can more reliably be used to step out of an item that is not
|
||||
- Nav: Tabbing/Shift+Tabbing can more reliably be used to step out of an item that is not
|
||||
tab-stoppable. (#3092, #5759, #787)
|
||||
- Nav: Made Enter key submit the same type of Activation event as Space key,
|
||||
allowing to press buttons with Enter. (#5606)
|
||||
@ -1922,20 +2153,20 @@ Other changes:
|
||||
due to how unique table instance id was generated. (#6140) [@ocornut, @rodrigorc]
|
||||
- Inputs, Scrolling: Made horizontal scroll wheel and horizontal scroll direction consistent
|
||||
across backends/os. (#4019, #6096, #1463) [@PathogenDavid, @ocornut, @rokups]
|
||||
- Clarified that 'wheel_y > 0.0f' scrolls Up, 'wheel_y > 0.0f' scrolls Down.
|
||||
Clarified that 'wheel_x > 0.0f' scrolls Left, 'wheel_x > 0.0f' scrolls Right.
|
||||
- Clarified that 'wheel_y > 0.0f' scrolls Up, 'wheel_y < 0.0f' scrolls Down.
|
||||
Clarified that 'wheel_x > 0.0f' scrolls Left, 'wheel_x < 0.0f' scrolls Right.
|
||||
- Backends: Fixed horizontal scroll direction for Win32 and SDL backends. (#4019)
|
||||
- Shift+WheelY support on non-OSX machines was already correct. (#2424, #1463)
|
||||
(whereas on OSX machines Shift+WheelY turns into WheelX at the OS level).
|
||||
- If you use a custom backend, you should verify horizontal wheel direction.
|
||||
- Axises are flipped by OSX for mouse & touch-pad when 'Natural Scrolling' is on.
|
||||
- Axises are flipped by Windows for touch-pad when 'Settings->Touchpad->Down motion scrolls up' is on.
|
||||
- Axes are flipped by OSX for mouse & touch-pad when 'Natural Scrolling' is on.
|
||||
- Axes are flipped by Windows for touch-pad when 'Settings->Touchpad->Down motion scrolls up' is on.
|
||||
- You can use 'Demo->Tools->Debug Log->IO" to visualize values submitted to Dear ImGui.
|
||||
- Known issues remaining with Emscripten:
|
||||
- The magnitude of wheeling values on Emscripten was improved but isn't perfect. (#6096)
|
||||
- When running the Emscripten app on a Mac with a mouse, SHIFT+WheelY doesn't turn into WheelX.
|
||||
This is because we don't know that we are running on Mac and apply our own Shift+swapping
|
||||
on top of OSX' own swapping, so wheel axises are swapped twice. Emscripten apps may need
|
||||
on top of OSX's own swapping, so wheel axes are swapped twice. Emscripten apps may need
|
||||
to find a way to detect this and set io.ConfigMacOSXBehaviors manually (if you know a way
|
||||
let us know!), or offer the "OSX-style behavior" option to their user.
|
||||
- Window: Avoid rendering shapes for hidden resize grips.
|
||||
@ -1961,7 +2192,7 @@ Other changes:
|
||||
values for io.DeltaTime, and browser features such as "privacy.resistFingerprinting=true"
|
||||
can exacerbate that. (#6114, #3644)
|
||||
- Backends: OSX: Fixed scroll/wheel scaling for devices emitting events with
|
||||
hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
||||
hasPreciseScrollingDeltas==false (e.g. non-Apple mice).
|
||||
- Backends: Win32: flipping WM_MOUSEHWHEEL horizontal value to match other backends and
|
||||
offer consistent horizontal scrolling direction. (#4019)
|
||||
- Backends: SDL2: flipping SDL_MOUSEWHEEL horizontal value to match other backends and
|
||||
@ -2165,7 +2396,7 @@ Other Changes:
|
||||
- Scrolling: Mitigated issue where multi-axis mouse-wheel inputs (usually from touch pad
|
||||
events) are incorrectly locking scrolling in a parent window. (#4559, #3795, #2604)
|
||||
- Scrolling: Exposed SetNextWindowScroll() in public API. Useful to remove a scrolling
|
||||
delay in some situations where e.g. windows need to be synched. (#1526)
|
||||
delay in some situations where e.g. windows need to be synced. (#1526)
|
||||
- InputText: added experimental io.ConfigInputTextEnterKeepActive feature to make pressing
|
||||
Enter keep the input active and select all text.
|
||||
- InputText: numerical fields automatically accept full-width characters (U+FF01..U+FF5E)
|
||||
@ -2209,7 +2440,7 @@ Other Changes:
|
||||
- Menus: Fixed using IsItemHovered()/IsItemClicked() on BeginMenu(). (#5775)
|
||||
- Menus, Popups: Experimental fix for issue where clicking on an open BeginMenu() item called from
|
||||
a window which is neither a popup neither a menu used to incorrectly close and reopen the menu
|
||||
(the fix may have side-effect and is labelld as experimental as we may need to revert). (#5775)
|
||||
(the fix may have side-effect and is labelled as experimental as we may need to revert). (#5775)
|
||||
- Menus, Nav: Fixed keyboard/gamepad navigation occasionally erroneously landing on menu-item
|
||||
in parent window when the parent is not a popup. (#5730)
|
||||
- Menus, Nav: Fixed not being able to close a menu with Left arrow when parent is not a popup. (#5730)
|
||||
@ -2347,7 +2578,7 @@ Other Changes:
|
||||
always lead to menu closure. Fixes using items that are not MenuItem() or BeginItem() at the root
|
||||
level of a popup with a child menu opened.
|
||||
- Menus: Menus emitted from the main/scrolling layer are not part of the same menu-set as menus emitted
|
||||
from the menu-bar, avoiding accidental hovering from one to the other. (#3496, #4797) [@rokups]
|
||||
from the menu-bar, avoiding accidental hovering from one to the other. (#3496, #4797) [@rokups]
|
||||
- Style: Adjust default value of GrabMinSize from 10.0f to 12.0f.
|
||||
- Stack Tool: Added option to copy item path to clipboard. (#4631)
|
||||
- Settings: Fixed out-of-bounds read when .ini file on disk is empty. (#5351) [@quantum5]
|
||||
@ -2449,7 +2680,7 @@ Breaking Changes:
|
||||
io.AddKeyEvent(), io.AddKeyAnalogEvent().
|
||||
- Added io.AddKeyAnalogEvent() function, obsoleting writing directly to io.NavInputs[] arrays.
|
||||
- Renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. (#2625)
|
||||
- Removed support for legacy arithmetic operators (+,+-,*,/) when inputing text into a slider/drag. (#4917, #3184)
|
||||
- Removed support for legacy arithmetic operators (+,+-,*,/) when inputting text into a slider/drag. (#4917, #3184)
|
||||
This doesn't break any api/code but a feature that was accessible by end-users (which seemingly no one used).
|
||||
(Instead you may implement custom expression evaluators to provide a better version of this).
|
||||
- Backends: GLFW: backend now uses glfwSetCursorPosCallback().
|
||||
@ -2505,7 +2736,7 @@ Other Changes:
|
||||
- Backends: GLFW: Retrieve mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured.
|
||||
- Backends: GLFW: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921)
|
||||
- Backends: GLFW: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing
|
||||
callbacks after iniitializing backend. (#4981)
|
||||
callbacks after initializing backend. (#4981)
|
||||
- Backends: Win32: Submit keys and key mods using io.AddKeyEvent(). (#2625, #4921)
|
||||
- Backends: Win32: Retrieve mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured.
|
||||
- Backends: Win32: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921)
|
||||
@ -2587,7 +2818,7 @@ Other Changes:
|
||||
- Menus: fixed sub-menu items inside a popups from closing the popup.
|
||||
- Menus: fixed top-level menu from not consistently using style.PopupRounding. (#4788)
|
||||
- InputText, Nav: fixed repeated calls to SetKeyboardFocusHere() preventing to use InputText(). (#4682)
|
||||
- Inputtext, Nav: fixed using SetKeyboardFocusHere() on InputTextMultiline(). (#4761)
|
||||
- InputText, Nav: fixed using SetKeyboardFocusHere() on InputTextMultiline(). (#4761)
|
||||
- InputText: made double-click select word, triple-line select line. Word delimitation logic differs
|
||||
slightly from the one used by CTRL+arrows. (#2244)
|
||||
- InputText: fixed ReadOnly flag preventing callbacks from receiving the text buffer. (#4762) [@actondev]
|
||||
@ -2618,7 +2849,7 @@ Other Changes:
|
||||
- Misc: Fix MinGW DLL build issue (when IMGUI_API is defined). [@rokups]
|
||||
- CI: Add MinGW DLL build to test suite. [@rokups]
|
||||
- Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce
|
||||
likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling
|
||||
likelihood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling
|
||||
vkCmdSetScissor() explicitly every frame. (#4644)
|
||||
- Backends: OpenGL3: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports
|
||||
with some Intel HD drivers, and perhaps improve performances. (#4468, #4504, #2981, #3381) [@parbo]
|
||||
@ -2694,7 +2925,7 @@ Other Changes:
|
||||
- Nav: Fixed vertical scoring offset when wrapping on Y in a decorated window.
|
||||
- Nav: Improve scrolling behavior when navigating to an item larger than view.
|
||||
- TreePush(): removed unnecessary/inconsistent legacy behavior where passing a NULL value to
|
||||
the TreePush(const char*) and TreePush(const void*) functions would use an hard-coded replacement.
|
||||
the TreePush(const char*) and TreePush(const void*) functions would use a hard-coded replacement.
|
||||
The only situation where that change would make a meaningful difference is TreePush((const char*)NULL)
|
||||
(_explicitly_ casting a null pointer to const char*), which is unlikely and will now crash.
|
||||
You may replace it with anything else.
|
||||
@ -2817,9 +3048,9 @@ Other Changes:
|
||||
- Fonts: Functions with a 'float size_pixels' parameter can accept zero if it is set in ImFontSize::SizePixels.
|
||||
- Fonts: Prefer using U+FFFD character for fallback instead of '?', if available. (#4269)
|
||||
- Fonts: Use U+FF0E dot character to construct an ellipsis if U+002E '.' is not available. (#4269)
|
||||
- Fonts: Added U+FFFD ("replacement character") to default asian glyphs ranges. (#4269)
|
||||
- Fonts: Added U+FFFD ("replacement character") to default Asian glyphs ranges. (#4269)
|
||||
- Fonts: Fixed calling ClearTexData() (clearing CPU side font data) triggering an assert in NewFrame(). (#3487)
|
||||
- DrawList: Fixed AddCircle/AddCircleFilled() with auto-tesselation not using accelerated paths for small circles.
|
||||
- DrawList: Fixed AddCircle/AddCircleFilled() with auto-tessellation not using accelerated paths for small circles.
|
||||
Fixed AddCircle/AddCircleFilled() with 12 segments which had a broken edge. (#4419, #4421) [@thedmd]
|
||||
- Demo: Fixed requirement in 1.83 to link with imgui_demo.cpp if IMGUI_DISABLE_METRICS_WINDOW is not set. (#4171)
|
||||
Normally the right way to disable compiling the demo is to set IMGUI_DISABLE_DEMO_WINDOWS, but we want to avoid
|
||||
@ -2863,7 +3094,7 @@ Other Changes:
|
||||
- Examples: OSX+OpenGL2: Fix event forwarding (fix key remaining stuck when using shortcuts with Cmd/Super key).
|
||||
Other OSX examples were not affected. (#4253, #1873) [@rokups]
|
||||
- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg.
|
||||
- Examples: SDL2: Accommodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
||||
- Examples: SDL2: Accommodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
@ -2985,7 +3216,7 @@ Breaking Changes:
|
||||
- ImDrawList: clarified that PathArcTo()/PathArcToFast() won't render with radius < 0.0f. Previously it sorts
|
||||
of accidentally worked but would lead to counter-clockwise paths which and have an effect on anti-aliasing.
|
||||
- InputText: renamed ImGuiInputTextFlags_AlwaysInsertMode to ImGuiInputTextFlags_AlwaysOverwrite, old name was an
|
||||
incorrect description of behavior. Was ostly used by memory editor. Kept inline redirection function. (#2863)
|
||||
incorrect description of behavior. Was mostly used by memory editor. Kept inline redirection function. (#2863)
|
||||
- Moved 'misc/natvis/imgui.natvis' to 'misc/debuggers/imgui.natvis' as we will provide scripts for other debuggers.
|
||||
- Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f)
|
||||
to style.CircleTessellationMaxError (new default = 0.30f) as its meaning changed. (#3808) [@thedmd]
|
||||
@ -3083,7 +3314,7 @@ Other Changes:
|
||||
- For a Platform Monitor, the work area is generally the full area minus space used by task-bars.
|
||||
- All of this has been the case in 'docking' branch for a long time. What we've done is merely merging
|
||||
a small chunk of the multi-viewport logic into 'master' to standardize some concepts ahead of time.
|
||||
- Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760)
|
||||
- Tables: Fixed PopItemWidth() or multi-components items not restoring per-column ItemWidth correctly. (#3760)
|
||||
- Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no
|
||||
close button in the window. (#3731)
|
||||
- SliderInt: Fixed click/drag when v_min==v_max from setting the value to zero. (#3774) [@erwincoumans]
|
||||
@ -3120,7 +3351,7 @@ Other Changes:
|
||||
User needs to call ImGui_ImplVulkan_LoadFunctions() with their custom loader prior to other functions.
|
||||
- Backends: Metal: Fixed texture storage mode when building on Mac Catalyst. (#3748) [@Belinsky-L-V]
|
||||
- Backends: OSX: Fixed mouse position not being reported when mouse buttons other than left one are down. (#3762) [@rokups]
|
||||
- Backends: WebGPU: Added enderer backend for WebGPU support (imgui_impl_wgpu.cpp) (#3632) [@bfierz]
|
||||
- Backends: WebGPU: Added renderer backend for WebGPU support (imgui_impl_wgpu.cpp) (#3632) [@bfierz]
|
||||
Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.
|
||||
- Examples: WebGPU: Added Emscripten+WebGPU example. (#3632) [@bfierz]
|
||||
- Backends: GLFW: Added ImGui_ImplGlfw_InitForOther() initialization call to use with non OpenGL API. (#3632)
|
||||
@ -3319,12 +3550,12 @@ Other Changes:
|
||||
- Columns: Fix inverted ClipRect being passed to renderer when using certain primitives inside of
|
||||
a fully clipped column. (#3475) [@szreder]
|
||||
- Popups, Tooltips: Fix edge cases issues with positioning popups and tooltips when they are larger than
|
||||
viewport on either or both axises. [@Rokups]
|
||||
viewport on either or both axes. [@Rokups]
|
||||
- Fonts: AddFontDefault() adjust its vertical offset based on floor(size/13) instead of always +1.
|
||||
Was previously done by altering DisplayOffset.y but wouldn't work for DPI scaled font.
|
||||
- Metrics: Various tweaks, listing windows front-to-back, greying inactive items when possible.
|
||||
- Demo: Add simple InputText() callbacks demo (aside from the more elaborate ones in 'Examples->Console').
|
||||
- Backends: OpenGL3: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 contexts which have
|
||||
- Backends: OpenGL3: Fix to avoid compiling/calling glBindSampler() on ES or pre-3.3 contexts which have
|
||||
the defines set by a loader. (#3467, #1985) [@jjwebb]
|
||||
- Backends: Vulkan: Some internal refactor aimed at allowing multi-viewport feature to create their
|
||||
own render pass. (#3455, #3459) [@FunMiles]
|
||||
@ -3413,7 +3644,7 @@ Other Changes:
|
||||
and allowed to pass them to InvisibleButton(): ImGuiButtonFlags_MouseButtonLeft/Right/Middle.
|
||||
This is a small but rather important change because lots of multi-button behaviors could previously
|
||||
only be achieved using lower-level/internal API. Now also available via high-level InvisibleButton()
|
||||
with is a de-facto versatile building block to creating custom widgets with the public API.
|
||||
with is a de facto versatile building block to creating custom widgets with the public API.
|
||||
- Fonts: Fixed ImFontConfig::GlyphExtraSpacing and ImFontConfig::PixelSnapH settings being pulled
|
||||
from the merged/target font settings when merging fonts, instead of being pulled from the source
|
||||
font settings.
|
||||
@ -3560,7 +3791,7 @@ Other Changes:
|
||||
ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073)
|
||||
- Added optional support for Unicode plane 1-16 (#2538, #2541, #2815) [@cloudwu, @samhocevar]
|
||||
- Compile-time enable with '#define IMGUI_USE_WCHAR32' in imconfig.h.
|
||||
- More onsistent handling of unsupported code points (0xFFFD).
|
||||
- More consistent handling of unsupported code points (0xFFFD).
|
||||
- Surrogate pairs are supported when submitting UTF-16 data via io.AddInputCharacterUTF16(),
|
||||
allowing for more complete CJK input.
|
||||
- sizeof(ImWchar) goes from 2 to 4. IM_UNICODE_CODEPOINT_MAX goes from 0xFFFF to 0x10FFFF.
|
||||
@ -3644,7 +3875,7 @@ Other Changes:
|
||||
|
||||
- Inputs: Added ImGuiMouseButton enum for convenience (e.g. ImGuiMouseButton_Right=1).
|
||||
We forever guarantee that the existing value will not changes so existing code is free to use 0/1/2.
|
||||
- Nav: Fixed a bug where the initial CTRL-Tab press while in a child window sometimes selected
|
||||
- Nav: Fixed a bug where the initial CTRL+Tab press while in a child window sometimes selected
|
||||
the current root window instead of always selecting the previous root window. (#787)
|
||||
- ColorEdit: Fix label alignment when using ImGuiColorEditFlags_NoInputs. (#2955) [@rokups]
|
||||
- ColorEdit: In HSV display of a RGB stored value, attempt to locally preserve Saturation
|
||||
@ -3817,7 +4048,7 @@ Other Changes:
|
||||
mostly for consistency. (#2159, #2160) [@goran-w]
|
||||
- Selectable: Added ImGuiSelectableFlags_AllowItemOverlap flag in public api (was previously internal only).
|
||||
- Style: Allow style.WindowMenuButtonPosition to be set to ImGuiDir_None to hide the collapse button. (#2634, #2639)
|
||||
- Font: Better ellipsis ("...") drawing implementation. Instead of drawing three pixel-ey dots (which was glaringly
|
||||
- Font: Better ellipsis ("...") drawing implementation. Instead of drawing three pixely dots (which was glaringly
|
||||
unfitting with many types of fonts) we first attempt to find a standard ellipsis glyphs within the loaded set.
|
||||
Otherwise we render ellipsis using '.' from the font from where we trim excessive spacing to make it as narrow
|
||||
as possible. (#2775) [@rokups]
|
||||
@ -4153,7 +4384,7 @@ Other Changes:
|
||||
- InputText: Fixed an edge case crash that would happen if another widget sharing the same ID
|
||||
is being swapped with an InputText that has yet to be activated.
|
||||
- InputText: Fixed various display corruption related to swapping the underlying buffer while
|
||||
a input widget is active (both for writable and read-only paths). Often they would manifest
|
||||
an input widget is active (both for writable and read-only paths). Often they would manifest
|
||||
when manipulating the scrollbar of a multi-line input text.
|
||||
- ColorEdit, ColorPicker, ColorButton: Added ImGuiColorEditFlags_InputHSV to manipulate color
|
||||
values encoded as HSV (in order to avoid HSV<>RGB round trips and associated singularities).
|
||||
@ -4164,7 +4395,7 @@ Other Changes:
|
||||
reading the 4th float in the array (value was read and discarded). (#2384) [@haldean]
|
||||
- MenuItem, Selectable: Fixed disabled widget interfering with navigation (fix c2db7f63 in 1.67).
|
||||
- Tabs: Fixed a crash when using many BeginTabBar() recursively (didn't affect docking). (#2371)
|
||||
- Tabs: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to
|
||||
- Tabs: Added extra misusage error recovery. Past the assert, common misusage don't lead to
|
||||
hard crashes any more, facilitating integration with scripting languages. (#1651)
|
||||
- Tabs: Fixed ImGuiTabItemFlags_SetSelected being ignored if the tab is not visible (with
|
||||
scrolling policy enabled) or if is currently appearing.
|
||||
@ -4207,7 +4438,7 @@ Breaking Changes:
|
||||
|
||||
- Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
|
||||
- Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame).
|
||||
If for some reason your time step calculation gives you a zero value, replace it with a arbitrarily small value!
|
||||
If for some reason your time step calculation gives you a zero value, replace it with an arbitrarily small value!
|
||||
|
||||
Other Changes:
|
||||
|
||||
@ -4305,7 +4536,7 @@ Other Changes:
|
||||
in the parent window, so there is no mismatch between the layout in parent and the position of the child window.
|
||||
- InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257)
|
||||
- DragFloat: Fixed broken mouse direction change with power!=1.0. (#2174, #2206) [@Joshhua5]
|
||||
- Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary
|
||||
- Nav: Fixed a keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary
|
||||
keep the focus on the parent window, which could steal it from newly appearing windows. (#787)
|
||||
- Nav: Fixed animated window titles from being updated when displayed in the CTRL+Tab list. (#787)
|
||||
- Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function closer
|
||||
@ -4457,7 +4688,7 @@ Changes:
|
||||
then separate your changes into several patches that can more easily be applied to 1.64 on a per-file basis.
|
||||
What I found worked nicely for me, was to open the diff of the old patches in an interactive merge/diff tool,
|
||||
search for the corresponding function in the new code and apply the chunks manually.
|
||||
- As a reminder, if you have any change to imgui.cpp it is a good habit to discuss them on the github,
|
||||
- As a reminder, if you have any change to imgui.cpp it is a good habit to discuss them on the GitHub,
|
||||
so a solution applicable on the Master branch can be found. If your company has changes that you cannot
|
||||
disclose you may also contact me privately.
|
||||
|
||||
@ -4492,7 +4723,7 @@ Other Changes:
|
||||
- Nav: Added a CTRL+TAB window list and changed the highlight system accordingly. The change is motivated by upcoming
|
||||
Docking features. (#787)
|
||||
- Nav: Made CTRL+TAB skip menus + skip the current navigation window if is has the ImGuiWindow_NoNavFocus set. (#787)
|
||||
While it was previously possible, you won't be able to CTRL-TAB out and immediately back in a window with the
|
||||
While it was previously possible, you won't be able to CTRL+TAB out and immediately back in a window with the
|
||||
ImGuiWindow_NoNavFocus flag.
|
||||
- Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909)
|
||||
- Window: Added global io.ConfigResizeWindowsFromEdges option to enable resizing windows from their edges and from
|
||||
@ -4527,7 +4758,7 @@ Other Changes:
|
||||
- Fixed assertion when transitioning from an active ID to another within a group, affecting ColorPicker (broken in 1.62). (#2023, #820, #956, #1875).
|
||||
- Fixed PushID() from keeping alive the new ID Stack top value (if a previously active widget shared the ID it would be erroneously kept alive).
|
||||
- Fixed horizontal mouse wheel not forwarding the request to the parent window if ImGuiWindowFlags_NoScrollWithMouse is set. (#1463, #1380, #1502)
|
||||
- Fixed a include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276)
|
||||
- Fixed an include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276)
|
||||
- ImDrawList: Improved handling for worst-case vertices reservation policy when large amount of text (e.g. 1+ million character strings)
|
||||
are being submitted in a single call. It would typically have crashed InputTextMultiline(). (#200)
|
||||
- OS/Windows: Fixed missing ImmReleaseContext() call in the default Win32 IME handler. (#1932) [@vby]
|
||||
@ -4762,7 +4993,7 @@ Other Changes:
|
||||
- Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically
|
||||
fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays.
|
||||
- Basic controls: arrows to navigate, Alt to enter menus, Space to activate item, Enter to edit text,
|
||||
Escape to cancel/close, Ctrl-Tab to focus windows, etc.
|
||||
Escape to cancel/close, Ctrl+Tab to focus windows, etc.
|
||||
- When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard),
|
||||
the io.WantCaptureKeyboard flag will be set.
|
||||
- For more advanced uses, you may want to read from io.NavActive or io.NavVisible. Read imgui.cpp for more details.
|
||||
@ -4812,7 +5043,7 @@ Other Changes:
|
||||
- Style: Exposed ImGuiStyleVar_WindowTitleAlign, ImGuiStyleVar_ScrollbarSize, ImGuiStyleVar_ScrollbarRounding,
|
||||
ImGuiStyleVar_GrabRounding + added an assert to reduce accidental breakage. (#1181)
|
||||
- Style: Added style.MouseCursorScale help when using the software mouse cursor facility. (#939).
|
||||
- Style: Close button nows display a cross before hovering. Fixed cross positioning being a little off. Uses button colors for highlight when hovering. (#707)
|
||||
- Style: Close buttons now display a cross before hovering. Fixed cross positioning being a little off. Uses button colors for highlight when hovering. (#707)
|
||||
- Popup: OpenPopup() Always reopen existing pop-ups. (Removed imgui_internal.h's OpenPopupEx() which was used for this.) (#1497, #1533).
|
||||
- Popup: BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse press. (~#439)
|
||||
- Popup: Better handling of user mistakenly calling OpenPopup() every frame (with the 'reopen_existing' option).
|
||||
@ -4835,7 +5066,7 @@ Other Changes:
|
||||
- Drag and Drop: Increased payload type string to 32 characters instead of 8. (#143)
|
||||
- Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143)
|
||||
- DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559)
|
||||
- InputFloat: Allow inputing value using scientific notation e.g. "1e+10".
|
||||
- InputFloat: Allow inputting value using scientific notation e.g. "1e+10".
|
||||
- InputDouble: Added InputDouble() function. We use a format string instead of a 'decimal_precision'
|
||||
parameter to also for "%e" and variants. (#1011)
|
||||
- Slider, Combo: Use ImGuiCol_FrameBgHovered color when hovered. (#1456) [@stfx]
|
||||
@ -4880,7 +5111,7 @@ Other Changes:
|
||||
- Demo: Improved Selectable() examples. (#1528)
|
||||
- Demo: Tweaked the Child demos, added a menu bar to the second child to test some navigation functions.
|
||||
- Demo: Console: Using ImGuiCol_Text to be more friendly to color changes.
|
||||
- Demo: Using IM_COL32() instead of ImColor() in ImDrawList centric contexts. Trying to phase out use of the ImColor helper whenever possible.
|
||||
- Demo: Using IM_COL32() instead of ImColor() in ImDrawList-centric contexts. Trying to phase out use of the ImColor helper whenever possible.
|
||||
- Examples: Files in examples/ now include their own changelog so it is easier to occasionally update your backends if needed.
|
||||
- Examples: Using Dark theme by default. (#707). Tweaked demo code.
|
||||
- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) [@tseeker]
|
||||
@ -4998,7 +5229,7 @@ Other Changes:
|
||||
- Window: Added ImGuiWindowFlags_ResizeFromAnySide flag to resize from any borders or from the
|
||||
lower-left corner of a window. This requires your backend to honor GetMouseCursor() requests
|
||||
for full usability. (#822)
|
||||
- Window: Sizing fixes when using SetNextWindowSize() on individual axises.
|
||||
- Window: Sizing fixes when using SetNextWindowSize() on individual axes.
|
||||
- Window: Hide new window for one frame until they calculate their size.
|
||||
Also fixes SetNextWindowPos() given a non-zero pivot. (#1694)
|
||||
- Window: Made mouse wheel scrolling accommodate better to windows that are smaller than the scroll step.
|
||||
@ -5300,7 +5531,7 @@ Other Changes:
|
||||
check the Demo window and comment for `ImGuiColorEditFlags_`.
|
||||
Some of the options it supports are: two color picker types (hue bar + sat/val rectangle,
|
||||
hue wheel + rotating sat/val triangle), display as u8 or float, lifting 0.0..1.0 constraints
|
||||
(currently rgba only), context menus, alpha bar, background checkerboard options, preview tooltip,
|
||||
(currently rgba only), context menus, alpha bar, background checkerboard options, preview tooltip,
|
||||
basic revert. For simple use, calling the existing `ColorEdit4()` function as you did before
|
||||
will be enough, as you can now open the color picker from there.
|
||||
- Added `SetColorEditOptions()` to set default color options (e.g. if you want HSV over RGBA,
|
||||
@ -5402,7 +5633,7 @@ Other Changes:
|
||||
certain style settings and zero WindowMinSize).
|
||||
- EndGroup(): Made IsItemHovered() work when an item was activated within the group. (#849)
|
||||
- BulletText(): Fixed stopping to display formatted string after the '##' mark.
|
||||
- Closing the focused window restore focus to the first active root window in descending z-order .(part of #727)
|
||||
- Closing the focused window restore focus to the first active root window in descending z-order. (part of #727)
|
||||
- Word-wrapping: Fixed a bug where we never wrapped after a 1 character word. [@sronsse]
|
||||
- Word-wrapping: Fixed TextWrapped() overriding wrap position if one is already set. (#690)
|
||||
- Word-wrapping: Fixed incorrect testing for negative wrap coordinates, they are perfectly legal. (#706)
|
||||
@ -5439,7 +5670,7 @@ Other Changes:
|
||||
- Demo: ShowStyleEditor: show font character map / grid in more details.
|
||||
- Demo: Console: Fixed a completion bug when multiple candidates are equals and match until the end.
|
||||
- Demo: Fixed 1-byte off overflow in the ShowStyleEditor() combo usage. (#783) [@bear24rw]
|
||||
- Examples: Accessing ImVector fields directly, feel less stl-ey. (#810)
|
||||
- Examples: Accessing ImVector fields directly, feel less stl-y. (#810)
|
||||
- Examples: OpenGL*: Saving/restoring existing scissor rectangle for completeness. (#807)
|
||||
- Examples: OpenGL*: Saving/restoring active texture number (the value modified by glActiveTexture). (#1087, #1088, #1116)
|
||||
- Examples: OpenGL*: Saving/restoring separate color/alpha blend functions correctly. (#1120) [@greggman]
|
||||
@ -5603,7 +5834,7 @@ Other Changes:
|
||||
after a text input modification (e.g. "0.0" --> "0.000" would keep returning true). (#564)
|
||||
- DragFloat(): Always apply value when mouse is held/widget active, so that an always-resetting
|
||||
variable (e.g. non saved local) can be passed.
|
||||
- InputText(): OS X friendly behaviors: (@zhiayang), (#473)
|
||||
- InputText(): OS X friendly behaviors: (@zhiayang), (#473)
|
||||
- Word movement uses ALT key;
|
||||
- Shortcuts uses CMD key;
|
||||
- Double-clicking text select a single word;
|
||||
@ -5728,7 +5959,7 @@ Changes:
|
||||
- PlotHistogram(): improved rendering of histogram with a lot of values.
|
||||
- Dummy(): creates an item so functions such as IsItemHovered() can be used.
|
||||
- BeginChildFrame() helper: added the extra_flags parameter.
|
||||
- Scrollbar: fixed rounding of background + child window consistenly have ChildWindowBg color under ScrollbarBg fill. (#355).
|
||||
- Scrollbar: fixed rounding of background + child window consistently have ChildWindowBg color under ScrollbarBg fill. (#355).
|
||||
- Scrollbar: background color less translucent in default style so it works better when changing background color.
|
||||
- Scrollbar: fixed minor rendering offset when borders are enabled. (#365)
|
||||
- ImDrawList: fixed 1 leak per ImDrawList using the ChannelsSplit() API (via Columns). (#318)
|
||||
@ -5744,7 +5975,7 @@ Changes:
|
||||
- Internal: Extracted a EndFrame() function out of Render() but kept it internal/private + clarified some asserts. (#335)
|
||||
- Internal: Added missing IMGUI_API definitions in imgui_internal.h (#326)
|
||||
- Internal: ImLoadFileToMemory() return void\* instead of taking void*\* + allow optional int\* file_size.
|
||||
- Demo: Horizontal scrollbar demo allows to enable simultanaeous scrollbars on both axises.
|
||||
- Demo: Horizontal scrollbar demo allows to enable simultaneous scrollbars on both axes.
|
||||
- Tools: binary_to_compressed_c.cpp: added -nocompress option.
|
||||
- Examples: Added example for the Marmalade platform.
|
||||
- Examples: Added batch files to build Windows examples with VS.
|
||||
@ -5789,7 +6020,7 @@ Other Changes:
|
||||
- ImDrawList: Added an assert on overflowing index value (#292).
|
||||
- ImDrawList: Fixed issues with channels split/merge. Now functional without manually adding a draw cmd. Added comments.
|
||||
- ImDrawData: Added ScaleClipRects() helper useful when rendering scaled. (#287).
|
||||
- Fixed Bullet() inconsistent layout behaviour when clipped.
|
||||
- Fixed Bullet() inconsistent layout behavior when clipped.
|
||||
- Fixed IsWindowHovered() not taking account of window hoverability (may be disabled because of a popup).
|
||||
- Fixed InvisibleButton() not honoring negative size consistently with other widgets that do so.
|
||||
- Fixed OpenPopup() accessing current window, effectively opening "Debug" when called from an empty window stack.
|
||||
@ -5801,7 +6032,7 @@ Other Changes:
|
||||
the first place so it's not really a useful default.
|
||||
- Begin(): Minor fixes with windows main clipping rectangle (e.g. child window with border).
|
||||
- Begin(): Window flags are only read on the first call of the frame. Subsequent calls ignore flags, which allows
|
||||
appending to a window without worryin about flags.
|
||||
appending to a window without worrying about flags.
|
||||
- InputText(): ignore character input when ctrl/alt are held. (Normally those text input are ignored by most wrappers.) (#279).
|
||||
- Demo: Fixed incorrectly formed string passed to Combo (#298).
|
||||
- Demo: Added simple Log demo.
|
||||
@ -5835,7 +6066,7 @@ Other Changes:
|
||||
and more natural to extend ImGui. However please note that none of the content in imgui_internal.h is guaranteed
|
||||
for forward-compatibility and code using those types/functions may occasionally break. (#219)
|
||||
- All sample code is in imgui_demo.cpp. Please keep this file in your project and consider allowing your code to call
|
||||
the ShowTestWindow() function as de-facto guide to ImGui features. It will be stripped out by the linker when unused.
|
||||
the ShowTestWindow() function as de facto guide to ImGui features. It will be stripped out by the linker when unused.
|
||||
- Added GetContentRegionAvail() helper (basically GetContentRegionMax() - GetCursorPos()).
|
||||
- Added ImGuiWindowFlags_NoInputs for totally input-passthru window.
|
||||
- Button(): honor negative size consistently with other widgets that do so (width -100 to align the button 100 pixels
|
||||
@ -6200,7 +6431,7 @@ Other Changes:
|
||||
- IsItemHovered() return false if another widget is active, aka we can't use what we are hovering now.
|
||||
- Added IsItemHoveredRect() if old behavior of IsItemHovered() is needed (e.g. for implementing
|
||||
the drop side of a drag'n drop operation).
|
||||
- IsItemhovered() include space taken by label and behave consistently for all widgets (#145)
|
||||
- IsItemHovered() include space taken by label and behave consistently for all widgets (#145)
|
||||
- Auto-filling child window feed their content size to parent (#170)
|
||||
- InputText() removed the odd ~ characters when clipping.
|
||||
- InputText() update its width in case of resize initiated programmatically while the widget is active.
|
||||
@ -6264,7 +6495,7 @@ Other Changes:
|
||||
- Sliders: Fixed parsing of decimal precision back from format string when using %%.
|
||||
- Sliders: Fixed hovering bounding test excluding padding between outer frame and grab (there was a few pixels dead-zone).
|
||||
- Separator() logs itself as text when passing through text log.
|
||||
- Optimisation: TreeNodeV() early out if SkipItems is set without formatting.
|
||||
- Optimization: TreeNodeV() early out if SkipItems is set without formatting.
|
||||
- Moved various static buffers into state. Increase the formatted string buffer from 1K to 3K.
|
||||
- Examples: Example console keeps focus on input box at all times.
|
||||
- Examples: Updated to GLFW 3.1. Moved to examples/libs/ folder.
|
||||
@ -6393,8 +6624,8 @@ Other Changes:
|
||||
Callback now passed an "EventFlag" parameter.
|
||||
- InputText: Added ImGuiInputTextFlags_CharsUppercase and ImGuiInputTextFlags_CharsNoBlank stock filters.
|
||||
- PushItemWidth() can take negative value to right-align items.
|
||||
- Optimisation: Columns offsets cached to avoid unnecessary binary search.
|
||||
- Optimisation: Optimized CalcTextSize() function by about 25% (they are often the bottleneck when
|
||||
- Optimization: Columns offsets cached to avoid unnecessary binary search.
|
||||
- Optimization: Optimized CalcTextSize() function by about 25% (they are often the bottleneck when
|
||||
submitting thousands of clipped items).
|
||||
- Added ImGuiCol_ChildWindowBg, ImGuiStyleVar_ChildWindowRounding for completeness and flexibility.
|
||||
- Added BeginChild() variant that takes an ImGuiID.
|
||||
@ -6437,7 +6668,7 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Big update! Initialisation had to be changed. You don't need to load PNG data anymore. Th
|
||||
- Big update! Initialization had to be changed. You don't need to load PNG data anymore. The
|
||||
new system gives you uncompressed texture data.
|
||||
- This sequence:
|
||||
const void* png_data;
|
||||
@ -6447,7 +6678,7 @@ Breaking Changes:
|
||||
- Became:
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
// io.Fonts->AddFontFromFileTTF("myfontfile.ttf", 24.0f); // Optionally load another font
|
||||
// io.Fonts->AddFontFromFileTTF("myfontfile.ttf", 24.0f); // Optionally load another font
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
// <Copy to GPU>
|
||||
io.Fonts->TexID = (your_texture_identifier);
|
||||
@ -6469,7 +6700,7 @@ Other Changes:
|
||||
- Added IsItemActive() to tell if last widget is being held / modified (as opposed to just
|
||||
being hovered). Useful for custom dragging behaviors.
|
||||
- Style: Added FrameRounding setting for a more rounded look (default to 0 for now).
|
||||
- Window: Fixed using multiple Begin/End pair on the same wnidow.
|
||||
- Window: Fixed using multiple Begin/End pair on the same window.
|
||||
- Window: Fixed style.WindowMinSize not being honored properly.
|
||||
- Window: Added SetCursorScreenPos() helper (WindowPos+CursorPos = ScreenPos).
|
||||
- ColorEdit3: clicking on color square change the edition. The toggle button is hidden by default.
|
||||
@ -6500,10 +6731,10 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
- Dragging outside area of a widget while it is active doesn't trigger hover on other widgets.
|
||||
- Activating widget bring parent window to front if not already.
|
||||
- Checkbox and Radio buttons activate on click-release to be consistent with other widgets and most UI.
|
||||
- InputText() nows consume input characters immediately so they cannot be reused if
|
||||
- InputText() now consumes input characters immediately so they cannot be reused if
|
||||
ImGui::Update is called again with a call to ImGui::Render(). (fixes #105)
|
||||
- Examples: Console: added support for History callbacks + some cleanup.
|
||||
- Various small optimisations.
|
||||
- Various small optimizations.
|
||||
- Cleanup and other fixes.
|
||||
|
||||
|
||||
@ -6706,7 +6937,7 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- The behaviour of PixelCenterOffset changed! You may need to change your value if you had set
|
||||
- The behavior of PixelCenterOffset changed! You may need to change your value if you had set
|
||||
it to non-default in your code and/or offset your projection matrix by 0.5 pixels. It is
|
||||
likely that the default PixelCenterOffset value of 0.0 is now suitable unless your rendering
|
||||
uses some form of multisampling.
|
||||
@ -6800,7 +7031,7 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
- OpenGL example now use the fixed function-pipeline + cleanups, down by 150 lines.
|
||||
- Added quick & dirty Makefiles for MacOSX and Linux.
|
||||
- Simplified the DrawList system, ImDrawCmd include the clipping rectangle + some optimisations.
|
||||
- Simplified the DrawList system, ImDrawCmd include the clipping rectangle + some optimizations.
|
||||
- Fixed warnings for more stringent compilation settings.
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ Only if you:
|
||||
|
||||
Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue.
|
||||
|
||||
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue.
|
||||
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue.
|
||||
|
||||
## How to open an issue
|
||||
|
||||
@ -52,7 +52,7 @@ Steps:
|
||||
- **Please INCLUDE CODE. Provide a Minimal, Complete, and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem**. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/../main.cpp) or demo (imgui_demo.cpp) to understand and reproduce it. **Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it**. Please test your shortened code to ensure it exhibits the problem. **Often while creating the MCVE you will solve the problem!** Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
|
||||
- **Attach screenshots (or GIF/video) to clarify the context**. They often convey useful information that is omitted by the description. You can drag pictures/files in the message edit box. Avoid using 3rd party image hosting services, prefer the long-term longevity of GitHub attachments (you can drag pictures into your post). On Windows, you can use [ScreenToGif](https://www.screentogif.com/) to easily capture .gif files.
|
||||
- **If you are discussing an assert or a crash, please provide a debugger callstack**. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful.
|
||||
- **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled.
|
||||
- **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled.
|
||||
- Please state if you have made substantial modifications to your copy of Dear ImGui or the back-end.
|
||||
- If you are not calling Dear ImGui directly from C++, please provide information about your Language and the wrapper/binding you are using.
|
||||
- Be mindful that messages are being sent to the mailbox of "Watching" users. Try to proofread your messages before sending them. Edits are not seen by those users unless they browse the site.
|
||||
@ -65,17 +65,17 @@ If you have been using Dear ImGui for a while or have been using C/C++ for sever
|
||||
|
||||
## How to open a Pull Request
|
||||
|
||||
- **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||
- **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||
- Many PRs are useful to demonstrate a need and a possible solution but aren't adequate for merging (causing other issues, not seeing other aspects of the big picture, etc.). In doubt, don't hesitate to push a PR because that is always the first step toward pointing toward a problem, and finding the mergeable solution! Even if a PR stays unmerged for a long time, its presence can be useful for other users and helps toward finding a general solution.
|
||||
- **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/).
|
||||
- **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/).
|
||||
- **When fixing a warning or compilation problem,** please post the compiler log and specify the compiler version and platform you are using.
|
||||
- **Attach screenshots (or GIF/video) to clarify the context and demonstrate the feature at a glance.** You can drag pictures/files in the message edit box. Prefer the long-term longevity of GitHub attachments over 3rd party hosting (you can drag pictures into your post).
|
||||
- **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample).
|
||||
- **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample).
|
||||
- **Make sure you create a branch dedicated to the pull request**. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits).
|
||||
|
||||
## Copyright / Contributor License Agreement
|
||||
|
||||
Any code you submit will become part of the repository and be distributed under the [Dear ImGui license](https://github.com/ocornut/imgui/blob/master/LICENSE.txt). By submitting code to the project you agree that the code is your work and that you can give it to the project.
|
||||
|
||||
You also agree by submitting your code that you grant all transferrable rights to the code to the project maintainer, including for example re-licensing the code, modifying the code, and distributing it in source or binary forms. Specifically, this includes a requirement that you assign copyright to the project maintainer. For this reason, do not modify any copyright statements in files in any PRs.
|
||||
You also agree by submitting your code that you grant all transferable rights to the code to the project maintainer, including for example re-licensing the code, modifying the code, and distributing it in source or binary forms. Specifically, this includes a requirement that you assign copyright to the project maintainer. For this reason, do not modify any copyright statements in files in any PRs.
|
||||
|
||||
|
@ -233,7 +233,7 @@ for (int n = 0; n < 3; n++)
|
||||
ImGui::End();
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
A primer on labels and the ID Stack...
|
||||
@ -543,7 +543,7 @@ The short answer is: obtain the desired DPI scale, load your fonts resized with
|
||||
|
||||
Your application may want to detect DPI change and reload the fonts and reset style between frames.
|
||||
|
||||
Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
|
||||
Your UI code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
|
||||
|
||||
Down the line Dear ImGui will provide a variety of standardized reference values to facilitate using this.
|
||||
|
||||
@ -562,7 +562,8 @@ Please note that if you are not using multi-viewports with multi-monitors using
|
||||
|
||||
On Windows, in addition to scaling the font size (make sure to round to an integer) and using `style.ScaleAllSizes()`, you will need to inform Windows that your application is DPI aware. If this is not done, Windows will scale the application window and the UI text will be blurry. Potential solutions to indicate DPI awareness on Windows are:
|
||||
|
||||
- For SDL: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()``.
|
||||
- For SDL2: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()`.
|
||||
- For SDL3: the flag `SDL_WINDOW_HIGH_PIXEL_DENSITY` needs to be passed to `SDL_CreateWindow()`.
|
||||
- For GLFW: this is done automatically.
|
||||
- For other Windows projects with other backends, or wrapper projects:
|
||||
- We provide a `ImGui_ImplWin32_EnableDpiAwareness()` helper method in the Win32 backend.
|
||||
@ -666,7 +667,7 @@ You may take a look at:
|
||||
|
||||
Yes. People have written game editors, data browsers, debuggers, profilers, and all sorts of non-trivial tools with the library. In my experience, the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library.
|
||||
|
||||
Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient, and powerful.
|
||||
Dear ImGui is very programmer-centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient, and powerful.
|
||||
|
||||
Dear ImGui is built to be efficient and scalable toward the needs for AAA-quality applications running all day. The IMGUI paradigm offers different opportunities for optimization than the more typical RMGUI paradigm.
|
||||
|
||||
|
@ -110,9 +110,7 @@ ImGui::PopFont();
|
||||
**For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):**
|
||||
```cpp
|
||||
ImFontConfig config;
|
||||
config.OversampleH = 2;
|
||||
config.OversampleV = 1;
|
||||
config.GlyphExtraSpacing.x = 1.0f;
|
||||
config.RasterizerDensity = 2.0f;
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
|
||||
```
|
||||
|
||||
|
@ -9,7 +9,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- doc: add a proper documentation system (maybe relying on automation? #435)
|
||||
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
|
||||
- doc/tips: tips of the day: website? applet in imgui_club?
|
||||
|
||||
|
||||
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
|
||||
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
|
||||
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
|
||||
@ -22,7 +22,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
|
||||
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
|
||||
- window: investigate better auto-positioning for new windows.
|
||||
- window: top most window flag? more z-order contrl? (#2574)
|
||||
- window: top most window flag? more z-order control? (#2574)
|
||||
- window/size: manually triggered auto-fit (double-click on grip) shouldn't resize window down to viewport size?
|
||||
- window/size: how to allow to e.g. auto-size vertically to fit contents, but be horizontally resizable? Assuming SetNextWindowSize() is modified to treat -1.0f on each axis as "keep as-is" (would be good but might break erroneous code): Problem is UpdateWindowManualResize() and lots of code treat (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) together.
|
||||
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false.
|
||||
@ -57,7 +57,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- widgets: start exposing PushItemFlag() and ImGuiItemFlags
|
||||
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
|
||||
- widgets: activate by identifier (trigger button, focus given id)
|
||||
- widgets: custom glyph/shapes replacements for stock sapes. (also #6090 #2431 #2235 #6517)
|
||||
- widgets: custom glyph/shapes replacements for stock shapes. (also #6090 #2431 #2235 #6517)
|
||||
- widgets: coloredit: keep reporting as active when picker is on?
|
||||
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
|
||||
- selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
|
||||
@ -137,7 +137,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- image/image button: misalignment on padded/bordered button?
|
||||
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
|
||||
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
|
||||
- slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate.
|
||||
- slider: add dragging-based widgets to edit values with mouse (on 2 axes), saving screen real-estate.
|
||||
- slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign)
|
||||
- slider: relative dragging? + precision dragging
|
||||
- slider: step option (#1183)
|
||||
@ -213,7 +213,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
|
||||
- log: obsolete LogButtons().... (was: LogButtons() options for specifying depth and/or hiding depth slider)
|
||||
|
||||
- filters: set a current filter that certains items (e.g. tree node) can automatically query to hide themselves
|
||||
- filters: set a current filter that certain items (e.g. tree node) can automatically query to hide themselves
|
||||
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
|
||||
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
|
||||
|
||||
@ -279,7 +279,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- nav: expose wrap around flags/logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
|
||||
- nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch)
|
||||
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
|
||||
- nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem
|
||||
- nav: SetItemDefaultFocus() level of priority, so widgets like Selectable when inside a popup could claim a low-priority default focus on the first selected item
|
||||
- nav: holding space to repeat a button doesn't show button activated during hold.
|
||||
- nav: NavFlattened: init requests don't work properly on flattened siblings.
|
||||
- nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings.
|
||||
@ -329,7 +329,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- backends: opengl: explicitly disable GL_STENCIL_TEST in bindings.
|
||||
- backends: vulkan: viewport: support for synchronized swapping of multiple swap chains.
|
||||
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
|
||||
- backends: emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
||||
- backends: emscripten: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
||||
|
||||
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) (--> use https://github.com/dearimgui/dear_bindings)
|
||||
|
||||
|
@ -24,9 +24,9 @@ You may install Allegro using vcpkg:
|
||||
git clone https://github.com/Microsoft/vcpkg
|
||||
cd vcpkg
|
||||
bootstrap-vcpkg.bat
|
||||
vcpkg install allegro5 --triplet=x86-windows ; for win32
|
||||
vcpkg install allegro5 --triplet=x64-windows ; for win64
|
||||
vcpkg integrate install ; register include / libs in Visual Studio
|
||||
vcpkg install allegro5 --triplet=x86-windows ; for win32
|
||||
vcpkg install allegro5 --triplet=x64-windows ; for win64
|
||||
vcpkg integrate install ; register include / libs in Visual Studio
|
||||
```
|
||||
|
||||
Build:
|
||||
|
@ -42,5 +42,5 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
@ -268,9 +268,9 @@
|
||||
8309BDBB253CCCAD0045E2A1 /* imgui_impl_metal.mm in Sources */,
|
||||
83BBEA0920EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
8309BDA5253CCC070045E2A1 /* main.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -281,10 +281,10 @@
|
||||
files = (
|
||||
8309BDBE253CCCB60045E2A1 /* imgui_impl_metal.mm in Sources */,
|
||||
8309BDBF253CCCB60045E2A1 /* imgui_impl_osx.mm in Sources */,
|
||||
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
8309BDA8253CCC080045E2A1 /* main.mm in Sources */,
|
||||
);
|
||||
|
@ -129,7 +129,7 @@
|
||||
if (renderPassDescriptor == nil)
|
||||
{
|
||||
[commandBuffer commit];
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
@ -192,7 +192,7 @@
|
||||
[renderEncoder popDebugGroup];
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
// Present
|
||||
// Present
|
||||
[commandBuffer presentDrawable:view.currentDrawable];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES")
|
||||
|
||||
# GLFW
|
||||
set(GLFW_DIR ../../../glfw) # Set this to point to an up-to-date GLFW repo
|
||||
if(NOT GLFW_DIR)
|
||||
set(GLFW_DIR ../../../glfw) # Set this to point to an up-to-date GLFW repo
|
||||
endif()
|
||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
|
||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
|
||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
|
||||
|
@ -61,7 +61,7 @@ static void glfw_error_callback(int error, const char* description)
|
||||
}
|
||||
static void check_vk_result(VkResult err)
|
||||
{
|
||||
if (err == 0)
|
||||
if (err == VK_SUCCESS)
|
||||
return;
|
||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||
if (err < 0)
|
||||
@ -263,17 +263,15 @@ static void CleanupVulkanWindow()
|
||||
|
||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
{
|
||||
VkResult err;
|
||||
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
{
|
||||
@ -342,11 +340,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
@ -398,6 +396,7 @@ int main(int, char**)
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||
init_info.Instance = g_Instance;
|
||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||
init_info.Device = g_Device;
|
||||
|
@ -49,7 +49,7 @@ static bool g_SwapChainRebuild = false;
|
||||
|
||||
static void check_vk_result(VkResult err)
|
||||
{
|
||||
if (err == 0)
|
||||
if (err == VK_SUCCESS)
|
||||
return;
|
||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||
if (err < 0)
|
||||
@ -217,7 +217,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
#ifdef APP_UNLIMITED_FRAME_RATE
|
||||
#ifdef APP_USE_UNLIMITED_FRAME_RATE
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
#else
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
||||
@ -251,17 +251,15 @@ static void CleanupVulkanWindow()
|
||||
|
||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
{
|
||||
VkResult err;
|
||||
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
{
|
||||
@ -330,11 +328,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
@ -398,6 +396,7 @@ int main(int, char**)
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForVulkan(window);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||
init_info.Instance = g_Instance;
|
||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||
init_info.Device = g_Device;
|
||||
|
@ -54,11 +54,11 @@ ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl3`
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl3`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
// This example doesn't compile with Emscripten yet! Awaiting SDL3 support.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
@ -27,6 +26,7 @@
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
@ -140,6 +140,7 @@ int main(int, char**)
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
@ -149,6 +150,8 @@ int main(int, char**)
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
@ -210,6 +213,7 @@ int main(int, char**)
|
||||
#endif
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
@ -43,11 +43,11 @@ ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -limm32 `pkg-config --static --libs sdl3`
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -limm32 `pkg-config --static --libs sdl3`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
|
@ -7,7 +7,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||
// - Unline other backends, the user must call the function Imgui_ImplSDLGPU_PrepareDrawData BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData.
|
||||
// - Unlike other backends, the user must call the function Imgui_ImplSDLGPU_PrepareDrawData() BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData.
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
#include "imgui.h"
|
||||
@ -26,7 +26,8 @@
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD) != 0)
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
@ -54,6 +55,7 @@ int main(int, char**)
|
||||
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_MAILBOX);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
@ -69,7 +71,7 @@ int main(int, char**)
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForSDLGPU(window);
|
||||
ImGui_ImplSDLGPU3_InitInfo init_info = {};
|
||||
init_info.GpuDevice = gpu_device;
|
||||
init_info.Device = gpu_device;
|
||||
init_info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpu_device, window);
|
||||
init_info.MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
ImGui_ImplSDLGPU3_Init(&init_info);
|
||||
@ -104,6 +106,7 @@ int main(int, char**)
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
@ -113,6 +116,8 @@ int main(int, char**)
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
@ -140,7 +145,7 @@ int main(int, char**)
|
||||
ImGui::Checkbox("Another Window", &show_another_window);
|
||||
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||
ImGui::ColorEdit4("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||
|
||||
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
||||
counter++;
|
||||
@ -179,7 +184,7 @@ int main(int, char**)
|
||||
// Setup and start a render pass
|
||||
SDL_GPUColorTargetInfo target_info = {};
|
||||
target_info.texture = swapchain_texture;
|
||||
target_info.clear_color = SDL_FColor{ clear_color.x,clear_color.y,clear_color.z,clear_color.w };
|
||||
target_info.clear_color = SDL_FColor { clear_color.x, clear_color.y, clear_color.z, clear_color.w };
|
||||
target_info.load_op = SDL_GPU_LOADOP_CLEAR;
|
||||
target_info.store_op = SDL_GPU_STOREOP_STORE;
|
||||
target_info.mip_level = 0;
|
||||
@ -196,7 +201,9 @@ int main(int, char**)
|
||||
// Submit the command buffer
|
||||
SDL_SubmitGPUCommandBuffer(command_buffer);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
SDL_WaitForGPUIdle(gpu_device);
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui_ImplSDLGPU3_Shutdown();
|
||||
|
@ -34,7 +34,7 @@ endif
|
||||
|
||||
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
ECHO_MESSAGE = "Mac OS X"
|
||||
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl3-config --libs`
|
||||
LIBS += -framework Cocoa -framework IOKit -framework CoreVideo `sdl3-config --libs`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
@ -43,11 +43,11 @@ ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl3`
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -limm32 `pkg-config --static --libs sdl3`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
|
@ -15,16 +15,16 @@
|
||||
#include "imgui_impl_sdlrenderer3.h"
|
||||
#include <stdio.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
#else
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
@ -32,7 +32,7 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Create window with SDL_Renderer graphics context
|
||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
|
||||
Uint32 window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
@ -102,6 +102,7 @@ int main(int, char**)
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
@ -111,6 +112,8 @@ int main(int, char**)
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
@ -172,6 +175,7 @@ int main(int, char**)
|
||||
#endif
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
ImGui_ImplSDLRenderer3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
@ -54,7 +54,7 @@ static bool g_SwapChainRebuild = false;
|
||||
|
||||
static void check_vk_result(VkResult err)
|
||||
{
|
||||
if (err == 0)
|
||||
if (err == VK_SUCCESS)
|
||||
return;
|
||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||
if (err < 0)
|
||||
@ -222,7 +222,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
#ifdef APP_UNLIMITED_FRAME_RATE
|
||||
#ifdef APP_USE_UNLIMITED_FRAME_RATE
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
#else
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
||||
@ -256,17 +256,15 @@ static void CleanupVulkanWindow()
|
||||
|
||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
{
|
||||
VkResult err;
|
||||
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
{
|
||||
@ -335,11 +333,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
@ -347,7 +345,8 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD) != 0)
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
@ -402,6 +401,7 @@ int main(int, char**)
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForVulkan(window);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||
init_info.Instance = g_Instance;
|
||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||
init_info.Device = g_Device;
|
||||
@ -448,6 +448,7 @@ int main(int, char**)
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
@ -457,6 +458,8 @@ int main(int, char**)
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
@ -532,6 +535,7 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
err = vkDeviceWaitIdle(g_Device);
|
||||
check_vk_result(err);
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
@ -23,8 +23,8 @@
|
||||
#endif
|
||||
|
||||
// Config for example app
|
||||
static const int APP_NUM_FRAMES_IN_FLIGHT = 3;
|
||||
static const int APP_NUM_BACK_BUFFERS = 3;
|
||||
static const int APP_NUM_FRAMES_IN_FLIGHT = 2;
|
||||
static const int APP_NUM_BACK_BUFFERS = 2;
|
||||
static const int APP_SRV_HEAP_SIZE = 64;
|
||||
|
||||
struct FrameContext
|
||||
@ -54,7 +54,7 @@ struct ExampleDescriptorHeapAllocator
|
||||
HeapHandleIncrement = device->GetDescriptorHandleIncrementSize(HeapType);
|
||||
FreeIndices.reserve((int)desc.NumDescriptors);
|
||||
for (int n = desc.NumDescriptors; n > 0; n--)
|
||||
FreeIndices.push_back(n);
|
||||
FreeIndices.push_back(n - 1);
|
||||
}
|
||||
void Destroy()
|
||||
{
|
||||
@ -154,6 +154,9 @@ int main(int, char**)
|
||||
init_info.SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle) { return g_pd3dSrvDescHeapAlloc.Free(cpu_handle, gpu_handle); };
|
||||
ImGui_ImplDX12_Init(&init_info);
|
||||
|
||||
// Before 1.91.6: our signature was using a single descriptor. From 1.92, specifying SrvDescriptorAllocFn/SrvDescriptorFreeFn will be required to benefit from new features.
|
||||
//ImGui_ImplDX12_Init(g_pd3dDevice, APP_NUM_FRAMES_IN_FLIGHT, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||
|
@ -1,4 +1,4 @@
|
||||
@REM Build for MINGW64 or 32 from MSYS2.
|
||||
@REM Build for MINGW64 or 32 from MSYS2.
|
||||
@set OUT_DIR=Debug
|
||||
@set OUT_EXE=example_win32_opengl3
|
||||
@set INCLUDES=-I../.. -I../../backends
|
||||
|
@ -50,7 +50,7 @@ static bool g_SwapChainRebuild = false;
|
||||
|
||||
static void check_vk_result(VkResult err)
|
||||
{
|
||||
if (err == 0)
|
||||
if (err == VK_SUCCESS)
|
||||
return;
|
||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||
if (err < 0)
|
||||
@ -252,17 +252,15 @@ static void CleanupVulkanWindow()
|
||||
|
||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
{
|
||||
VkResult err;
|
||||
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
{
|
||||
@ -331,11 +329,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
if (err != VK_SUBOPTIMAL_KHR)
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
@ -389,6 +387,7 @@ int main(int, char**)
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||
init_info.Instance = g_Instance;
|
||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||
init_info.Device = g_Device;
|
||||
|
@ -88,8 +88,7 @@
|
||||
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
|
||||
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
|
||||
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
|
191
imgui.h
191
imgui.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.9b
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -28,8 +28,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.91.7"
|
||||
#define IMGUI_VERSION_NUM 19170
|
||||
#define IMGUI_VERSION "1.91.9b"
|
||||
#define IMGUI_VERSION_NUM 19191
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
@ -37,6 +37,7 @@
|
||||
Index of this file:
|
||||
// [SECTION] Header mess
|
||||
// [SECTION] Forward declarations and basic types
|
||||
// [SECTION] Texture identifier (ImTextureID)
|
||||
// [SECTION] Dear ImGui end-user API functions
|
||||
// [SECTION] Flags & Enumerations
|
||||
// [SECTION] Tables API flags and structures (ImGuiTableFlags, ImGuiTableColumnFlags, ImGuiTableRowFlags, ImGuiTableBgTarget, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)
|
||||
@ -158,7 +159,7 @@ typedef unsigned int ImU32; // 32-bit unsigned integer (often used to st
|
||||
typedef signed long long ImS64; // 64-bit signed integer
|
||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||
|
||||
// Forward declarations
|
||||
// Forward declarations: ImDrawList, ImFontAtlas layer
|
||||
struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
|
||||
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
|
||||
struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix.
|
||||
@ -173,6 +174,8 @@ struct ImFontConfig; // Configuration data when adding a font or
|
||||
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
|
||||
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
|
||||
struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using)
|
||||
|
||||
// Forward declarations: ImGui layer
|
||||
struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h)
|
||||
struct ImGuiIO; // Main configuration and I/O between your application and ImGui (also see: ImGuiPlatformIO)
|
||||
struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use)
|
||||
@ -248,22 +251,6 @@ typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: f
|
||||
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
|
||||
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
|
||||
|
||||
// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
|
||||
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
|
||||
// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
|
||||
// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators.
|
||||
// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings)
|
||||
#ifndef ImTextureID
|
||||
typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
|
||||
#endif
|
||||
|
||||
// ImDrawIdx: vertex index. [Compile-time configurable type]
|
||||
// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
|
||||
// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
|
||||
#ifndef ImDrawIdx
|
||||
typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
|
||||
#endif
|
||||
|
||||
// Character types
|
||||
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
|
||||
typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
|
||||
@ -313,6 +300,19 @@ struct ImVec4
|
||||
};
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Texture identifier (ImTextureID)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
|
||||
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
|
||||
// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
|
||||
// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators.
|
||||
// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings)
|
||||
#ifndef ImTextureID
|
||||
typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Dear ImGui end-user API functions
|
||||
// (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
|
||||
@ -542,7 +542,7 @@ namespace ImGui
|
||||
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2);
|
||||
IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text()
|
||||
IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||
IMGUI_API void SeparatorText(const char* label); // currently: formatted text with an horizontal line
|
||||
IMGUI_API void SeparatorText(const char* label); // currently: formatted text with a horizontal line
|
||||
|
||||
// Widgets: Main
|
||||
// - Most widgets return true when the value has been changed or when pressed/selected
|
||||
@ -564,9 +564,10 @@ namespace ImGui
|
||||
// Widgets: Images
|
||||
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||||
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
|
||||
// - Note that Image() may add +2.0f to provided size if a border is visible, ImageButton() adds style.FramePadding*2.0f to provided size.
|
||||
// - Image() pads adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side.
|
||||
// - ImageButton() draws a background based on regular Button() color + optionally an inner background if specified.
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1));
|
||||
IMGUI_API void ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||
IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||
|
||||
// Widgets: Combo Box (Dropdown)
|
||||
@ -904,7 +905,7 @@ namespace ImGui
|
||||
IMGUI_API void PopClipRect();
|
||||
|
||||
// Focus, Activation
|
||||
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of of a newly appearing window.
|
||||
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a newly appearing window.
|
||||
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
|
||||
|
||||
// Keyboard/Gamepad Navigation
|
||||
@ -972,7 +973,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)?
|
||||
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord); // was key chord (mods + key) pressed, e.g. you can pass 'ImGuiMod_Ctrl | ImGuiKey_S' as a key-chord. This doesn't do any routing or focus check, please consider using Shortcut() function instead.
|
||||
IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate
|
||||
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared.
|
||||
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names are provided for debugging purpose and are not meant to be saved persistently nor compared.
|
||||
IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call.
|
||||
|
||||
// Inputs Utilities: Shortcut Testing & Routing [BETA]
|
||||
@ -1009,6 +1010,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
|
||||
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
|
||||
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true)
|
||||
IMGUI_API bool IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay); // delayed mouse release (use very sparingly!). Generally used with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount==1' test. This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
|
||||
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
|
||||
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
|
||||
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
|
||||
@ -1174,7 +1176,7 @@ enum ImGuiInputTextFlags_
|
||||
ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID().
|
||||
|
||||
// Elide display / Alignment
|
||||
ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only!
|
||||
ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only!
|
||||
|
||||
// Callback features
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 << 18, // Callback on pressing TAB (for completion handling)
|
||||
@ -1489,6 +1491,7 @@ enum ImGuiKey : int
|
||||
ImGuiKey_KeypadEqual,
|
||||
ImGuiKey_AppBack, // Available on some keyboard/mouses. Often referred as "Browser Back"
|
||||
ImGuiKey_AppForward,
|
||||
ImGuiKey_Oem102, // Non-US backslash.
|
||||
|
||||
// Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION
|
||||
// (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets)
|
||||
@ -1711,6 +1714,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
|
||||
ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize
|
||||
@ -1751,10 +1755,16 @@ enum ImGuiColorEditFlags_
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
||||
|
||||
// Alpha preview
|
||||
// - Prior to 1.91.8 (2025/01/21): alpha was made opaque in the preview by default using old name ImGuiColorEditFlags_AlphaPreview.
|
||||
// - We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||
// - The new flags may be combined better and allow finer controls.
|
||||
ImGuiColorEditFlags_AlphaOpaque = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||
ImGuiColorEditFlags_AlphaNoBg = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 13, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||
|
||||
// User Options (right-click on widget to change some of them).
|
||||
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||
ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.
|
||||
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
|
||||
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
|
||||
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
|
||||
@ -1771,12 +1781,16 @@ enum ImGuiColorEditFlags_
|
||||
ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar,
|
||||
|
||||
// [Internal] Masks
|
||||
ImGuiColorEditFlags_AlphaMask_ = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque | ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf,
|
||||
ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex,
|
||||
ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float,
|
||||
ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar,
|
||||
ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV,
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiColorEditFlags_AlphaPreview = 0, // [Removed in 1.91.8] This is the default now. Will display a checkerboard unless ImGuiColorEditFlags_AlphaNoBg is set.
|
||||
#endif
|
||||
//ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
|
||||
};
|
||||
|
||||
@ -1820,6 +1834,8 @@ enum ImGuiMouseCursor_
|
||||
ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window
|
||||
ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window
|
||||
ImGuiMouseCursor_Hand, // (Unused by Dear ImGui functions. Use for e.g. hyperlinks)
|
||||
ImGuiMouseCursor_Wait, // When waiting for something to process/load.
|
||||
ImGuiMouseCursor_Progress, // When waiting for something to process/load, but application is still interactive.
|
||||
ImGuiMouseCursor_NotAllowed, // When hovering something with disallowed interaction. Usually a crossed circle.
|
||||
ImGuiMouseCursor_COUNT
|
||||
};
|
||||
@ -2133,6 +2149,7 @@ struct ImGuiStyle
|
||||
ImVec2 WindowPadding; // Padding within a window.
|
||||
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
|
||||
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
|
||||
float WindowBorderHoverPadding; // Hit-testing extent outside/inside resizing border. Also extend determination of hovered window. Generally meaningfully larger than WindowBorderSize to make it easy to reach borders.
|
||||
ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constrain individual windows, use SetNextWindowSizeConstraints().
|
||||
ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered.
|
||||
ImGuiDir WindowMenuButtonPosition; // Side of the collapsing/docking button in the title bar (None/Left/Right). Defaults to ImGuiDir_Left.
|
||||
@ -2154,9 +2171,11 @@ struct ImGuiStyle
|
||||
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
|
||||
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||
float ImageBorderSize; // Thickness of border around Image() calls.
|
||||
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
float TabBorderSize; // Thickness of border around tabs.
|
||||
float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
||||
float TabCloseButtonMinWidthSelected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width.
|
||||
float TabCloseButtonMinWidthUnselected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected.
|
||||
float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
|
||||
float TabBarOverlineSize; // Thickness of tab-bar overline, which highlights the selected tab-bar.
|
||||
float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees).
|
||||
@ -2175,6 +2194,8 @@ struct ImGuiStyle
|
||||
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
|
||||
|
||||
// Colors
|
||||
ImVec4 Colors[ImGuiCol_COUNT];
|
||||
|
||||
// Behaviors
|
||||
@ -2187,6 +2208,11 @@ struct ImGuiStyle
|
||||
|
||||
IMGUI_API ImGuiStyle();
|
||||
IMGUI_API void ScaleAllSizes(float scale_factor);
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9.
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2297,7 +2323,8 @@ struct ImGuiIO
|
||||
// - Code should use PushID()/PopID() in loops, or append "##xx" to same-label identifiers.
|
||||
// - Empty label e.g. Button("") == same ID as parent widget/node. Use Button("##xx") instead!
|
||||
// - See FAQ https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-about-the-id-stack-system
|
||||
bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message when multiple items have conflicting identifiers.
|
||||
bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message popup when multiple items have conflicting identifiers.
|
||||
bool ConfigDebugHighlightIdConflictsShowItemPicker;//=true // Show "Item Picker" button in aforementioned popup.
|
||||
|
||||
// Tools to test correct Begin/End and BeginChild/EndChild behaviors.
|
||||
// - Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
|
||||
@ -2403,10 +2430,11 @@ struct ImGuiIO
|
||||
ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down
|
||||
ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done.
|
||||
bool MouseReleased[5]; // Mouse button went from Down to !Down
|
||||
double MouseReleasedTime[5]; // Time of last released (rarely used! but useful to handle delayed single-click when trying to disambiguate them from double-click).
|
||||
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
|
||||
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
|
||||
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
|
||||
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a ctrl-click that spawned a simulated right click
|
||||
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a Ctrl+click that spawned a simulated right click
|
||||
float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)
|
||||
float MouseDownDurationPrev[5]; // Previous time the mouse button has been down
|
||||
float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds)
|
||||
@ -2571,10 +2599,11 @@ struct ImGuiTextBuffer
|
||||
ImGuiTextBuffer() { }
|
||||
inline char operator[](int i) const { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; }
|
||||
const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; }
|
||||
const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator
|
||||
const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator
|
||||
int size() const { return Buf.Size ? Buf.Size - 1 : 0; }
|
||||
bool empty() const { return Buf.Size <= 1; }
|
||||
void clear() { Buf.clear(); }
|
||||
void resize(int size) { if (Buf.Size > size) Buf.Data[size] = 0; Buf.resize(size ? size + 1 : 0, 0); } // Similar to resize(0) on ImVector: empty string but don't free buffer.
|
||||
void reserve(int capacity) { Buf.reserve(capacity); }
|
||||
const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; }
|
||||
IMGUI_API void append(const char* str, const char* str_end = NULL);
|
||||
@ -2923,7 +2952,14 @@ struct ImGuiSelectionExternalStorage
|
||||
|
||||
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63)
|
||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32)
|
||||
#endif
|
||||
|
||||
// ImDrawIdx: vertex index. [Compile-time configurable type]
|
||||
// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
|
||||
// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
|
||||
#ifndef ImDrawIdx
|
||||
typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
|
||||
#endif
|
||||
|
||||
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
|
||||
@ -2997,7 +3033,6 @@ struct ImDrawChannel
|
||||
ImVector<ImDrawIdx> _IdxBuffer;
|
||||
};
|
||||
|
||||
|
||||
// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
|
||||
// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call.
|
||||
struct ImDrawListSplitter
|
||||
@ -3118,7 +3153,7 @@ struct ImDrawList
|
||||
|
||||
// General polygon
|
||||
// - Only simple polygons are supported by filling functions (no self-intersections, no holes).
|
||||
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience fo user but not used by main library.
|
||||
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library.
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||
@ -3232,26 +3267,28 @@ struct ImDrawData
|
||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// A font input/source (we may rename this to ImFontSource in the future)
|
||||
struct ImFontConfig
|
||||
{
|
||||
void* FontData; // // TTF/OTF data
|
||||
int FontDataSize; // // TTF/OTF data size
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
|
||||
int FontNo; // 0 // Index of font within TTF/OTF file
|
||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
int OversampleH; // 2 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
||||
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
|
||||
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
||||
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
|
||||
int FontNo; // 0 // Index of font within TTF/OTF file
|
||||
int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
||||
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
|
||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX)
|
||||
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
|
||||
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
|
||||
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
|
||||
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
|
||||
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
||||
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this.
|
||||
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
||||
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
|
||||
// [Internal]
|
||||
char Name[40]; // Name (strictly to ease debugging)
|
||||
@ -3267,7 +3304,7 @@ struct ImFontGlyph
|
||||
unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops)
|
||||
unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering.
|
||||
unsigned int Codepoint : 30; // 0x0000..0x10FFFF
|
||||
float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)
|
||||
float AdvanceX; // Horizontal distance to advance layout with
|
||||
float X0, Y0, X1, Y1; // Glyph corners
|
||||
float U0, V0, U1, V1; // Texture coordinates
|
||||
};
|
||||
@ -3341,8 +3378,8 @@ struct ImFontAtlas
|
||||
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
|
||||
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
|
||||
IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
|
||||
IMGUI_API void ClearFonts(); // Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
|
||||
IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory.
|
||||
IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates).
|
||||
IMGUI_API void Clear(); // Clear all input and output.
|
||||
|
||||
// Build atlas, retrieve pixel data.
|
||||
@ -3375,7 +3412,7 @@ struct ImFontAtlas
|
||||
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters
|
||||
|
||||
//-------------------------------------------
|
||||
// [BETA] Custom Rectangles/Glyphs API
|
||||
// [ALPHA] Custom Rectangles/Glyphs API
|
||||
//-------------------------------------------
|
||||
|
||||
// You can request arbitrary rectangles to be packed into the atlas, for your own purposes.
|
||||
@ -3391,21 +3428,21 @@ struct ImFontAtlas
|
||||
|
||||
// [Internal]
|
||||
IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const;
|
||||
IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]);
|
||||
|
||||
//-------------------------------------------
|
||||
// Members
|
||||
//-------------------------------------------
|
||||
|
||||
// Input
|
||||
ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_)
|
||||
ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
|
||||
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
|
||||
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
|
||||
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
|
||||
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
|
||||
|
||||
// [Internal]
|
||||
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
|
||||
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
|
||||
bool TexReady; // Set when texture was built matching current font input
|
||||
bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format.
|
||||
unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight
|
||||
@ -3416,7 +3453,7 @@ struct ImFontAtlas
|
||||
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
|
||||
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
|
||||
ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas.
|
||||
ImVector<ImFontConfig> ConfigData; // Configuration data
|
||||
ImVector<ImFontConfig> Sources; // Source/configuration data
|
||||
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
|
||||
|
||||
// [Internal] Font builder
|
||||
@ -3428,8 +3465,8 @@ struct ImFontAtlas
|
||||
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
|
||||
|
||||
// [Obsolete]
|
||||
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
|
||||
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
|
||||
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
|
||||
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
|
||||
};
|
||||
|
||||
// Font runtime data and rendering
|
||||
@ -3437,40 +3474,41 @@ struct ImFontAtlas
|
||||
struct ImFont
|
||||
{
|
||||
// [Internal] Members: Hot ~20/24 bytes (for CalcTextSize)
|
||||
ImVector<float> IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
|
||||
ImVector<float> IndexAdvanceX; // 12-16 // out // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
|
||||
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
|
||||
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
|
||||
float FontSize; // 4 // in // Height of characters/line, set during loading (don't change after loading)
|
||||
|
||||
// [Internal] Members: Hot ~28/40 bytes (for RenderText loop)
|
||||
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
|
||||
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
|
||||
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
||||
ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point.
|
||||
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs.
|
||||
ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
||||
|
||||
// [Internal] Members: Cold ~32/40 bytes
|
||||
// Conceptually ConfigData[] is the list of font sources merged to create this font.
|
||||
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
|
||||
const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
|
||||
short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
|
||||
// Conceptually Sources[] is the list of font sources merged to create this font.
|
||||
ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into
|
||||
ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances
|
||||
short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
|
||||
short EllipsisCharCount; // 1 // out // 1 or 3
|
||||
ImWchar EllipsisChar; // 2-4 // out // = '...'/'.'// Character used for ellipsis rendering.
|
||||
ImWchar FallbackChar; // 2-4 // out // = FFFD/'?' // Character used if a glyph isn't found.
|
||||
float EllipsisWidth; // 4 // out // Width
|
||||
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
|
||||
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
|
||||
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
|
||||
float EllipsisWidth; // 4 // out // Total ellipsis Width
|
||||
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
|
||||
float Scale; // 4 // in // Base font scale (1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
|
||||
int MetricsTotalSurface;// 4 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
bool DirtyLookupTables; // 1 // out //
|
||||
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
|
||||
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
|
||||
// Methods
|
||||
IMGUI_API ImFont();
|
||||
IMGUI_API ~ImFont();
|
||||
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
|
||||
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
|
||||
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
|
||||
bool IsLoaded() const { return ContainerAtlas != NULL; }
|
||||
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
|
||||
IMGUI_API ImFontGlyph* FindGlyph(ImWchar c);
|
||||
IMGUI_API ImFontGlyph* FindGlyphNoFallback(ImWchar c);
|
||||
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
|
||||
bool IsLoaded() const { return ContainerAtlas != NULL; }
|
||||
const char* GetDebugName() const { return Sources ? Sources->Name : "<unknown>"; }
|
||||
|
||||
// [Internal] Don't use!
|
||||
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
||||
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8
|
||||
@ -3484,7 +3522,6 @@ struct ImFont
|
||||
IMGUI_API void GrowIndex(int new_size);
|
||||
IMGUI_API void AddGlyph(const ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
|
||||
IMGUI_API void SetGlyphVisible(ImWchar c, bool visible);
|
||||
IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);
|
||||
};
|
||||
|
||||
@ -3538,7 +3575,7 @@ struct ImGuiPlatformIO
|
||||
IMGUI_API ImGuiPlatformIO();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Interface with OS and Platform backend
|
||||
// Input - Interface with OS and Platform backend (most common stuff)
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Optional: Access OS clipboard
|
||||
@ -3548,7 +3585,7 @@ struct ImGuiPlatformIO
|
||||
void* Platform_ClipboardUserData;
|
||||
|
||||
// Optional: Open link/folder/file in OS Shell
|
||||
// (default to use ShellExecuteA() on Windows, system() on Linux/Mac)
|
||||
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac)
|
||||
bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path);
|
||||
void* Platform_OpenInShellUserData;
|
||||
|
||||
@ -3563,7 +3600,7 @@ struct ImGuiPlatformIO
|
||||
ImWchar Platform_LocaleDecimalPoint; // '.'
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Interface with Renderer Backend
|
||||
// Input - Interface with Renderer Backend
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
|
||||
@ -3589,6 +3626,8 @@ struct ImGuiPlatformImeData
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
namespace ImGui
|
||||
{
|
||||
// OBSOLETED in 1.91.9 (from February 2025)
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- border_col was removed in favor of ImGuiCol_ImageBorder.
|
||||
// OBSOLETED in 1.91.0 (from July 2024)
|
||||
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
|
||||
static inline void PopButtonRepeat() { PopItemFlag(); }
|
||||
|
3186
imgui_demo.cpp
3186
imgui_demo.cpp
File diff suppressed because it is too large
Load Diff
255
imgui_draw.cpp
255
imgui_draw.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.9b
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@ -68,6 +68,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
@ -143,6 +144,7 @@ namespace IMGUI_STB_NAMESPACE
|
||||
#define STBTT_fabs(x) ImFabs(x)
|
||||
#define STBTT_ifloor(x) ((int)ImFloor(x))
|
||||
#define STBTT_iceil(x) ((int)ImCeil(x))
|
||||
#define STBTT_strlen(x) ImStrlen(x)
|
||||
#define STBTT_STATIC
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#else
|
||||
@ -374,6 +376,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
InitialFringeScale = 1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
|
||||
@ -433,7 +436,7 @@ void ImDrawList::_ResetForNewFrame()
|
||||
_Path.resize(0);
|
||||
_Splitter.Clear();
|
||||
CmdBuffer.push_back(ImDrawCmd());
|
||||
_FringeScale = 1.0f;
|
||||
_FringeScale = _Data->InitialFringeScale;
|
||||
}
|
||||
|
||||
void ImDrawList::_ClearFreeMemory()
|
||||
@ -1669,8 +1672,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
// Accept null ranges
|
||||
if (text_begin == text_end || text_begin[0] == 0)
|
||||
return;
|
||||
if (text_end == NULL)
|
||||
text_end = text_begin + strlen(text_begin);
|
||||
// No need to strlen() here: font->RenderText() will do it and may early out.
|
||||
|
||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||
if (font == NULL)
|
||||
@ -1693,7 +1695,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
|
||||
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
||||
{
|
||||
AddText(NULL, 0.0f, pos, col, text_begin, text_end);
|
||||
AddText(_Data->Font, _Data->FontSize, pos, col, text_begin, text_end);
|
||||
}
|
||||
|
||||
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
||||
@ -2375,8 +2377,8 @@ ImFontConfig::ImFontConfig()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
FontDataOwnedByAtlas = true;
|
||||
OversampleH = 2;
|
||||
OversampleV = 1;
|
||||
OversampleH = 0; // Auto == 1 or 2 depending on size
|
||||
OversampleV = 0; // Auto == 1
|
||||
GlyphMaxAdvanceX = FLT_MAX;
|
||||
RasterizerMultiply = 1.0f;
|
||||
RasterizerDensity = 1.0f;
|
||||
@ -2402,13 +2404,13 @@ ImFontConfig::ImFontConfig()
|
||||
// - ImFontAtlas::AddCustomRectRegular()
|
||||
// - ImFontAtlas::AddCustomRectFontGlyph()
|
||||
// - ImFontAtlas::CalcCustomRectUV()
|
||||
// - ImFontAtlas::GetMouseCursorTexData()
|
||||
// - ImFontAtlasGetMouseCursorTexData()
|
||||
// - ImFontAtlas::Build()
|
||||
// - ImFontAtlasBuildMultiplyCalcLookupTable()
|
||||
// - ImFontAtlasBuildMultiplyRectAlpha8()
|
||||
// - ImFontAtlasBuildWithStbTruetype()
|
||||
// - ImFontAtlasGetBuilderForStbTruetype()
|
||||
// - ImFontAtlasUpdateConfigDataPointers()
|
||||
// - ImFontAtlasUpdateSourcesPointers()
|
||||
// - ImFontAtlasBuildSetupFont()
|
||||
// - ImFontAtlasBuildPackCustomRects()
|
||||
// - ImFontAtlasBuildRender8bppRectFromString()
|
||||
@ -2466,6 +2468,8 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
|
||||
{ ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW
|
||||
{ ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE
|
||||
{ ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand
|
||||
{ ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Wait // Arrow + custom code in ImGui::RenderMouseCursor()
|
||||
{ ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Progress // Arrow + custom code in ImGui::RenderMouseCursor()
|
||||
{ ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed
|
||||
};
|
||||
|
||||
@ -2485,7 +2489,7 @@ ImFontAtlas::~ImFontAtlas()
|
||||
void ImFontAtlas::ClearInputData()
|
||||
{
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||
for (ImFontConfig& font_cfg : ConfigData)
|
||||
for (ImFontConfig& font_cfg : Sources)
|
||||
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas)
|
||||
{
|
||||
IM_FREE(font_cfg.FontData);
|
||||
@ -2494,12 +2498,12 @@ void ImFontAtlas::ClearInputData()
|
||||
|
||||
// When clearing this we lose access to the font name and other information used to build the font.
|
||||
for (ImFont* font : Fonts)
|
||||
if (font->ConfigData >= ConfigData.Data && font->ConfigData < ConfigData.Data + ConfigData.Size)
|
||||
if (font->Sources >= Sources.Data && font->Sources < Sources.Data + Sources.Size)
|
||||
{
|
||||
font->ConfigData = NULL;
|
||||
font->ConfigDataCount = 0;
|
||||
font->Sources = NULL;
|
||||
font->SourcesCount = 0;
|
||||
}
|
||||
ConfigData.clear();
|
||||
Sources.clear();
|
||||
CustomRects.clear();
|
||||
PackIdMouseCursors = PackIdLines = -1;
|
||||
// Important: we leave TexReady untouched
|
||||
@ -2521,6 +2525,7 @@ void ImFontAtlas::ClearTexData()
|
||||
void ImFontAtlas::ClearFonts()
|
||||
{
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||
ClearInputData();
|
||||
Fonts.clear_delete();
|
||||
TexReady = false;
|
||||
}
|
||||
@ -2573,8 +2578,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
|
||||
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||
IM_ASSERT(font_cfg->OversampleH > 0 && font_cfg->OversampleV > 0 && "Is ImFontConfig struct correctly initialized?");
|
||||
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f);
|
||||
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||
|
||||
// Create new font
|
||||
if (!font_cfg->MergeMode)
|
||||
@ -2582,8 +2586,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||
else
|
||||
IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
|
||||
|
||||
ConfigData.push_back(*font_cfg);
|
||||
ImFontConfig& new_font_cfg = ConfigData.back();
|
||||
Sources.push_back(*font_cfg);
|
||||
ImFontConfig& new_font_cfg = Sources.back();
|
||||
if (new_font_cfg.DstFont == NULL)
|
||||
new_font_cfg.DstFont = Fonts.back();
|
||||
if (!new_font_cfg.FontDataOwnedByAtlas)
|
||||
@ -2599,8 +2603,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||
// - We may support it better later and remove this rounding.
|
||||
new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels);
|
||||
|
||||
// Pointers to ConfigData and BuilderData are otherwise dangling
|
||||
ImFontAtlasUpdateConfigDataPointers(this);
|
||||
// Pointers to Sources data are otherwise dangling
|
||||
ImFontAtlasUpdateSourcesPointers(this);
|
||||
|
||||
// Invalidate texture
|
||||
TexReady = false;
|
||||
@ -2670,7 +2674,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
|
||||
{
|
||||
// Store a short copy of filename into into the font name for convenience
|
||||
const char* p;
|
||||
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
|
||||
}
|
||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||
@ -2705,7 +2709,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
|
||||
|
||||
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
|
||||
{
|
||||
int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4;
|
||||
int compressed_ttf_size = (((int)ImStrlen(compressed_ttf_data_base85) + 4) / 5) * 4;
|
||||
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
|
||||
Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
|
||||
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
|
||||
@ -2752,24 +2756,24 @@ void ImFontAtlas::CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* ou
|
||||
*out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y);
|
||||
}
|
||||
|
||||
bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2])
|
||||
bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2])
|
||||
{
|
||||
if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_COUNT)
|
||||
return false;
|
||||
if (Flags & ImFontAtlasFlags_NoMouseCursors)
|
||||
if (atlas->Flags & ImFontAtlasFlags_NoMouseCursors)
|
||||
return false;
|
||||
|
||||
IM_ASSERT(PackIdMouseCursors != -1);
|
||||
ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors);
|
||||
IM_ASSERT(atlas->PackIdMouseCursors != -1);
|
||||
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
|
||||
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y);
|
||||
ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1];
|
||||
*out_size = size;
|
||||
*out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2];
|
||||
out_uv_border[0] = (pos) * TexUvScale;
|
||||
out_uv_border[1] = (pos + size) * TexUvScale;
|
||||
out_uv_border[0] = (pos) * atlas->TexUvScale;
|
||||
out_uv_border[1] = (pos + size) * atlas->TexUvScale;
|
||||
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
|
||||
out_uv_fill[0] = (pos) * TexUvScale;
|
||||
out_uv_fill[1] = (pos + size) * TexUvScale;
|
||||
out_uv_fill[0] = (pos) * atlas->TexUvScale;
|
||||
out_uv_fill[1] = (pos + size) * atlas->TexUvScale;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2778,7 +2782,7 @@ bool ImFontAtlas::Build()
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||
|
||||
// Default font is none are specified
|
||||
if (ConfigData.Size == 0)
|
||||
if (Sources.Size == 0)
|
||||
AddFontDefault();
|
||||
|
||||
// Select builder
|
||||
@ -2820,6 +2824,13 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
|
||||
*data = table[*data];
|
||||
}
|
||||
|
||||
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v)
|
||||
{
|
||||
// Automatically disable horizontal oversampling over size 36
|
||||
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (src->SizePixels * src->RasterizerDensity > 36.0f || src->PixelSnapH) ? 1 : 2;
|
||||
*out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1;
|
||||
}
|
||||
|
||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
|
||||
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
|
||||
@ -2860,7 +2871,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>*
|
||||
|
||||
static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
{
|
||||
IM_ASSERT(atlas->ConfigData.Size > 0);
|
||||
IM_ASSERT(atlas->Sources.Size > 0);
|
||||
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
|
||||
@ -2874,32 +2885,32 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
// Temporary storage for building
|
||||
ImVector<ImFontBuildSrcData> src_tmp_array;
|
||||
ImVector<ImFontBuildDstData> dst_tmp_array;
|
||||
src_tmp_array.resize(atlas->ConfigData.Size);
|
||||
src_tmp_array.resize(atlas->Sources.Size);
|
||||
dst_tmp_array.resize(atlas->Fonts.Size);
|
||||
memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
|
||||
memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
|
||||
|
||||
// 1. Initialize font loading structure, check font data validity
|
||||
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
|
||||
for (int src_i = 0; src_i < atlas->Sources.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas));
|
||||
|
||||
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
// Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
src_tmp.DstIndex = -1;
|
||||
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
|
||||
if (cfg.DstFont == atlas->Fonts[output_i])
|
||||
if (src.DstFont == atlas->Fonts[output_i])
|
||||
src_tmp.DstIndex = output_i;
|
||||
if (src_tmp.DstIndex == -1)
|
||||
{
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array?
|
||||
return false;
|
||||
}
|
||||
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src.FontData, src.FontNo);
|
||||
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
|
||||
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
|
||||
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)src.FontData, font_offset))
|
||||
{
|
||||
IM_ASSERT(0 && "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
|
||||
return false;
|
||||
@ -2907,7 +2918,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
|
||||
// Measure highest codepoints
|
||||
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
{
|
||||
// Check for valid range. This may also help detect *some* dangling pointers, because a common
|
||||
@ -2985,26 +2996,30 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
buf_rects_out_n += src_tmp.GlyphsCount;
|
||||
buf_packedchars_out_n += src_tmp.GlyphsCount;
|
||||
|
||||
// Automatic selection of oversampling parameters
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
int oversample_h, oversample_v;
|
||||
ImFontAtlasBuildGetOversampleFactors(&src, &oversample_h, &oversample_v);
|
||||
|
||||
// Convert our ranges in the format stb_truetype wants
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
|
||||
src_tmp.PackRange.font_size = src.SizePixels * src.RasterizerDensity;
|
||||
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
|
||||
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
|
||||
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
|
||||
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
|
||||
src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH;
|
||||
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
|
||||
src_tmp.PackRange.h_oversample = (unsigned char)oversample_h;
|
||||
src_tmp.PackRange.v_oversample = (unsigned char)oversample_v;
|
||||
|
||||
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
|
||||
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
|
||||
const float scale = (src.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels * src.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -src.SizePixels * src.RasterizerDensity);
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
|
||||
IM_ASSERT(glyph_index_in_font != 0);
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + cfg.OversampleH - 1);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + cfg.OversampleV - 1);
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * oversample_h, scale * oversample_v, 0, 0, &x0, &y0, &x1, &y1);
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + oversample_h - 1);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + oversample_v - 1);
|
||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||
}
|
||||
}
|
||||
@ -3056,7 +3071,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
// 8. Render/rasterize font characters into the texture
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
@ -3064,10 +3079,10 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
stbtt_PackFontRangesRenderIntoRects(&spc, &src_tmp.FontInfo, &src_tmp.PackRange, 1, src_tmp.Rects);
|
||||
|
||||
// Apply multiply operator
|
||||
if (cfg.RasterizerMultiply != 1.0f)
|
||||
if (src.RasterizerMultiply != 1.0f)
|
||||
{
|
||||
unsigned char multiply_table[256];
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply);
|
||||
stbrp_rect* r = &src_tmp.Rects[0];
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++, r++)
|
||||
if (r->was_packed)
|
||||
@ -3085,22 +3100,22 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
{
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
// - dst_font->Sources is != from src which is our source configuration.
|
||||
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
ImFont* dst_font = src.DstFont;
|
||||
|
||||
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels);
|
||||
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels);
|
||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
|
||||
|
||||
const float ascent = ImCeil(unscaled_ascent * font_scale);
|
||||
const float descent = ImFloor(unscaled_descent * font_scale);
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||
const float font_off_x = cfg.GlyphOffset.x;
|
||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent);
|
||||
const float font_off_x = src.GlyphOffset.x;
|
||||
const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
|
||||
const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity;
|
||||
const float inv_rasterization_scale = 1.0f / src.RasterizerDensity;
|
||||
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
{
|
||||
@ -3114,7 +3129,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
float y0 = q.y0 * inv_rasterization_scale + font_off_y;
|
||||
float x1 = q.x1 * inv_rasterization_scale + font_off_x;
|
||||
float y1 = q.y1 * inv_rasterization_scale + font_off_y;
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
|
||||
dst_font->AddGlyph(&src, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3134,17 +3149,17 @@ const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
|
||||
|
||||
#endif // IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas)
|
||||
void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas)
|
||||
{
|
||||
for (ImFontConfig& font_cfg : atlas->ConfigData)
|
||||
for (ImFontConfig& src : atlas->Sources)
|
||||
{
|
||||
ImFont* font = font_cfg.DstFont;
|
||||
if (!font_cfg.MergeMode)
|
||||
ImFont* font = src.DstFont;
|
||||
if (!src.MergeMode)
|
||||
{
|
||||
font->ConfigData = &font_cfg;
|
||||
font->ConfigDataCount = 0;
|
||||
font->Sources = &src;
|
||||
font->SourcesCount = 0;
|
||||
}
|
||||
font->ConfigDataCount++;
|
||||
font->SourcesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3154,7 +3169,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
|
||||
{
|
||||
font->ClearOutputData();
|
||||
font->FontSize = font_config->SizePixels;
|
||||
IM_ASSERT(font->ConfigData == font_config);
|
||||
IM_ASSERT(font->Sources == font_config);
|
||||
font->ContainerAtlas = atlas;
|
||||
font->Ascent = ascent;
|
||||
font->Descent = descent;
|
||||
@ -3339,7 +3354,7 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||
if (r->Font == NULL || r->GlyphID == 0)
|
||||
continue;
|
||||
|
||||
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH
|
||||
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, PixelSnapH
|
||||
IM_ASSERT(r->Font->ContainerAtlas == atlas);
|
||||
ImVec2 uv0, uv1;
|
||||
atlas->CalcCustomRectUV(r, &uv0, &uv1);
|
||||
@ -3675,21 +3690,8 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
|
||||
|
||||
ImFont::ImFont()
|
||||
{
|
||||
FontSize = 0.0f;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
FallbackChar = 0;
|
||||
EllipsisChar = 0;
|
||||
EllipsisWidth = EllipsisCharStep = 0.0f;
|
||||
EllipsisCharCount = 0;
|
||||
FallbackGlyph = NULL;
|
||||
ContainerAtlas = NULL;
|
||||
ConfigData = NULL;
|
||||
ConfigDataCount = 0;
|
||||
DirtyLookupTables = false;
|
||||
memset(this, 0, sizeof(*this));
|
||||
Scale = 1.0f;
|
||||
Ascent = Descent = 0.0f;
|
||||
MetricsTotalSurface = 0;
|
||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
||||
}
|
||||
|
||||
ImFont::~ImFont()
|
||||
@ -3709,7 +3711,7 @@ void ImFont::ClearOutputData()
|
||||
DirtyLookupTables = true;
|
||||
Ascent = Descent = 0.0f;
|
||||
MetricsTotalSurface = 0;
|
||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
||||
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||
}
|
||||
|
||||
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
|
||||
@ -3732,17 +3734,17 @@ void ImFont::BuildLookupTable()
|
||||
IndexAdvanceX.clear();
|
||||
IndexLookup.clear();
|
||||
DirtyLookupTables = false;
|
||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
||||
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||
GrowIndex(max_codepoint + 1);
|
||||
for (int i = 0; i < Glyphs.Size; i++)
|
||||
{
|
||||
int codepoint = (int)Glyphs[i].Codepoint;
|
||||
IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX;
|
||||
IndexLookup[codepoint] = (ImWchar)i;
|
||||
IndexLookup[codepoint] = (ImU16)i;
|
||||
|
||||
// Mark 4K page as used
|
||||
const int page_n = codepoint / 4096;
|
||||
Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
|
||||
const int page_n = codepoint / 8192;
|
||||
Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
|
||||
}
|
||||
|
||||
// Create a glyph to handle TAB
|
||||
@ -3756,12 +3758,14 @@ void ImFont::BuildLookupTable()
|
||||
tab_glyph.Codepoint = '\t';
|
||||
tab_glyph.AdvanceX *= IM_TABSIZE;
|
||||
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
|
||||
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1);
|
||||
IndexLookup[(int)tab_glyph.Codepoint] = (ImU16)(Glyphs.Size - 1);
|
||||
}
|
||||
|
||||
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
|
||||
SetGlyphVisible((ImWchar)' ', false);
|
||||
SetGlyphVisible((ImWchar)'\t', false);
|
||||
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)' '))
|
||||
glyph->Visible = false;
|
||||
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)'\t'))
|
||||
glyph->Visible = false;
|
||||
|
||||
// Setup Fallback character
|
||||
const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' };
|
||||
@ -3784,7 +3788,7 @@ void ImFont::BuildLookupTable()
|
||||
// Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
|
||||
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
|
||||
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
|
||||
const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar ellipsis_chars[] = { Sources->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
|
||||
if (EllipsisChar == 0)
|
||||
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
|
||||
@ -3804,57 +3808,51 @@ void ImFont::BuildLookupTable()
|
||||
}
|
||||
}
|
||||
|
||||
// API is designed this way to avoid exposing the 4K page size
|
||||
// API is designed this way to avoid exposing the 8K page size
|
||||
// e.g. use with IsGlyphRangeUnused(0, 255)
|
||||
bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
|
||||
{
|
||||
unsigned int page_begin = (c_begin / 4096);
|
||||
unsigned int page_last = (c_last / 4096);
|
||||
unsigned int page_begin = (c_begin / 8192);
|
||||
unsigned int page_last = (c_last / 8192);
|
||||
for (unsigned int page_n = page_begin; page_n <= page_last; page_n++)
|
||||
if ((page_n >> 3) < sizeof(Used4kPagesMap))
|
||||
if (Used4kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
|
||||
if ((page_n >> 3) < sizeof(Used8kPagesMap))
|
||||
if (Used8kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImFont::SetGlyphVisible(ImWchar c, bool visible)
|
||||
{
|
||||
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c))
|
||||
glyph->Visible = visible ? 1 : 0;
|
||||
}
|
||||
|
||||
void ImFont::GrowIndex(int new_size)
|
||||
{
|
||||
IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size);
|
||||
if (new_size <= IndexLookup.Size)
|
||||
return;
|
||||
IndexAdvanceX.resize(new_size, -1.0f);
|
||||
IndexLookup.resize(new_size, (ImWchar)-1);
|
||||
IndexLookup.resize(new_size, (ImU16)-1);
|
||||
}
|
||||
|
||||
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
|
||||
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
|
||||
// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font.
|
||||
void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
// 'src' is not necessarily == 'this->Sources' because multiple source fonts+configs can be used to build one target font.
|
||||
void ImFont::AddGlyph(const ImFontConfig* src, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
{
|
||||
if (cfg != NULL)
|
||||
if (src != NULL)
|
||||
{
|
||||
// Clamp & recenter if needed
|
||||
const float advance_x_original = advance_x;
|
||||
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
|
||||
advance_x = ImClamp(advance_x, src->GlyphMinAdvanceX, src->GlyphMaxAdvanceX);
|
||||
if (advance_x != advance_x_original)
|
||||
{
|
||||
float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
||||
float char_off_x = src->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
||||
x0 += char_off_x;
|
||||
x1 += char_off_x;
|
||||
}
|
||||
|
||||
// Snap to pixel
|
||||
if (cfg->PixelSnapH)
|
||||
if (src->PixelSnapH)
|
||||
advance_x = IM_ROUND(advance_x);
|
||||
|
||||
// Bake spacing
|
||||
advance_x += cfg->GlyphExtraSpacing.x;
|
||||
// Bake extra spacing
|
||||
advance_x += src->GlyphExtraAdvanceX;
|
||||
}
|
||||
|
||||
int glyph_idx = Glyphs.Size;
|
||||
@ -3872,6 +3870,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
|
||||
glyph.U1 = u1;
|
||||
glyph.V1 = v1;
|
||||
glyph.AdvanceX = advance_x;
|
||||
IM_ASSERT(Glyphs.Size < 0xFFFF); // IndexLookup[] hold 16-bit values and -1 is reserved.
|
||||
|
||||
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
|
||||
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
|
||||
@ -3885,33 +3884,33 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
|
||||
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
|
||||
unsigned int index_size = (unsigned int)IndexLookup.Size;
|
||||
|
||||
if (dst < index_size && IndexLookup.Data[dst] == (ImWchar)-1 && !overwrite_dst) // 'dst' already exists
|
||||
if (dst < index_size && IndexLookup.Data[dst] == (ImU16)-1 && !overwrite_dst) // 'dst' already exists
|
||||
return;
|
||||
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
|
||||
return;
|
||||
|
||||
GrowIndex(dst + 1);
|
||||
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImWchar)-1;
|
||||
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImU16)-1;
|
||||
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
|
||||
}
|
||||
|
||||
// Find glyph, return fallback if missing
|
||||
const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
|
||||
ImFontGlyph* ImFont::FindGlyph(ImWchar c)
|
||||
{
|
||||
if (c >= (size_t)IndexLookup.Size)
|
||||
return FallbackGlyph;
|
||||
const ImWchar i = IndexLookup.Data[c];
|
||||
if (i == (ImWchar)-1)
|
||||
const ImU16 i = IndexLookup.Data[c];
|
||||
if (i == (ImU16)-1)
|
||||
return FallbackGlyph;
|
||||
return &Glyphs.Data[i];
|
||||
}
|
||||
|
||||
const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
|
||||
ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
|
||||
{
|
||||
if (c >= (size_t)IndexLookup.Size)
|
||||
return NULL;
|
||||
const ImWchar i = IndexLookup.Data[c];
|
||||
if (i == (ImWchar)-1)
|
||||
const ImU16 i = IndexLookup.Data[c];
|
||||
if (i == (ImU16)-1)
|
||||
return NULL;
|
||||
return &Glyphs.Data[i];
|
||||
}
|
||||
@ -4032,7 +4031,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this.
|
||||
text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
|
||||
|
||||
const float line_height = size;
|
||||
const float scale = size / FontSize;
|
||||
@ -4125,15 +4124,15 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
|
||||
// Align to be pixel perfect
|
||||
float x = IM_TRUNC(pos.x);
|
||||
float y = IM_TRUNC(pos.y);
|
||||
if (y > clip_rect.w)
|
||||
return;
|
||||
|
||||
if (!text_end)
|
||||
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
|
||||
const float scale = size / FontSize;
|
||||
const float line_height = FontSize * scale;
|
||||
const float origin_x = x;
|
||||
@ -4144,7 +4143,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
if (y + line_height < clip_rect.y)
|
||||
while (y + line_height < clip_rect.y && s < text_end)
|
||||
{
|
||||
const char* line_end = (const char*)memchr(s, '\n', text_end - s);
|
||||
const char* line_end = (const char*)ImMemchr(s, '\n', text_end - s);
|
||||
if (word_wrap_enabled)
|
||||
{
|
||||
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
|
||||
@ -4168,7 +4167,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
float y_end = y;
|
||||
while (y_end < clip_rect.w && s_end < text_end)
|
||||
{
|
||||
s_end = (const char*)memchr(s_end, '\n', text_end - s_end);
|
||||
s_end = (const char*)ImMemchr(s_end, '\n', text_end - s_end);
|
||||
s_end = s_end ? s_end + 1 : text_end;
|
||||
y_end += line_height;
|
||||
}
|
||||
|
140
imgui_internal.h
140
imgui_internal.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.9b
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@ -14,6 +14,7 @@ Index of this file:
|
||||
// [SECTION] Macros
|
||||
// [SECTION] Generic helpers
|
||||
// [SECTION] ImDrawList support
|
||||
// [SECTION] Style support
|
||||
// [SECTION] Data types support
|
||||
// [SECTION] Widgets support: flags, enums, data structures
|
||||
// [SECTION] Popup support
|
||||
@ -130,15 +131,21 @@ Index of this file:
|
||||
// [SECTION] Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Utilities
|
||||
// (other types which are not forwarded declared are: ImBitArray<>, ImSpan<>, ImSpanAllocator<>, ImPool<>, ImChunkStream<>)
|
||||
struct ImBitVector; // Store 1-bit per value
|
||||
struct ImRect; // An axis-aligned rectangle (2 points)
|
||||
struct ImGuiTextIndex; // Maintain a line index for a text buffer.
|
||||
|
||||
// ImDrawList/ImFontAtlas
|
||||
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
|
||||
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
|
||||
|
||||
// ImGui
|
||||
struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others)
|
||||
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
|
||||
struct ImGuiContext; // Main Dear ImGui context
|
||||
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
|
||||
struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum)
|
||||
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
|
||||
struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function.
|
||||
struct ImGuiErrorRecoveryState; // Storage of stack sizes for error handling and recovery
|
||||
@ -159,6 +166,7 @@ struct ImGuiOldColumns; // Storage data for a columns set for legacy
|
||||
struct ImGuiPopupData; // Storage for current popup stack
|
||||
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
|
||||
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
|
||||
struct ImGuiStyleVarInfo; // Style variable information (e.g. to access style variables from an enum)
|
||||
struct ImGuiTabBar; // Storage for a tab bar
|
||||
struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
|
||||
struct ImGuiTable; // Storage for a table
|
||||
@ -222,7 +230,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#endif
|
||||
|
||||
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
|
||||
#define IMGUI_DEBUG_LOG_ERROR(...) do { ImGuiContext& g2 = *GImGui; if (g2.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g2.DebugLogSkippedErrors++; } while (0)
|
||||
#define IMGUI_DEBUG_LOG_ERROR(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g.DebugLogSkippedErrors++; } while (0)
|
||||
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
@ -359,11 +367,14 @@ static inline void ImQsort(void* base, size_t count, size_t size_of_element
|
||||
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
|
||||
|
||||
// Helpers: Bit manipulation
|
||||
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
static inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
|
||||
|
||||
// Helpers: String
|
||||
#define ImStrlen strlen
|
||||
#define ImMemchr memchr
|
||||
IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare.
|
||||
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count.
|
||||
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't).
|
||||
@ -462,7 +473,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
@ -736,6 +747,7 @@ struct ImGuiTextIndex
|
||||
|
||||
// Helper: ImGuiStorage
|
||||
IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImDrawList support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -778,8 +790,9 @@ struct IMGUI_API ImDrawListSharedData
|
||||
float FontScale; // Current/default font scale (== FontSize / Font->FontSize)
|
||||
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo()
|
||||
float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
|
||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||
float InitialFringeScale; // Initial scale to apply to AA fringe
|
||||
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
|
||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||
ImVector<ImVec2> TempBuffer; // Temporary write buffer
|
||||
|
||||
// Lookup tables
|
||||
@ -800,17 +813,38 @@ struct ImDrawDataBuilder
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Data types support
|
||||
// [SECTION] Style support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataVarInfo
|
||||
struct ImGuiStyleVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count; // 1+
|
||||
ImU32 Offset; // Offset in parent structure
|
||||
ImU32 Count : 8; // 1+
|
||||
ImGuiDataType DataType : 8;
|
||||
ImU32 Offset : 16; // Offset in parent structure
|
||||
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
|
||||
};
|
||||
|
||||
// Stacked color modifier, backup of modified data so we can restore it
|
||||
struct ImGuiColorMod
|
||||
{
|
||||
ImGuiCol Col;
|
||||
ImVec4 BackupValue;
|
||||
};
|
||||
|
||||
// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
|
||||
struct ImGuiStyleMod
|
||||
{
|
||||
ImGuiStyleVar VarIdx;
|
||||
union { int BackupInt[2]; float BackupFloat[2]; };
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Data types support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataTypeStorage
|
||||
{
|
||||
ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT
|
||||
@ -828,7 +862,7 @@ struct ImGuiDataTypeInfo
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer = ImGuiDataType_COUNT,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
@ -1029,23 +1063,6 @@ enum ImGuiPlotType
|
||||
ImGuiPlotType_Histogram,
|
||||
};
|
||||
|
||||
// Stacked color modifier, backup of modified data so we can restore it
|
||||
struct ImGuiColorMod
|
||||
{
|
||||
ImGuiCol Col;
|
||||
ImVec4 BackupValue;
|
||||
};
|
||||
|
||||
// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
|
||||
struct ImGuiStyleMod
|
||||
{
|
||||
ImGuiStyleVar VarIdx;
|
||||
union { int BackupInt[2]; float BackupFloat[2]; };
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
|
||||
ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
|
||||
};
|
||||
|
||||
// Storage data for BeginComboPreview()/EndComboPreview()
|
||||
struct IMGUI_API ImGuiComboPreviewData
|
||||
{
|
||||
@ -1186,14 +1203,17 @@ enum ImGuiNextWindowDataFlags_
|
||||
ImGuiNextWindowDataFlags_HasFocus = 1 << 5,
|
||||
ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6,
|
||||
ImGuiNextWindowDataFlags_HasScroll = 1 << 7,
|
||||
ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8,
|
||||
ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 9,
|
||||
ImGuiNextWindowDataFlags_HasWindowFlags = 1 << 8,
|
||||
ImGuiNextWindowDataFlags_HasChildFlags = 1 << 9,
|
||||
ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 10,
|
||||
};
|
||||
|
||||
// Storage for SetNexWindow** functions
|
||||
struct ImGuiNextWindowData
|
||||
{
|
||||
ImGuiNextWindowDataFlags Flags;
|
||||
ImGuiNextWindowDataFlags HasFlags;
|
||||
|
||||
// Members below are NOT cleared. Always rely on HasFlags.
|
||||
ImGuiCond PosCond;
|
||||
ImGuiCond SizeCond;
|
||||
ImGuiCond CollapsedCond;
|
||||
@ -1202,6 +1222,7 @@ struct ImGuiNextWindowData
|
||||
ImVec2 SizeVal;
|
||||
ImVec2 ContentSizeVal;
|
||||
ImVec2 ScrollVal;
|
||||
ImGuiWindowFlags WindowFlags; // Only honored by BeginTable()
|
||||
ImGuiChildFlags ChildFlags;
|
||||
bool CollapsedVal;
|
||||
ImRect SizeConstraintRect;
|
||||
@ -1212,7 +1233,7 @@ struct ImGuiNextWindowData
|
||||
ImGuiWindowRefreshFlags RefreshFlagsVal;
|
||||
|
||||
ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
|
||||
inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; }
|
||||
inline void ClearFlags() { HasFlags = ImGuiNextWindowDataFlags_None; }
|
||||
};
|
||||
|
||||
enum ImGuiNextItemDataFlags_
|
||||
@ -1229,7 +1250,8 @@ struct ImGuiNextItemData
|
||||
{
|
||||
ImGuiNextItemDataFlags HasFlags; // Called HasFlags instead of Flags to avoid mistaking this
|
||||
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData.
|
||||
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
|
||||
|
||||
// Members below are NOT cleared by ItemAdd() meaning they are still valid during e.g. NavProcessItem(). Always rely on HasFlags.
|
||||
ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData()
|
||||
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
@ -1297,6 +1319,7 @@ struct ImGuiWindowStackData
|
||||
ImGuiLastItemData ParentLastItemDataBackup;
|
||||
ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
|
||||
bool DisabledOverrideReenable; // Non-child window override disabled flag
|
||||
float DisabledOverrideReenableAlphaBackup;
|
||||
};
|
||||
|
||||
struct ImGuiShrinkWidthItem
|
||||
@ -1984,7 +2007,6 @@ struct ImGuiMetricsConfig
|
||||
bool ShowDrawCmdMesh = true;
|
||||
bool ShowDrawCmdBoundingBoxes = true;
|
||||
bool ShowTextEncodingViewer = false;
|
||||
bool ShowAtlasTintedWithTextColor = false;
|
||||
int ShowWindowsRectsType = -1;
|
||||
int ShowTablesRectsType = -1;
|
||||
int HighlightMonitorIdx = -1;
|
||||
@ -2011,6 +2033,7 @@ struct ImGuiIDStackTool
|
||||
ImVector<ImGuiStackLevelInfo> Results;
|
||||
bool CopyToClipboardOnCtrlC;
|
||||
float CopyToClipboardLastTime;
|
||||
ImGuiTextBuffer ResultPathBuf;
|
||||
|
||||
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
|
||||
};
|
||||
@ -2075,7 +2098,7 @@ struct ImGuiContext
|
||||
ImVector<ImGuiWindowStackData> CurrentWindowStack;
|
||||
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
||||
int WindowsActiveCount; // Number of unique windows submitted by frame
|
||||
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING).
|
||||
float WindowsBorderHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, style.WindowBorderHoverPadding). This isn't so multi-dpi friendly.
|
||||
ImGuiID DebugBreakInWindow; // Set to break in Begin() call.
|
||||
ImGuiWindow* CurrentWindow; // Window being drawn into
|
||||
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
|
||||
@ -2448,6 +2471,8 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
ImGuiLayoutType LayoutType;
|
||||
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
|
||||
ImU32 ModalDimBgColor;
|
||||
ImGuiItemStatusFlags WindowItemStatusFlags;
|
||||
ImGuiItemStatusFlags ChildItemStatusFlags;
|
||||
|
||||
// Local parameters stacks
|
||||
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||
@ -2490,6 +2515,8 @@ struct IMGUI_API ImGuiWindow
|
||||
ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold
|
||||
ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar.
|
||||
bool ScrollbarX, ScrollbarY; // Are scrollbars visible?
|
||||
bool ScrollbarXStabilizeEnabled; // Was ScrollbarX previously auto-stabilized?
|
||||
ImU8 ScrollbarXStabilizeToggledHistory; // Used to stabilize scrollbar visibility in case of feedback loops
|
||||
bool Active; // Set to true on Begin(), unless Collapsed
|
||||
bool WasActive;
|
||||
bool WriteAccessed; // Set to true when any widget access the current window
|
||||
@ -2543,6 +2570,8 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiStorage StateStorage;
|
||||
ImVector<ImGuiOldColumns> ColumnsStorage;
|
||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||
float FontWindowScaleParents;
|
||||
float FontRefSize; // This is a copy of window->CalcFontSize() at the time of Begin(), trying to phase out CalcFontSize() especially as it may be called on non-current window.
|
||||
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
|
||||
|
||||
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
||||
@ -2577,7 +2606,7 @@ public:
|
||||
|
||||
// We don't use g.FontSize because the window may be != g.CurrentWindow.
|
||||
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
|
||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontBaseSize * FontWindowScale * FontWindowScaleParents; }
|
||||
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
|
||||
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
|
||||
};
|
||||
@ -2600,6 +2629,8 @@ enum ImGuiTabItemFlagsPrivate_
|
||||
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
|
||||
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
|
||||
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
|
||||
ImGuiTabItemFlags_Invisible = 1 << 22, // To reserve space e.g. with ImGuiTabItemFlags_Leading
|
||||
//ImGuiTabItemFlags_Unsorted = 1 << 23, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
|
||||
};
|
||||
|
||||
// Storage for one active tab item (sizeof() 40 bytes)
|
||||
@ -2773,7 +2804,7 @@ struct IMGUI_API ImGuiTable
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiTableFlags Flags;
|
||||
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[]
|
||||
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[], and RowCellData[]
|
||||
ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[]
|
||||
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
|
||||
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
|
||||
@ -2787,7 +2818,7 @@ struct IMGUI_API ImGuiTable
|
||||
int ColumnsCount; // Number of columns declared in BeginTable()
|
||||
int CurrentRow;
|
||||
int CurrentColumn;
|
||||
ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched.
|
||||
ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple tables with the same ID are multiple tables, they are just synced.
|
||||
ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with
|
||||
float RowPosY1;
|
||||
float RowPosY2;
|
||||
@ -2819,7 +2850,7 @@ struct IMGUI_API ImGuiTable
|
||||
float AngledHeadersHeight; // Set by TableAngledHeadersRow(), used in TableUpdateLayout()
|
||||
float AngledHeadersSlope; // Set by TableAngledHeadersRow(), used in TableUpdateLayout()
|
||||
ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
|
||||
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is
|
||||
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is "
|
||||
ImRect WorkRect;
|
||||
ImRect InnerClipRect;
|
||||
ImRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries
|
||||
@ -2863,6 +2894,7 @@ struct IMGUI_API ImGuiTable
|
||||
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
|
||||
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
|
||||
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
|
||||
ImS8 NavLayer; // ImGuiNavLayer at the time of BeginTable().
|
||||
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
|
||||
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
|
||||
bool IsInitializing;
|
||||
@ -2915,7 +2947,7 @@ struct IMGUI_API ImGuiTableTempData
|
||||
ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
|
||||
};
|
||||
|
||||
// sizeof() ~ 12
|
||||
// sizeof() ~ 16
|
||||
struct ImGuiTableColumnSettings
|
||||
{
|
||||
float WidthOrWeight;
|
||||
@ -2924,7 +2956,7 @@ struct ImGuiTableColumnSettings
|
||||
ImGuiTableColumnIdx DisplayOrder;
|
||||
ImGuiTableColumnIdx SortOrder;
|
||||
ImU8 SortDirection : 2;
|
||||
ImU8 IsEnabled : 1; // "Visible" in ini file
|
||||
ImS8 IsEnabled : 2; // "Visible" in ini file
|
||||
ImU8 IsStretch : 1;
|
||||
|
||||
ImGuiTableColumnSettings()
|
||||
@ -2934,7 +2966,7 @@ struct ImGuiTableColumnSettings
|
||||
Index = -1;
|
||||
DisplayOrder = SortOrder = -1;
|
||||
SortDirection = ImGuiSortDirection_None;
|
||||
IsEnabled = 1;
|
||||
IsEnabled = -1;
|
||||
IsStretch = 0;
|
||||
}
|
||||
};
|
||||
@ -2965,7 +2997,8 @@ namespace ImGui
|
||||
// If this ever crashes because g.CurrentWindow is NULL, it means that either:
|
||||
// - ImGui::NewFrame() has never been called, which is illegal.
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
IMGUI_API ImGuiIO& GetIOEx(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
|
||||
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
|
||||
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
|
||||
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
|
||||
@ -3004,6 +3037,7 @@ namespace ImGui
|
||||
// Fonts, drawing
|
||||
IMGUI_API void SetCurrentFont(ImFont* font);
|
||||
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
|
||||
IMGUI_API void PushPasswordFont();
|
||||
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
|
||||
IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
|
||||
IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
|
||||
@ -3085,14 +3119,14 @@ namespace ImGui
|
||||
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
|
||||
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
|
||||
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
|
||||
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags item_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
||||
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
|
||||
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
|
||||
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
|
||||
|
||||
// Parameter stacks (shared)
|
||||
IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
|
||||
IMGUI_API const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
|
||||
IMGUI_API void BeginDisabledOverrideReenable();
|
||||
IMGUI_API void EndDisabledOverrideReenable();
|
||||
|
||||
@ -3107,6 +3141,7 @@ namespace ImGui
|
||||
|
||||
// Popups, Modals
|
||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
|
||||
IMGUI_API bool BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags extra_window_flags);
|
||||
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
|
||||
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
|
||||
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
|
||||
@ -3366,6 +3401,7 @@ namespace ImGui
|
||||
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
|
||||
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
|
||||
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window);
|
||||
IMGUI_API void TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width);
|
||||
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
|
||||
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
|
||||
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
|
||||
@ -3457,6 +3493,7 @@ namespace ImGui
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
|
||||
inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active
|
||||
IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data);
|
||||
inline bool IsItemActiveAsInputText() { ImGuiContext& g = *GImGui; return g.ActiveId != 0 && g.ActiveId == g.LastItemData.ID && g.InputTextState.ID == g.LastItemData.ID; } // This may be useful to apply workaround that a based on distinguish whenever an item is active as a text input field.
|
||||
|
||||
// Color
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
@ -3552,15 +3589,18 @@ struct ImFontBuilderIO
|
||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||
IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
|
||||
#endif
|
||||
IMGUI_API void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
|
||||
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, float ascent, float descent);
|
||||
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
|
||||
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
|
||||
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
|
||||
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
|
||||
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
|
||||
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v);
|
||||
|
||||
IMGUI_API bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Test Engine specific hooks (imgui_test_engine)
|
||||
|
102
imgui_tables.cpp
102
imgui_tables.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91b
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@ -221,6 +221,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
@ -230,6 +231,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
@ -340,6 +342,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
{
|
||||
ItemSize(outer_rect);
|
||||
ItemAdd(outer_rect, id);
|
||||
g.NextWindowData.ClearFlags();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -374,6 +377,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->ColumnsCount = columns_count;
|
||||
table->IsLayoutLocked = false;
|
||||
table->InnerWidth = inner_width;
|
||||
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
|
||||
temp_data->UserOuterSize = outer_size;
|
||||
|
||||
// Instance data (for instance 0, TableID == TableInstanceID)
|
||||
@ -414,12 +418,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
|
||||
// Reset scroll if we are reactivating it
|
||||
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
|
||||
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) == 0)
|
||||
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) == 0)
|
||||
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
|
||||
// Create scrolling region (without border and zero window padding)
|
||||
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
|
||||
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags);
|
||||
ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None;
|
||||
ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None;
|
||||
if (flags & ImGuiTableFlags_ScrollX)
|
||||
child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar;
|
||||
BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags);
|
||||
table->InnerWindow = g.CurrentWindow;
|
||||
table->WorkRect = table->InnerWindow->WorkRect;
|
||||
table->OuterRect = table->InnerWindow->Rect();
|
||||
@ -572,6 +579,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// Initialize
|
||||
table->SettingsOffset = -1;
|
||||
table->IsSortSpecsDirty = true;
|
||||
table->IsSettingsDirty = true; // Records itself into .ini file even when in default state (#7934)
|
||||
table->InstanceInteracted = -1;
|
||||
table->ContextPopupColumn = -1;
|
||||
table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1;
|
||||
@ -971,7 +979,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
// [Part 4] Apply final widths based on requested widths
|
||||
const ImRect work_rect = table->WorkRect;
|
||||
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
||||
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920)
|
||||
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synced tables with mismatching scrollbar state (#5920)
|
||||
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
|
||||
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
|
||||
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
|
||||
@ -1050,7 +1058,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
|
||||
// Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
|
||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
|
||||
|
||||
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
||||
{
|
||||
@ -1383,7 +1392,7 @@ void ImGui::EndTable()
|
||||
|
||||
// Setup inner scrolling range
|
||||
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
|
||||
// but since the later is likely to be impossible to do we'd rather update both axises together.
|
||||
// but since the later is likely to be impossible to do we'd rather update both axes together.
|
||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||
{
|
||||
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
|
||||
@ -1493,7 +1502,7 @@ void ImGui::EndTable()
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
||||
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
|
||||
inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
|
||||
g.CurrentTable = NULL; // To avoid error recovery recursing
|
||||
EndChild();
|
||||
g.CurrentTable = table;
|
||||
@ -1558,6 +1567,31 @@ void ImGui::EndTable()
|
||||
NavUpdateCurrentWindowIsScrollPushableX();
|
||||
}
|
||||
|
||||
// Called in TableSetupColumn() when initializing and in TableLoadSettings() for defaults before applying stored settings.
|
||||
// 'init_mask' specify which fields to initialize.
|
||||
static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags init_mask)
|
||||
{
|
||||
ImGuiTableColumnFlags flags = column->Flags;
|
||||
if (init_mask & ImGuiTableFlags_Resizable)
|
||||
{
|
||||
float init_width_or_weight = column->InitStretchWeightOrWidth;
|
||||
column->WidthRequest = ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
|
||||
column->StretchWeight = (init_width_or_weight > 0.0f && (flags & ImGuiTableColumnFlags_WidthStretch)) ? init_width_or_weight : -1.0f;
|
||||
if (init_width_or_weight > 0.0f) // Disable auto-fit if an explicit width/weight has been specified
|
||||
column->AutoFitQueue = 0x00;
|
||||
}
|
||||
if (init_mask & ImGuiTableFlags_Reorderable)
|
||||
column->DisplayOrder = (ImGuiTableColumnIdx)table->Columns.index_from_ptr(column);
|
||||
if (init_mask & ImGuiTableFlags_Hideable)
|
||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = (flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1;
|
||||
if (init_mask & ImGuiTableFlags_Sortable)
|
||||
{
|
||||
// Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
|
||||
column->SortOrder = (flags & ImGuiTableColumnFlags_DefaultSort) ? 0 : -1;
|
||||
column->SortDirection = (flags & ImGuiTableColumnFlags_DefaultSort) ? ((flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending)) : (ImS8)ImGuiSortDirection_None;
|
||||
}
|
||||
}
|
||||
|
||||
// See "COLUMNS SIZING POLICIES" comments at the top of this file
|
||||
// If (init_width_or_weight <= 0.0f) it is ignored
|
||||
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
||||
@ -1586,7 +1620,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
||||
|
||||
// When passing a width automatically enforce WidthFixed policy
|
||||
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
|
||||
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable)
|
||||
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
|
||||
if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
|
||||
flags |= ImGuiTableColumnFlags_WidthFixed;
|
||||
@ -1604,27 +1638,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
column->InitStretchWeightOrWidth = init_width_or_weight;
|
||||
if (table->IsInitializing)
|
||||
{
|
||||
// Init width or weight
|
||||
ImGuiTableFlags init_flags = ~table->SettingsLoadedFlags;
|
||||
if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f)
|
||||
{
|
||||
if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
|
||||
column->WidthRequest = init_width_or_weight;
|
||||
if (flags & ImGuiTableColumnFlags_WidthStretch)
|
||||
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
|
||||
|
||||
// Disable auto-fit if an explicit width/weight has been specified
|
||||
if (init_width_or_weight > 0.0f)
|
||||
column->AutoFitQueue = 0x00;
|
||||
}
|
||||
|
||||
// Init default visibility/sort state
|
||||
if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
|
||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = false;
|
||||
if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0)
|
||||
{
|
||||
column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
|
||||
column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending);
|
||||
}
|
||||
init_flags |= ImGuiTableFlags_Resizable;
|
||||
TableInitColumnDefaults(table, column, init_flags);
|
||||
}
|
||||
|
||||
// Store name (append with zero-terminator in contiguous buffer)
|
||||
@ -1633,7 +1650,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
if (label != NULL && label[0] != 0)
|
||||
{
|
||||
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
||||
table->ColumnsNames.append(label, label + strlen(label) + 1);
|
||||
table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2032,7 +2049,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
if (unfreeze_rows_request)
|
||||
{
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
|
||||
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
|
||||
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
||||
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
||||
|
||||
@ -2099,7 +2116,11 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
||||
{
|
||||
if (table->CurrentColumn != -1)
|
||||
TableEndCell(table);
|
||||
IM_ASSERT(column_n >= 0 && table->ColumnsCount);
|
||||
if ((column_n >= 0 && column_n < table->ColumnsCount) == false)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!");
|
||||
return false;
|
||||
}
|
||||
TableBeginCell(table, column_n);
|
||||
}
|
||||
|
||||
@ -3712,6 +3733,14 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
table->SettingsLoadedFlags = settings->SaveFlags;
|
||||
table->RefScale = settings->RefScale;
|
||||
|
||||
// Initialize default columns settings
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
TableInitColumnDefaults(table, column, ~0);
|
||||
column->AutoFitQueue = 0x00;
|
||||
}
|
||||
|
||||
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
||||
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
||||
ImU64 display_order_mask = 0;
|
||||
@ -3728,14 +3757,12 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
column->StretchWeight = column_settings->WidthOrWeight;
|
||||
else
|
||||
column->WidthRequest = column_settings->WidthOrWeight;
|
||||
column->AutoFitQueue = 0x00;
|
||||
}
|
||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||
column->DisplayOrder = column_settings->DisplayOrder;
|
||||
else
|
||||
column->DisplayOrder = (ImGuiTableColumnIdx)column_n;
|
||||
display_order_mask |= (ImU64)1 << column->DisplayOrder;
|
||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled;
|
||||
if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1)
|
||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1;
|
||||
column->SortOrder = column_settings->SortOrder;
|
||||
column->SortDirection = column_settings->SortDirection;
|
||||
}
|
||||
@ -3831,8 +3858,7 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
|
||||
const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0;
|
||||
const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0;
|
||||
const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0;
|
||||
if (!save_size && !save_visible && !save_order && !save_sort)
|
||||
continue;
|
||||
// We need to save the [Table] entry even if all the bools are false, since this records a table with "default settings".
|
||||
|
||||
buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve
|
||||
buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount);
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91b
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -70,6 +70,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
|
||||
@ -80,6 +81,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
@ -169,7 +171,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
// Calculate length
|
||||
const char* text_begin = text;
|
||||
if (text_end == NULL)
|
||||
text_end = text + strlen(text); // FIXME-OPT
|
||||
text_end = text + ImStrlen(text); // FIXME-OPT
|
||||
|
||||
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||
@ -209,7 +211,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
int lines_skipped = 0;
|
||||
while (line < text_end && lines_skipped < lines_skippable)
|
||||
{
|
||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
||||
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
|
||||
if (!line_end)
|
||||
line_end = text_end;
|
||||
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
||||
@ -230,7 +232,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
if (IsClippedEx(line_rect, 0))
|
||||
break;
|
||||
|
||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
||||
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
|
||||
if (!line_end)
|
||||
line_end = text_end;
|
||||
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
||||
@ -245,7 +247,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
int lines_skipped = 0;
|
||||
while (line < text_end)
|
||||
{
|
||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
||||
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
|
||||
if (!line_end)
|
||||
line_end = text_end;
|
||||
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
||||
@ -909,15 +911,17 @@ ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis)
|
||||
// Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set.
|
||||
ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImRect outer_rect = window->Rect();
|
||||
const ImRect inner_rect = window->InnerRect;
|
||||
const float border_size = window->WindowBorderSize;
|
||||
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
|
||||
IM_ASSERT(scrollbar_size > 0.0f);
|
||||
IM_ASSERT(scrollbar_size >= 0.0f);
|
||||
const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f);
|
||||
const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f;
|
||||
if (axis == ImGuiAxis_X)
|
||||
return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
|
||||
return ImRect(inner_rect.Min.x + border_size, ImMax(outer_rect.Min.y + border_size, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
|
||||
else
|
||||
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
|
||||
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::Scrollbar(ImGuiAxis axis)
|
||||
@ -969,8 +973,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab)
|
||||
float alpha = 1.0f;
|
||||
if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f)
|
||||
alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f));
|
||||
if ((axis == ImGuiAxis_Y) && bb_frame_height < bb_frame_width)
|
||||
alpha = ImSaturate(bb_frame_height / ImMax(bb_frame_width * 2.0f, 1.0f));
|
||||
if (alpha <= 0.0f)
|
||||
return false;
|
||||
|
||||
@ -987,7 +991,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||
IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1);
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||
const float grab_h_minsize = ImMin(bb.GetSize()[axis], style.GrabMinSize);
|
||||
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;
|
||||
|
||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||
@ -1059,25 +1064,45 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||||
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
|
||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||
void ImGui::ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
const float border_size = (border_col.w > 0.0f) ? 1.0f : 0.0f;
|
||||
const ImVec2 padding(border_size, border_size);
|
||||
const ImVec2 padding(g.Style.ImageBorderSize, g.Style.ImageBorderSize);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + image_size + padding * 2.0f);
|
||||
ItemSize(bb);
|
||||
if (!ItemAdd(bb, 0))
|
||||
return;
|
||||
|
||||
// Render
|
||||
if (border_size > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f, ImDrawFlags_None, border_size);
|
||||
if (g.Style.ImageBorderSize > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), 0.0f, ImDrawFlags_None, g.Style.ImageBorderSize);
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(user_texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
}
|
||||
|
||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
|
||||
{
|
||||
ImageWithBg(user_texture_id, image_size, uv0, uv1);
|
||||
}
|
||||
|
||||
// 1.91.9 (February 2025) removed 'tint_col' and 'border_col' parameters, made border size not depend on color value. (#8131, #8238)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
PushStyleVar(ImGuiStyleVar_ImageBorderSize, (border_col.w > 0.0f) ? ImMax(1.0f, g.Style.ImageBorderSize) : 0.0f); // Preserve legacy behavior where border is always visible when border_col's Alpha is >0.0f
|
||||
PushStyleColor(ImGuiCol_Border, border_col);
|
||||
ImageWithBg(user_texture_id, image_size, uv0, uv1, ImVec4(0, 0, 0, 0), tint_col);
|
||||
PopStyleColor();
|
||||
PopStyleVar();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -1421,7 +1446,7 @@ bool ImGui::TextLink(const char* label)
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 size = CalcTextSize(label, label_end, true);
|
||||
ImRect bb(pos, pos + size);
|
||||
ItemSize(size, 0.0f);
|
||||
@ -1826,7 +1851,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags;
|
||||
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.HasFlags;
|
||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
@ -1895,7 +1920,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
if (!popup_open)
|
||||
return false;
|
||||
|
||||
g.NextWindowData.Flags = backup_next_window_data_flags;
|
||||
g.NextWindowData.HasFlags = backup_next_window_data_flags;
|
||||
return BeginComboPopup(popup_id, bb, flags);
|
||||
}
|
||||
|
||||
@ -1910,7 +1935,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
|
||||
// Set popup size
|
||||
float w = bb.GetWidth();
|
||||
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)
|
||||
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint)
|
||||
{
|
||||
g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w);
|
||||
}
|
||||
@ -1924,9 +1949,9 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4;
|
||||
else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20;
|
||||
ImVec2 constraint_min(0.0f, 0.0f), constraint_max(FLT_MAX, FLT_MAX);
|
||||
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size
|
||||
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size
|
||||
constraint_min.x = w;
|
||||
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f)
|
||||
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f)
|
||||
constraint_max.y = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items);
|
||||
SetNextWindowSizeConstraints(constraint_min, constraint_max);
|
||||
}
|
||||
@ -2041,7 +2066,7 @@ static const char* Items_SingleStringGetter(void* data, int idx)
|
||||
{
|
||||
if (idx == items_count)
|
||||
break;
|
||||
p += strlen(p) + 1;
|
||||
p += ImStrlen(p) + 1;
|
||||
items_count++;
|
||||
}
|
||||
return *p ? p : NULL;
|
||||
@ -2058,7 +2083,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo
|
||||
preview_value = getter(user_data, *current_item);
|
||||
|
||||
// The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here.
|
||||
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
|
||||
if (popup_max_height_in_items != -1 && !(g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint))
|
||||
SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items)));
|
||||
|
||||
if (!BeginCombo(label, preview_value, ImGuiComboFlags_None))
|
||||
@ -2109,7 +2134,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
|
||||
const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open
|
||||
while (*p)
|
||||
{
|
||||
p += strlen(p) + 1;
|
||||
p += ImStrlen(p) + 1;
|
||||
items_count++;
|
||||
}
|
||||
bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items);
|
||||
@ -2619,7 +2644,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an InputText
|
||||
// Tabbing or CTRL+click on Drag turns it into an InputText
|
||||
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
|
||||
const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id));
|
||||
const bool make_active = (clicked || double_clicked || g.NavActivateId == id);
|
||||
@ -3223,7 +3248,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
||||
// Tabbing or CTRL+click on Slider turns it into an input box
|
||||
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
|
||||
const bool make_active = (clicked || g.NavActivateId == id);
|
||||
if (make_active && clicked)
|
||||
@ -3876,7 +3901,7 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
|
||||
line_count++;
|
||||
if (s_eol == NULL)
|
||||
{
|
||||
s = s + strlen(s);
|
||||
s = s + ImStrlen(s);
|
||||
break;
|
||||
}
|
||||
s = s_eol + 1;
|
||||
@ -4164,7 +4189,7 @@ void ImGuiInputTextState::OnCharPressed(unsigned int c)
|
||||
// The changes we had to make to stb_textedit_key made it very much UTF-8 specific which is not too great.
|
||||
char utf8[5];
|
||||
ImTextCharToUtf8(utf8, c);
|
||||
stb_textedit_text(this, Stb, utf8, (int)strlen(utf8));
|
||||
stb_textedit_text(this, Stb, utf8, (int)ImStrlen(utf8));
|
||||
CursorFollow = true;
|
||||
CursorAnimReset();
|
||||
}
|
||||
@ -4215,7 +4240,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
|
||||
// Grow internal buffer if needed
|
||||
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text);
|
||||
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
|
||||
if (new_text_len + BufTextLen >= BufSize)
|
||||
{
|
||||
if (!is_resizable)
|
||||
@ -4244,6 +4269,23 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
BufTextLen += new_text_len;
|
||||
}
|
||||
|
||||
void ImGui::PushPasswordFont()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImFont* in_font = g.Font;
|
||||
ImFont* out_font = &g.InputTextPasswordFont;
|
||||
ImFontGlyph* glyph = in_font->FindGlyph('*');
|
||||
out_font->FontSize = in_font->FontSize;
|
||||
out_font->Scale = in_font->Scale;
|
||||
out_font->Ascent = in_font->Ascent;
|
||||
out_font->Descent = in_font->Descent;
|
||||
out_font->ContainerAtlas = in_font->ContainerAtlas;
|
||||
out_font->FallbackGlyph = glyph;
|
||||
out_font->FallbackAdvanceX = glyph->AdvanceX;
|
||||
IM_ASSERT(out_font->Glyphs.Size == 0 && out_font->IndexAdvanceX.Size == 0 && out_font->IndexLookup.Size == 0);
|
||||
PushFont(out_font);
|
||||
}
|
||||
|
||||
// Return false to discard a character.
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
{
|
||||
@ -4254,7 +4296,13 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
if (c < 0x20)
|
||||
{
|
||||
bool pass = false;
|
||||
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
|
||||
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
|
||||
if (c == '\n' && input_source_is_clipboard && (flags & ImGuiInputTextFlags_Multiline) == 0) // In single line mode, replace \n with a space
|
||||
{
|
||||
c = *p_char = ' ';
|
||||
pass = true;
|
||||
}
|
||||
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0;
|
||||
pass |= (c == '\t') && (flags & ImGuiInputTextFlags_AllowTabInput) != 0;
|
||||
if (!pass)
|
||||
return false;
|
||||
@ -4520,7 +4568,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
int new_len = (int)strlen(buf);
|
||||
int new_len = (int)ImStrlen(buf);
|
||||
IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->WantReloadUserBuf = false;
|
||||
InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
|
||||
@ -4542,7 +4590,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Take a copy of the initial buffer value.
|
||||
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
const int buf_len = (int)strlen(buf);
|
||||
const int buf_len = (int)ImStrlen(buf);
|
||||
IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||
@ -4627,7 +4675,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
|
||||
if (is_readonly && state != NULL)
|
||||
state->TextLen = (int)strlen(buf);
|
||||
state->TextLen = (int)ImStrlen(buf);
|
||||
//if (is_readonly && state != NULL)
|
||||
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
|
||||
}
|
||||
@ -4650,23 +4698,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Select the buffer to render.
|
||||
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state;
|
||||
const bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
|
||||
// Password pushes a temporary font with only a fallback glyph
|
||||
if (is_password && !is_displaying_hint)
|
||||
{
|
||||
const ImFontGlyph* glyph = g.Font->FindGlyph('*');
|
||||
ImFont* password_font = &g.InputTextPasswordFont;
|
||||
password_font->FontSize = g.Font->FontSize;
|
||||
password_font->Scale = g.Font->Scale;
|
||||
password_font->Ascent = g.Font->Ascent;
|
||||
password_font->Descent = g.Font->Descent;
|
||||
password_font->ContainerAtlas = g.Font->ContainerAtlas;
|
||||
password_font->FallbackGlyph = glyph;
|
||||
password_font->FallbackAdvanceX = glyph->AdvanceX;
|
||||
IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty());
|
||||
PushFont(password_font);
|
||||
}
|
||||
PushPasswordFont();
|
||||
|
||||
// Process mouse inputs and character inputs
|
||||
if (g.ActiveId == id)
|
||||
@ -4796,14 +4832,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
|
||||
const bool is_startend_key_down = is_osx && io.KeyCtrl && !io.KeySuper && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
|
||||
|
||||
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText)
|
||||
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: former would be handled by InputText)
|
||||
// Otherwise we could simply assume that we own the keys as we are active.
|
||||
const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat;
|
||||
const bool is_cut = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_X, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, f_repeat, id)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection());
|
||||
const bool is_copy = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, 0, id)) && !is_password && (!is_multiline || state->HasSelection());
|
||||
const bool is_paste = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_V, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, f_repeat, id)) && !is_readonly;
|
||||
const bool is_undo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable;
|
||||
const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || (is_osx && Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id))) && !is_readonly && is_undoable;
|
||||
const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable;
|
||||
const bool is_select_all = Shortcut(ImGuiMod_Ctrl | ImGuiKey_A, 0, id);
|
||||
|
||||
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
|
||||
@ -4918,7 +4954,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (const char* clipboard = GetClipboardText())
|
||||
{
|
||||
// Filter pasted buffer
|
||||
const int clipboard_len = (int)strlen(clipboard);
|
||||
const int clipboard_len = (int)ImStrlen(clipboard);
|
||||
ImVector<char> clipboard_filtered;
|
||||
clipboard_filtered.reserve(clipboard_len + 1);
|
||||
for (const char* s = clipboard; *s != 0; )
|
||||
@ -4930,7 +4966,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
continue;
|
||||
char c_utf8[5];
|
||||
ImTextCharToUtf8(c_utf8, c);
|
||||
int out_len = (int)strlen(c_utf8);
|
||||
int out_len = (int)ImStrlen(c_utf8);
|
||||
clipboard_filtered.resize(clipboard_filtered.Size + out_len);
|
||||
memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len);
|
||||
}
|
||||
@ -5060,7 +5096,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (buf_dirty)
|
||||
{
|
||||
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen);
|
||||
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||
state->CursorAnimReset();
|
||||
@ -5144,10 +5180,22 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
const int buf_display_max_length = 2 * 1024 * 1024;
|
||||
const char* buf_display = buf_display_from_state ? state->TextA.Data : buf; //-V595
|
||||
const char* buf_display_end = NULL; // We have specialized paths below for setting the length
|
||||
|
||||
// Display hint when contents is empty
|
||||
// At this point we need to handle the possibility that a callback could have modified the underlying buffer (#8368)
|
||||
const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
if (new_is_displaying_hint != is_displaying_hint)
|
||||
{
|
||||
if (is_password && !is_displaying_hint)
|
||||
PopFont();
|
||||
is_displaying_hint = new_is_displaying_hint;
|
||||
if (is_password && !is_displaying_hint)
|
||||
PushPasswordFont();
|
||||
}
|
||||
if (is_displaying_hint)
|
||||
{
|
||||
buf_display = hint;
|
||||
buf_display_end = hint + strlen(hint);
|
||||
buf_display_end = hint + ImStrlen(hint);
|
||||
}
|
||||
|
||||
// Render text. We currently only render selection when the widget is active or while scrolling.
|
||||
@ -5180,7 +5228,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
int line_count = 1;
|
||||
if (is_multiline)
|
||||
{
|
||||
for (const char* s = text_begin; (s = (const char*)memchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
|
||||
for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
|
||||
{
|
||||
if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; }
|
||||
if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; }
|
||||
@ -5258,7 +5306,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
break;
|
||||
if (rect_pos.y < clip_rect.y)
|
||||
{
|
||||
p = (const char*)memchr((void*)p, '\n', text_selected_end - p);
|
||||
p = (const char*)ImMemchr((void*)p, '\n', text_selected_end - p);
|
||||
p = p ? p + 1 : text_selected_end;
|
||||
}
|
||||
else
|
||||
@ -5310,7 +5358,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
else if (!is_displaying_hint && g.ActiveId == id)
|
||||
buf_display_end = buf_display + state->TextLen;
|
||||
else if (!is_displaying_hint)
|
||||
buf_display_end = buf_display + strlen(buf_display);
|
||||
buf_display_end = buf_display + ImStrlen(buf_display);
|
||||
|
||||
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
||||
{
|
||||
@ -5455,7 +5503,7 @@ static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V)
|
||||
|
||||
// Edit colors components (each component in 0.0f..1.0f range).
|
||||
// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
|
||||
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item.
|
||||
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL+Click over input fields to edit them and TAB to go to next item.
|
||||
bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@ -5902,7 +5950,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
if ((flags & ImGuiColorEditFlags_NoLabel))
|
||||
Text("Current");
|
||||
|
||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip;
|
||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoTooltip;
|
||||
ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2));
|
||||
if (ref_col != NULL)
|
||||
{
|
||||
@ -5942,7 +5990,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
if ((flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
{
|
||||
PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x);
|
||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview;
|
||||
ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker;
|
||||
if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags_DisplayMask_) == 0)
|
||||
if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB))
|
||||
@ -6118,8 +6166,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
|
||||
|
||||
if (flags & ImGuiColorEditFlags_NoAlpha)
|
||||
flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf);
|
||||
if (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque))
|
||||
flags &= ~(ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf);
|
||||
|
||||
ImVec4 col_rgb = col;
|
||||
if (flags & ImGuiColorEditFlags_InputHSV)
|
||||
@ -6138,14 +6186,17 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||
{
|
||||
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
|
||||
if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
|
||||
else
|
||||
window->DrawList->AddRectFilled(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha
|
||||
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col_rgb : col_rgb_without_alpha;
|
||||
if (col_source.w < 1.0f)
|
||||
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaOpaque) ? col_rgb_without_alpha : col_rgb;
|
||||
if (col_source.w < 1.0f && (flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding);
|
||||
else
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding);
|
||||
@ -6156,7 +6207,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 button are often in need of some sort of border
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color buttons are often in need of some sort of border
|
||||
}
|
||||
|
||||
// Drag and Drop Source
|
||||
@ -6175,7 +6226,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
|
||||
// Tooltip
|
||||
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
|
||||
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@ -6216,7 +6267,8 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
|
||||
ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2);
|
||||
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
||||
ColorButton("##preview", cf, (flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz);
|
||||
ImGuiColorEditFlags flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_;
|
||||
ColorButton("##preview", cf, (flags & flags_to_forward) | ImGuiColorEditFlags_NoTooltip, sz);
|
||||
SameLine();
|
||||
if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_))
|
||||
{
|
||||
@ -6937,13 +6989,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
|
||||
size.x = ImMax(label_size.x, max_x - min_x);
|
||||
|
||||
// Text stays at the submission position, but bounding box may be extended on both sides
|
||||
const ImVec2 text_min = pos;
|
||||
const ImVec2 text_max(min_x + size.x, pos.y + size.y);
|
||||
|
||||
// Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable.
|
||||
// FIXME: Not part of layout so not included in clipper calculation, but ItemSize currently doesn't allow offsetting CursorPos.
|
||||
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
|
||||
ImRect bb(min_x, pos.y, min_x + size.x, pos.y + size.y);
|
||||
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
|
||||
{
|
||||
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
||||
@ -7079,8 +7127,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
PopColumnsBackground();
|
||||
}
|
||||
|
||||
// Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns.
|
||||
if (is_visible)
|
||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
|
||||
// Automatically close popups
|
||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
|
||||
@ -7143,7 +7192,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f
|
||||
|
||||
// Append to buffer
|
||||
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
|
||||
int buffer_len = (int)strlen(data->SearchBuffer);
|
||||
int buffer_len = (int)ImStrlen(data->SearchBuffer);
|
||||
bool select_request = false;
|
||||
for (ImWchar w : g.IO.InputQueueCharacters)
|
||||
{
|
||||
@ -8622,12 +8671,13 @@ bool ImGui::BeginMenuBar()
|
||||
|
||||
IM_ASSERT(!window->DC.MenuBarAppending);
|
||||
BeginGroup(); // Backup position on layer 0 // FIXME: Misleading to use a group for that backup/restore
|
||||
PushID("##menubar");
|
||||
PushID("##MenuBar");
|
||||
|
||||
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
|
||||
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
|
||||
const float border_top = ImMax(window->WindowBorderSize * 0.5f - window->TitleBarHeight, 0.0f);
|
||||
ImRect bar_rect = window->MenuBarRect();
|
||||
ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize))), IM_ROUND(bar_rect.Max.y));
|
||||
ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize * 0.5f), IM_ROUND(bar_rect.Min.y + border_top), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize * 0.5f))), IM_ROUND(bar_rect.Max.y));
|
||||
clip_rect.ClipWith(window->OuterRectClipped);
|
||||
PushClipRect(clip_rect.Min, clip_rect.Max, false);
|
||||
|
||||
@ -8648,6 +8698,10 @@ void ImGui::EndMenuBar()
|
||||
return;
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
|
||||
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
|
||||
IM_ASSERT(window->DC.MenuBarAppending);
|
||||
|
||||
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
|
||||
if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
||||
{
|
||||
@ -8674,9 +8728,6 @@ void ImGui::EndMenuBar()
|
||||
}
|
||||
}
|
||||
|
||||
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
|
||||
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
|
||||
IM_ASSERT(window->DC.MenuBarAppending);
|
||||
PopClipRect();
|
||||
PopID();
|
||||
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
||||
@ -8745,22 +8796,33 @@ bool ImGui::BeginMainMenuBar()
|
||||
float height = GetFrameHeight();
|
||||
bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags);
|
||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
||||
|
||||
if (is_open)
|
||||
BeginMenuBar();
|
||||
else
|
||||
if (!is_open)
|
||||
{
|
||||
End();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Temporarily disable _NoSavedSettings, in the off-chance that tables or child windows submitted within the menu-bar may want to use settings. (#8356)
|
||||
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_NoSavedSettings;
|
||||
BeginMenuBar();
|
||||
return is_open;
|
||||
}
|
||||
|
||||
void ImGui::EndMainMenuBar()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!g.CurrentWindow->DC.MenuBarAppending)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||
return;
|
||||
}
|
||||
|
||||
EndMenuBar();
|
||||
g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356)
|
||||
|
||||
// When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window
|
||||
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
|
||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest && g.ActiveId == 0)
|
||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
|
||||
|
||||
End();
|
||||
@ -8813,7 +8875,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
if (g.MenusIdSubmittedThisFrame.contains(id))
|
||||
{
|
||||
if (menu_is_open)
|
||||
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
else
|
||||
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
|
||||
return menu_is_open;
|
||||
@ -8844,7 +8906,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
// Menu inside an horizontal menu bar
|
||||
// Menu inside a horizontal menu bar
|
||||
// Selectable extend their highlight by half ItemSpacing in each direction.
|
||||
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight);
|
||||
@ -8975,7 +9037,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
ImGuiLastItemData last_item_in_parent = g.LastItemData;
|
||||
SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
|
||||
PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding
|
||||
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open may be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
PopStyleVar();
|
||||
if (menu_is_open)
|
||||
{
|
||||
@ -9921,7 +9983,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
||||
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT(!(flags & ImGuiTabItemFlags_Button)); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
||||
@ -9967,6 +10029,23 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
||||
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
||||
}
|
||||
|
||||
void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
SetNextItemWidth(width);
|
||||
TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
|
||||
}
|
||||
|
||||
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
|
||||
{
|
||||
// Layout whole tab bar if not already done
|
||||
@ -10040,7 +10119,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
else
|
||||
{
|
||||
tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
|
||||
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
|
||||
tab_bar->TabsNames.append(label, label + ImStrlen(label) + 1);
|
||||
}
|
||||
|
||||
// Update selected tab
|
||||
@ -10112,8 +10191,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
||||
if (g.DragDropActive)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
bool hovered, held, pressed;
|
||||
if (flags & ImGuiTabItemFlags_Invisible)
|
||||
hovered = held = pressed = false;
|
||||
else
|
||||
pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
if (pressed && !is_tab_button)
|
||||
TabBarQueueFocus(tab_bar, tab);
|
||||
|
||||
@ -10145,36 +10227,59 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
#endif
|
||||
|
||||
// Render tab shape
|
||||
ImDrawList* display_draw_list = window->DrawList;
|
||||
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
||||
TabItemBackground(display_draw_list, bb, flags, tab_col);
|
||||
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
||||
const bool is_visible = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) && !(flags & ImGuiTabItemFlags_Invisible);
|
||||
if (is_visible)
|
||||
{
|
||||
float x_offset = IM_TRUNC(0.4f * style.TabRounding);
|
||||
if (x_offset < 2.0f * g.CurrentDpiScale)
|
||||
x_offset = 0.0f;
|
||||
float y_offset = 1.0f * g.CurrentDpiScale;
|
||||
display_draw_list->AddLine(bb.GetTL() + ImVec2(x_offset, y_offset), bb.GetTR() + ImVec2(-x_offset, y_offset), GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline), style.TabBarOverlineSize);
|
||||
}
|
||||
RenderNavCursor(bb, id);
|
||||
ImDrawList* display_draw_list = window->DrawList;
|
||||
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
||||
TabItemBackground(display_draw_list, bb, flags, tab_col);
|
||||
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
||||
{
|
||||
// Might be moved to TabItemBackground() ?
|
||||
ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||
ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||
ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
|
||||
if (style.TabRounding > 0.0f)
|
||||
{
|
||||
float rounding = style.TabRounding;
|
||||
display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
|
||||
display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
|
||||
display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
|
||||
}
|
||||
}
|
||||
RenderNavCursor(bb, id);
|
||||
|
||||
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
||||
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
||||
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
||||
TabBarQueueFocus(tab_bar, tab);
|
||||
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
||||
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
||||
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
||||
TabBarQueueFocus(tab_bar, tab);
|
||||
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
||||
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
||||
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
||||
|
||||
// Render tab label, process close button
|
||||
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0;
|
||||
bool just_closed;
|
||||
bool text_clipped;
|
||||
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
||||
if (just_closed && p_open != NULL)
|
||||
{
|
||||
*p_open = false;
|
||||
TabBarCloseTab(tab_bar, tab);
|
||||
// Render tab label, process close button
|
||||
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0;
|
||||
bool just_closed;
|
||||
bool text_clipped;
|
||||
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
||||
if (just_closed && p_open != NULL)
|
||||
{
|
||||
*p_open = false;
|
||||
TabBarCloseTab(tab_bar, tab);
|
||||
}
|
||||
|
||||
// Tooltip
|
||||
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
|
||||
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
|
||||
// FIXME: This is a mess.
|
||||
// FIXME: We may want disabled tab to still display the tooltip?
|
||||
if (text_clipped && g.HoveredId == id && !held)
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
}
|
||||
|
||||
// Restore main window position so user can draw there
|
||||
@ -10182,15 +10287,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
PopClipRect();
|
||||
window->DC.CursorPos = backup_main_cursor_pos;
|
||||
|
||||
// Tooltip
|
||||
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
|
||||
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
|
||||
// FIXME: This is a mess.
|
||||
// FIXME: We may want disabled tab to still display the tooltip?
|
||||
if (text_clipped && g.HoveredId == id && !held)
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
|
||||
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
||||
if (is_tab_button)
|
||||
return pressed;
|
||||
@ -10300,13 +10396,24 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
// 'g.ActiveId==close_button_id' will be true when we are holding on the close button, in which case both hovered booleans are false
|
||||
bool close_button_pressed = false;
|
||||
bool close_button_visible = false;
|
||||
if (close_button_id != 0)
|
||||
if (is_contents_visible || bb.GetWidth() >= ImMax(button_sz, g.Style.TabMinWidthForCloseButton))
|
||||
if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id)
|
||||
close_button_visible = true;
|
||||
bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x);
|
||||
bool is_hovered = g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id; // Any interaction account for this too.
|
||||
|
||||
if (close_button_visible)
|
||||
if (close_button_id != 0)
|
||||
{
|
||||
if (is_contents_visible)
|
||||
close_button_visible = (g.Style.TabCloseButtonMinWidthSelected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthSelected));
|
||||
else
|
||||
close_button_visible = (g.Style.TabCloseButtonMinWidthUnselected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthUnselected));
|
||||
}
|
||||
|
||||
// When tabs/document is unsaved, the unsaved marker takes priority over the close button.
|
||||
const bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x) && (!close_button_visible || !is_hovered);
|
||||
if (unsaved_marker_visible)
|
||||
{
|
||||
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
|
||||
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
|
||||
}
|
||||
else if (close_button_visible)
|
||||
{
|
||||
ImGuiLastItemData last_item_backup = g.LastItemData;
|
||||
if (CloseButton(close_button_id, button_pos))
|
||||
@ -10314,14 +10421,9 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
g.LastItemData = last_item_backup;
|
||||
|
||||
// Close with middle mouse button
|
||||
if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2))
|
||||
if (is_hovered && !(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2))
|
||||
close_button_pressed = true;
|
||||
}
|
||||
else if (unsaved_marker_visible)
|
||||
{
|
||||
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
|
||||
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
|
||||
}
|
||||
|
||||
// This is all rather complicated
|
||||
// (the main idea is that because the close button only appears on hover, we don't want it to alter the ellipsis position)
|
||||
|
@ -38,7 +38,7 @@ You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain color
|
||||
|
||||
### Using OpenType SVG fonts (SVGinOT)
|
||||
- *SVG in Open Type* is a standard by Adobe and Mozilla for color OpenType and Open Font Format fonts. It allows font creators to embed complete SVG files within a font enabling full color and even animations.
|
||||
- Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT
|
||||
- Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT.
|
||||
- Two alternatives are possible to render SVG fonts: use "lunasvg" or "plutosvg". plutosvg will support some more fonts (e.g. NotoColorEmoji-Regular) and may load them faster.
|
||||
|
||||
#### Using lunasvg
|
||||
@ -48,15 +48,7 @@ Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above
|
||||
|
||||
#### Using plutosvg (and plutovg)
|
||||
- Add `#define IMGUI_ENABLE_FREETYPE_PLUTOSVG` in your `imconfig.h`.
|
||||
- Compile and link with plutosvg *and* plutovg (which is required by plutosvg)
|
||||
|
||||
_Compilation hints for plutovg_
|
||||
- Compile all source files in `plutovg/source/*.c`
|
||||
- Add include directory: `plutovg/include` + `plutovg/stb`
|
||||
|
||||
_Compilation hints for plutosvg_
|
||||
- Compile `plutosvg/source/plutosvg.c`
|
||||
- Add include directory: `plutosvg/source`
|
||||
- Add define: `PLUTOSVG_HAS_FREETYPE`
|
||||
- Link with: plutovg, freetype
|
||||
|
||||
- Get latest plutosvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install plutosvg --triplet=x64-windows`. Alternatively, if you build imgui from vcpkg, you just need to enable the plutosvg feature: `vcpkg install imgui[plutosvg] --triplet=x64-windows`
|
||||
- If you prefer to build plutosvg manually:
|
||||
- Compilation hints for plutovg: Compile all source files in `plutovg/source/*.c` + Add include directory: `plutovg/include` + `plutovg/stb`
|
||||
- Compilation hints for plutosvg: Compile `plutosvg/source/plutosvg.c` + Add include directory: `plutosvg/source` + Add define: `PLUTOSVG_HAS_FREETYPE` + Link with: plutovg, freetype
|
||||
|
@ -33,7 +33,7 @@
|
||||
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported, but generally not necessary with this rasterizer because Hinting makes everything look better.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
@ -104,6 +104,9 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
|
||||
// Code
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64) // From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_SCALEFACTOR 64.0f
|
||||
|
||||
namespace
|
||||
{
|
||||
// Glyph metrics:
|
||||
@ -163,7 +166,7 @@ namespace
|
||||
// NB: No ctor/dtor, explicitly call Init()/Shutdown()
|
||||
struct FreeTypeFont
|
||||
{
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
|
||||
void CloseFont();
|
||||
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
|
||||
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
||||
@ -182,12 +185,9 @@ namespace
|
||||
float InvRasterizationDensity;
|
||||
};
|
||||
|
||||
// From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64)
|
||||
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_font_builder_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src.FontData, (uint32_t)src.FontDataSize, (uint32_t)src.FontNo, &Face);
|
||||
if (error != 0)
|
||||
return false;
|
||||
error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
|
||||
@ -195,7 +195,7 @@ namespace
|
||||
return false;
|
||||
|
||||
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
|
||||
UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
|
||||
UserFlags = src.FontBuilderFlags | extra_font_builder_flags;
|
||||
|
||||
LoadFlags = 0;
|
||||
if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0)
|
||||
@ -222,11 +222,11 @@ namespace
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
|
||||
LoadFlags |= FT_LOAD_COLOR;
|
||||
|
||||
RasterizationDensity = cfg.RasterizerDensity;
|
||||
RasterizationDensity = src.RasterizerDensity;
|
||||
InvRasterizationDensity = 1.0f / RasterizationDensity;
|
||||
|
||||
memset(&Info, 0, sizeof(Info));
|
||||
SetPixelHeight((uint32_t)cfg.SizePixels);
|
||||
SetPixelHeight((uint32_t)src.SizePixels);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -269,11 +269,11 @@ namespace
|
||||
if (glyph_index == 0)
|
||||
return nullptr;
|
||||
|
||||
// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
|
||||
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
|
||||
// - https://github.com/ocornut/imgui/issues/4567
|
||||
// - https://github.com/ocornut/imgui/issues/4566
|
||||
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
|
||||
// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
|
||||
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
|
||||
// - https://github.com/ocornut/imgui/issues/4567
|
||||
// - https://github.com/ocornut/imgui/issues/4566
|
||||
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
|
||||
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
|
||||
if (error)
|
||||
return nullptr;
|
||||
@ -316,7 +316,7 @@ namespace
|
||||
out_glyph_info->Height = (int)ft_bitmap->rows;
|
||||
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
||||
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
||||
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
|
||||
out_glyph_info->AdvanceX = (float)slot->advance.x / FT_SCALEFACTOR;
|
||||
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
|
||||
|
||||
return ft_bitmap;
|
||||
@ -443,7 +443,7 @@ struct ImFontBuildDstDataFT
|
||||
|
||||
bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
|
||||
{
|
||||
IM_ASSERT(atlas->ConfigData.Size > 0);
|
||||
IM_ASSERT(atlas->Sources.Size > 0);
|
||||
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
|
||||
@ -458,36 +458,36 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
bool src_load_color = false;
|
||||
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
|
||||
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
|
||||
src_tmp_array.resize(atlas->ConfigData.Size);
|
||||
src_tmp_array.resize(atlas->Sources.Size);
|
||||
dst_tmp_array.resize(atlas->Fonts.Size);
|
||||
memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
|
||||
memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
|
||||
|
||||
// 1. Initialize font loading structure, check font data validity
|
||||
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
|
||||
for (int src_i = 0; src_i < atlas->Sources.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
FreeTypeFont& font_face = src_tmp.Font;
|
||||
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
|
||||
IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas));
|
||||
|
||||
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
// Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
src_tmp.DstIndex = -1;
|
||||
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
|
||||
if (cfg.DstFont == atlas->Fonts[output_i])
|
||||
if (src.DstFont == atlas->Fonts[output_i])
|
||||
src_tmp.DstIndex = output_i;
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array?
|
||||
if (src_tmp.DstIndex == -1)
|
||||
return false;
|
||||
|
||||
// Load font
|
||||
if (!font_face.InitFont(ft_library, cfg, extra_flags))
|
||||
if (!font_face.InitFont(ft_library, src, extra_flags))
|
||||
return false;
|
||||
|
||||
// Measure highest codepoints
|
||||
src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
|
||||
src_load_color |= (src.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
{
|
||||
// Check for valid range. This may also help detect *some* dangling pointers, because a common
|
||||
@ -577,7 +577,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
@ -585,10 +585,10 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
buf_rects_out_n += src_tmp.GlyphsCount;
|
||||
|
||||
// Compute multiply table if requested
|
||||
const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
|
||||
const bool multiply_enabled = (src.RasterizerMultiply != 1.0f);
|
||||
unsigned char multiply_table[256];
|
||||
if (multiply_enabled)
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply);
|
||||
|
||||
// Gather the sizes of all rectangles we will need to pack
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||
@ -687,18 +687,18 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
// - dst_font->Sources is != from src which is our source configuration.
|
||||
ImFontConfig& src = atlas->Sources[src_i];
|
||||
ImFont* dst_font = src.DstFont;
|
||||
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent);
|
||||
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
const float font_off_x = cfg.GlyphOffset.x;
|
||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
const float font_off_x = src.GlyphOffset.x;
|
||||
const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
@ -724,7 +724,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
|
||||
dst_font->AddGlyph(&src, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
|
||||
|
||||
ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
|
||||
IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);
|
||||
|
Loading…
x
Reference in New Issue
Block a user