mirror of
https://github.com/ocornut/imgui.git
synced 2026-07-07 01:49:41 +00:00
Compare commits
86 Commits
v1.90.2-do
...
v1.90.5-do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1db579d458 | ||
|
|
231cbee0fc | ||
|
|
4f9ba19e52 | ||
|
|
e7712ff103 | ||
|
|
f959c417fe | ||
|
|
0bf134a8e2 | ||
|
|
9a2b598ec1 | ||
|
|
d3c3514a59 | ||
|
|
25a492f330 | ||
|
|
9638c2839a | ||
|
|
742e53434f | ||
|
|
515b437c08 | ||
|
|
976dc23965 | ||
|
|
37b37fc2a3 | ||
|
|
5c5ae806aa | ||
|
|
cf4c10bef7 | ||
|
|
f0802287db | ||
|
|
29ff159f94 | ||
|
|
38ddfb24f0 | ||
|
|
8be48a44f7 | ||
|
|
085781f5ca | ||
|
|
868facff9d | ||
|
|
0a1f5b94e3 | ||
|
|
40df3db1a2 | ||
|
|
adcc3217c3 | ||
|
|
9d9ca37a84 | ||
|
|
da29b776ee | ||
|
|
3c435c0297 | ||
|
|
286cd5bd41 | ||
|
|
fc570ac922 | ||
|
|
fd75685fb0 | ||
|
|
65dc67f63c | ||
|
|
6b7358e9f3 | ||
|
|
fbf45ad149 | ||
|
|
1ff90c52d5 | ||
|
|
04f40014a6 | ||
|
|
c623669967 | ||
|
|
0573513d6d | ||
|
|
77dff5a735 | ||
|
|
4e8c43f6b7 | ||
|
|
44c7dfca03 | ||
|
|
1a487165b1 | ||
|
|
c3f8f4de25 | ||
|
|
9877941775 | ||
|
|
725f91922d | ||
|
|
e46d1e69ac | ||
|
|
c6aa051629 | ||
|
|
277ae93c41 | ||
|
|
f5be90523d | ||
|
|
13d91ff918 | ||
|
|
34965cf23a | ||
|
|
659fb41d0a | ||
|
|
198c38f0b1 | ||
|
|
3b6d924acd | ||
|
|
2b662b1ab9 | ||
|
|
d3f1a7165c | ||
|
|
e78ce72eb6 | ||
|
|
014e0ac8c9 | ||
|
|
c16043c1d5 | ||
|
|
405e54ebd5 | ||
|
|
6655ab2e43 | ||
|
|
9159cd7b4a | ||
|
|
ccc5347e45 | ||
|
|
8a14b71f22 | ||
|
|
b19a4c5f2b | ||
|
|
8048b52498 | ||
|
|
c66a1e7d51 | ||
|
|
d79514c407 | ||
|
|
5b6f03213d | ||
|
|
f80e65a406 | ||
|
|
829f45df99 | ||
|
|
3cc37170ca | ||
|
|
891b81fc5d | ||
|
|
262e30e300 | ||
|
|
9dfa2397de | ||
|
|
d15e4100b8 | ||
|
|
f966da1f8f | ||
|
|
bf1c96d4fa | ||
|
|
fd8d6dc5d1 | ||
|
|
e0ba0d0433 | ||
|
|
11d73f03ee | ||
|
|
89019319dd | ||
|
|
1d6f0cea0e | ||
|
|
3af739a2d1 | ||
|
|
2af01baffd | ||
|
|
915c6393ad |
@@ -16,7 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 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-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 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-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 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-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 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-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||
@@ -330,6 +331,24 @@ void ImGui_ImplDX9_Shutdown()
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
|
||||
{
|
||||
IDirect3D9* pd3d = nullptr;
|
||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||
return false;
|
||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||
D3DDISPLAYMODE mode = {};
|
||||
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||
{
|
||||
pd3d->Release();
|
||||
return false;
|
||||
}
|
||||
// Font texture should support linear filter, color blend and write to render-target
|
||||
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||
pd3d->Release();
|
||||
return support;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
@@ -341,18 +360,21 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (io.Fonts->TexPixelsUseColors)
|
||||
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
{
|
||||
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
||||
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
||||
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
||||
pixels = (unsigned char*)dst_start;
|
||||
}
|
||||
#else
|
||||
const bool rgba_support = false;
|
||||
#endif
|
||||
|
||||
// Upload texture to graphics system
|
||||
bd->FontTexture = nullptr;
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, rgba_support ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
return false;
|
||||
D3DLOCKED_RECT tex_locked_rect;
|
||||
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
||||
@@ -365,7 +387,7 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
||||
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (io.Fonts->TexPixelsUseColors)
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
ImGui::MemFree(pixels);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// 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.
|
||||
@@ -24,7 +23,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
|
||||
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
|
||||
@@ -581,7 +580,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
#ifndef __EMSCRIPTEN__
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
#endif
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
#endif
|
||||
|
||||
@@ -748,7 +747,8 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag.
|
||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag (since we implement hit via our WndProc hook)
|
||||
// On other platforms we rely on the library fallbacking to its own search when reporting a viewport with _NoInputs flag.
|
||||
// - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
@@ -756,12 +756,12 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
// - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
// FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
|
||||
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH
|
||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
||||
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
|
||||
#endif
|
||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input)
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED))
|
||||
mouse_viewport_id = viewport->ID;
|
||||
#else
|
||||
// We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse.
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 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).
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink.
|
||||
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
|
||||
// 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// - [ ] Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// - [ ] Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// 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.
|
||||
@@ -31,7 +33,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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).
|
||||
@@ -571,7 +573,6 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
static void ImGui_ImplOSX_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
return;
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -24,7 +25,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-02-14: Inputs: Handle gamepad disconnection. Added ImGui_ImplSDL2_SetGamepadMode().
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
|
||||
@@ -116,19 +118,26 @@ static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
||||
// SDL Data
|
||||
struct ImGui_ImplSDL2_Data
|
||||
{
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* LastMouseCursor;
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
// Mouse handling
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* MouseLastCursor;
|
||||
int MouseLastLeaveFrame;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
|
||||
// Gamepad handling
|
||||
ImVector<SDL_GameController*> Gamepads;
|
||||
ImGui_ImplSDL2_GamepadMode GamepadMode;
|
||||
bool WantUpdateGamepadsList;
|
||||
|
||||
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -405,10 +414,10 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
if (window_event == SDL_WINDOWEVENT_ENTER)
|
||||
{
|
||||
bd->MouseWindowID = event->window.windowID;
|
||||
bd->PendingMouseLeaveFrame = 0;
|
||||
bd->MouseLastLeaveFrame = 0;
|
||||
}
|
||||
if (window_event == SDL_WINDOWEVENT_LEAVE)
|
||||
bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
io.AddFocusEvent(true);
|
||||
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
@@ -426,6 +435,12 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
{
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -473,6 +488,10 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
io.ClipboardUserData = nullptr;
|
||||
io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData;
|
||||
|
||||
// Gamepad handling
|
||||
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
|
||||
// Load mouse cursors
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
@@ -569,6 +588,8 @@ bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_CloseGamepads();
|
||||
|
||||
void ImGui_ImplSDL2_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
@@ -581,7 +602,7 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
SDL_FreeCursor(bd->MouseCursors[cursor_n]);
|
||||
bd->LastMouseCursor = nullptr;
|
||||
ImGui_ImplSDL2_CloseGamepads();
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
@@ -670,59 +691,118 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
|
||||
{
|
||||
// Show OS mouse cursor
|
||||
SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||
if (bd->LastMouseCursor != expected_cursor)
|
||||
if (bd->MouseLastCursor != expected_cursor)
|
||||
{
|
||||
SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
|
||||
bd->LastMouseCursor = expected_cursor;
|
||||
bd->MouseLastCursor = expected_cursor;
|
||||
}
|
||||
SDL_ShowCursor(SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_CloseGamepads()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
if (bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
|
||||
for (SDL_GameController* gamepad : bd->Gamepads)
|
||||
SDL_GameControllerClose(gamepad);
|
||||
bd->Gamepads.resize(0);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array, int manual_gamepads_count)
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGui_ImplSDL2_CloseGamepads();
|
||||
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
else
|
||||
{
|
||||
IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
}
|
||||
bd->GamepadMode = mode;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_UpdateGamepadButton(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerButton button_no)
|
||||
{
|
||||
bool merged_value = false;
|
||||
for (SDL_GameController* gamepad : bd->Gamepads)
|
||||
merged_value |= SDL_GameControllerGetButton(gamepad, button_no) != 0;
|
||||
io.AddKeyEvent(key, merged_value);
|
||||
}
|
||||
|
||||
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
|
||||
static void ImGui_ImplSDL2_UpdateGamepadAnalog(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerAxis axis_no, float v0, float v1)
|
||||
{
|
||||
float merged_value = 0.0f;
|
||||
for (SDL_GameController* gamepad : bd->Gamepads)
|
||||
{
|
||||
float vn = Saturate((float)(SDL_GameControllerGetAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
|
||||
if (merged_value < vn)
|
||||
merged_value = vn;
|
||||
}
|
||||
io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
return;
|
||||
|
||||
// Get gamepad
|
||||
// Update list of controller(s) to use
|
||||
if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
|
||||
{
|
||||
ImGui_ImplSDL2_CloseGamepads();
|
||||
int joystick_count = SDL_NumJoysticks();
|
||||
for (int n = 0; n < joystick_count; n++)
|
||||
if (SDL_IsGameController(n))
|
||||
if (SDL_GameController* gamepad = SDL_GameControllerOpen(n))
|
||||
{
|
||||
bd->Gamepads.push_back(gamepad);
|
||||
if (bd->GamepadMode == ImGui_ImplSDL2_GamepadMode_AutoFirst)
|
||||
break;
|
||||
}
|
||||
bd->WantUpdateGamepadsList = false;
|
||||
}
|
||||
|
||||
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
SDL_GameController* game_controller = SDL_GameControllerOpen(0);
|
||||
if (!game_controller)
|
||||
if (bd->Gamepads.Size == 0)
|
||||
return;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); }
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||
}
|
||||
|
||||
// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has).
|
||||
@@ -791,10 +871,10 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
|
||||
if (bd->MouseLastLeaveFrame && bd->MouseLastLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
|
||||
{
|
||||
bd->MouseWindowID = 0;
|
||||
bd->PendingMouseLeaveFrame = 0;
|
||||
bd->MouseLastLeaveFrame = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -27,6 +28,7 @@
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
struct _SDL_GameController;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
@@ -39,8 +41,9 @@ IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
static inline void ImGui_ImplSDL2_NewFrame(SDL_Window*) { ImGui_ImplSDL2_NewFrame(); } // 1.84: removed unnecessary parameter
|
||||
#endif
|
||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -24,7 +25,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-02-13: Inputs: Fixed gamepad support. Handle gamepad disconnection. Added ImGui_ImplSDL3_SetGamepadMode().
|
||||
// 2023-11-13: Updated for recent SDL3 API changes.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-05-04: Fixed build on Emscripten/iOS/Android. (#6391)
|
||||
@@ -64,19 +66,26 @@
|
||||
// SDL Data
|
||||
struct ImGui_ImplSDL3_Data
|
||||
{
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* LastMouseCursor;
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
// Mouse handling
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* MouseLastCursor;
|
||||
int MousePendingLeaveFrame;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
|
||||
// Gamepad handling
|
||||
ImVector<SDL_Gamepad*> Gamepads;
|
||||
ImGui_ImplSDL3_GamepadMode GamepadMode;
|
||||
bool WantUpdateGamepadsList;
|
||||
|
||||
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -339,7 +348,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
{
|
||||
bd->MouseWindowID = event->window.windowID;
|
||||
bd->PendingMouseLeaveFrame = 0;
|
||||
bd->MousePendingLeaveFrame = 0;
|
||||
return true;
|
||||
}
|
||||
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
|
||||
@@ -348,7 +357,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
// FIXME: Unconfirmed whether this is still needed with SDL3.
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
{
|
||||
bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
bd->MousePendingLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
@@ -371,6 +380,12 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
{
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -430,6 +445,10 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
io.ClipboardUserData = nullptr;
|
||||
io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData;
|
||||
|
||||
// Gamepad handling
|
||||
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
|
||||
// Load mouse cursors
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
@@ -504,6 +523,8 @@ bool ImGui_ImplSDL3_InitForOther(SDL_Window* window)
|
||||
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_CloseGamepads();
|
||||
|
||||
void ImGui_ImplSDL3_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
@@ -516,7 +537,7 @@ void ImGui_ImplSDL3_Shutdown()
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
SDL_DestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
bd->LastMouseCursor = nullptr;
|
||||
ImGui_ImplSDL3_CloseGamepads();
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
@@ -605,59 +626,119 @@ static void ImGui_ImplSDL3_UpdateMouseCursor()
|
||||
{
|
||||
// Show OS mouse cursor
|
||||
SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||
if (bd->LastMouseCursor != expected_cursor)
|
||||
if (bd->MouseLastCursor != expected_cursor)
|
||||
{
|
||||
SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
|
||||
bd->LastMouseCursor = expected_cursor;
|
||||
bd->MouseLastCursor = expected_cursor;
|
||||
}
|
||||
SDL_ShowCursor();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_CloseGamepads()
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
if (bd->GamepadMode != ImGui_ImplSDL3_GamepadMode_Manual)
|
||||
for (SDL_Gamepad* gamepad : bd->Gamepads)
|
||||
SDL_CloseGamepad(gamepad);
|
||||
bd->Gamepads.resize(0);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array, int manual_gamepads_count)
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
ImGui_ImplSDL3_CloseGamepads();
|
||||
if (mode == ImGui_ImplSDL3_GamepadMode_Manual)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
else
|
||||
{
|
||||
IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
}
|
||||
bd->GamepadMode = mode;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_UpdateGamepadButton(ImGui_ImplSDL3_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GamepadButton button_no)
|
||||
{
|
||||
bool merged_value = false;
|
||||
for (SDL_Gamepad* gamepad : bd->Gamepads)
|
||||
merged_value |= SDL_GetGamepadButton(gamepad, button_no) != 0;
|
||||
io.AddKeyEvent(key, merged_value);
|
||||
}
|
||||
|
||||
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
|
||||
static void ImGui_ImplSDL3_UpdateGamepadAnalog(ImGui_ImplSDL3_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GamepadAxis axis_no, float v0, float v1)
|
||||
{
|
||||
float merged_value = 0.0f;
|
||||
for (SDL_Gamepad* gamepad : bd->Gamepads)
|
||||
{
|
||||
float vn = Saturate((float)(SDL_GetGamepadAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
|
||||
if (merged_value < vn)
|
||||
merged_value = vn;
|
||||
}
|
||||
io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
return;
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
|
||||
// Get gamepad
|
||||
// Update list of gamepads to use
|
||||
if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL3_GamepadMode_Manual)
|
||||
{
|
||||
ImGui_ImplSDL3_CloseGamepads();
|
||||
int sdl_gamepads_count = 0;
|
||||
SDL_JoystickID* sdl_gamepads = SDL_GetGamepads(&sdl_gamepads_count);
|
||||
for (int n = 0; n < sdl_gamepads_count; n++)
|
||||
if (SDL_Gamepad* gamepad = SDL_OpenGamepad(sdl_gamepads[n]))
|
||||
{
|
||||
bd->Gamepads.push_back(gamepad);
|
||||
if (bd->GamepadMode == ImGui_ImplSDL3_GamepadMode_AutoFirst)
|
||||
break;
|
||||
}
|
||||
SDL_free(sdl_gamepads);
|
||||
bd->WantUpdateGamepadsList = false;
|
||||
}
|
||||
|
||||
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
SDL_Gamepad* gamepad = SDL_OpenGamepad(0);
|
||||
if (!gamepad)
|
||||
if (bd->Gamepads.Size == 0)
|
||||
return;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GetGamepadButton(gamepad, BUTTON_NO) != 0); }
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GetGamepadAxis(gamepad, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, SDL_GAMEPAD_BUTTON_START);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, SDL_GAMEPAD_BUTTON_BACK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_GAMEPAD_BUTTON_WEST); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_GAMEPAD_BUTTON_EAST); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_GAMEPAD_BUTTON_NORTH); // Xbox Y, PS Triangle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_GAMEPAD_BUTTON_SOUTH); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_GAMEPAD_BUTTON_DPAD_UP);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0.0f, 32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0.0f, 32767);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, SDL_GAMEPAD_BUTTON_LEFT_STICK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, SDL_GAMEPAD_BUTTON_RIGHT_STICK);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_GAMEPAD_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_GAMEPAD_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_GAMEPAD_AXIS_LEFTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_GAMEPAD_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_GAMEPAD_AXIS_RIGHTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_GAMEPAD_AXIS_RIGHTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_GAMEPAD_AXIS_RIGHTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
const int thumb_dead_zone = 8000; // SDL_gamepad.h suggests using this value.
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart, SDL_GAMEPAD_BUTTON_START);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack, SDL_GAMEPAD_BUTTON_BACK);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft, SDL_GAMEPAD_BUTTON_WEST); // Xbox X, PS Square
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight, SDL_GAMEPAD_BUTTON_EAST); // Xbox B, PS Circle
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp, SDL_GAMEPAD_BUTTON_NORTH); // Xbox Y, PS Triangle
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown, SDL_GAMEPAD_BUTTON_SOUTH); // Xbox A, PS Cross
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp, SDL_GAMEPAD_BUTTON_DPAD_UP);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0.0f, 32767);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0.0f, 32767);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3, SDL_GAMEPAD_BUTTON_LEFT_STICK);
|
||||
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3, SDL_GAMEPAD_BUTTON_RIGHT_STICK);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft, SDL_GAMEPAD_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_GAMEPAD_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp, SDL_GAMEPAD_AXIS_LEFTY, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown, SDL_GAMEPAD_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft, SDL_GAMEPAD_AXIS_RIGHTX, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_GAMEPAD_AXIS_RIGHTX, +thumb_dead_zone, +32767);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp, SDL_GAMEPAD_AXIS_RIGHTY, -thumb_dead_zone, -32768);
|
||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_UpdateMonitors()
|
||||
@@ -719,10 +800,10 @@ void ImGui_ImplSDL3_NewFrame()
|
||||
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
|
||||
if (bd->MousePendingLeaveFrame && bd->MousePendingLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
|
||||
{
|
||||
bd->MouseWindowID = 0;
|
||||
bd->PendingMouseLeaveFrame = 0;
|
||||
bd->MousePendingLeaveFrame = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -28,6 +29,7 @@
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
struct SDL_Gamepad;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
@@ -40,4 +42,9 @@ IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
|
||||
// 2023-05-30: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
@@ -131,10 +132,12 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data)
|
||||
struct BackupSDLRendererState
|
||||
{
|
||||
SDL_Rect Viewport;
|
||||
bool ViewportEnabled;
|
||||
bool ClipEnabled;
|
||||
SDL_Rect ClipRect;
|
||||
};
|
||||
BackupSDLRendererState old = {};
|
||||
old.ViewportEnabled = SDL_RenderViewportSet(bd->SDLRenderer) == SDL_TRUE;
|
||||
old.ClipEnabled = SDL_RenderClipEnabled(bd->SDLRenderer) == SDL_TRUE;
|
||||
SDL_GetRenderViewport(bd->SDLRenderer, &old.Viewport);
|
||||
SDL_GetRenderClipRect(bd->SDLRenderer, &old.ClipRect);
|
||||
@@ -180,11 +183,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
||||
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
||||
#if SDL_VERSION_ATLEAST(2,0,19)
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
||||
#else
|
||||
const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
|
||||
#endif
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
@@ -199,7 +198,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_SetRenderViewport(bd->SDLRenderer, &old.Viewport);
|
||||
SDL_SetRenderViewport(bd->SDLRenderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
||||
SDL_SetRenderClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,12 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering.
|
||||
// 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure.
|
||||
// 2024-01-19: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by allocating one extra semaphore than in-flight frames. (#7236)
|
||||
// 2024-01-11: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size (#3957). Fixed MinAllocationSize handing (#7189).
|
||||
// 2024-01-03: Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous "best practice" validation layer. (#7189, #4238)
|
||||
// 2024-01-03: Vulkan: Stoped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT as we don't reset them.
|
||||
// 2024-01-03: Vulkan: Stopped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT as we don't reset them.
|
||||
// 2023-11-29: Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs vkDestroyCommandPool(). (#7075)
|
||||
// 2023-11-10: *BREAKING CHANGE*: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own command-buffer to upload fonts.
|
||||
// *BREAKING CHANGE*: Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary as we create and destroy those objects in the backend.
|
||||
@@ -194,8 +196,7 @@ IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||
#undef IMGUI_VULKAN_FUNC_DEF
|
||||
#endif // VK_NO_PROTOTYPES
|
||||
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
|
||||
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
||||
#endif
|
||||
@@ -237,13 +238,11 @@ struct ImGui_ImplVulkan_ViewportData
|
||||
struct ImGui_ImplVulkan_Data
|
||||
{
|
||||
ImGui_ImplVulkan_InitInfo VulkanInitInfo;
|
||||
VkRenderPass RenderPass;
|
||||
VkDeviceSize BufferMemoryAlignment;
|
||||
VkPipelineCreateFlags PipelineCreateFlags;
|
||||
VkDescriptorSetLayout DescriptorSetLayout;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkPipeline Pipeline;
|
||||
uint32_t Subpass;
|
||||
VkShaderModule ShaderModuleVert;
|
||||
VkShaderModule ShaderModuleFrag;
|
||||
|
||||
@@ -981,13 +980,11 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
|
||||
info.subpass = subpass;
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {};
|
||||
pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
|
||||
pipelineRenderingCreateInfo.colorAttachmentCount = 1;
|
||||
pipelineRenderingCreateInfo.pColorAttachmentFormats = &bd->VulkanInitInfo.ColorAttachmentFormat;
|
||||
if (bd->VulkanInitInfo.UseDynamicRendering)
|
||||
{
|
||||
info.pNext = &pipelineRenderingCreateInfo;
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be NULL");
|
||||
info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo;
|
||||
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
|
||||
}
|
||||
#endif
|
||||
@@ -1052,7 +1049,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, bd->RenderPass, v->MSAASamples, &bd->Pipeline, bd->Subpass);
|
||||
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, &bd->Pipeline, v->Subpass);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1102,7 +1099,7 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
|
||||
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!");
|
||||
|
||||
@@ -1138,11 +1135,9 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
IM_ASSERT(info->MinImageCount >= 2);
|
||||
IM_ASSERT(info->ImageCount >= info->MinImageCount);
|
||||
if (info->UseDynamicRendering == false)
|
||||
IM_ASSERT(render_pass != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->RenderPass != VK_NULL_HANDLE);
|
||||
|
||||
bd->VulkanInitInfo = *info;
|
||||
bd->RenderPass = render_pass;
|
||||
bd->Subpass = info->Subpass;
|
||||
|
||||
ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
|
||||
@@ -1538,7 +1533,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
|
||||
// We do not create a pipeline by default as this is also used by examples' main.cpp,
|
||||
// but secondary viewport in multi-viewport mode may want to create one with:
|
||||
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, bd->Subpass);
|
||||
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, v->Subpass);
|
||||
}
|
||||
|
||||
// Create The Image Views
|
||||
@@ -1672,13 +1667,17 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
||||
}
|
||||
|
||||
// Select Surface Format
|
||||
const VkFormat requestSurfaceImageFormat[] = {
|
||||
#if defined(IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING)
|
||||
v->UseDynamicRendering && v->ColorAttachmentFormat ? v->ColorAttachmentFormat : VK_FORMAT_B8G8R8A8_UNORM,
|
||||
ImVector<VkFormat> requestSurfaceImageFormats;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
for (uint32_t n = 0; n < v->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
|
||||
requestSurfaceImageFormats.push_back(v->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);
|
||||
#endif
|
||||
VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||
const VkFormat defaultFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||
for (VkFormat format : defaultFormats)
|
||||
requestSurfaceImageFormats.push_back(format);
|
||||
|
||||
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormats.Data, (size_t)requestSurfaceImageFormats.Size, requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
// FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1)
|
||||
|
||||
@@ -53,8 +53,14 @@
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
@@ -63,25 +69,31 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
||||
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;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
uint32_t Subpass;
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
|
||||
|
||||
// Dynamic Rendering (Optional)
|
||||
bool UseDynamicRendering; // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
VkFormat ColorAttachmentFormat; // Required for dynamic rendering
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// Allocation, Debugging
|
||||
// (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.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
|
||||
@@ -34,7 +34,7 @@ struct ImGui_ImplWGPU_InitInfo
|
||||
ImGui_ImplWGPU_InitInfo()
|
||||
{
|
||||
PipelineMultisampleState.count = 1;
|
||||
PipelineMultisampleState.mask = -1u;
|
||||
PipelineMultisampleState.mask = UINT32_MAX;
|
||||
PipelineMultisampleState.alphaToCoverageEnabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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).
|
||||
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||
@@ -1067,10 +1067,20 @@ static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
|
||||
// ShowParent() also brings parent to front, which is not always desirable,
|
||||
// so we temporarily disable parenting. (#7354)
|
||||
if (vd->HwndParent != NULL)
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)nullptr);
|
||||
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA);
|
||||
else
|
||||
::ShowWindow(vd->Hwnd, SW_SHOW);
|
||||
|
||||
// Restore
|
||||
if (vd->HwndParent != NULL)
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
||||
|
||||
@@ -36,7 +36,143 @@ HOW TO UPDATE?
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.2 (Released 2024-01-09)
|
||||
VERSION 1.90.5 (Released 2024-04-11)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.5
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- More formally obsoleted GetKeyIndex() when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is set.
|
||||
It has been unnecessary and a no-op since 1.87 (it returns the same value as passed
|
||||
when used with a 1.87+ backend using io.AddKeyEvent() function). (#4921)
|
||||
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) --> IsKeyPressed(ImGuiKey_XXX)
|
||||
- ImDrawList: Merged the radius_x/radius_y parameters in AddEllipse(), AddEllipseFilled()
|
||||
and PathEllipticalArcTo() into a single ImVec2 parameter. Exceptionally, because those
|
||||
functions were added recently in 1.90, we are not adding inline redirection functions.
|
||||
The transition is easy and should affect few users. (#2743, #7417) [@cfillion]
|
||||
|
||||
Other changes:
|
||||
|
||||
- Windows: Scrollbar visibility decision uses current size when both size and contents
|
||||
size are submitted by API. (#7252)
|
||||
- Windows: Double-click to collapse may be disabled via key-ownership mechanism. (#7369)
|
||||
- Windows: BeginChild(): Extend outer resize borders to the edges when there are no corner
|
||||
grips. Essentially affects resizable child windows. (#7440, #1710) [@cfillion]
|
||||
- Windows: BeginChild(): Resizing logic for child windows evaluates whether per-axis clamping
|
||||
should be applied based on parent scrollbars, not child scrollbars. (#7440, #1710) [@cfillion]
|
||||
Adjust those resizing limits to match window padding rather than inner clipping rectangle.
|
||||
- Tables: Fixed auto-width columns when using synced-instances of same table, width of
|
||||
one instance would bleed into next one instead of sharing their widths. (#7218)
|
||||
- Tables: Angled headers: fixed border hit box extending beyond when used within
|
||||
non-scrollable tables. (#7416) [@cfillion]
|
||||
- Tables: Angled headers: fixed borders not moving back up after TableAngleHeadersRow()
|
||||
stops being called. (#7416) [@cfillion]
|
||||
- Tables: Angled headers: rounding header size to nearest integers, fixes some issues
|
||||
when using clipper.
|
||||
- Menus, Popups: Fixed an issue where sibling menu popups re-opening in successive
|
||||
frames would erroneously close the window. While it is technically a popup issue
|
||||
it would generally manifest when fast moving the mouse bottom to top in a sub-menu.
|
||||
(#7325, #7287, #7063)
|
||||
- ProgressBar: Fixed passing fraction==NaN from leading to a crash. (#7451)
|
||||
- ListBox: Fixed text-baseline offset when using SameLine()+Text() after a labeled ListBox().
|
||||
- Drags, Sliders, Inputs: Fixed io.PlatformLocaleDecimalPoint decimal point localization
|
||||
feature not working regression from 1.90.1. (#7389, #6719, #2278) [@GamingMinds-DanielC]
|
||||
- Style: Added ImGuiStyleVar_TabBorderSize, ImGuiStyleVar_TableAngledHeadersAngle for
|
||||
consistency. (#7411) [@cfillion]
|
||||
- DrawList: Added AddConcavePolyFilled(), PathFillConcave() concave filling. (#760) [@thedmd]
|
||||
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.
|
||||
- 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,
|
||||
to increase its search rank.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Backends: Win32: made it so that an appearing viewport showing up doesn't bring
|
||||
its parent to front. (#7354)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.4 (Released 2024-02-22)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.4
|
||||
|
||||
Other changes:
|
||||
|
||||
- Nav: Fixed SetKeyboardFocusHere() or programmatic tabbing API from not working on
|
||||
windows with the ImGuiWindowFlags_NoNavInputs flag (regression in 1.90.2, which
|
||||
among other things broke imgui_memory_editor).
|
||||
- Menus, Popups: Fixed an issue where hovering a parent-menu upward would
|
||||
erroneously close the window. (#7325, #7287, #7063)
|
||||
- Popups: Fixed resizable popup minimum size being too small. Standardized minimum
|
||||
size logic. (#7329).
|
||||
- Modals: Temporary changes of ImGuiCol_ModalWindowDimBg are properly handled by
|
||||
BeginPopupModal(). (#7340)
|
||||
- Tables: Angled headers: fixed support for multi-line labels. (#6917)
|
||||
- Tables: Angled headers: various fixes to accurately handle CellPadding changes. (#6917)
|
||||
- Tables: Angled headers: properly registers horizontal component of angled headers
|
||||
for auto-resizing of columns. (#6917)
|
||||
- Tables: Angled headers: fixed TableAngledHeadersRow() incorrect background fill
|
||||
drawn too low, particularly visible with tables that have no scrolling. (#6917)
|
||||
- ProgressBar: Fixed a minor tessellation issue when rendering rounded progress bars,
|
||||
where in some situations the rounded section wouldn't follow regular tessellation rules.
|
||||
- Debug Tools: Item Picker: Promoted ImGui::DebugStartItemPicker() to public API. (#2673)
|
||||
- Debug Tools: Item Picker: Menu entry visible in Demo->Tools but greyed out unless
|
||||
io.ConfigDebugIsDebuggerPresent is set. (#2673)
|
||||
- Misc: Added optional alpha multiplier parameter to GetColorU32(ImU32) variant.
|
||||
- Demo: Custom Rendering: better demonstrate PathArcTo(), PathBezierQuadraticCurveTo(),
|
||||
PathBezierCubicCurveTo(), PathStroke(), PathFillConvex() functions.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Backends: GLFW: enable ImGuiBackendFlags_HasMouseHoveredViewport support with GLFW 3.3.x,
|
||||
as required specs for it was relaxed in 1.87. This enable better viewport hovering detection
|
||||
without GLFW 3.4's GLFW_MOUSE_PASSTHROUGH, with less reliance on dear imgui's own heuristic
|
||||
of platform windows order. (#7316)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.3 (Released 2024-02-14)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.3
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Backends: SDL2: Removed obsolete ImGui_ImplSDL2_NewFrame(SDL_Window*) signature which
|
||||
was obsoleted in 1.84. Calling ImGui_ImplSDL2_NewFrame() is fine.
|
||||
- Backends: Vulkan: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to
|
||||
ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering. (#7308) [@shawnhatori]
|
||||
- Backends: Vulkan: Using dynamic rendering now require filling the PipelineRenderingCreateInfo
|
||||
structure in ImGui_ImplVulkan_InitInfo, allowing to configure color/depth/stencil formats.
|
||||
Removed ColorAttachmentFormat field previously provided for dynamic rendering.
|
||||
(#7166, #6855, #5446, #5037) [@shawnhatori]
|
||||
|
||||
Other changes:
|
||||
|
||||
- Menus, Popups: Fixed menus and popups with ChildWindow flag erroneously not displaying
|
||||
a scrollbar when contents is over parent viewport size. (#7287, #7063) [@ZingBallyhoo]
|
||||
- Backends: SDL2, SDL3: Handle gamepad disconnection + fixed increasing gamepad reference
|
||||
counter continuously. Added support for multiple simultaneous gamepads.
|
||||
Added ImGui_ImplSDL2_SetGamepadMode()) function to select whether to automatically pick
|
||||
first available gamepad, all gamepads, or specific gamepads.
|
||||
(#3884, #6559, #6890, #7180) [@ocornut, @lethal-guitar, @wn2000, @bog-dan-ro]
|
||||
- Backends: SDL3: Fixed gamepad handling. (#7180) [@bog-dan-ro]
|
||||
- Backends: SDLRenderer3: query newly added SDL_RenderViewportSet() to not restore
|
||||
a wrong viewport if none was initially set.
|
||||
- Backends: DirectX9: Using RGBA format when allowed by the driver to avoid CPU side
|
||||
conversion. (#6575) [@Demonese]
|
||||
- Internals: Fixed ImFileOpen not working before context is created, preventing creation
|
||||
of a font atlas before main context creation. (#7314, #7315) [@PathogenDavid, @ocornut]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.2 (Released 2024-02-09)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.2
|
||||
@@ -209,7 +345,7 @@ Docking+Viewports Branch:
|
||||
- Backends: DX12: Changed swapchain scaling mode to DXGI_SCALING_NONE to reduce artifacts as
|
||||
queued frames aren't synchronized with platform window resizes. (#7152, #7153) [@SuperWangKai]
|
||||
- Backends: OSX: Fixed monitor and window position by correctly transforming Y origin on multi-viewports
|
||||
multi-monitor setups. (#7028, #7101, #6009, #6432) [@dmirty-kuzmenko, @734vin]
|
||||
multi-monitor setups. (#7028, #7101, #6009, #6432) [@dmirty-kuzmenko, @734vin]
|
||||
- Backends: OSX: Fixed IME position in multi-monitor multi-viewports setups. (#7028) [@734vin]
|
||||
|
||||
|
||||
@@ -332,7 +468,7 @@ Other changes:
|
||||
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
|
||||
- Tables:
|
||||
- Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
|
||||
columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option.
|
||||
columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option. (#6917)
|
||||
- Added ImGuiTableFlags_HighlightHoveredColumn flag, currently highlighting column header.
|
||||
- Fixed an edge-case when no columns are visible + table scrollbar is visible + user
|
||||
code is always testing return value of TableSetColumnIndex() to coarse clip. With an active
|
||||
|
||||
@@ -58,7 +58,7 @@ Steps:
|
||||
- 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.
|
||||
|
||||
**Some unfortunate words of warning**
|
||||
- If you are involved in cheating schemes (e.g. DLL injection) for competitive online multiplayer games, please don't post here. We won't answer and you will be blocked. It doesn't matter if your question relates to said project. We've had too many of you and need to project our time and sanity.
|
||||
- If you are involved in cheating schemes (e.g. DLL injection) for competitive online multiplayer games, please don't post here. We won't answer and you will be blocked. It doesn't matter if your question relates to said project. We've had too many of you and need to protect our time and sanity.
|
||||
- Due to frequent abuse of this service from the aforementioned users, if your GitHub account is anonymous and was created five minutes ago please understand that your post will receive more scrutiny and incomplete questions will be harshly dismissed.
|
||||
|
||||
If you have been using Dear ImGui for a while or have been using C/C++ for several years or have demonstrated good behavior here, it is ok to not fulfill every item to the letter. Those are guidelines and experienced users or members of the community will know which information is useful in a given context.
|
||||
|
||||
@@ -621,7 +621,7 @@ You may take a look at:
|
||||
|
||||
- [Quotes](https://github.com/ocornut/imgui/wiki/Quotes)
|
||||
- [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui)
|
||||
- [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors)
|
||||
- [Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)
|
||||
- [Gallery](https://github.com/ocornut/imgui/issues/6897)
|
||||
|
||||
##### [Return to Index](#index)
|
||||
@@ -664,7 +664,7 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci
|
||||
# Q&A: Community
|
||||
|
||||
### Q: How can I help?
|
||||
- Businesses: please reach out to `omar AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance, or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people to work on this project.
|
||||
- Businesses: please reach out to `omar AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance, or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people to work on this project. Please see [Funding](https://github.com/ocornut/imgui/wiki/Funding) page.
|
||||
- Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md).
|
||||
- If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt), and see how you want to help and can help!
|
||||
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere, etc.
|
||||
|
||||
@@ -11,11 +11,11 @@ Dear ImGui
|
||||
|
||||
Businesses: support continued development and maintenance via invoiced sponsoring/support contracts:
|
||||
<br> _E-mail: contact @ dearimgui dot com_
|
||||
<br>Individuals: support continued development and maintenance [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). Also see [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) page.
|
||||
<br>Individuals: support continued development and maintenance [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). Also see [Funding](https://github.com/ocornut/imgui/wiki/Funding) page.
|
||||
|
||||
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Integration](#integration) |
|
||||
:----------------------------------------------------------: |
|
||||
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) - [Credits](#credits) - [License](#license) |
|
||||
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Languages bindings & frameworks backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||
|
||||
### The Pitch
|
||||
@@ -162,6 +162,8 @@ See: [Upcoming Changes](https://github.com/ocornut/imgui/wiki/Upcoming-Changes).
|
||||
|
||||
See: [Dear ImGui Test Engine + Test Suite](https://github.com/ocornut/imgui_test_engine) for Automation & Testing.
|
||||
|
||||
For the purposes of getting search engines to crawl the wiki, here's a link to the [Crawable Wiki](https://github-wiki-see.page/m/ocornut/imgui/wiki) (not for humans, [here's why](https://github-wiki-see.page/)).
|
||||
|
||||
Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). For ANY other questions, bug reports, requests, feedback, please post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully.
|
||||
|
||||
Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_).
|
||||
@@ -172,7 +174,7 @@ We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) (with
|
||||
|
||||
**Who uses Dear ImGui?**
|
||||
|
||||
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), and [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also, see the [Gallery Threads](https://github.com/ocornut/imgui/issues/6897)!
|
||||
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding), and [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also, see the [Gallery Threads](https://github.com/ocornut/imgui/issues/6897)!
|
||||
|
||||
How to help
|
||||
-----------
|
||||
@@ -182,13 +184,13 @@ How to help
|
||||
- See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues).
|
||||
- You may help with development and submit pull requests! 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 forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
|
||||
- Be a [sponsor](https://github.com/ocornut/imgui/wiki/Sponsors)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: omar AT dearimgui DOT com).
|
||||
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: omar AT dearimgui DOT com).
|
||||
|
||||
Sponsors
|
||||
--------
|
||||
|
||||
Ongoing Dear ImGui development is and has been financially supported by users and private sponsors.
|
||||
<BR>Please see the **[detailed list of current and past Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors)** for details.
|
||||
<BR>Please see the **[detailed list of current and past Dear ImGui funding supporters and sponsors](https://github.com/ocornut/imgui/wiki/Funding)** for details.
|
||||
<BR>From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
|
||||
|
||||
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
|
||||
@@ -205,7 +207,7 @@ Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or ind
|
||||
|
||||
Recurring contributors include Rokas Kupstys [@rokups](https://github.com/rokups) (2020-2022): a good portion of work on automation system and regression tests now available in [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine).
|
||||
|
||||
Sponsoring, maintenance/support contracts and other B2B transactions are hosted and handled by [Disco Hello](https://www.discohello.com).
|
||||
Maintenance/support contracts, sponsoring invoices and other B2B transactions are hosted and handled by [Disco Hello](https://www.discohello.com).
|
||||
|
||||
Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ int main(int, char**)
|
||||
ImGui::Render();
|
||||
|
||||
WGPURenderPassColorAttachment color_attachments = {};
|
||||
color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
|
||||
color_attachments.loadOp = WGPULoadOp_Clear;
|
||||
color_attachments.storeOp = WGPUStoreOp_Store;
|
||||
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
||||
|
||||
@@ -14,10 +14,10 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
|
||||
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
|
||||
LIBS += -L/usr/local/lib -L/opt/homebrew/lib
|
||||
LIBS += -L/usr/local/lib -L/opt/homebrew/lib -L/opt/local/lib
|
||||
LIBS += -lglfw
|
||||
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include -I/opt/local/include
|
||||
CXXFLAGS += -Wall -Wformat
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
|
||||
@@ -446,13 +446,14 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -446,13 +446,14 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
// 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.
|
||||
|
||||
307
imgui.cpp
307
imgui.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@@ -7,15 +7,19 @@
|
||||
// - Read top of imgui.cpp for more details, links and comments.
|
||||
|
||||
// Resources:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Homepage https://github.com/ocornut/imgui
|
||||
// - Releases & changelog https://github.com/ocornut/imgui/releases
|
||||
// - Gallery https://github.com/ocornut/imgui/issues/6897 (please post your screenshots/video there!)
|
||||
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
||||
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||||
// - Issues & support https://github.com/ocornut/imgui/issues
|
||||
// - Tests & Automation https://github.com/ocornut/imgui_test_engine
|
||||
// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md)
|
||||
// - Homepage ................... https://github.com/ocornut/imgui
|
||||
// - Releases & changelog ....... https://github.com/ocornut/imgui/releases
|
||||
// - Gallery .................... https://github.com/ocornut/imgui/issues/6897 (please post your screenshots/video there!)
|
||||
// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
||||
// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code)
|
||||
// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more)
|
||||
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines)
|
||||
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||||
// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools
|
||||
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
|
||||
// - Issues & support ........... https://github.com/ocornut/imgui/issues
|
||||
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
|
||||
|
||||
// For first-time users having issues compiling/linking/running/loading fonts:
|
||||
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
||||
@@ -26,7 +30,7 @@
|
||||
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
||||
// This library is free but needs your support to sustain development and maintenance.
|
||||
// Businesses: you can support continued development via B2B invoiced technical support, maintenance and sponsoring contracts.
|
||||
// PLEASE reach out at omar AT dearimgui DOT com. See https://github.com/ocornut/imgui/wiki/Sponsors
|
||||
// PLEASE reach out at omar AT dearimgui DOT com. See https://github.com/ocornut/imgui/wiki/Funding
|
||||
// Businesses: you can also purchase licenses for the Dear ImGui Automation/Test Engine.
|
||||
|
||||
// It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library.
|
||||
@@ -73,6 +77,7 @@ CODE
|
||||
// [SECTION] RENDER HELPERS
|
||||
// [SECTION] INITIALIZATION, SHUTDOWN
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] ID STACK
|
||||
// [SECTION] INPUTS
|
||||
// [SECTION] ERROR CHECKING
|
||||
// [SECTION] ITEM SUBMISSION
|
||||
@@ -433,6 +438,9 @@ CODE
|
||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
|
||||
- 2024/03/18 (1.90.5) - merged the radius_x/radius_y parameters in ImDrawList::AddEllipse(), AddEllipseFilled() and PathEllipticalArcTo() into a single ImVec2 parameter. Exceptionally, because those functions were added in 1.90, we are not adding inline redirection functions. The transition is easy and should affect few users. (#2743, #7417)
|
||||
- 2024/03/08 (1.90.5) - inputs: more formally obsoleted GetKeyIndex() when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is set. It has been unnecessary and a no-op since 1.87 (it returns the same value as passed when used with a 1.87+ backend using io.AddKeyEvent() function). (#4921)
|
||||
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
|
||||
- 2024/01/15 (1.90.2) - commented out obsolete ImGuiIO::ImeWindowHandle marked obsolete in 1.87, favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.
|
||||
- 2023/12/19 (1.90.1) - commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter.
|
||||
- 2023/11/06 (1.90.1) - removed CalcListClipping() marked obsolete in 1.86. Prefer using ImGuiListClipper which can return non-contiguous ranges.
|
||||
@@ -925,7 +933,7 @@ CODE
|
||||
Q: How can I easily use icons in my application?
|
||||
Q: How can I load multiple fonts?
|
||||
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
||||
>> See https://www.dearimgui.com/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md
|
||||
>> See https://www.dearimgui.com/faq and https://github.com/ocornut/imgui/blob/master/docs/FONTS.md
|
||||
|
||||
Q&A: Concerns
|
||||
=============
|
||||
@@ -943,7 +951,7 @@ CODE
|
||||
A: - Businesses: please reach out to "omar AT dearimgui DOT com" if you work in a place using Dear ImGui!
|
||||
We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts.
|
||||
This is among the most useful thing you can do for Dear ImGui. With increased funding, we sustain and grow work on this project.
|
||||
Also see https://github.com/ocornut/imgui/wiki/Sponsors
|
||||
>>> See https://github.com/ocornut/imgui/wiki/Funding
|
||||
- Businesses: you can also purchase licenses for the Dear ImGui Automation/Test Engine.
|
||||
- If you are experienced with Dear ImGui and C++, look at the GitHub issues, look at the Wiki, and see how you want to help and can help!
|
||||
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.
|
||||
@@ -1218,7 +1226,7 @@ ImGuiStyle::ImGuiStyle()
|
||||
FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested.
|
||||
ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
|
||||
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
|
||||
CellPadding = ImVec2(4,2); // Padding within a table cell. CellPadding.y may be altered between different rows.
|
||||
CellPadding = ImVec2(4,2); // Padding within a table cell. Cellpadding.x is locked for entire table. CellPadding.y may be altered between different rows.
|
||||
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
|
||||
IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
|
||||
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
||||
@@ -2121,12 +2129,18 @@ ImFileHandle ImFileOpen(const char* filename, const char* mode)
|
||||
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
|
||||
const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
|
||||
const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.TempBuffer.reserve((filename_wsize + mode_wsize) * sizeof(wchar_t));
|
||||
wchar_t* buf = (wchar_t*)(void*)g.TempBuffer.Data;
|
||||
::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize);
|
||||
return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
|
||||
|
||||
// Use stack buffer if possible, otherwise heap buffer. Sizes include zero terminator.
|
||||
// We don't rely on current ImGuiContext as this is implied to be a helper function which doesn't depend on it (see #7314).
|
||||
wchar_t local_temp_stack[FILENAME_MAX];
|
||||
ImVector<wchar_t> local_temp_heap;
|
||||
if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))
|
||||
local_temp_heap.resize(filename_wsize + mode_wsize);
|
||||
wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;
|
||||
wchar_t* mode_wbuf = filename_wbuf + filename_wsize;
|
||||
::MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_wbuf, filename_wsize);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_wbuf, mode_wsize);
|
||||
return ::_wfopen(filename_wbuf, mode_wbuf);
|
||||
#else
|
||||
return fopen(filename, mode);
|
||||
#endif
|
||||
@@ -3099,13 +3113,14 @@ const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx)
|
||||
return style.Colors[idx];
|
||||
}
|
||||
|
||||
ImU32 ImGui::GetColorU32(ImU32 col)
|
||||
ImU32 ImGui::GetColorU32(ImU32 col, float alpha_mul)
|
||||
{
|
||||
ImGuiStyle& style = GImGui->Style;
|
||||
if (style.Alpha >= 1.0f)
|
||||
alpha_mul *= style.Alpha;
|
||||
if (alpha_mul >= 1.0f)
|
||||
return col;
|
||||
ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
|
||||
a = (ImU32)(a * style.Alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range.
|
||||
a = (ImU32)(a * alpha_mul); // We don't need to clamp 0..255 because alpha is in 0..1 range.
|
||||
return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
|
||||
}
|
||||
|
||||
@@ -3179,7 +3194,9 @@ static const ImGuiDataVarInfo GStyleVarInfo[] =
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)},// ImGuiStyleVar_TableAngledHeadersAngle
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize
|
||||
@@ -3854,45 +3871,6 @@ ImGuiWindow::~ImGuiWindow()
|
||||
ColumnsStorage.clear_destruct();
|
||||
}
|
||||
|
||||
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
||||
return id;
|
||||
}
|
||||
|
||||
ImGuiID ImGuiWindow::GetID(const void* ptr)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
ImGuiID ImGuiWindow::GetID(int n)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
// This is only used in rare/specific situations to manufacture an ID out of nowhere.
|
||||
ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs);
|
||||
ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed);
|
||||
return id;
|
||||
}
|
||||
|
||||
static void SetCurrentWindow(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -5222,7 +5200,7 @@ static void ImGui::RenderDimmedBackgrounds()
|
||||
{
|
||||
// Draw dimming behind modal or a begin stack child, whichever comes first in draw order.
|
||||
ImGuiWindow* dim_behind_window = FindBottomMostVisibleWindowWithinBeginStack(modal_window);
|
||||
RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio));
|
||||
RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(modal_window->DC.ModalDimBgColor, g.DimBgRatio));
|
||||
viewports_already_dimmed[0] = modal_window->Viewport;
|
||||
}
|
||||
else if (dim_bg_for_window_list)
|
||||
@@ -5963,22 +5941,25 @@ static ImGuiWindow* GetWindowForTitleAndMenuHeight(ImGuiWindow* window)
|
||||
|
||||
static inline ImVec2 CalcWindowMinSize(ImGuiWindow* window)
|
||||
{
|
||||
// Popups, menus and childs bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups)
|
||||
// FIXME: the if/else could probably be removed, "reduce artifacts" section for all windows.
|
||||
// We give windows non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups)
|
||||
// FIXME: Essentially we want to restrict manual resizing to WindowMinSize+Decoration, and allow api resizing to be smaller.
|
||||
// Perhaps should tend further a neater test for this.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 size_min;
|
||||
if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_ChildWindow))
|
||||
if ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Popup))
|
||||
{
|
||||
size_min.x = (window->ChildFlags & ImGuiChildFlags_ResizeX) ? g.Style.WindowMinSize.x : 4.0f;
|
||||
size_min.y = (window->ChildFlags & ImGuiChildFlags_ResizeY) ? g.Style.WindowMinSize.y : 4.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
||||
size_min.x = ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) == 0) ? g.Style.WindowMinSize.x : 4.0f;
|
||||
size_min.y = ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) == 0) ? g.Style.WindowMinSize.y : 4.0f;
|
||||
size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
||||
}
|
||||
|
||||
// Reduce artifacts with very small windows
|
||||
ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
||||
size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f));
|
||||
return size_min;
|
||||
}
|
||||
|
||||
@@ -6048,7 +6029,7 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
|
||||
{
|
||||
// Maximum window size is determined by the viewport size or monitor size
|
||||
ImVec2 size_min = CalcWindowMinSize(window);
|
||||
ImVec2 size_max = (window->ViewportOwned || (window->Flags & ImGuiWindowFlags_ChildWindow)) ? ImVec2(FLT_MAX, FLT_MAX) : window->Viewport->WorkSize - style.DisplaySafeAreaPadding * 2.0f;
|
||||
ImVec2 size_max = (window->ViewportOwned || ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Popup))) ? ImVec2(FLT_MAX, FLT_MAX) : ImGui::GetMainViewport()->WorkSize - style.DisplaySafeAreaPadding * 2.0f;
|
||||
const int monitor_idx = window->ViewportAllowPlatformMonitorExtend;
|
||||
if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0)
|
||||
size_max = g.PlatformIO.Monitors[monitor_idx].WorkSize - style.DisplaySafeAreaPadding * 2.0f;
|
||||
@@ -6178,7 +6159,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
||||
|
||||
int ret_auto_fit_mask = 0x00;
|
||||
const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
|
||||
const float grip_hover_inner_size = (resize_grip_count > 0) ? IM_TRUNC(grip_draw_size * 0.75f) : 0.0f;
|
||||
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
||||
|
||||
ImRect clamp_rect = visibility_rect;
|
||||
@@ -6316,10 +6297,13 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
||||
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
||||
if (flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
|
||||
{
|
||||
if ((flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (flags & ImGuiWindowFlags_NoScrollbar))
|
||||
border_target.x = ImClamp(border_target.x, window->ParentWindow->InnerClipRect.Min.x, window->ParentWindow->InnerClipRect.Max.x);
|
||||
if (flags & ImGuiWindowFlags_NoScrollbar)
|
||||
border_target.y = ImClamp(border_target.y, window->ParentWindow->InnerClipRect.Min.y, window->ParentWindow->InnerClipRect.Max.y);
|
||||
ImGuiWindowFlags parent_flags = window->ParentWindow->Flags;
|
||||
ImRect border_limit_rect = window->ParentWindow->InnerRect;
|
||||
border_limit_rect.Expand(ImVec2(-ImMax(window->WindowPadding.x, window->WindowBorderSize), -ImMax(window->WindowPadding.y, window->WindowBorderSize)));
|
||||
if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar))
|
||||
border_target.x = ImClamp(border_target.x, border_limit_rect.Min.x, border_limit_rect.Max.x);
|
||||
if (parent_flags & ImGuiWindowFlags_NoScrollbar)
|
||||
border_target.y = ImClamp(border_target.y, border_limit_rect.Min.y, border_limit_rect.Max.y);
|
||||
}
|
||||
if (!ignore_resize)
|
||||
CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target);
|
||||
@@ -6869,7 +6853,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
PushFocusScope((flags & ImGuiWindowFlags_NavFlattened) ? g.CurrentFocusScopeId : window->ID);
|
||||
window->NavRootFocusScopeId = g.CurrentFocusScopeId;
|
||||
|
||||
// Add to popup stack
|
||||
// Add to popup stacks: update OpenPopupStack[] data, push to BeginPopupStack[]
|
||||
if (flags & ImGuiWindowFlags_Popup)
|
||||
{
|
||||
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
@@ -7032,8 +7016,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
|
||||
// Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible.
|
||||
// Those flags will be altered further down in the function depending on more conditions.
|
||||
bool use_current_size_for_scrollbar_x = window_just_created;
|
||||
bool use_current_size_for_scrollbar_y = window_just_created;
|
||||
if (window_size_x_set_by_api && window->ContentSizeExplicit.x != 0.0f)
|
||||
use_current_size_for_scrollbar_x = true;
|
||||
if (window_size_y_set_by_api && window->ContentSizeExplicit.y != 0.0f) // #7252
|
||||
use_current_size_for_scrollbar_y = true;
|
||||
|
||||
// Collapse window by double-clicking on title bar
|
||||
// At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
|
||||
@@ -7041,8 +7031,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
// We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar.
|
||||
ImRect title_bar_rect = window->TitleBarRect();
|
||||
if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseClickedCount[0] == 2)
|
||||
window->WantCollapseToggle = true;
|
||||
if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max))
|
||||
if (g.IO.MouseClickedCount[0] == 2 && GetKeyOwner(ImGuiKey_MouseLeft) == ImGuiKeyOwner_None)
|
||||
window->WantCollapseToggle = true;
|
||||
if (window->WantCollapseToggle)
|
||||
{
|
||||
window->Collapsed = !window->Collapsed;
|
||||
@@ -7229,7 +7220,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
int border_hovered = -1, border_held = -1;
|
||||
ImU32 resize_grip_col[4] = {};
|
||||
const int resize_grip_count = (window->Flags & ImGuiWindowFlags_ChildWindow) ? 0 : g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||
const int resize_grip_count = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) ? 0 : g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||
const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
if (handle_borders_and_resize_grips && !window->Collapsed)
|
||||
if (int auto_fit_mask = UpdateWindowManualResize(window, size_auto_fit, &border_hovered, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
||||
@@ -7446,6 +7437,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.TextWrapPos = -1.0f; // disabled
|
||||
window->DC.ItemWidthStack.resize(0);
|
||||
window->DC.TextWrapPosStack.resize(0);
|
||||
if (flags & ImGuiWindowFlags_Modal)
|
||||
window->DC.ModalDimBgColor = ColorConvertFloat4ToU32(GetStyleColorVec4(ImGuiCol_ModalWindowDimBg));
|
||||
|
||||
if (window->AutoFitFramesX > 0)
|
||||
window->AutoFitFramesX--;
|
||||
@@ -8573,6 +8566,69 @@ ImGuiStorage* ImGui::GetStateStorage()
|
||||
return window->DC.StateStorage;
|
||||
}
|
||||
|
||||
bool ImGui::IsRectVisible(const ImVec2& size)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
|
||||
}
|
||||
|
||||
bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ID STACK
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// This is one of the very rare legacy case where we use ImGuiWindow methods,
|
||||
// it should ideally be flattened at some point but it's been used a lots by widgets.
|
||||
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
ImGuiID ImGuiWindow::GetID(const void* ptr)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
ImGuiID ImGuiWindow::GetID(int n)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
ImGuiContext& g = *Ctx;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
// This is only used in rare/specific situations to manufacture an ID out of nowhere.
|
||||
ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
|
||||
{
|
||||
ImGuiID seed = IDStack.back();
|
||||
ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs);
|
||||
ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed);
|
||||
return id;
|
||||
}
|
||||
|
||||
void ImGui::PushID(const char* str_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -8610,8 +8666,10 @@ void ImGui::PushOverrideID(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
if (g.DebugHookIdInfo == id)
|
||||
DebugHookIdInfo(id, ImGuiDataType_ID, NULL, NULL);
|
||||
#endif
|
||||
window->IDStack.push_back(id);
|
||||
}
|
||||
|
||||
@@ -8621,18 +8679,22 @@ void ImGui::PushOverrideID(ImGuiID id)
|
||||
ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed)
|
||||
{
|
||||
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
ImGuiID ImGui::GetIDWithSeed(int n, ImGuiID seed)
|
||||
{
|
||||
ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.DebugHookIdInfo == id)
|
||||
DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -8661,19 +8723,6 @@ ImGuiID ImGui::GetID(const void* ptr_id)
|
||||
return window->GetID(ptr_id);
|
||||
}
|
||||
|
||||
bool ImGui::IsRectVisible(const ImVec2& size)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
|
||||
}
|
||||
|
||||
bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] INPUTS
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -9809,7 +9858,7 @@ void ImGui::SetNextFrameWantCaptureMouse(bool want_capture_mouse)
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
static const char* GetInputSourceName(ImGuiInputSource source)
|
||||
{
|
||||
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Clipboard" };
|
||||
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad" };
|
||||
IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT);
|
||||
return input_source_names[source];
|
||||
}
|
||||
@@ -11432,7 +11481,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
||||
popup_ref.PopupId = id;
|
||||
popup_ref.Window = NULL;
|
||||
popup_ref.BackupNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type).
|
||||
popup_ref.RestoreNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type).
|
||||
popup_ref.OpenFrameCount = g.FrameCount;
|
||||
popup_ref.OpenParentId = parent_window->IDStack.back();
|
||||
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
|
||||
@@ -11461,7 +11510,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||
else
|
||||
{
|
||||
// Reopen: close child popups if any, then flag popup for open/reopen (set position, focus, init navigation)
|
||||
ClosePopupToLevel(current_stack_size, false);
|
||||
ClosePopupToLevel(current_stack_size, true);
|
||||
g.OpenPopupStack.push_back(popup_ref);
|
||||
}
|
||||
|
||||
@@ -11481,6 +11530,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
|
||||
return;
|
||||
|
||||
// Don't close our own child popup windows.
|
||||
//IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupsOverWindow(\"%s\") restore_under=%d\n", ref_window ? ref_window->Name : "<NULL>", restore_focus_to_window_under_popup);
|
||||
int popup_count_to_keep = 0;
|
||||
if (ref_window)
|
||||
{
|
||||
@@ -11538,18 +11588,19 @@ void ImGui::ClosePopupsExceptModals()
|
||||
void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup);
|
||||
IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupToLevel(%d), restore_under=%d\n", remaining, restore_focus_to_window_under_popup);
|
||||
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
|
||||
|
||||
// Trim open popup stack
|
||||
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
|
||||
ImGuiWindow* popup_backup_nav_window = g.OpenPopupStack[remaining].BackupNavWindow;
|
||||
ImGuiPopupData prev_popup = g.OpenPopupStack[remaining];
|
||||
g.OpenPopupStack.resize(remaining);
|
||||
|
||||
if (restore_focus_to_window_under_popup)
|
||||
// Restore focus (unless popup window was not yet submitted, and didn't have a chance to take focus anyhow. See #7325 for an edge case)
|
||||
if (restore_focus_to_window_under_popup && prev_popup.Window)
|
||||
{
|
||||
ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window;
|
||||
if (focus_window && !focus_window->WasActive && popup_window)
|
||||
ImGuiWindow* popup_window = prev_popup.Window;
|
||||
ImGuiWindow* focus_window = (popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : prev_popup.RestoreNavWindow;
|
||||
if (focus_window && !focus_window->WasActive)
|
||||
FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback
|
||||
else
|
||||
FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None);
|
||||
@@ -12193,25 +12244,28 @@ static void ImGui::NavProcessItem()
|
||||
|
||||
// Process Move Request (scoring for navigation)
|
||||
// FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy)
|
||||
if (g.NavMoveScoringItems && (item_flags & ImGuiItemFlags_Disabled) == 0 && (window->Flags & ImGuiWindowFlags_NoNavInputs) == 0)
|
||||
if (g.NavMoveScoringItems && (item_flags & ImGuiItemFlags_Disabled) == 0)
|
||||
{
|
||||
const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0;
|
||||
if (is_tabbing)
|
||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi) || (window->Flags & ImGuiWindowFlags_NoNavInputs) == 0)
|
||||
{
|
||||
NavProcessItemForTabbingRequest(id, item_flags, g.NavMoveFlags);
|
||||
}
|
||||
else if (g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId))
|
||||
{
|
||||
ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
|
||||
if (NavScoreItem(result))
|
||||
NavApplyItemToResult(result);
|
||||
const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0;
|
||||
if (is_tabbing)
|
||||
{
|
||||
NavProcessItemForTabbingRequest(id, item_flags, g.NavMoveFlags);
|
||||
}
|
||||
else if (g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId))
|
||||
{
|
||||
ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
|
||||
if (NavScoreItem(result))
|
||||
NavApplyItemToResult(result);
|
||||
|
||||
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
|
||||
const float VISIBLE_RATIO = 0.70f;
|
||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
|
||||
if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
|
||||
if (NavScoreItem(&g.NavMoveResultLocalVisible))
|
||||
NavApplyItemToResult(&g.NavMoveResultLocalVisible);
|
||||
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
|
||||
const float VISIBLE_RATIO = 0.70f;
|
||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
|
||||
if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
|
||||
if (NavScoreItem(&g.NavMoveResultLocalVisible))
|
||||
NavApplyItemToResult(&g.NavMoveResultLocalVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12952,8 +13006,10 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
|
||||
}
|
||||
|
||||
// FIXME: Could become optional e.g. ImGuiNavMoveFlags_NoClearActiveId if we later want to apply navigation requests without altering active input.
|
||||
if (g.ActiveId != result->ID)
|
||||
// Clear active id unless requested not to
|
||||
// FIXME: ImGuiNavMoveFlags_NoClearActiveId is currently unused as we don't have a clear strategy to preserve active id after interaction,
|
||||
// so this is mostly provided as a gateway for further experiments (see #1418, #2890)
|
||||
if (g.ActiveId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoClearActiveId) == 0)
|
||||
ClearActiveID();
|
||||
|
||||
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
|
||||
@@ -20113,9 +20169,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
{
|
||||
// As it's difficult to interact with tree nodes while popups are open, we display everything inline.
|
||||
ImGuiWindow* window = popup_data.Window;
|
||||
BulletText("PopupID: %08x, Window: '%s' (%s%s), BackupNavWindow '%s', ParentWindow '%s'",
|
||||
BulletText("PopupID: %08x, Window: '%s' (%s%s), RestoreNavWindow '%s', ParentWindow '%s'",
|
||||
popup_data.PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? "Child;" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? "Menu;" : "",
|
||||
popup_data.BackupNavWindow ? popup_data.BackupNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL");
|
||||
popup_data.RestoreNavWindow ? popup_data.RestoreNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL");
|
||||
}
|
||||
TreePop();
|
||||
}
|
||||
@@ -20804,7 +20860,7 @@ void ImGui::DebugNodeFont(ImFont* font)
|
||||
SetNextItemWidth(GetFontSize() * 8);
|
||||
DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");
|
||||
SameLine(); MetricsHelpMarker(
|
||||
"Note than the default embedded font is NOT meant to be scaled.\n\n"
|
||||
"Note that the default embedded font is NOT meant to be scaled.\n\n"
|
||||
"Font are currently rendered into bitmaps at a given size at the time of building the atlas. "
|
||||
"You may oversample them to get some flexibility with scaling. "
|
||||
"You can also render at multiple sizes and select which one to use at runtime.\n\n"
|
||||
@@ -21287,6 +21343,12 @@ void ImGui::DebugLocateItemResolveWithLastItem()
|
||||
draw_list->AddLine(p1, p2, DEBUG_LOCATE_ITEM_COLOR);
|
||||
}
|
||||
|
||||
void ImGui::DebugStartItemPicker()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.DebugItemPickerActive = true;
|
||||
}
|
||||
|
||||
// [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
|
||||
void ImGui::UpdateDebugToolItemPicker()
|
||||
{
|
||||
@@ -21455,7 +21517,7 @@ void ImGui::ShowIDStackToolWindow(bool* p_open)
|
||||
Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC);
|
||||
SameLine();
|
||||
TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*");
|
||||
if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiMod_Ctrl) && IsKeyPressed(ImGuiKey_C))
|
||||
if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, ImGuiInputFlags_RouteGlobal))
|
||||
{
|
||||
tool->CopyToClipboardLastTime = (float)g.Time;
|
||||
char* p = g.TempBuffer.Data;
|
||||
@@ -21522,6 +21584,7 @@ void ImGui::DebugLog(const char*, ...) {}
|
||||
void ImGui::DebugLogV(const char*, va_list) {}
|
||||
void ImGui::ShowDebugLogWindow(bool*) {}
|
||||
void ImGui::ShowIDStackToolWindow(bool*) {}
|
||||
void ImGui::DebugStartItemPicker() {}
|
||||
void ImGui::DebugHookIdInfo(ImGuiID, ImGuiDataType, const void*, const void*) {}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
|
||||
89
imgui.h
89
imgui.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -7,15 +7,19 @@
|
||||
// - Read top of imgui.cpp for more details, links and comments.
|
||||
|
||||
// Resources:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Homepage https://github.com/ocornut/imgui
|
||||
// - Releases & changelog https://github.com/ocornut/imgui/releases
|
||||
// - Gallery https://github.com/ocornut/imgui/issues/6897 (please post your screenshots/video there!)
|
||||
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
||||
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||||
// - Issues & support https://github.com/ocornut/imgui/issues
|
||||
// - Tests & Automation https://github.com/ocornut/imgui_test_engine
|
||||
// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md)
|
||||
// - Homepage ................... https://github.com/ocornut/imgui
|
||||
// - Releases & changelog ....... https://github.com/ocornut/imgui/releases
|
||||
// - Gallery .................... https://github.com/ocornut/imgui/issues/6897 (please post your screenshots/video there!)
|
||||
// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
||||
// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code)
|
||||
// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more)
|
||||
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines)
|
||||
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||||
// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools
|
||||
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
|
||||
// - Issues & support ........... https://github.com/ocornut/imgui/issues
|
||||
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
|
||||
|
||||
// For first-time users having issues compiling/linking/running/loading fonts:
|
||||
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
||||
@@ -23,8 +27,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.90.2"
|
||||
#define IMGUI_VERSION_NUM 19020
|
||||
#define IMGUI_VERSION "1.90.5"
|
||||
#define IMGUI_VERSION_NUM 19050
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@@ -176,8 +180,9 @@ struct ImGuiWindowClass; // Window class (rare/advanced uses: provide
|
||||
// Enumerations
|
||||
// - We don't use strongly typed enums much because they add constraints (can't extend in private code, can't store typed in bit fields, extra casting on iteration)
|
||||
// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists!
|
||||
// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value)
|
||||
enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen)
|
||||
typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling
|
||||
@@ -192,8 +197,9 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A
|
||||
|
||||
// Flags (declared as int to allow using as flags without overhead, and to not pollute the top of this file)
|
||||
// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists!
|
||||
// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
|
||||
@@ -454,7 +460,7 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
|
||||
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API ImU32 GetColorU32(ImU32 col, float alpha_mul = 1.0f); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.
|
||||
|
||||
// Layout cursor positioning
|
||||
@@ -998,6 +1004,7 @@ namespace ImGui
|
||||
// - Your main debugging friend is the ShowMetricsWindow() function, which is also accessible from Demo->Tools->Metrics Debugger
|
||||
IMGUI_API void DebugTextEncoding(const char* text);
|
||||
IMGUI_API void DebugFlashStyleColor(ImGuiCol idx);
|
||||
IMGUI_API void DebugStartItemPicker();
|
||||
IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro.
|
||||
|
||||
// Memory Allocators
|
||||
@@ -1622,8 +1629,9 @@ enum ImGuiCol_
|
||||
// - The enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code.
|
||||
// During initialization or between frames, feel free to just poke into ImGuiStyle directly.
|
||||
// - Tip: Use your programming IDE navigation facilities on the names in the _second column_ below to find the actual members and their description.
|
||||
// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
// - When changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type.
|
||||
enum ImGuiStyleVar_
|
||||
{
|
||||
@@ -1651,7 +1659,9 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
|
||||
ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize
|
||||
ImGuiStyleVar_TableAngledHeadersAngle,// float TableAngledHeadersAngle
|
||||
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
|
||||
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
|
||||
ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize
|
||||
@@ -2072,7 +2082,7 @@ struct ImGuiStyle
|
||||
float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
|
||||
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines.
|
||||
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label).
|
||||
ImVec2 CellPadding; // Padding within a table cell. CellPadding.y may be altered between different rows.
|
||||
ImVec2 CellPadding; // Padding within a table cell. Cellpadding.x is locked for entire table. CellPadding.y may be altered between different rows.
|
||||
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
|
||||
float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
|
||||
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
||||
@@ -2120,6 +2130,9 @@ struct ImGuiStyle
|
||||
//-----------------------------------------------------------------------------
|
||||
// Communicate most settings and inputs/outputs to Dear ImGui using this structure.
|
||||
// Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage.
|
||||
// It is generally expected that:
|
||||
// - initialization: backends and user code writes to ImGuiIO.
|
||||
// - main loop: backends writes to ImGuiIO, user code and imgui code reads from ImGuiIO.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// [Internal] Storage used by IsKeyDown(), IsKeyPressed() etc functions.
|
||||
@@ -2360,6 +2373,8 @@ struct ImGuiInputTextCallbackData
|
||||
void* UserData; // What user passed to InputText() // Read-only
|
||||
|
||||
// Arguments for the different callback events
|
||||
// - During Resize callback, Buf will be same as your input buffer.
|
||||
// - However, during Completion/History/Always callback, Buf always points to our own internal data (it is not the same as your buffer)! Changes to it will be reflected into your own buffer shortly after the callback.
|
||||
// - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary.
|
||||
// - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state.
|
||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||
@@ -2866,15 +2881,20 @@ struct ImDrawList
|
||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||
IMGUI_API void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0);
|
||||
IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||
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 AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
|
||||
// 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.
|
||||
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);
|
||||
|
||||
// Image primitives
|
||||
// - Read FAQ to understand what ImTextureID is.
|
||||
// - "p_min" and "p_max" represent the upper-left and lower-right corners of the rectangle.
|
||||
@@ -2884,15 +2904,17 @@ struct ImDrawList
|
||||
IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags = 0);
|
||||
|
||||
// Stateful path API, add points then finish with PathFillConvex() or PathStroke()
|
||||
// - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
||||
// - Important: filled shapes must always use clockwise winding order! The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
||||
// so e.g. 'PathArcTo(center, radius, PI * -0.5f, PI)' is ok, whereas 'PathArcTo(center, radius, PI, PI * -0.5f)' won't have correct anti-aliasing when followed by PathFillConvex().
|
||||
inline void PathClear() { _Path.Size = 0; }
|
||||
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
|
||||
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); }
|
||||
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
|
||||
inline void PathFillConcave(ImU32 col) { AddConcavePolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
|
||||
inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; }
|
||||
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0);
|
||||
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
|
||||
IMGUI_API void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse
|
||||
IMGUI_API void PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse
|
||||
IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
@@ -2925,6 +2947,9 @@ struct ImDrawList
|
||||
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index
|
||||
|
||||
// Obsolete names
|
||||
//inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024)
|
||||
//inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
|
||||
//inline void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0) { PathEllipticalArcTo(center, ImVec2(radius_x, radius_y), rot, a_min, a_max, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
|
||||
//inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021)
|
||||
//inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021)
|
||||
|
||||
@@ -3425,15 +3450,6 @@ struct ImGuiPlatformImeData
|
||||
// Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]
|
||||
#else
|
||||
static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END && "ImGuiKey and native_index was merged together and native_index is disabled by IMGUI_DISABLE_OBSOLETE_KEYIO. Please switch to ImGuiKey."); return key; }
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
namespace ImGui
|
||||
{
|
||||
@@ -3455,6 +3471,9 @@ namespace ImGui
|
||||
// OBSOLETED in 1.88 (from May 2022)
|
||||
static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value.
|
||||
static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value.
|
||||
// OBSOLETED in 1.87 (from February 2022)
|
||||
IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value!
|
||||
//static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; }
|
||||
|
||||
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
|
||||
//-- OBSOLETED in 1.86 (from November 2021)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -7,7 +7,7 @@
|
||||
// - Need help integrating Dear ImGui in your codebase?
|
||||
// - Read Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started
|
||||
// - Read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
|
||||
// Read imgui.cpp for more details, documentation and comments.
|
||||
// Read top of imgui.cpp and imgui.h for many details, documentation, comments, links.
|
||||
// Get the latest version at https://github.com/ocornut/imgui
|
||||
|
||||
//---------------------------------------------------
|
||||
@@ -54,8 +54,9 @@
|
||||
// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp.
|
||||
|
||||
// Navigating this file:
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
|
||||
/*
|
||||
|
||||
@@ -418,6 +419,12 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::MenuItem("Debug Log", NULL, &show_tool_debug_log, has_debug_tools);
|
||||
ImGui::MenuItem("ID Stack Tool", NULL, &show_tool_id_stack_tool, has_debug_tools);
|
||||
ImGui::MenuItem("Style Editor", NULL, &show_tool_style_editor);
|
||||
bool is_debugger_present = ImGui::GetIO().ConfigDebugIsDebuggerPresent;
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools && is_debugger_present))
|
||||
ImGui::DebugStartItemPicker();
|
||||
if (!is_debugger_present)
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable the menu option to avoid casual users crashing the application.\n\nYou can however always access the Item Picker in Metrics->Tools.");
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("About Dear ImGui", NULL, &show_tool_about);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -1343,6 +1350,7 @@ static void ShowDemoWindowWidgets()
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
ImGui::SameLine(); HelpMarker("Here we are sharing selection state between both boxes.");
|
||||
|
||||
// Custom size: use all width, 5 items tall
|
||||
ImGui::Text("Full-width:");
|
||||
@@ -1877,6 +1885,7 @@ static void ShowDemoWindowWidgets()
|
||||
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
||||
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
|
||||
ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f));
|
||||
//ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!");
|
||||
|
||||
// Fill an array of contiguous float values to plot
|
||||
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
|
||||
@@ -2536,9 +2545,7 @@ static void ShowDemoWindowWidgets()
|
||||
{
|
||||
IM_UNUSED(payload);
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Cannot drop here!");
|
||||
ImGui::EndTooltip();
|
||||
ImGui::SetTooltip("Cannot drop here!");
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@@ -5383,23 +5390,26 @@ static void ShowDemoWindowTables()
|
||||
const int rows_count = 12;
|
||||
|
||||
static ImGuiTableFlags table_flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_HighlightHoveredColumn;
|
||||
static ImGuiTableColumnFlags column_flags = ImGuiTableColumnFlags_AngledHeader | ImGuiTableColumnFlags_WidthFixed;
|
||||
static bool bools[columns_count * rows_count] = {}; // Dummy storage selection storage
|
||||
static int frozen_cols = 1;
|
||||
static int frozen_rows = 2;
|
||||
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
|
||||
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
|
||||
ImGui::CheckboxFlags("_Resizable", &table_flags, ImGuiTableFlags_Resizable);
|
||||
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags, ImGuiTableFlags_NoBordersInBody);
|
||||
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
|
||||
ImGui::CheckboxFlags("Disable header contributing to column width", &column_flags, ImGuiTableColumnFlags_NoHeaderWidth);
|
||||
|
||||
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
|
||||
{
|
||||
ImGui::TableSetupColumn(column_names[0], ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder);
|
||||
for (int n = 1; n < columns_count; n++)
|
||||
ImGui::TableSetupColumn(column_names[n], ImGuiTableColumnFlags_AngledHeader | ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn(column_names[n], column_flags);
|
||||
ImGui::TableSetupScrollFreeze(frozen_cols, frozen_rows);
|
||||
|
||||
ImGui::TableAngledHeadersRow(); // Draw angled headers for all columns with the ImGuiTableColumnFlags_AngledHeader flag.
|
||||
@@ -5546,6 +5556,7 @@ static void ShowDemoWindowTables()
|
||||
HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc.");
|
||||
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings;
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_SizingFixedFit", &flags, ImGuiTableFlags_SizingFixedFit);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
@@ -6418,7 +6429,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::Separator();
|
||||
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
|
||||
ImGui::Text("If your company uses this, please consider sponsoring the project!");
|
||||
ImGui::Text("If your company uses this, please consider funding the project.");
|
||||
|
||||
static bool show_config_info = false;
|
||||
ImGui::Checkbox("Config/Build Information", &show_config_info);
|
||||
@@ -7880,7 +7891,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
|
||||
if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Resize vertical + lock current width
|
||||
if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Resize horizontal + lock current height
|
||||
if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width Between and 400 and 500
|
||||
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 500), ImVec2(-1, FLT_MAX)); // Height at least 400
|
||||
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, FLT_MAX)); // Height at least 400
|
||||
if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::AspectRatio, (void*)&aspect_ratio); // Aspect ratio
|
||||
if (type == 7) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
|
||||
if (type == 8) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)&fixed_step); // Fixed Step
|
||||
@@ -8058,6 +8069,14 @@ static void ShowExampleAppWindowTitles(bool*)
|
||||
// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Add a |_| looking shape
|
||||
static void PathConcaveShape(ImDrawList* draw_list, float x, float y, float sz)
|
||||
{
|
||||
const ImVec2 pos_norms[] = { { 0.0f, 0.0f }, { 0.3f, 0.0f }, { 0.3f, 0.7f }, { 0.7f, 0.7f }, { 0.7f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } };
|
||||
for (const ImVec2& p : pos_norms)
|
||||
draw_list->PathLineTo(ImVec2(x + 0.5f + (int)(sz * p.x), y + 0.5f + (int)(sz * p.y)));
|
||||
}
|
||||
|
||||
// Demonstrate using the low-level ImDrawList to draw custom shapes.
|
||||
static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
{
|
||||
@@ -8130,6 +8149,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
const float rounding = sz / 5.0f;
|
||||
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
|
||||
const int curve_segments = curve_segments_override ? curve_segments_override_v : 0;
|
||||
const ImVec2 cp3[3] = { ImVec2(0.0f, sz * 0.6f), ImVec2(sz * 0.5f, -sz * 0.4f), ImVec2(sz, sz) }; // Control points for curves
|
||||
const ImVec2 cp4[4] = { ImVec2(0.0f, 0.0f), ImVec2(sz * 1.3f, sz * 0.3f), ImVec2(sz - sz * 1.3f, sz - sz * 0.3f), ImVec2(sz, sz) };
|
||||
|
||||
float x = p.x + 4.0f;
|
||||
float y = p.y + 4.0f;
|
||||
for (int n = 0; n < 2; n++)
|
||||
@@ -8138,41 +8160,63 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
float th = (n == 0) ? 1.0f : thickness;
|
||||
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
|
||||
draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, sz*0.3f, col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse
|
||||
draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
|
||||
PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, ImDrawFlags_Closed, th); x += sz + spacing; // Concave Shape
|
||||
//draw_list->AddPolyline(concave_shape, IM_ARRAYSIZE(concave_shape), col, ImDrawFlags_Closed, th);
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||
|
||||
// Path
|
||||
draw_list->PathArcTo(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, 3.141592f, 3.141592f * -0.5f);
|
||||
draw_list->PathStroke(col, ImDrawFlags_None, th);
|
||||
x += sz + spacing;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
ImVec2 cp3[3] = { ImVec2(x, y + sz * 0.6f), ImVec2(x + sz * 0.5f, y - sz * 0.4f), ImVec2(x + sz, y + sz) };
|
||||
draw_list->AddBezierQuadratic(cp3[0], cp3[1], cp3[2], col, th, curve_segments); x += sz + spacing;
|
||||
draw_list->AddBezierQuadratic(ImVec2(x + cp3[0].x, y + cp3[0].y), ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), col, th, curve_segments);
|
||||
x += sz + spacing;
|
||||
|
||||
// Cubic Bezier Curve (4 control points)
|
||||
ImVec2 cp4[4] = { ImVec2(x, y), ImVec2(x + sz * 1.3f, y + sz * 0.3f), ImVec2(x + sz - sz * 1.3f, y + sz - sz * 0.3f), ImVec2(x + sz, y + sz) };
|
||||
draw_list->AddBezierCubic(cp4[0], cp4[1], cp4[2], cp4[3], col, th, curve_segments);
|
||||
draw_list->AddBezierCubic(ImVec2(x + cp4[0].x, y + cp4[0].y), ImVec2(x + cp4[1].x, y + cp4[1].y), ImVec2(x + cp4[2].x, y + cp4[2].y), ImVec2(x + cp4[3].x, y + cp4[3].y), col, th, curve_segments);
|
||||
|
||||
x = p.x + 4;
|
||||
y += sz + spacing;
|
||||
}
|
||||
|
||||
// Filled shapes
|
||||
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, ngon_sides); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, circle_segments); x += sz + spacing; // Circle
|
||||
draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, sz * 0.3f, col, -0.3f, circle_segments); x += sz + spacing;// Ellipse
|
||||
draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), ImVec2(sz * 0.5f, sz * 0.3f), col, -0.3f, circle_segments); x += sz + spacing;// Ellipse
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
PathConcaveShape(draw_list, x, y, sz); draw_list->PathFillConcave(col); x += sz + spacing; // Concave shape
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 11.2f, (sz + spacing) * 3.0f));
|
||||
// Path
|
||||
draw_list->PathArcTo(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, 3.141592f * -0.5f, 3.141592f);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += sz + spacing;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
draw_list->PathLineTo(ImVec2(x + cp3[0].x, y + cp3[0].y));
|
||||
draw_list->PathBezierQuadraticCurveTo(ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), curve_segments);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += sz + spacing;
|
||||
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
x += sz + spacing;
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 13.2f, (sz + spacing) * 3.0f));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
351
imgui_draw.cpp
351
imgui_draw.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -8,6 +8,7 @@ Index of this file:
|
||||
// [SECTION] STB libraries implementation
|
||||
// [SECTION] Style functions
|
||||
// [SECTION] ImDrawList
|
||||
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
|
||||
// [SECTION] ImDrawListSplitter
|
||||
// [SECTION] ImDrawData
|
||||
// [SECTION] Helpers ShadeVertsXXX functions
|
||||
@@ -1223,10 +1224,10 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
|
||||
}
|
||||
}
|
||||
|
||||
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments)
|
||||
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments)
|
||||
{
|
||||
if (num_segments <= 0)
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
|
||||
_Path.reserve(_Path.Size + (num_segments + 1));
|
||||
|
||||
@@ -1235,11 +1236,10 @@ void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float
|
||||
for (int i = 0; i <= num_segments; i++)
|
||||
{
|
||||
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
|
||||
ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y);
|
||||
const float rel_x = (point.x * cos_rot) - (point.y * sin_rot);
|
||||
const float rel_y = (point.x * sin_rot) + (point.y * cos_rot);
|
||||
point.x = rel_x + center.x;
|
||||
point.y = rel_y + center.y;
|
||||
ImVec2 point(ImCos(a) * radius.x, ImSin(a) * radius.y);
|
||||
const ImVec2 rel((point.x * cos_rot) - (point.y * sin_rot), (point.x * sin_rot) + (point.y * cos_rot));
|
||||
point.x = rel.x + center.x;
|
||||
point.y = rel.y + center.y;
|
||||
_Path.push_back(point);
|
||||
}
|
||||
}
|
||||
@@ -1564,31 +1564,31 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
|
||||
}
|
||||
|
||||
// Ellipse
|
||||
void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness)
|
||||
void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments, float thickness)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
if (num_segments <= 0)
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
|
||||
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
|
||||
PathStroke(col, true, thickness);
|
||||
}
|
||||
|
||||
void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments)
|
||||
void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
if (num_segments <= 0)
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
|
||||
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
|
||||
PathFillConvex(col);
|
||||
}
|
||||
|
||||
@@ -1619,10 +1619,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
// Accept null ranges
|
||||
if (text_begin == text_end || text_begin[0] == 0)
|
||||
return;
|
||||
if (text_end == NULL)
|
||||
text_end = text_begin + strlen(text_begin);
|
||||
if (text_begin == text_end)
|
||||
return;
|
||||
|
||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||
if (font == NULL)
|
||||
@@ -1706,6 +1707,316 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi
|
||||
PopTextureID();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
|
||||
//-----------------------------------------------------------------------------
|
||||
// Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
|
||||
// Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
||||
// Provided as a convenience for user but not used by main library.
|
||||
//-----------------------------------------------------------------------------
|
||||
// - ImTriangulator [Internal]
|
||||
// - AddConcavePolyFilled()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum ImTriangulatorNodeType
|
||||
{
|
||||
ImTriangulatorNodeType_Convex,
|
||||
ImTriangulatorNodeType_Ear,
|
||||
ImTriangulatorNodeType_Reflex
|
||||
};
|
||||
|
||||
struct ImTriangulatorNode
|
||||
{
|
||||
ImTriangulatorNodeType Type;
|
||||
int Index;
|
||||
ImVec2 Pos;
|
||||
ImTriangulatorNode* Next;
|
||||
ImTriangulatorNode* Prev;
|
||||
|
||||
void Unlink() { Next->Prev = Prev; Prev->Next = Next; }
|
||||
};
|
||||
|
||||
struct ImTriangulatorNodeSpan
|
||||
{
|
||||
ImTriangulatorNode** Data = NULL;
|
||||
int Size = 0;
|
||||
|
||||
void push_back(ImTriangulatorNode* node) { Data[Size++] = node; }
|
||||
void find_erase_unsorted(int idx) { for (int i = Size - 1; i >= 0; i--) if (Data[i]->Index == idx) { Data[i] = Data[Size - 1]; Size--; return; } }
|
||||
};
|
||||
|
||||
struct ImTriangulator
|
||||
{
|
||||
static int EstimateTriangleCount(int points_count) { return (points_count < 3) ? 0 : points_count - 2; }
|
||||
static int EstimateScratchBufferSize(int points_count) { return sizeof(ImTriangulatorNode) * points_count + sizeof(ImTriangulatorNode*) * points_count * 2; }
|
||||
|
||||
void Init(const ImVec2* points, int points_count, void* scratch_buffer);
|
||||
void GetNextTriangle(unsigned int out_triangle[3]); // Return relative indexes for next triangle
|
||||
|
||||
// Internal functions
|
||||
void BuildNodes(const ImVec2* points, int points_count);
|
||||
void BuildReflexes();
|
||||
void BuildEars();
|
||||
void FlipNodeList();
|
||||
bool IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const;
|
||||
void ReclassifyNode(ImTriangulatorNode* node);
|
||||
|
||||
// Internal members
|
||||
int _TrianglesLeft = 0;
|
||||
ImTriangulatorNode* _Nodes = NULL;
|
||||
ImTriangulatorNodeSpan _Ears;
|
||||
ImTriangulatorNodeSpan _Reflexes;
|
||||
};
|
||||
|
||||
// Distribute storage for nodes, ears and reflexes.
|
||||
// FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
|
||||
// (this would require first building reflexes to bail to convex if empty, without even building nodes)
|
||||
void ImTriangulator::Init(const ImVec2* points, int points_count, void* scratch_buffer)
|
||||
{
|
||||
IM_ASSERT(scratch_buffer != NULL && points_count >= 3);
|
||||
_TrianglesLeft = EstimateTriangleCount(points_count);
|
||||
_Nodes = (ImTriangulatorNode*)scratch_buffer; // points_count x Node
|
||||
_Ears.Data = (ImTriangulatorNode**)(_Nodes + points_count); // points_count x Node*
|
||||
_Reflexes.Data = (ImTriangulatorNode**)(_Nodes + points_count) + points_count; // points_count x Node*
|
||||
BuildNodes(points, points_count);
|
||||
BuildReflexes();
|
||||
BuildEars();
|
||||
}
|
||||
|
||||
void ImTriangulator::BuildNodes(const ImVec2* points, int points_count)
|
||||
{
|
||||
for (int i = 0; i < points_count; i++)
|
||||
{
|
||||
_Nodes[i].Type = ImTriangulatorNodeType_Convex;
|
||||
_Nodes[i].Index = i;
|
||||
_Nodes[i].Pos = points[i];
|
||||
_Nodes[i].Next = _Nodes + i + 1;
|
||||
_Nodes[i].Prev = _Nodes + i - 1;
|
||||
}
|
||||
_Nodes[0].Prev = _Nodes + points_count - 1;
|
||||
_Nodes[points_count - 1].Next = _Nodes;
|
||||
}
|
||||
|
||||
void ImTriangulator::BuildReflexes()
|
||||
{
|
||||
ImTriangulatorNode* n1 = _Nodes;
|
||||
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
|
||||
{
|
||||
if (ImTriangleIsClockwise(n1->Prev->Pos, n1->Pos, n1->Next->Pos))
|
||||
continue;
|
||||
n1->Type = ImTriangulatorNodeType_Reflex;
|
||||
_Reflexes.push_back(n1);
|
||||
}
|
||||
}
|
||||
|
||||
void ImTriangulator::BuildEars()
|
||||
{
|
||||
ImTriangulatorNode* n1 = _Nodes;
|
||||
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
|
||||
{
|
||||
if (n1->Type != ImTriangulatorNodeType_Convex)
|
||||
continue;
|
||||
if (!IsEar(n1->Prev->Index, n1->Index, n1->Next->Index, n1->Prev->Pos, n1->Pos, n1->Next->Pos))
|
||||
continue;
|
||||
n1->Type = ImTriangulatorNodeType_Ear;
|
||||
_Ears.push_back(n1);
|
||||
}
|
||||
}
|
||||
|
||||
void ImTriangulator::GetNextTriangle(unsigned int out_triangle[3])
|
||||
{
|
||||
if (_Ears.Size == 0)
|
||||
{
|
||||
FlipNodeList();
|
||||
|
||||
ImTriangulatorNode* node = _Nodes;
|
||||
for (int i = _TrianglesLeft; i >= 0; i--, node = node->Next)
|
||||
node->Type = ImTriangulatorNodeType_Convex;
|
||||
_Reflexes.Size = 0;
|
||||
BuildReflexes();
|
||||
BuildEars();
|
||||
|
||||
// If we still don't have ears, it means geometry is degenerated.
|
||||
if (_Ears.Size == 0)
|
||||
{
|
||||
// Return first triangle available, mimicking the behavior of convex fill.
|
||||
IM_ASSERT(_TrianglesLeft > 0); // Geometry is degenerated
|
||||
_Ears.Data[0] = _Nodes;
|
||||
_Ears.Size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ImTriangulatorNode* ear = _Ears.Data[--_Ears.Size];
|
||||
out_triangle[0] = ear->Prev->Index;
|
||||
out_triangle[1] = ear->Index;
|
||||
out_triangle[2] = ear->Next->Index;
|
||||
|
||||
ear->Unlink();
|
||||
if (ear == _Nodes)
|
||||
_Nodes = ear->Next;
|
||||
|
||||
ReclassifyNode(ear->Prev);
|
||||
ReclassifyNode(ear->Next);
|
||||
_TrianglesLeft--;
|
||||
}
|
||||
|
||||
void ImTriangulator::FlipNodeList()
|
||||
{
|
||||
ImTriangulatorNode* prev = _Nodes;
|
||||
ImTriangulatorNode* temp = _Nodes;
|
||||
ImTriangulatorNode* current = _Nodes->Next;
|
||||
prev->Next = prev;
|
||||
prev->Prev = prev;
|
||||
while (current != _Nodes)
|
||||
{
|
||||
temp = current->Next;
|
||||
|
||||
current->Next = prev;
|
||||
prev->Prev = current;
|
||||
_Nodes->Next = current;
|
||||
current->Prev = _Nodes;
|
||||
|
||||
prev = current;
|
||||
current = temp;
|
||||
}
|
||||
_Nodes = prev;
|
||||
}
|
||||
|
||||
// A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
|
||||
bool ImTriangulator::IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const
|
||||
{
|
||||
ImTriangulatorNode** p_end = _Reflexes.Data + _Reflexes.Size;
|
||||
for (ImTriangulatorNode** p = _Reflexes.Data; p < p_end; p++)
|
||||
{
|
||||
ImTriangulatorNode* reflex = *p;
|
||||
if (reflex->Index != i0 && reflex->Index != i1 && reflex->Index != i2)
|
||||
if (ImTriangleContainsPoint(v0, v1, v2, reflex->Pos))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImTriangulator::ReclassifyNode(ImTriangulatorNode* n1)
|
||||
{
|
||||
// Classify node
|
||||
ImTriangulatorNodeType type;
|
||||
const ImTriangulatorNode* n0 = n1->Prev;
|
||||
const ImTriangulatorNode* n2 = n1->Next;
|
||||
if (!ImTriangleIsClockwise(n0->Pos, n1->Pos, n2->Pos))
|
||||
type = ImTriangulatorNodeType_Reflex;
|
||||
else if (IsEar(n0->Index, n1->Index, n2->Index, n0->Pos, n1->Pos, n2->Pos))
|
||||
type = ImTriangulatorNodeType_Ear;
|
||||
else
|
||||
type = ImTriangulatorNodeType_Convex;
|
||||
|
||||
// Update lists when a type changes
|
||||
if (type == n1->Type)
|
||||
return;
|
||||
if (n1->Type == ImTriangulatorNodeType_Reflex)
|
||||
_Reflexes.find_erase_unsorted(n1->Index);
|
||||
else if (n1->Type == ImTriangulatorNodeType_Ear)
|
||||
_Ears.find_erase_unsorted(n1->Index);
|
||||
if (type == ImTriangulatorNodeType_Reflex)
|
||||
_Reflexes.push_back(n1);
|
||||
else if (type == ImTriangulatorNodeType_Ear)
|
||||
_Ears.push_back(n1);
|
||||
n1->Type = type;
|
||||
}
|
||||
|
||||
// Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
|
||||
// (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
|
||||
// It is up to caller to ensure not making costly calls that will be outside of visible area.
|
||||
// As concave fill is noticeably more expensive than other primitives, be mindful of this...
|
||||
// Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
|
||||
void ImDrawList::AddConcavePolyFilled(const ImVec2* points, const int points_count, ImU32 col)
|
||||
{
|
||||
if (points_count < 3 || (col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
ImTriangulator triangulator;
|
||||
unsigned int triangle[3];
|
||||
if (Flags & ImDrawListFlags_AntiAliasedFill)
|
||||
{
|
||||
// Anti-aliased Fill
|
||||
const float AA_SIZE = _FringeScale;
|
||||
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
|
||||
const int idx_count = (points_count - 2) * 3 + points_count * 6;
|
||||
const int vtx_count = (points_count * 2);
|
||||
PrimReserve(idx_count, vtx_count);
|
||||
|
||||
// Add indexes for fill
|
||||
unsigned int vtx_inner_idx = _VtxCurrentIdx;
|
||||
unsigned int vtx_outer_idx = _VtxCurrentIdx + 1;
|
||||
|
||||
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
|
||||
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
|
||||
while (triangulator._TrianglesLeft > 0)
|
||||
{
|
||||
triangulator.GetNextTriangle(triangle);
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (triangle[0] << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (triangle[1] << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (triangle[2] << 1));
|
||||
_IdxWritePtr += 3;
|
||||
}
|
||||
|
||||
// Compute normals
|
||||
_Data->TempBuffer.reserve_discard(points_count);
|
||||
ImVec2* temp_normals = _Data->TempBuffer.Data;
|
||||
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
|
||||
{
|
||||
const ImVec2& p0 = points[i0];
|
||||
const ImVec2& p1 = points[i1];
|
||||
float dx = p1.x - p0.x;
|
||||
float dy = p1.y - p0.y;
|
||||
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
|
||||
temp_normals[i0].x = dy;
|
||||
temp_normals[i0].y = -dx;
|
||||
}
|
||||
|
||||
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
|
||||
{
|
||||
// Average normals
|
||||
const ImVec2& n0 = temp_normals[i0];
|
||||
const ImVec2& n1 = temp_normals[i1];
|
||||
float dm_x = (n0.x + n1.x) * 0.5f;
|
||||
float dm_y = (n0.y + n1.y) * 0.5f;
|
||||
IM_FIXNORMAL2F(dm_x, dm_y);
|
||||
dm_x *= AA_SIZE * 0.5f;
|
||||
dm_y *= AA_SIZE * 0.5f;
|
||||
|
||||
// Add vertices
|
||||
_VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
|
||||
_VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
|
||||
_VtxWritePtr += 2;
|
||||
|
||||
// Add indexes for fringes
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
|
||||
_IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
|
||||
_IdxWritePtr += 6;
|
||||
}
|
||||
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non Anti-aliased Fill
|
||||
const int idx_count = (points_count - 2) * 3;
|
||||
const int vtx_count = points_count;
|
||||
PrimReserve(idx_count, vtx_count);
|
||||
for (int i = 0; i < vtx_count; i++)
|
||||
{
|
||||
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
|
||||
_VtxWritePtr++;
|
||||
}
|
||||
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
|
||||
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
|
||||
while (triangulator._TrianglesLeft > 0)
|
||||
{
|
||||
triangulator.GetNextTriangle(triangle);
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + triangle[0]); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + triangle[1]); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + triangle[2]);
|
||||
_IdxWritePtr += 3;
|
||||
}
|
||||
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImDrawListSplitter
|
||||
@@ -4012,8 +4323,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL
|
||||
draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR
|
||||
draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b); // BL
|
||||
draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e); // TR
|
||||
}
|
||||
if (p1.x > rect.Min.x + rounding)
|
||||
{
|
||||
@@ -4032,8 +4343,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR
|
||||
draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR
|
||||
draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b); // TR
|
||||
draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e); // BR
|
||||
}
|
||||
}
|
||||
draw_list->PathFillConvex(col);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (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.
|
||||
@@ -87,10 +87,12 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn'
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#endif
|
||||
|
||||
// In 1.89.4, we moved the implementation of "courtesy maths operators" from imgui_internal.h in imgui.h
|
||||
@@ -508,7 +510,8 @@ IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const
|
||||
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
|
||||
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
|
||||
IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w);
|
||||
inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
|
||||
inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
|
||||
inline bool ImTriangleIsClockwise(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0f; }
|
||||
|
||||
// Helper: ImVec1 (1D vector)
|
||||
// (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
|
||||
@@ -873,6 +876,7 @@ enum ImGuiInputTextFlagsPrivate_
|
||||
ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline()
|
||||
ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data
|
||||
ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match.
|
||||
ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 29, // For internal use by InputScalar() and TempInputScalar()
|
||||
};
|
||||
|
||||
// Extend ImGuiButtonFlags_
|
||||
@@ -1310,7 +1314,7 @@ struct ImGuiPopupData
|
||||
{
|
||||
ImGuiID PopupId; // Set on OpenPopup()
|
||||
ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
|
||||
ImGuiWindow* BackupNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close
|
||||
ImGuiWindow* RestoreNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close
|
||||
int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value
|
||||
int OpenFrameCount; // Set on OpenPopup()
|
||||
ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items)
|
||||
@@ -1368,7 +1372,6 @@ enum ImGuiInputSource
|
||||
ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them.
|
||||
ImGuiInputSource_Keyboard,
|
||||
ImGuiInputSource_Gamepad,
|
||||
ImGuiInputSource_Clipboard, // Currently only used by InputText()
|
||||
ImGuiInputSource_COUNT
|
||||
};
|
||||
|
||||
@@ -1599,6 +1602,7 @@ enum ImGuiNavMoveFlags_
|
||||
ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item.
|
||||
ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo
|
||||
ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight
|
||||
ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result
|
||||
};
|
||||
|
||||
enum ImGuiNavLayer
|
||||
@@ -2701,6 +2705,7 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
int CurrentTableIdx; // Current table index (into g.Tables)
|
||||
ImGuiLayoutType LayoutType;
|
||||
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
|
||||
ImU32 ModalDimBgColor;
|
||||
|
||||
// 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.
|
||||
@@ -3161,7 +3166,7 @@ struct IMGUI_API ImGuiTableTempData
|
||||
{
|
||||
int TableIndex; // Index in g.Tables.Buf[] pool
|
||||
float LastTimeActive; // Last timestamp this structure was used
|
||||
float AngledheadersExtraWidth; // Used in EndTable()
|
||||
float AngledHeadersExtraWidth; // Used in EndTable()
|
||||
|
||||
ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
|
||||
ImDrawListSplitter DrawSplitter;
|
||||
@@ -3605,7 +3610,7 @@ namespace ImGui
|
||||
IMGUI_API float TableGetHeaderAngledMaxLabelWidth();
|
||||
IMGUI_API void TablePushBackgroundChannel();
|
||||
IMGUI_API void TablePopBackgroundChannel();
|
||||
IMGUI_API void TableAngledHeadersRowEx(float angle, float label_width = 0.0f);
|
||||
IMGUI_API void TableAngledHeadersRowEx(float angle, float max_label_width = 0.0f);
|
||||
|
||||
// Tables: Internals
|
||||
inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; }
|
||||
@@ -3792,7 +3797,6 @@ namespace ImGui
|
||||
IMGUI_API void DebugBreakClearData();
|
||||
IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location);
|
||||
IMGUI_API void DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location);
|
||||
inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }
|
||||
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
|
||||
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
|
||||
|
||||
107
imgui_tables.cpp
107
imgui_tables.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -24,8 +24,9 @@ Index of this file:
|
||||
*/
|
||||
|
||||
// Navigating this file:
|
||||
// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Commentary
|
||||
@@ -498,7 +499,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->DeclColumnsCount = table->AngledHeadersCount = 0;
|
||||
if (previous_frame_active + 1 < g.FrameCount)
|
||||
table->IsActiveIdInTable = false;
|
||||
temp_data->AngledheadersExtraWidth = 0.0f;
|
||||
table->AngledHeadersHeight = 0.0f;
|
||||
temp_data->AngledHeadersExtraWidth = 0.0f;
|
||||
|
||||
// Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders()
|
||||
table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong);
|
||||
@@ -1066,6 +1068,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
// - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column.
|
||||
// - ClipRect.Max.x: using MaxX makes it easier for header to receive hover highlight with no discontinuity and display sorting arrow.
|
||||
// - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter.
|
||||
const float previous_instance_work_min_x = column->WorkMinX;
|
||||
column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1;
|
||||
column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max
|
||||
column->ItemWidth = ImTrunc(column->WidthGiven * 0.65f);
|
||||
@@ -1118,8 +1121,22 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
// column->WorkMinX = ImLerp(column->WorkMinX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f);
|
||||
|
||||
// Reset content width variables
|
||||
column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX;
|
||||
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX;
|
||||
if (table->InstanceCurrent == 0)
|
||||
{
|
||||
column->ContentMaxXFrozen = column->WorkMinX;
|
||||
column->ContentMaxXUnfrozen = column->WorkMinX;
|
||||
column->ContentMaxXHeadersUsed = column->WorkMinX;
|
||||
column->ContentMaxXHeadersIdeal = column->WorkMinX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// As we store an absolute value to make per-cell updates faster, we need to offset values used for width computation.
|
||||
const float offset_from_previous_instance = column->WorkMinX - previous_instance_work_min_x;
|
||||
column->ContentMaxXFrozen += offset_from_previous_instance;
|
||||
column->ContentMaxXUnfrozen += offset_from_previous_instance;
|
||||
column->ContentMaxXHeadersUsed += offset_from_previous_instance;
|
||||
column->ContentMaxXHeadersIdeal += offset_from_previous_instance;
|
||||
}
|
||||
|
||||
// Don't decrement auto-fit counters until container window got a chance to submit its items
|
||||
if (table->HostSkipItems == false)
|
||||
@@ -1240,7 +1257,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
|
||||
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
|
||||
const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS;
|
||||
const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight;
|
||||
const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight);
|
||||
const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight);
|
||||
const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight;
|
||||
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
@@ -1344,7 +1361,7 @@ void ImGui::EndTable()
|
||||
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border);
|
||||
if (table->ResizedColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
|
||||
table->InnerWindow->DC.CursorMaxPos.x = max_pos_x + table->TempData->AngledheadersExtraWidth;
|
||||
table->InnerWindow->DC.CursorMaxPos.x = max_pos_x + table->TempData->AngledHeadersExtraWidth;
|
||||
}
|
||||
|
||||
// Pop clipping rect
|
||||
@@ -1462,7 +1479,7 @@ void ImGui::EndTable()
|
||||
}
|
||||
else if (temp_data->UserOuterSize.x <= 0.0f)
|
||||
{
|
||||
const float decoration_size = table->TempData->AngledheadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f);
|
||||
const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f);
|
||||
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x);
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
|
||||
}
|
||||
@@ -1567,6 +1584,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
}
|
||||
|
||||
// Store name (append with zero-terminator in contiguous buffer)
|
||||
// FIXME: If we recorded the number of \n in names we could compute header row height
|
||||
column->NameOffset = -1;
|
||||
if (label != NULL && label[0] != 0)
|
||||
{
|
||||
@@ -1889,7 +1907,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
if (is_visible)
|
||||
{
|
||||
// Update data for TableGetHoveredRow()
|
||||
if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2)
|
||||
if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2 && table_instance->HoveredRowNext < 0)
|
||||
table_instance->HoveredRowNext = table->CurrentRow;
|
||||
|
||||
// Decide of background color for the row
|
||||
@@ -2154,6 +2172,8 @@ void ImGui::TableEndCell(ImGuiTable* table)
|
||||
// - TableSetColumnWidthAutoAll() [Internal]
|
||||
// - TableUpdateColumnsWeightFromWidth() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
// Note that actual columns widths are computed in TableUpdateLayout().
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis.
|
||||
float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
|
||||
@@ -2927,6 +2947,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
|
||||
// [SECTION] Tables: Headers
|
||||
//-------------------------------------------------------------------------
|
||||
// - TableGetHeaderRowHeight() [Internal]
|
||||
// - TableGetHeaderAngledMaxLabelWidth() [Internal]
|
||||
// - TableHeadersRow()
|
||||
// - TableHeader()
|
||||
// - TableAngledHeadersRow()
|
||||
@@ -2958,7 +2979,7 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth()
|
||||
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
||||
if (table->Columns[column_n].Flags & ImGuiTableColumnFlags_AngledHeader)
|
||||
width = ImMax(width, CalcTextSize(TableGetColumnName(table, column_n), NULL, true).x);
|
||||
return width + g.Style.CellPadding.x * 2.0f;
|
||||
return width + g.Style.CellPadding.y * 2.0f; // Swap padding
|
||||
}
|
||||
|
||||
// [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn().
|
||||
@@ -3180,25 +3201,25 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
||||
|
||||
// Calculate our base metrics and set angled headers data _before_ the first call to TableNextRow()
|
||||
// FIXME-STYLE: Would it be better for user to submit 'max_label_width' or 'row_height' ? One can be derived from the other.
|
||||
const float header_height = table->RowCellPaddingY * 2.0f + g.FontSize;
|
||||
const float row_height = ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y);
|
||||
const ImVec2 header_angled_vector = unit_right * (row_height / -sin_a);
|
||||
const float header_height = g.FontSize + g.Style.CellPadding.x * 2.0f;
|
||||
const float row_height = ImTrunc(ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y));
|
||||
table->AngledHeadersHeight = row_height;
|
||||
table->AngledHeadersSlope = (sin_a != 0.0f) ? (cos_a / sin_a) : 0.0f;
|
||||
const ImVec2 header_angled_vector = unit_right * (row_height / -sin_a); // vector from bottom-left to top-left, and from bottom-right to top-right
|
||||
|
||||
// Declare row, override and draw our own background
|
||||
TableNextRow(ImGuiTableRowFlags_Headers, row_height);
|
||||
TableNextColumn();
|
||||
const ImRect row_r(table->WorkRect.Min.x, table->BgClipRect.Min.y, table->WorkRect.Max.x, table->RowPosY2);
|
||||
table->DrawSplitter->SetCurrentChannel(draw_list, TABLE_DRAW_CHANNEL_BG0);
|
||||
float clip_rect_min_x = table->BgClipRect.Min.x;
|
||||
if (table->FreezeColumnsCount > 0)
|
||||
clip_rect_min_x = ImMax(clip_rect_min_x, table->Columns[table->FreezeColumnsCount - 1].MaxX);
|
||||
TableSetBgColor(ImGuiTableBgTarget_RowBg0, 0); // Cancel
|
||||
PushClipRect(table->BgClipRect.Min, table->BgClipRect.Max, false); // Span all columns
|
||||
draw_list->AddRectFilled(table->BgClipRect.Min, table->BgClipRect.Max, GetColorU32(ImGuiCol_TableHeaderBg, 0.25f)); // FIXME-STYLE: Change row background with an arbitrary color.
|
||||
draw_list->AddRectFilled(ImVec2(table->BgClipRect.Min.x, row_r.Min.y), ImVec2(table->BgClipRect.Max.x, row_r.Max.y), GetColorU32(ImGuiCol_TableHeaderBg, 0.25f)); // FIXME-STYLE: Change row background with an arbitrary color.
|
||||
PushClipRect(ImVec2(clip_rect_min_x, table->BgClipRect.Min.y), table->BgClipRect.Max, true); // Span all columns
|
||||
|
||||
const ImRect row_r(table->WorkRect.Min.x, table->BgClipRect.Min.y, table->WorkRect.Max.x, window->DC.CursorPos.y + row_height);
|
||||
const ImGuiID row_id = GetID("##AngledHeaders");
|
||||
ButtonBehavior(row_r, row_id, NULL, NULL);
|
||||
KeepAliveID(row_id);
|
||||
@@ -3209,7 +3230,9 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
||||
if (table_instance->HoveredRowLast == 0 && table->HoveredColumnBorder == -1 && (g.ActiveId == 0 || g.ActiveId == row_id || (table->IsActiveIdInTable || g.DragDropActive)))
|
||||
highlight_column_n = table->HoveredColumnBody;
|
||||
|
||||
// Draw background and labels in first pass, then all borders.
|
||||
float max_x = 0.0f;
|
||||
ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
{
|
||||
@@ -3231,25 +3254,45 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
||||
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableHeaderBg));
|
||||
if (column_n == highlight_column_n)
|
||||
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_Header)); // Highlight on hover
|
||||
//draw_list->AddQuad(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableBorderLight), 1.0f);
|
||||
max_x = ImMax(max_x, bg_shape[3].x);
|
||||
|
||||
// Draw label (first draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset)
|
||||
// FIXME: May be worth tidying up all those operations to make them easier to understand.
|
||||
// Draw label
|
||||
// - First draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset.
|
||||
// - Handle multiple lines manually, as we want each lines to follow on the horizontal border, rather than see a whole block rotated.
|
||||
const char* label_name = TableGetColumnName(table, column_n);
|
||||
const float clip_width = max_label_width - (sin_a * table->RowCellPaddingY);
|
||||
ImRect label_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width + (flip_label ? 0.0f : table->CellPaddingX), header_height + table->RowCellPaddingY));
|
||||
ImVec2 label_size = CalcTextSize(label_name, NULL, true);
|
||||
ImVec2 label_off = ImVec2(flip_label ? ImMax(0.0f, max_label_width - label_size.x - table->CellPaddingX) : table->CellPaddingX, table->RowCellPaddingY);
|
||||
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
||||
RenderTextEllipsis(draw_list, label_r.Min + label_off, label_r.Max, label_r.Max.x, label_r.Max.x, label_name, NULL, &label_size);
|
||||
//if (g.IO.KeyShift) { draw_list->AddRect(label_r.Min, label_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f); }
|
||||
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
||||
const char* label_name_end = FindRenderedTextEnd(label_name);
|
||||
const float line_off_step_x = g.FontSize / -sin_a;
|
||||
float line_off_curr_x = 0.0f;
|
||||
while (label_name < label_name_end)
|
||||
{
|
||||
const char* label_name_eol = strchr(label_name, '\n');
|
||||
if (label_name_eol == NULL)
|
||||
label_name_eol = label_name_end;
|
||||
|
||||
// Rotate and offset label
|
||||
ImVec2 pivot_in = label_r.GetBL();
|
||||
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y) + (flip_label ? (unit_right * clip_width) : ImVec2(header_height, 0.0f));
|
||||
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
|
||||
// FIXME: Individual line clipping for right-most column is broken for negative angles.
|
||||
ImVec2 label_size = CalcTextSize(label_name, label_name_eol);
|
||||
float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symetrical but hide more text.
|
||||
float clip_height = ImMin(label_size.y, column->ClipRect.Max.x - column->WorkMinX - line_off_curr_x);
|
||||
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
|
||||
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
||||
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size);
|
||||
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
||||
|
||||
// Rotate and offset label
|
||||
ImVec2 pivot_in = ImVec2(window->ClipRect.Min.x, window->ClipRect.Min.y + label_size.y);
|
||||
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y);
|
||||
line_off_curr_x += line_off_step_x;
|
||||
pivot_out += unit_right * padding.y;
|
||||
if (flip_label)
|
||||
pivot_out += unit_right * (clip_width - ImMax(0.0f, clip_width - label_size.x));
|
||||
pivot_out.x += flip_label ? line_off_curr_x - line_off_step_x : line_off_curr_x;
|
||||
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
|
||||
//if (g.IO.KeyShift) { ImDrawList* fg_dl = GetForegroundDrawList(); vtx_idx_begin = fg_dl->_VtxCurrentIdx; fg_dl->AddRect(clip_r.Min, clip_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f); ShadeVertsTransformPos(fg_dl, vtx_idx_begin, fg_dl->_VtxCurrentIdx, pivot_in, label_cos_a, label_sin_a, pivot_out); }
|
||||
|
||||
// Register header width
|
||||
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(line_off_curr_x);
|
||||
label_name = label_name_eol + 1;
|
||||
}
|
||||
}
|
||||
if (pass == 1)
|
||||
{
|
||||
@@ -3259,7 +3302,7 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
||||
}
|
||||
PopClipRect();
|
||||
PopClipRect();
|
||||
table->TempData->AngledheadersExtraWidth = ImMax(0.0f, max_x - table->Columns[table->RightMostEnabledColumn].MaxX);
|
||||
table->TempData->AngledHeadersExtraWidth = ImMax(0.0f, max_x - table->Columns[table->RightMostEnabledColumn].MaxX);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.2
|
||||
// dear imgui, v1.90.5
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -122,9 +122,9 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// For InputTextEx()
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source);
|
||||
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
|
||||
static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false);
|
||||
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
|
||||
static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: Text, etc.
|
||||
@@ -1294,12 +1294,15 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
if (!ItemAdd(bb, 0))
|
||||
return;
|
||||
|
||||
// Render
|
||||
// Out of courtesy we accept a NaN fraction without crashing
|
||||
fraction = ImSaturate(fraction);
|
||||
const float fraction_not_nan = (fraction == fraction) ? fraction : 0.0f;
|
||||
|
||||
// Render
|
||||
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
|
||||
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
|
||||
RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding);
|
||||
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction_not_nan), bb.Max.y);
|
||||
RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction_not_nan, style.FrameRounding);
|
||||
|
||||
// Default displaying the fraction as percentage string, but user can override it
|
||||
char overlay_buf[32];
|
||||
@@ -2001,7 +2004,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*old_getter)(void*
|
||||
// - DataTypeGetInfo()
|
||||
// - DataTypeFormatString()
|
||||
// - DataTypeApplyOp()
|
||||
// - DataTypeApplyOpFromText()
|
||||
// - DataTypeApplyFromText()
|
||||
// - DataTypeCompare()
|
||||
// - DataTypeClamp()
|
||||
// - GetMinimumStepAtDecimalPrecision
|
||||
@@ -3432,7 +3435,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited;
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
|
||||
bool value_changed = false;
|
||||
if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags))
|
||||
@@ -3477,6 +3480,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
|
||||
flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
flags |= (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
|
||||
bool value_changed = false;
|
||||
if (p_step == NULL)
|
||||
@@ -3922,9 +3926,8 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
}
|
||||
|
||||
// Return false to discard a character.
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source)
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
{
|
||||
IM_ASSERT(input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Clipboard);
|
||||
unsigned int c = *p_char;
|
||||
|
||||
// Filter non-printable (NB: isprint is unreliable! see #2467)
|
||||
@@ -3939,7 +3942,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted.
|
||||
}
|
||||
|
||||
if (input_source != ImGuiInputSource_Clipboard)
|
||||
if (input_source_is_clipboard == false)
|
||||
{
|
||||
// We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817)
|
||||
if (c == 127)
|
||||
@@ -3955,7 +3958,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
return false;
|
||||
|
||||
// Generic named filters
|
||||
if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)))
|
||||
if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint)))
|
||||
{
|
||||
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.'.
|
||||
// The standard mandate that programs starts in the "C" locale where the decimal point is '.'.
|
||||
@@ -3965,7 +3968,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
// Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions.
|
||||
ImGuiContext& g = *ctx;
|
||||
const unsigned c_decimal_point = (unsigned int)g.IO.PlatformLocaleDecimalPoint;
|
||||
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsScientific))
|
||||
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsScientific | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint))
|
||||
if (c == '.' || c == ',')
|
||||
c = c_decimal_point;
|
||||
|
||||
@@ -4424,7 +4427,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (Shortcut(ImGuiKey_Tab, id, ImGuiInputFlags_Repeat))
|
||||
{
|
||||
unsigned int c = '\t'; // Insert TAB
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
state->OnKeyPressed((int)c);
|
||||
}
|
||||
// FIXME: Implement Shift+Tab
|
||||
@@ -4447,7 +4450,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
unsigned int c = (unsigned int)io.InputQueueCharacters[n];
|
||||
if (c == '\t') // Skip Tab, see above.
|
||||
continue;
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
state->OnKeyPressed((int)c);
|
||||
}
|
||||
|
||||
@@ -4530,7 +4533,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
else if (!is_readonly)
|
||||
{
|
||||
unsigned int c = '\n'; // Insert new line
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
state->OnKeyPressed((int)c);
|
||||
}
|
||||
}
|
||||
@@ -4597,7 +4600,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
unsigned int c;
|
||||
s += ImTextCharFromUtf8(&c, s, NULL);
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard))
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
continue;
|
||||
clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c;
|
||||
}
|
||||
@@ -6935,6 +6938,7 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
|
||||
ImVec2 label_pos = ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y);
|
||||
RenderText(label_pos, label);
|
||||
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, label_pos + label_size);
|
||||
AlignTextToFramePadding();
|
||||
}
|
||||
|
||||
BeginChild(id, frame_bb.GetSize(), ImGuiChildFlags_FrameStyle);
|
||||
|
||||
Reference in New Issue
Block a user