forked from Green-Sky/tomato
imgui v1.90.4 Merge commit 'a148d9accf852689a1e521e1ca0da3af82fe70f8'
This commit is contained in:
commit
e4d6d20269
14
external/imgui/imgui/.github/workflows/build.yml
vendored
14
external/imgui/imgui/.github/workflows/build.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
|
||||
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
shell: powershell
|
||||
@ -209,7 +209,7 @@ jobs:
|
||||
Linux:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
@ -402,7 +402,7 @@ jobs:
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
@ -462,7 +462,7 @@ jobs:
|
||||
iOS:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build example_apple_metal
|
||||
run: |
|
||||
@ -472,7 +472,7 @@ jobs:
|
||||
Emscripten:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
@ -494,12 +494,12 @@ jobs:
|
||||
pushd emsdk-master
|
||||
source ./emsdk_env.sh
|
||||
popd
|
||||
make -C examples/example_emscripten_wgpu
|
||||
make -C examples/example_emscripten_wgpu -f Makefile.emscripten
|
||||
|
||||
Android:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build example_android_opengl3
|
||||
run: |
|
||||
|
@ -12,7 +12,7 @@ jobs:
|
||||
PVS-Studio:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-12-08: Renderer: 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-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
|
||||
// 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: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
28
external/imgui/imgui/backends/imgui_impl_dx9.cpp
vendored
28
external/imgui/imgui/backends/imgui_impl_dx9.cpp
vendored
@ -15,6 +15,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 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.
|
||||
@ -312,6 +313,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
|
||||
@ -323,18 +342,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)
|
||||
@ -347,7 +369,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
|
||||
|
||||
|
@ -114,7 +114,7 @@ enum GlfwClientApi
|
||||
{
|
||||
GlfwClientApi_Unknown,
|
||||
GlfwClientApi_OpenGL,
|
||||
GlfwClientApi_Vulkan
|
||||
GlfwClientApi_Vulkan,
|
||||
};
|
||||
|
||||
struct ImGui_ImplGlfw_Data
|
||||
@ -674,11 +674,9 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
|
||||
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||
{
|
||||
GLFWwindow* window = bd->Window;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const bool is_window_focused = true;
|
||||
#else
|
||||
|
@ -23,7 +23,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 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).
|
||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
||||
|
@ -176,9 +176,20 @@
|
||||
#define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES
|
||||
#endif
|
||||
|
||||
// Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have.
|
||||
#ifdef GL_POLYGON_MODE
|
||||
#define IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
// Desktop GL 2.0+ has extension and glPolygonMode() which GL ES and WebGL don't have..
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#define IMGUI_IMPL_OPENGL_HAS_EXTENSIONS // has glGetIntegerv(GL_NUM_EXTENSIONS)
|
||||
#define IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE // has glPolygonMode()
|
||||
#endif
|
||||
|
||||
// Desktop GL 2.1+ and GL ES 3.0+ have glBindBuffer() with GL_PIXEL_UNPACK_BUFFER target.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
|
||||
@ -191,16 +202,6 @@
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
#endif
|
||||
|
||||
// Desktop GL use extension detection
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
@ -359,7 +360,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
|
||||
// Detect extensions we support
|
||||
bd->HasClipOrigin = (bd->GlVersion >= 450);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS
|
||||
GLint num_extensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
for (GLint i = 0; i < num_extensions; i++)
|
||||
@ -411,7 +412,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
if (bd->GlVersion >= 310)
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
|
||||
@ -500,7 +501,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
#endif
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
@ -639,7 +640,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
|
||||
// Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
|
||||
if (bd->GlVersion <= 310 || bd->GlProfileIsCompat)
|
||||
{
|
||||
@ -650,7 +651,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
||||
}
|
||||
#endif // IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
#endif // IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
|
||||
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
@ -747,6 +748,10 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
GLint last_texture, last_array_buffer;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
GLint last_pixel_unpack_buffer;
|
||||
if (bd->GlVersion >= 210) { glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &last_pixel_unpack_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); }
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLint last_vertex_array;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
@ -920,6 +925,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
// Restore modified GL state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
if (bd->GlVersion >= 210) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, last_pixel_unpack_buffer); }
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindVertexArray(last_vertex_array);
|
||||
#endif
|
||||
|
@ -260,6 +260,8 @@ typedef khronos_intptr_t GLintptr;
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
|
||||
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||
|
@ -534,7 +534,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;
|
||||
|
||||
|
167
external/imgui/imgui/backends/imgui_impl_sdl2.cpp
vendored
167
external/imgui/imgui/backends/imgui_impl_sdl2.cpp
vendored
@ -21,6 +21,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 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)
|
||||
@ -106,14 +107,21 @@ struct ImGui_ImplSDL2_Data
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
|
||||
// Mouse handling
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* LastMouseCursor;
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
SDL_Cursor* MouseLastCursor;
|
||||
int MouseLastLeaveFrame;
|
||||
bool MouseCanUseGlobalState;
|
||||
|
||||
// Gamepad handling
|
||||
ImVector<SDL_GameController*> Gamepads;
|
||||
ImGui_ImplSDL2_GamepadMode GamepadMode;
|
||||
bool WantUpdateGamepadsList;
|
||||
|
||||
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
@ -368,16 +376,22 @@ 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 (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
io.AddFocusEvent(false);
|
||||
return true;
|
||||
}
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
{
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -414,6 +428,10 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
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);
|
||||
@ -501,6 +519,8 @@ bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_CloseGamepads();
|
||||
|
||||
void ImGui_ImplSDL2_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
@ -511,7 +531,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;
|
||||
@ -567,59 +587,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
|
||||
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);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_NewFrame()
|
||||
@ -651,10 +730,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);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,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);
|
||||
@ -36,8 +37,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
|
||||
|
169
external/imgui/imgui/backends/imgui_impl_sdl3.cpp
vendored
169
external/imgui/imgui/backends/imgui_impl_sdl3.cpp
vendored
@ -22,6 +22,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 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,14 +65,21 @@ struct ImGui_ImplSDL3_Data
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
|
||||
// Mouse handling
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
SDL_Cursor* LastMouseCursor;
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
SDL_Cursor* MouseLastCursor;
|
||||
int MousePendingLeaveFrame;
|
||||
bool MouseCanUseGlobalState;
|
||||
|
||||
// Gamepad handling
|
||||
ImVector<SDL_Gamepad*> Gamepads;
|
||||
ImGui_ImplSDL3_GamepadMode GamepadMode;
|
||||
bool WantUpdateGamepadsList;
|
||||
|
||||
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
@ -312,7 +320,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,
|
||||
@ -321,7 +329,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:
|
||||
@ -330,6 +338,12 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
io.AddFocusEvent(false);
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
{
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -378,6 +392,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);
|
||||
@ -445,6 +463,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();
|
||||
@ -455,7 +475,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;
|
||||
@ -514,59 +534,118 @@ 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL3_NewFrame()
|
||||
@ -595,10 +674,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);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,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);
|
||||
@ -38,4 +39,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
|
||||
|
@ -20,6 +20,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"
|
||||
@ -129,10 +130,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);
|
||||
@ -178,11 +181,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();
|
||||
@ -197,7 +196,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);
|
||||
}
|
||||
|
||||
|
146
external/imgui/imgui/backends/imgui_impl_vulkan.cpp
vendored
146
external/imgui/imgui/backends/imgui_impl_vulkan.cpp
vendored
@ -33,8 +33,12 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 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.
|
||||
@ -91,14 +95,14 @@
|
||||
#endif
|
||||
|
||||
// Forward Declarations
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers;
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers;
|
||||
struct ImGui_ImplVulkan_FrameRenderBuffers;
|
||||
struct ImGui_ImplVulkan_WindowRenderBuffers;
|
||||
bool ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
void ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||
|
||||
@ -182,15 +186,14 @@ 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
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
struct ImGui_ImplVulkan_FrameRenderBuffers
|
||||
{
|
||||
VkDeviceMemory VertexBufferMemory;
|
||||
VkDeviceMemory IndexBufferMemory;
|
||||
@ -202,24 +205,22 @@ struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
|
||||
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
struct ImGui_ImplVulkan_WindowRenderBuffers
|
||||
{
|
||||
uint32_t Index;
|
||||
uint32_t Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
||||
ImGui_ImplVulkan_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
// Vulkan data
|
||||
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;
|
||||
|
||||
@ -233,7 +234,7 @@ struct ImGui_ImplVulkan_Data
|
||||
VkCommandBuffer FontCommandBuffer;
|
||||
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
@ -385,7 +386,13 @@ static void check_vk_result(VkResult err)
|
||||
v->CheckVkResultFn(err);
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||
// Same as IM_MEMALIGN(). 'alignment' must be a power of two.
|
||||
static inline VkDeviceSize AlignBufferSize(VkDeviceSize size, VkDeviceSize alignment)
|
||||
{
|
||||
return (size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
@ -395,10 +402,10 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
||||
if (buffer_memory != VK_NULL_HANDLE)
|
||||
vkFreeMemory(v->Device, buffer_memory, v->Allocator);
|
||||
|
||||
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / bd->BufferMemoryAlignment + 1) * bd->BufferMemoryAlignment;
|
||||
VkDeviceSize buffer_size_aligned = AlignBufferSize(IM_MAX(v->MinAllocationSize, new_size), bd->BufferMemoryAlignment);
|
||||
VkBufferCreateInfo buffer_info = {};
|
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = vertex_buffer_size_aligned;
|
||||
buffer_info.size = buffer_size_aligned;
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer);
|
||||
@ -407,20 +414,19 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
||||
VkMemoryRequirements req;
|
||||
vkGetBufferMemoryRequirements(v->Device, buffer, &req);
|
||||
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
|
||||
VkDeviceSize size = IM_MAX(v->MinAllocationSize, req.size);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = size;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &buffer_memory);
|
||||
check_vk_result(err);
|
||||
|
||||
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
|
||||
check_vk_result(err);
|
||||
p_buffer_size = size;
|
||||
buffer_size = buffer_size_aligned;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
|
||||
@ -479,23 +485,23 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
// Allocate array to store enough vertex/index buffers
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == nullptr)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
wrb->Count = v->ImageCount;
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkanH_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
|
||||
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
}
|
||||
IM_ASSERT(wrb->Count == v->ImageCount);
|
||||
wrb->Index = (wrb->Index + 1) % wrb->Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
|
||||
ImGui_ImplVulkan_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
|
||||
|
||||
if (draw_data->TotalVtxCount > 0)
|
||||
{
|
||||
// Create or resize the vertex/index buffers
|
||||
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||
size_t vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment);
|
||||
size_t index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment);
|
||||
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
|
||||
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
|
||||
@ -504,9 +510,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)&vtx_dst);
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)&vtx_dst);
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)&idx_dst);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)&idx_dst);
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
@ -946,13 +952,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
|
||||
@ -1017,7 +1021,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;
|
||||
}
|
||||
@ -1026,7 +1030,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
|
||||
if (bd->FontCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->FontCommandPool, 1, &bd->FontCommandBuffer); bd->FontCommandBuffer = VK_NULL_HANDLE; }
|
||||
@ -1067,7 +1071,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!");
|
||||
|
||||
@ -1102,11 +1106,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();
|
||||
|
||||
@ -1145,7 +1147,7 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err = vkDeviceWaitIdle(v->Device);
|
||||
check_vk_result(err);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||
}
|
||||
|
||||
@ -1192,6 +1194,26 @@ void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
|
||||
vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set);
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
|
||||
buffers->VertexBufferSize = 0;
|
||||
buffers->IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkan_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
|
||||
@ -1279,15 +1301,13 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE);
|
||||
(void)physical_device;
|
||||
(void)allocator;
|
||||
IM_UNUSED(physical_device);
|
||||
|
||||
// Create Command Buffers
|
||||
VkResult err;
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
{
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
|
||||
{
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
@ -1312,6 +1332,11 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
|
||||
err = vkCreateFence(device, &info, allocator, &fd->Fence);
|
||||
check_vk_result(err);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
|
||||
{
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
|
||||
{
|
||||
VkSemaphoreCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
@ -1347,10 +1372,9 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
// We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
|
||||
// Destroy old Framebuffer
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
{
|
||||
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
|
||||
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
|
||||
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
||||
}
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = nullptr;
|
||||
@ -1409,11 +1433,12 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
|
||||
check_vk_result(err);
|
||||
|
||||
IM_ASSERT(wd->Frames == nullptr);
|
||||
IM_ASSERT(wd->Frames == nullptr && wd->FrameSemaphores == nullptr);
|
||||
wd->SemaphoreCount = wd->ImageCount + 1;
|
||||
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
|
||||
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->ImageCount);
|
||||
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->SemaphoreCount);
|
||||
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
|
||||
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->ImageCount);
|
||||
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount);
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
wd->Frames[i].Backbuffer = backbuffers[i];
|
||||
}
|
||||
@ -1459,7 +1484,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
|
||||
@ -1520,10 +1545,9 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
|
||||
//vkQueueWaitIdle(bd->Queue);
|
||||
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
{
|
||||
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
|
||||
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
|
||||
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
||||
}
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = nullptr;
|
||||
@ -1556,26 +1580,6 @@ void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH
|
||||
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
|
||||
buffers->VertexBufferSize = 0;
|
||||
buffers->IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
@ -46,9 +46,20 @@
|
||||
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#include <vulkan/vulkan.h>
|
||||
#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
|
||||
{
|
||||
@ -57,25 +68,31 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkPipelineCache PipelineCache;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
uint32_t Subpass;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults 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)
|
||||
VkPipelineCache PipelineCache;
|
||||
uint32_t Subpass;
|
||||
|
||||
// Allocation, Debugging
|
||||
// (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
|
||||
|
||||
// (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);
|
||||
@ -155,6 +172,7 @@ struct ImGui_ImplVulkanH_Window
|
||||
VkClearValue ClearValue;
|
||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
|
@ -16,6 +16,10 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
|
||||
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
|
||||
// 2024-01-22: Fixed pipeline layout leak. (#7245)
|
||||
// 2024-01-17: Explicitly fill all of WGPUDepthStencilState since standard removed defaults.
|
||||
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602)
|
||||
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V.
|
||||
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
@ -72,6 +76,7 @@ struct Uniforms
|
||||
|
||||
struct ImGui_ImplWGPU_Data
|
||||
{
|
||||
ImGui_ImplWGPU_InitInfo initInfo;
|
||||
WGPUDevice wgpuDevice = nullptr;
|
||||
WGPUQueue defaultQueue = nullptr;
|
||||
WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined;
|
||||
@ -179,6 +184,12 @@ static void SafeRelease(WGPUBuffer& res)
|
||||
wgpuBufferRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUPipelineLayout& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuPipelineLayoutRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPURenderPipeline& res)
|
||||
{
|
||||
if (res)
|
||||
@ -565,9 +576,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
|
||||
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
|
||||
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
|
||||
graphics_pipeline_desc.multisample.count = 1;
|
||||
graphics_pipeline_desc.multisample.mask = UINT_MAX;
|
||||
graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false;
|
||||
graphics_pipeline_desc.multisample = bd->initInfo.PipelineMultisampleState;
|
||||
|
||||
// Bind group layouts
|
||||
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
|
||||
@ -654,7 +663,13 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.passOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilBack.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.passOp = WGPUStencilOperation_Keep;
|
||||
|
||||
// Configure disabled depth-stencil state
|
||||
graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state;
|
||||
@ -684,6 +699,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
|
||||
SafeRelease(vertex_shader_desc.module);
|
||||
SafeRelease(pixel_shader_desc.module);
|
||||
SafeRelease(graphics_pipeline_desc.layout);
|
||||
SafeRelease(bg_layouts[0]);
|
||||
|
||||
return true;
|
||||
@ -705,7 +721,7 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects()
|
||||
SafeRelease(bd->pFrameResources[i]);
|
||||
}
|
||||
|
||||
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format)
|
||||
bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
@ -716,11 +732,12 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
|
||||
io.BackendRendererName = "imgui_impl_webgpu";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->wgpuDevice = device;
|
||||
bd->initInfo = *init_info;
|
||||
bd->wgpuDevice = init_info->Device;
|
||||
bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice);
|
||||
bd->renderTargetFormat = rt_format;
|
||||
bd->depthStencilFormat = depth_format;
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->renderTargetFormat = init_info->RenderTargetFormat;
|
||||
bd->depthStencilFormat = init_info->DepthStencilFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
|
||||
bd->renderResources.FontTexture = nullptr;
|
||||
@ -733,8 +750,8 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
|
||||
bd->renderResources.ImageBindGroupLayout = nullptr;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
bd->pFrameResources = new FrameResources[num_frames_in_flight];
|
||||
for (int i = 0; i < num_frames_in_flight; i++)
|
||||
bd->pFrameResources = new FrameResources[bd->numFramesInFlight];
|
||||
for (int i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
FrameResources* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = nullptr;
|
||||
|
19
external/imgui/imgui/backends/imgui_impl_wgpu.h
vendored
19
external/imgui/imgui/backends/imgui_impl_wgpu.h
vendored
@ -20,7 +20,24 @@
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined);
|
||||
// Initialization data, for ImGui_ImplWGPU_Init()
|
||||
struct ImGui_ImplWGPU_InitInfo
|
||||
{
|
||||
WGPUDevice Device;
|
||||
int NumFramesInFlight = 3;
|
||||
WGPUTextureFormat RenderTargetFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUTextureFormat DepthStencilFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUMultisampleState PipelineMultisampleState = {};
|
||||
|
||||
ImGui_ImplWGPU_InitInfo()
|
||||
{
|
||||
PipelineMultisampleState.count = 1;
|
||||
PipelineMultisampleState.mask = -1u;
|
||||
PipelineMultisampleState.alphaToCoverageEnabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info);
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
|
||||
|
127
external/imgui/imgui/docs/CHANGELOG.txt
vendored
127
external/imgui/imgui/docs/CHANGELOG.txt
vendored
@ -35,6 +35,126 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.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 tesselation issue when rendering rounded progress bars,
|
||||
where in some situations the rounded section wouldn't follow regular tesselation 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.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
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
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Commented out ImGuiIO::ImeWindowHandle obsoleted in 1.87 in favor of writing
|
||||
to 'void* ImGuiViewport::PlatformHandleRaw'.
|
||||
- Backends: WebGPU: ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure
|
||||
instead of variety of parameters, allowing for easier further changes. (#7240)
|
||||
|
||||
Other changes:
|
||||
|
||||
- Nav: keyboard/gamepad activation mark widgets as held to give better visual feedback.
|
||||
- Nav: tweak to logic marking navigated item as hovered when using keyboard, allowing
|
||||
the hover highlight to stay even while another item is activated.
|
||||
- Nav: Fixed SetKeyboardFocusHere() not working when current nav focus is in different scope,
|
||||
regression from 1.90.1 related to code scoping Tab presses to local scope. (#7226) [@bratpilz]
|
||||
- Nav: Fixed pressing Escape while in a child window with _NavFlattened flag. (#7237)
|
||||
- Nav: Improve handling of Alt key to toggle menu so that key ownership may be claimed on
|
||||
individual left/right alt key without interfering with the other.
|
||||
- Nav, Menus: Fixed click on a BeginMenu() followed by right-arrow from making the child menu
|
||||
reopen and flicker (using ImGuiPopupFlags_NoReopen).
|
||||
- Nav: ImGuiWindowFlags_NoNavInputs is tested during scoring so NavFlattened windows can use it.
|
||||
- Popups: OpenPopup(): added ImGuiPopupFlags_NoReopen flag to specifically not close and reopen
|
||||
a popup when it is already open. (#1497, #1533)
|
||||
(Note that this differs from specific handling we already have in place for the case of calling
|
||||
OpenPopup() repeatedly every frame: we already didn't reopen in that specific situation, otherwise
|
||||
the effect would be very disastrous in term of confusion, as reopening would steal focus).
|
||||
- Popups: Slight change to popup closing logic (e.g. after focusing another window) which skipped
|
||||
over popups that are also child windows.
|
||||
- Combo: Fixed not reusing windows optimally when used inside a popup stack.
|
||||
- Debug Tools: Metrics: Fixed debug break in SetShortcutRouting() not handling ImGuiMod_Shortcut redirect.
|
||||
- Debug Tools: Metrics: Improved Monitors and Viewports minimap display. Highlight on hover.
|
||||
- Debug Tools: Debug Log: Added "Input Routing" logging.
|
||||
- Debug Tools: Added "nop" to IM_DEBUG_BREAK macro on GCC to work around GDB bug (#7266) [@Peter0x44]
|
||||
- Backends: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by
|
||||
allocating one extra semaphore than in-flight frames. (#7236) [@mklefrancois]
|
||||
- Backends: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size. (#3957)
|
||||
- Backends: Vulkan: Fixed handling of ImGui_ImplVulkan_InitInfo::MinAllocationSize field. (#7189, #4238)
|
||||
- Backends: WebGPU: Added ImGui_ImplWGPU_InitInfo::PipelineMultisampleState. (#7240)
|
||||
- Backends: WebGPU: Filling all WGPUDepthStencilState fields explicitly as a recent Dawn
|
||||
update stopped setting default values. (#7232) [@GrigoryGraborenko]
|
||||
- Backends: WebGPU: Fixed pipeline layout leak. (#7245) [@rajveermalviya]
|
||||
- Backends: OpenGL3: Backup and restore GL_PIXEL_UNPACK_BUFFER. (#7253)
|
||||
- Internals: Many improvements related to yet unpublicized shortcut routing and input ownership systems.
|
||||
- Internals: InputText: Added internal helpers to force reload of user-buf when active. (#2890) [@kudaba, @ocornut]
|
||||
Often requested in some form (#6962, #5219, #3290, #4627, #5054, #3878, #2881, #1506, #1216, #968),
|
||||
and useful for interactive completion/suggestions popups (#2057, #718)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.1 (Released 2024-01-10)
|
||||
@ -90,6 +210,9 @@ Other changes:
|
||||
- Color Editors:
|
||||
- ColorEdit: Layout tweaks for very small sizes. (#7120, #7121)
|
||||
- ColorPicker: Fixed saturation/value cursor radius not scaling properly.
|
||||
- Tabs: Added ImGuiTabItemFlags_NoAssumedClosure to enable app to react on closure attempt,
|
||||
without having to draw an unsaved document marker (ImGuiTabItemFlags_UnsavedDocument sets
|
||||
_NoAssumedClosure automatically). (#7084)
|
||||
- Debug Tools:
|
||||
- Added io.ConfigDebugIsDebuggerPresent option. When enabled, this adds buttons in various
|
||||
locations of Metrics/Debugger to manually request a debugger break:
|
||||
@ -256,7 +379,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
|
||||
@ -3530,8 +3653,6 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Tabs: Added ImGuiTabItemFlags_NoAssumedClosure to enable app to react on closure attempt, without having to draw
|
||||
an unsaved document marker (ImGuiTabItemFlags_UnsavedDocument sets _NoAssumedClosure automatically). (#7084)
|
||||
- DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally
|
||||
any more. If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format.
|
||||
To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d,
|
||||
|
2
external/imgui/imgui/docs/CONTRIBUTING.md
vendored
2
external/imgui/imgui/docs/CONTRIBUTING.md
vendored
@ -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.
|
||||
|
2
external/imgui/imgui/docs/FONTS.md
vendored
2
external/imgui/imgui/docs/FONTS.md
vendored
@ -53,7 +53,7 @@ All loaded fonts glyphs are rendered into a single texture atlas ahead of time.
|
||||
This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty black or white rectangle.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
|
||||
|
||||
Some solutions:
|
||||
- You may reduce oversampling, e.g. `font_config.OversampleH = 1`, this will half your texture size for a quality looss.
|
||||
- You may reduce oversampling, e.g. `font_config.OversampleH = 1`, this will half your texture size for a quality loss.
|
||||
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample).
|
||||
- Reduce glyphs ranges by calculating them from source localization data.
|
||||
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
|
||||
|
4
external/imgui/imgui/docs/README.md
vendored
4
external/imgui/imgui/docs/README.md
vendored
@ -16,7 +16,7 @@ Businesses: support continued development and maintenance via invoiced sponsorin
|
||||
| [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) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Languages & frameworks backends/bindings](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) |
|
||||
| [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
|
||||
|
||||
@ -139,6 +139,8 @@ Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
|
||||
|
||||
### Gallery
|
||||
|
||||
Examples projects using Dear ImGui: [Tracy](https://github.com/wolfpld/tracy) (profiler), [ImHex](https://github.com/WerWolv/ImHex) (hex editor/data analysis), [RemedyBG](https://remedybg.itch.io/remedybg) (debugger) and [hundreds of others](https://github.com/ocornut/imgui/wiki/Software-using-Dear-ImGui).
|
||||
|
||||
For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/6897)!
|
||||
|
||||
For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page.
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
|
||||
|
||||
- Then build using `make` while in the `example_emscripten_wgpu/` directory.
|
||||
- Then build using `make -f Makefile.emscripten` while in the `example_emscripten_wgpu/` directory.
|
||||
|
||||
- Requires recent Emscripten as WGPU is still a work-in-progress API.
|
||||
|
||||
|
@ -11,13 +11,20 @@
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_wgpu.h"
|
||||
#include <stdio.h>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/html5_webgpu.h>
|
||||
#endif
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <webgpu/webgpu.h>
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
// Global WebGPU required states
|
||||
static WGPUDevice wgpu_device = nullptr;
|
||||
static WGPUSurface wgpu_surface = nullptr;
|
||||
@ -27,15 +34,32 @@ static int wgpu_swap_chain_width = 0;
|
||||
static int wgpu_swap_chain_height = 0;
|
||||
|
||||
// Forward declarations
|
||||
static void MainLoopStep(void* window);
|
||||
static bool InitWGPU();
|
||||
static void print_glfw_error(int error, const char* description);
|
||||
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*);
|
||||
static void CreateSwapChain(int width, int height);
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
printf("GLFW Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
static void wgpu_error_callback(WGPUErrorType error_type, const char* message, void*)
|
||||
{
|
||||
const char* error_type_lbl = "";
|
||||
switch (error_type)
|
||||
{
|
||||
case WGPUErrorType_Validation: error_type_lbl = "Validation"; break;
|
||||
case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break;
|
||||
case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break;
|
||||
case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break;
|
||||
default: error_type_lbl = "Unknown";
|
||||
}
|
||||
printf("%s error: %s\n", error_type_lbl, message);
|
||||
}
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
glfwSetErrorCallback(print_glfw_error);
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
|
||||
@ -43,11 +67,8 @@ int main(int, char**)
|
||||
// This needs to be done explicitly later.
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
if (window == nullptr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize the WebGPU environment
|
||||
if (!InitWGPU())
|
||||
@ -66,18 +87,21 @@ int main(int, char**)
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
|
||||
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
||||
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
||||
io.IniFilename = nullptr;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
|
||||
ImGui_ImplWGPU_Init(wgpu_device, 3, wgpu_preferred_fmt, WGPUTextureFormat_Undefined);
|
||||
#endif
|
||||
ImGui_ImplWGPU_InitInfo init_info;
|
||||
init_info.Device = wgpu_device;
|
||||
init_info.NumFramesInFlight = 3;
|
||||
init_info.RenderTargetFormat = wgpu_preferred_fmt;
|
||||
init_info.DepthStencilFormat = WGPUTextureFormat_Undefined;
|
||||
ImGui_ImplWGPU_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.
|
||||
@ -99,64 +123,35 @@ int main(int, char**)
|
||||
//IM_ASSERT(font != nullptr);
|
||||
#endif
|
||||
|
||||
// This function will directly return and exit the main function.
|
||||
// Make sure that no required objects get cleaned up.
|
||||
// This way we can use the browsers 'requestAnimationFrame' to control the rendering.
|
||||
emscripten_set_main_loop_arg(MainLoopStep, window, 0, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool InitWGPU()
|
||||
{
|
||||
wgpu_device = emscripten_webgpu_get_device();
|
||||
if (!wgpu_device)
|
||||
return false;
|
||||
|
||||
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, print_wgpu_error, nullptr);
|
||||
|
||||
// Use C++ wrapper due to misbehavior in Emscripten.
|
||||
// Some offset computation for wgpuInstanceCreateSurface in JavaScript
|
||||
// seem to be inline with struct alignments in the C++ structure
|
||||
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.selector = "#canvas";
|
||||
|
||||
wgpu::SurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc;
|
||||
|
||||
wgpu::Instance instance = wgpuCreateInstance(nullptr);
|
||||
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
|
||||
wgpu::Adapter adapter = {};
|
||||
wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter);
|
||||
wgpu_surface = surface.Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void MainLoopStep(void* window)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
// Our state
|
||||
bool show_demo_window = true;
|
||||
bool show_another_window = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
||||
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
||||
io.IniFilename = nullptr;
|
||||
EMSCRIPTEN_MAINLOOP_BEGIN
|
||||
#else
|
||||
while (!glfwWindowShouldClose(window))
|
||||
#endif
|
||||
{
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
glfwPollEvents();
|
||||
|
||||
// React to changes in screen size
|
||||
int width, height;
|
||||
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
||||
|
||||
// React to changes in screen size
|
||||
if (width != wgpu_swap_chain_width && height != wgpu_swap_chain_height)
|
||||
{
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
if (wgpu_swap_chain)
|
||||
wgpuSwapChainRelease(wgpu_swap_chain);
|
||||
wgpu_swap_chain_width = width;
|
||||
wgpu_swap_chain_height = height;
|
||||
WGPUSwapChainDescriptor swap_chain_desc = {};
|
||||
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
|
||||
swap_chain_desc.format = wgpu_preferred_fmt;
|
||||
swap_chain_desc.width = width;
|
||||
swap_chain_desc.height = height;
|
||||
swap_chain_desc.presentMode = WGPUPresentMode_Fifo;
|
||||
wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc);
|
||||
CreateSwapChain(width, height);
|
||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
@ -165,12 +160,6 @@ static void MainLoopStep(void* window)
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Our state
|
||||
// (we use static, which essentially makes the variable globals, as a convenience to keep the example code easy to follow)
|
||||
static bool show_demo_window = true;
|
||||
static bool show_another_window = false;
|
||||
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
||||
if (show_demo_window)
|
||||
ImGui::ShowDemoWindow(&show_demo_window);
|
||||
@ -216,6 +205,7 @@ static void MainLoopStep(void* window)
|
||||
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 };
|
||||
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
|
||||
|
||||
WGPURenderPassDescriptor render_pass_desc = {};
|
||||
render_pass_desc.colorAttachmentCount = 1;
|
||||
render_pass_desc.colorAttachments = &color_attachments;
|
||||
@ -232,23 +222,59 @@ static void MainLoopStep(void* window)
|
||||
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
|
||||
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
|
||||
wgpuQueueSubmit(queue, 1, &cmd_buffer);
|
||||
}
|
||||
|
||||
static void print_glfw_error(int error, const char* description)
|
||||
{
|
||||
printf("GLFW Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*)
|
||||
{
|
||||
const char* error_type_lbl = "";
|
||||
switch (error_type)
|
||||
{
|
||||
case WGPUErrorType_Validation: error_type_lbl = "Validation"; break;
|
||||
case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break;
|
||||
case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break;
|
||||
case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break;
|
||||
default: error_type_lbl = "Unknown";
|
||||
}
|
||||
printf("%s error: %s\n", error_type_lbl, message);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EMSCRIPTEN_MAINLOOP_END;
|
||||
#endif
|
||||
|
||||
// Cleanup
|
||||
ImGui_ImplWGPU_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool InitWGPU()
|
||||
{
|
||||
wgpu_device = emscripten_webgpu_get_device();
|
||||
if (!wgpu_device)
|
||||
return false;
|
||||
|
||||
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr);
|
||||
|
||||
// Use C++ wrapper due to misbehavior in Emscripten.
|
||||
// Some offset computation for wgpuInstanceCreateSurface in JavaScript
|
||||
// seem to be inline with struct alignments in the C++ structure
|
||||
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.selector = "#canvas";
|
||||
|
||||
wgpu::SurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc;
|
||||
|
||||
wgpu::Instance instance = wgpuCreateInstance(nullptr);
|
||||
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
|
||||
wgpu::Adapter adapter = {};
|
||||
wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter);
|
||||
wgpu_surface = surface.MoveToCHandle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CreateSwapChain(int width, int height)
|
||||
{
|
||||
if (wgpu_swap_chain)
|
||||
wgpuSwapChainRelease(wgpu_swap_chain);
|
||||
wgpu_swap_chain_width = width;
|
||||
wgpu_swap_chain_height = height;
|
||||
WGPUSwapChainDescriptor swap_chain_desc = {};
|
||||
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
|
||||
swap_chain_desc.format = wgpu_preferred_fmt;
|
||||
swap_chain_desc.width = width;
|
||||
swap_chain_desc.height = height;
|
||||
swap_chain_desc.presentMode = WGPUPresentMode_Fifo;
|
||||
wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc);
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -31,9 +31,9 @@
|
||||
#pragma comment(lib, "legacy_stdio_definitions")
|
||||
#endif
|
||||
|
||||
//#define IMGUI_UNLIMITED_FRAME_RATE
|
||||
//#define APP_USE_UNLIMITED_FRAME_RATE
|
||||
#ifdef _DEBUG
|
||||
#define IMGUI_VULKAN_DEBUG_REPORT
|
||||
#define APP_USE_VULKAN_DEBUG_REPORT
|
||||
#endif
|
||||
|
||||
// Data
|
||||
@ -64,14 +64,14 @@ static void check_vk_result(VkResult err)
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
|
||||
{
|
||||
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
|
||||
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
|
||||
return VK_FALSE;
|
||||
}
|
||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
||||
#endif // APP_USE_VULKAN_DEBUG_REPORT
|
||||
|
||||
static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
|
||||
{
|
||||
@ -139,7 +139,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||
#endif
|
||||
|
||||
// Enabling validation layers
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
|
||||
create_info.enabledLayerCount = 1;
|
||||
create_info.ppEnabledLayerNames = layers;
|
||||
@ -153,7 +153,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||
check_vk_result(err);
|
||||
|
||||
// Setup the debug report callback
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
||||
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
|
||||
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
||||
@ -258,7 +258,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
#ifdef IMGUI_UNLIMITED_FRAME_RATE
|
||||
#ifdef APP_USE_UNLIMITED_FRAME_RATE
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
#else
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
||||
@ -275,11 +275,11 @@ static void CleanupVulkan()
|
||||
{
|
||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
// Remove the debug report callback
|
||||
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
|
||||
vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
|
||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
||||
#endif // APP_USE_VULKAN_DEBUG_REPORT
|
||||
|
||||
vkDestroyDevice(g_Device, g_Allocator);
|
||||
vkDestroyInstance(g_Instance, g_Allocator);
|
||||
@ -376,7 +376,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
// Main code
|
||||
@ -434,13 +434,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.
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include <vulkan/vulkan.h>
|
||||
//#include <vulkan/vulkan_beta.h>
|
||||
|
||||
//#define IMGUI_UNLIMITED_FRAME_RATE
|
||||
//#define APP_USE_UNLIMITED_FRAME_RATE
|
||||
#ifdef _DEBUG
|
||||
#define IMGUI_VULKAN_DEBUG_REPORT
|
||||
#define APP_USE_VULKAN_DEBUG_REPORT
|
||||
#endif
|
||||
|
||||
// Data
|
||||
@ -52,14 +52,14 @@ static void check_vk_result(VkResult err)
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
|
||||
{
|
||||
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
|
||||
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
|
||||
return VK_FALSE;
|
||||
}
|
||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
||||
#endif // APP_USE_VULKAN_DEBUG_REPORT
|
||||
|
||||
static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
|
||||
{
|
||||
@ -127,7 +127,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||
#endif
|
||||
|
||||
// Enabling validation layers
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
|
||||
create_info.enabledLayerCount = 1;
|
||||
create_info.ppEnabledLayerNames = layers;
|
||||
@ -141,7 +141,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||
check_vk_result(err);
|
||||
|
||||
// Setup the debug report callback
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
||||
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
|
||||
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
||||
@ -246,7 +246,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
#ifdef IMGUI_UNLIMITED_FRAME_RATE
|
||||
#ifdef APP_UNLIMITED_FRAME_RATE
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
#else
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
||||
@ -263,11 +263,11 @@ static void CleanupVulkan()
|
||||
{
|
||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||
|
||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||
#ifdef APP_USE_VULKAN_DEBUG_REPORT
|
||||
// Remove the debug report callback
|
||||
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
|
||||
vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
|
||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
||||
#endif // APP_USE_VULKAN_DEBUG_REPORT
|
||||
|
||||
vkDestroyDevice(g_Device, g_Allocator);
|
||||
vkDestroyInstance(g_Instance, g_Allocator);
|
||||
@ -364,7 +364,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
return;
|
||||
}
|
||||
check_vk_result(err);
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
// Main code
|
||||
@ -434,13 +434,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.
|
||||
|
721
external/imgui/imgui/imgui.cpp
vendored
721
external/imgui/imgui/imgui.cpp
vendored
File diff suppressed because it is too large
Load Diff
41
external/imgui/imgui/imgui.h
vendored
41
external/imgui/imgui/imgui.h
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -23,8 +23,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.1"
|
||||
#define IMGUI_VERSION_NUM 19010
|
||||
#define IMGUI_VERSION "1.90.4"
|
||||
#define IMGUI_VERSION_NUM 19040
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
@ -89,6 +89,8 @@ Index of this file:
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||
|
||||
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
|
||||
// (MSVC provides an equivalent mechanism via SAL Annotations but it would require the macros in a different
|
||||
// location. e.g. #include <sal.h> + void myprintf(_Printf_format_string_ const char* format, ...))
|
||||
#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__)
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1)))
|
||||
#define IM_FMTLIST(FMT) __attribute__((format(gnu_printf, FMT, 0)))
|
||||
@ -342,7 +344,7 @@ namespace ImGui
|
||||
// - Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window. Child windows can embed their own child.
|
||||
// - Before 1.90 (November 2023), the "ImGuiChildFlags child_flags = 0" parameter was "bool border = false".
|
||||
// This API is backward compatible with old code, as we guarantee that ImGuiChildFlags_Border == true.
|
||||
// Consider updating your old call sites:
|
||||
// Consider updating your old code:
|
||||
// BeginChild("Name", size, false) -> Begin("Name", size, 0); or Begin("Name", size, ImGuiChildFlags_None);
|
||||
// BeginChild("Name", size, true) -> Begin("Name", size, ImGuiChildFlags_Border);
|
||||
// - Manual sizing (each axis can use a different setting e.g. ImVec2(0.0f, 400.0f)):
|
||||
@ -443,7 +445,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
|
||||
@ -965,6 +967,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
|
||||
@ -1025,7 +1028,7 @@ enum ImGuiWindowFlags_
|
||||
};
|
||||
|
||||
// Flags for ImGui::BeginChild()
|
||||
// (Legacy: bot 0 must always correspond to ImGuiChildFlags_Border to be backward compatible with old API using 'bool border = false'.
|
||||
// (Legacy: bit 0 must always correspond to ImGuiChildFlags_Border to be backward compatible with old API using 'bool border = false'.
|
||||
// About using AutoResizeX/AutoResizeY flags:
|
||||
// - May be combined with SetNextWindowSizeConstraints() to set a min/max size for each axis (see "Demo->Child->Auto-resize with Constraints").
|
||||
// - Size measurement for a given axis is only performed when the child window is within visible boundaries, or is just appearing.
|
||||
@ -1036,7 +1039,7 @@ enum ImGuiWindowFlags_
|
||||
enum ImGuiChildFlags_
|
||||
{
|
||||
ImGuiChildFlags_None = 0,
|
||||
ImGuiChildFlags_Border = 1 << 0, // Show an outer border and enable WindowPadding. (Important: this is always == 1 == true for legacy reason)
|
||||
ImGuiChildFlags_Border = 1 << 0, // Show an outer border and enable WindowPadding. (IMPORTANT: this is always == 1 == true for legacy reason)
|
||||
ImGuiChildFlags_AlwaysUseWindowPadding = 1 << 1, // Pad with style.WindowPadding even if no border are drawn (no padding by default for non-bordered child windows because it makes more sense)
|
||||
ImGuiChildFlags_ResizeX = 1 << 2, // Allow resize from right border (layout direction). Enable .ini saving (unless ImGuiWindowFlags_NoSavedSettings passed to window flags)
|
||||
ImGuiChildFlags_ResizeY = 1 << 3, // Allow resize from bottom border (layout direction). "
|
||||
@ -1105,8 +1108,8 @@ enum ImGuiTreeNodeFlags_
|
||||
};
|
||||
|
||||
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
|
||||
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument, we need to treat
|
||||
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument instead of 'ImGuiPopupFlags flags',
|
||||
// we need to treat small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter
|
||||
@ -1120,10 +1123,12 @@ enum ImGuiPopupFlags_
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
|
||||
ImGuiPopupFlags_MouseButtonDefault_ = 1,
|
||||
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||
ImGuiPopupFlags_NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space
|
||||
ImGuiPopupFlags_AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||
ImGuiPopupFlags_AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||
ImGuiPopupFlags_NoReopen = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't reopen same popup if already open (won't reposition, won't reinitialize navigation)
|
||||
//ImGuiPopupFlags_NoReopenAlwaysNavInit = 1 << 6, // For OpenPopup*(), BeginPopupContext*(): focus and initialize navigation even when not reopening.
|
||||
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 7, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||
ImGuiPopupFlags_NoOpenOverItems = 1 << 8, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space
|
||||
ImGuiPopupFlags_AnyPopupId = 1 << 10, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||
ImGuiPopupFlags_AnyPopupLevel = 1 << 11, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||
ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel,
|
||||
};
|
||||
|
||||
@ -2187,11 +2192,7 @@ struct ImGuiIO
|
||||
int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512.
|
||||
bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow.
|
||||
float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums.
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
void* ImeWindowHandle; // = NULL // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
|
||||
#else
|
||||
void* _UnusedPadding;
|
||||
//void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -2765,7 +2766,8 @@ 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); }
|
||||
@ -3123,6 +3125,7 @@ enum ImGuiViewportFlags_
|
||||
// - Windows are generally trying to stay within the Work Area of their host viewport.
|
||||
struct ImGuiViewport
|
||||
{
|
||||
ImGuiID ID; // Unique identifier for the viewport
|
||||
ImGuiViewportFlags Flags; // See ImGuiViewportFlags_
|
||||
ImVec2 Pos; // Main Area: Position of the viewport (Dear ImGui coordinates are the same as OS desktop/native coordinates)
|
||||
ImVec2 Size; // Main Area: Size of the viewport.
|
||||
|
58
external/imgui/imgui/imgui_demo.cpp
vendored
58
external/imgui/imgui/imgui_demo.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@ -401,6 +401,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();
|
||||
}
|
||||
@ -5307,23 +5313,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.
|
||||
@ -6997,19 +7006,19 @@ struct ExampleAppConsole
|
||||
{
|
||||
ClearLog();
|
||||
for (int i = 0; i < History.Size; i++)
|
||||
free(History[i]);
|
||||
ImGui::MemFree(History[i]);
|
||||
}
|
||||
|
||||
// Portable helpers
|
||||
static int Stricmp(const char* s1, const char* s2) { int d; while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; } return d; }
|
||||
static int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; n--; } return d; }
|
||||
static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); }
|
||||
static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = ImGui::MemAlloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); }
|
||||
static void Strtrim(char* s) { char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; }
|
||||
|
||||
void ClearLog()
|
||||
{
|
||||
for (int i = 0; i < Items.Size; i++)
|
||||
free(Items[i]);
|
||||
ImGui::MemFree(Items[i]);
|
||||
Items.clear();
|
||||
}
|
||||
|
||||
@ -7175,7 +7184,7 @@ struct ExampleAppConsole
|
||||
for (int i = History.Size - 1; i >= 0; i--)
|
||||
if (Stricmp(History[i], command_line) == 0)
|
||||
{
|
||||
free(History[i]);
|
||||
ImGui::MemFree(History[i]);
|
||||
History.erase(History.begin() + i);
|
||||
break;
|
||||
}
|
||||
@ -8027,6 +8036,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++)
|
||||
@ -8045,17 +8057,23 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
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
|
||||
@ -8067,9 +8085,27 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
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)
|
||||
|
||||
// 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;
|
||||
|
||||
// Cubic Bezier Curve (4 control points): this is concave so not drawing it yet
|
||||
//draw_list->PathLineTo(ImVec2(x + cp4[0].x, y + cp4[0].y));
|
||||
//draw_list->PathBezierCubicCurveTo(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), 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));
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 11.2f, (sz + spacing) * 3.0f));
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 12.2f, (sz + spacing) * 3.0f));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
12
external/imgui/imgui/imgui_draw.cpp
vendored
12
external/imgui/imgui/imgui_draw.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@ -641,7 +641,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
|
||||
_IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size;
|
||||
}
|
||||
|
||||
// Release the a number of reserved vertices/indices from the end of the last reservation made with PrimReserve().
|
||||
// Release the number of reserved vertices/indices from the end of the last reservation made with PrimReserve().
|
||||
void ImDrawList::PrimUnreserve(int idx_count, int vtx_count)
|
||||
{
|
||||
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
||||
@ -3997,8 +3997,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)
|
||||
{
|
||||
@ -4017,8 +4017,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);
|
||||
|
265
external/imgui/imgui/imgui_internal.h
vendored
265
external/imgui/imgui/imgui_internal.h
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (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.
|
||||
@ -15,6 +15,8 @@ Index of this file:
|
||||
// [SECTION] Generic helpers
|
||||
// [SECTION] ImDrawList support
|
||||
// [SECTION] Widgets support: flags, enums, data structures
|
||||
// [SECTION] Data types support
|
||||
// [SECTION] Popup support
|
||||
// [SECTION] Inputs support
|
||||
// [SECTION] Clipper support
|
||||
// [SECTION] Navigation support
|
||||
@ -234,6 +236,7 @@ namespace ImStb
|
||||
#define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_INPUTROUTING(...) do{if (g.DebugLogFlags & ImGuiDebugLogFlags_EventInputRouting)IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
|
||||
// Static Asserts
|
||||
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
|
||||
@ -297,11 +300,11 @@ namespace ImStb
|
||||
#elif defined(__clang__)
|
||||
#define IM_DEBUG_BREAK() __builtin_debugtrap()
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile("int $0x03")
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile("int3;nop")
|
||||
#elif defined(__GNUC__) && defined(__thumb__)
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01")
|
||||
#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0");
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0")
|
||||
#else
|
||||
#define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger!
|
||||
#endif
|
||||
@ -689,9 +692,6 @@ struct ImPool
|
||||
int GetBufSize() const { return Buf.Size; }
|
||||
int GetMapSize() const { return Map.Data.Size; } // It is the map we need iterate to find valid items, since we don't have "alive" storage anywhere
|
||||
T* TryGetMapData(ImPoolIdx n) { int idx = Map.Data[n].val_i; if (idx == -1) return NULL; return GetByIndex(idx); }
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Helper: ImChunkStream<>
|
||||
@ -985,43 +985,6 @@ enum ImGuiPlotType
|
||||
ImGuiPlotType_Histogram,
|
||||
};
|
||||
|
||||
enum ImGuiPopupPositionPolicy
|
||||
{
|
||||
ImGuiPopupPositionPolicy_Default,
|
||||
ImGuiPopupPositionPolicy_ComboBox,
|
||||
ImGuiPopupPositionPolicy_Tooltip,
|
||||
};
|
||||
|
||||
struct ImGuiDataVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count; // 1+
|
||||
ImU32 Offset; // Offset in parent structure
|
||||
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
|
||||
};
|
||||
|
||||
struct ImGuiDataTypeTempStorage
|
||||
{
|
||||
ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size; // Size in bytes
|
||||
const char* Name; // Short descriptive name for the type, for debugging
|
||||
const char* PrintFmt; // Default printf format for the type
|
||||
const char* ScanFmt; // Default scanf format for the type
|
||||
};
|
||||
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
// Stacked color modifier, backup of modified data so we can restore it
|
||||
struct ImGuiColorMod
|
||||
{
|
||||
@ -1106,7 +1069,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not.
|
||||
ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
|
||||
ImVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity.
|
||||
ImVector<char> InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
ImVector<char> InitialTextA; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument)
|
||||
int BufCapacityA; // end-user buffer capacity
|
||||
float ScrollX; // horizontal scrolling/offset
|
||||
@ -1116,6 +1079,9 @@ struct IMGUI_API ImGuiInputTextState
|
||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||
bool Edited; // edited this frame
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet.
|
||||
int ReloadSelectionEnd;
|
||||
|
||||
ImGuiInputTextState() { memset(this, 0, sizeof(*this)); }
|
||||
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
|
||||
@ -1133,21 +1099,16 @@ struct IMGUI_API ImGuiInputTextState
|
||||
int GetSelectionStart() const { return Stb.select_start; }
|
||||
int GetSelectionEnd() const { return Stb.select_end; }
|
||||
void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
|
||||
};
|
||||
|
||||
// Storage for current popup stack
|
||||
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
|
||||
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)
|
||||
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
|
||||
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
|
||||
// Reload user buf (WIP #2890)
|
||||
// If you modify underlying user-passed const char* while active you need to call this (InputText V2 may lift this)
|
||||
// strcpy(my_buf, "hello");
|
||||
// if (ImGuiInputTextState* state = ImGui::GetInputTextState(id)) // id may be ImGui::GetItemID() is last item
|
||||
// state->ReloadUserBufAndSelectAll();
|
||||
void ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
void ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb.select_start; ReloadSelectionEnd = Stb.select_end; }
|
||||
void ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||
|
||||
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
};
|
||||
|
||||
enum ImGuiNextWindowDataFlags_
|
||||
@ -1197,6 +1158,7 @@ enum ImGuiNextItemDataFlags_
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@ -1204,10 +1166,11 @@ struct ImGuiNextItemData
|
||||
ImGuiNextItemDataFlags Flags;
|
||||
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap.
|
||||
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
|
||||
ImGuiCond OpenCond;
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut()
|
||||
bool OpenVal; // Set by SetNextItemOpen()
|
||||
ImGuiCond OpenCond : 8;
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
@ -1279,6 +1242,66 @@ struct ImGuiPtrOrIndex
|
||||
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Data types support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count; // 1+
|
||||
ImU32 Offset; // Offset in parent structure
|
||||
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
|
||||
};
|
||||
|
||||
struct ImGuiDataTypeTempStorage
|
||||
{
|
||||
ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size; // Size in bytes
|
||||
const char* Name; // Short descriptive name for the type, for debugging
|
||||
const char* PrintFmt; // Default printf format for the type
|
||||
const char* ScanFmt; // Default scanf format for the type
|
||||
};
|
||||
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Popup support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum ImGuiPopupPositionPolicy
|
||||
{
|
||||
ImGuiPopupPositionPolicy_Default,
|
||||
ImGuiPopupPositionPolicy_ComboBox,
|
||||
ImGuiPopupPositionPolicy_Tooltip,
|
||||
};
|
||||
|
||||
// Storage for popup stacks (g.OpenPopupStack and g.BeginPopupStack)
|
||||
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
|
||||
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)
|
||||
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
|
||||
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
|
||||
|
||||
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Inputs support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1369,11 +1392,12 @@ struct ImGuiKeyRoutingData
|
||||
{
|
||||
ImGuiKeyRoutingIndex NextEntryIndex;
|
||||
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImGuiMod_Shortcut is already translated to Ctrl/Super.
|
||||
ImU8 RoutingCurrScore; // [DEBUG] For debug display
|
||||
ImU8 RoutingNextScore; // Lower is better (0: perfect score)
|
||||
ImGuiID RoutingCurr;
|
||||
ImGuiID RoutingNext;
|
||||
|
||||
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; }
|
||||
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; }
|
||||
};
|
||||
|
||||
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
|
||||
@ -1401,17 +1425,19 @@ struct ImGuiKeyOwnerData
|
||||
};
|
||||
|
||||
// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner()
|
||||
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
|
||||
// Don't mistake with ImGuiInputTextFlags! (which is for ImGui::InputText() function)
|
||||
enum ImGuiInputFlags_
|
||||
{
|
||||
// Flags for IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(), Shortcut()
|
||||
ImGuiInputFlags_None = 0,
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
|
||||
// Repeat mode
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default)
|
||||
ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast
|
||||
ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster
|
||||
|
||||
// Specify when repeating key pressed can be interrupted.
|
||||
// Repeat mode: Specify when repeating key pressed can be interrupted.
|
||||
// In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in.
|
||||
ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior.
|
||||
ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut)
|
||||
@ -1422,38 +1448,46 @@ enum ImGuiInputFlags_
|
||||
ImGuiInputFlags_CondHovered = 1 << 8, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 9, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
|
||||
// Flags for SetKeyOwner(), SetItemKeyOwner()
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
// Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary.
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released.
|
||||
|
||||
// Routing policies for Shortcut() + low-level SetShortcutRouting()
|
||||
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
|
||||
// - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(),
|
||||
// Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
|
||||
// Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts)
|
||||
// Child2 -> no call // When Child2 is focused, Parent gets the shortcut.
|
||||
// The whole system is order independent, so if Child1 does it calls before Parent results will be identical.
|
||||
// This is an important property as it facilitate working with foreign code or larger codebase.
|
||||
// - Visualize registered routes in 'Metrics->Inputs' and submitted routes in 'Debug Log->InputRouting'.
|
||||
// - When a policy (except for _RouteAlways *) is set, Shortcut() will register itself with SetShortcutRouting(),
|
||||
// allowing the system to decide where to route the input among other route-aware calls.
|
||||
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll
|
||||
// will register a route and only succeed when parent window is in the focus stack and if no-one
|
||||
// with a higher priority is claiming the shortcut.
|
||||
// - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods.
|
||||
// (* Using ImGuiInputFlags_RouteAlways is roughly equivalent to calling IsKeyChordPressed(key)).
|
||||
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default. Meaning that a Shortcut() call will register
|
||||
// a route and only succeed when parent window is in the focus-stack and if no-one with a higher priority
|
||||
// is claiming the same shortcut.
|
||||
// - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute().
|
||||
// - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow.
|
||||
// - Can select only 1 policy among all available.
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
|
||||
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Honor focus route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority IF you need a Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (higher priority: unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overriden by this)
|
||||
ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly.
|
||||
// Routing polices: extra options
|
||||
ImGuiInputFlags_RouteUnlessBgFocused= 1 << 17, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
|
||||
|
||||
// [Internal] Mask of which function support which flags
|
||||
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
|
||||
ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress,
|
||||
ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
|
||||
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_,
|
||||
ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
|
||||
ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease,
|
||||
ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_,
|
||||
};
|
||||
@ -1499,6 +1533,7 @@ enum ImGuiActivateFlags_
|
||||
ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default for Space key and if keyboard is not used.
|
||||
ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
|
||||
ImGuiActivateFlags_FromTabbing = 1 << 3, // Activation requested by a tabbing request
|
||||
ImGuiActivateFlags_FromShortcut = 1 << 4, // Activation requested by an item shortcut via SetNextItemShortcut() function.
|
||||
};
|
||||
|
||||
// Early work-in-progress API for ScrollToItem()
|
||||
@ -1519,8 +1554,7 @@ enum ImGuiScrollFlags_
|
||||
enum ImGuiNavHighlightFlags_
|
||||
{
|
||||
ImGuiNavHighlightFlags_None = 0,
|
||||
ImGuiNavHighlightFlags_TypeDefault = 1 << 0,
|
||||
ImGuiNavHighlightFlags_TypeThin = 1 << 1,
|
||||
ImGuiNavHighlightFlags_Compact = 1 << 1, // Compact highlight, no padding
|
||||
ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse.
|
||||
ImGuiNavHighlightFlags_NoRounding = 1 << 3,
|
||||
};
|
||||
@ -1569,6 +1603,12 @@ struct ImGuiNavItemData
|
||||
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; }
|
||||
};
|
||||
|
||||
struct ImGuiFocusScopeData
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiID WindowID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Typing-select support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1788,8 +1828,9 @@ enum ImGuiDebugLogFlags_
|
||||
ImGuiDebugLogFlags_EventClipper = 1 << 4,
|
||||
ImGuiDebugLogFlags_EventSelection = 1 << 5,
|
||||
ImGuiDebugLogFlags_EventIO = 1 << 6,
|
||||
ImGuiDebugLogFlags_EventInputRouting = 1 << 7,
|
||||
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO,
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventInputRouting,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine
|
||||
};
|
||||
@ -1824,6 +1865,8 @@ struct ImGuiMetricsConfig
|
||||
bool ShowAtlasTintedWithTextColor = false;
|
||||
int ShowWindowsRectsType = -1;
|
||||
int ShowTablesRectsType = -1;
|
||||
int HighlightMonitorIdx = -1;
|
||||
ImGuiID HighlightViewportID = 0;
|
||||
};
|
||||
|
||||
struct ImGuiStackLevelInfo
|
||||
@ -1937,10 +1980,11 @@ struct ImGuiContext
|
||||
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
|
||||
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
|
||||
bool ActiveIdHasBeenEditedThisFrame;
|
||||
bool ActiveIdFromShortcut;
|
||||
int ActiveIdMouseButton : 8;
|
||||
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
|
||||
ImGuiWindow* ActiveIdWindow;
|
||||
ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad
|
||||
int ActiveIdMouseButton;
|
||||
ImGuiID ActiveIdPreviousFrame;
|
||||
bool ActiveIdPreviousFrameIsAlive;
|
||||
bool ActiveIdPreviousFrameHasBeenEditedBefore;
|
||||
@ -1955,6 +1999,7 @@ struct ImGuiContext
|
||||
double LastKeyModsChangeTime; // Record the last time key mods changed (affect repeat delay when using shortcut logic)
|
||||
double LastKeyModsChangeFromNoneTime; // Record the last time key mods changed away from being 0 (affect repeat delay when using shortcut logic)
|
||||
double LastKeyboardKeyPressTime; // Record the last time a keyboard key (ignore mouse/gamepad ones) was pressed.
|
||||
ImBitArrayForNamedKeys KeysMayBeCharInput; // Lookup to tell if a key can emit char input, see IsKeyChordPotentiallyCharInput(). sizeof() = 20 bytes
|
||||
ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT];
|
||||
ImGuiKeyRoutingTable KeysRoutingTable;
|
||||
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
|
||||
@ -1965,8 +2010,8 @@ struct ImGuiContext
|
||||
#endif
|
||||
|
||||
// Next window/item data
|
||||
ImGuiID CurrentFocusScopeId; // == g.FocusScopeStack.back()
|
||||
ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
|
||||
ImGuiID CurrentFocusScopeId; // Value for currently appending items == g.FocusScopeStack.back(). Not to be mistaken with g.NavFocusScopeId.
|
||||
ImGuiItemFlags CurrentItemFlags; // Value for currently appending items == g.ItemFlagsStack.back()
|
||||
ImGuiID DebugLocateId; // Storage for DebugLocateItemOnHover() feature: this is read by ItemAdd() so we keep it in a hot/cached location
|
||||
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
|
||||
ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd)
|
||||
@ -1978,26 +2023,27 @@ struct ImGuiContext
|
||||
ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
|
||||
ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
|
||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
|
||||
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin()
|
||||
ImVector<ImGuiFocusScopeData> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin()
|
||||
ImVector<ImGuiItemFlags> ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin()
|
||||
ImVector<ImGuiGroupData> GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin()
|
||||
ImVector<ImGuiPopupData> OpenPopupStack; // Which popups are open (persistent)
|
||||
ImVector<ImGuiPopupData> BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
|
||||
ImVector<ImGuiNavTreeNodeData> NavTreeNodeStack; // Stack for TreeNode() when a NavLeft requested is emitted.
|
||||
|
||||
int BeginMenuCount;
|
||||
|
||||
// Viewports
|
||||
ImVector<ImGuiViewportP*> Viewports; // Active viewports (Size==1 in 'master' branch). Each viewports hold their copy of ImDrawData.
|
||||
|
||||
// Gamepad/keyboard Navigation
|
||||
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
|
||||
ImGuiID NavId; // Focused item for navigation
|
||||
ImGuiID NavFocusScopeId; // Identify a selection scope (selection code often wants to "clear other items" when landing on an item of the selection set)
|
||||
ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope)
|
||||
ImVector<ImGuiFocusScopeData> NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
|
||||
ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0
|
||||
ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
|
||||
ImGuiActivateFlags NavActivateFlags;
|
||||
ImGuiID NavHighlightActivatedId;
|
||||
float NavHighlightActivatedTimer;
|
||||
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
|
||||
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
|
||||
ImGuiKeyChord NavJustMovedToKeyMods;
|
||||
@ -2044,6 +2090,7 @@ struct ImGuiContext
|
||||
float NavWindowingTimer;
|
||||
float NavWindowingHighlightAlpha;
|
||||
bool NavWindowingToggleLayer;
|
||||
ImGuiKey NavWindowingToggleKey;
|
||||
ImVec2 NavWindowingAccumDeltaPos;
|
||||
ImVec2 NavWindowingAccumDeltaSize;
|
||||
|
||||
@ -2107,6 +2154,8 @@ struct ImGuiContext
|
||||
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
|
||||
ImFont InputTextPasswordFont;
|
||||
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
|
||||
int BeginMenuDepth;
|
||||
int BeginComboDepth;
|
||||
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
|
||||
ImGuiID ColorEditCurrentID; // Set temporarily while inside of the parent-most ColorEdit4/ColorPicker4 (because they call each others).
|
||||
ImGuiID ColorEditSavedID; // ID we are saving/restoring HS for
|
||||
@ -2163,6 +2212,7 @@ struct ImGuiContext
|
||||
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
|
||||
|
||||
// Debug Tools
|
||||
// (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.)
|
||||
ImGuiDebugLogFlags DebugLogFlags;
|
||||
ImGuiTextBuffer DebugLogBuf;
|
||||
ImGuiTextIndex DebugLogIndex;
|
||||
@ -2190,6 +2240,7 @@ struct ImGuiContext
|
||||
int WantCaptureKeyboardNextFrame; // "
|
||||
int WantTextInputNextFrame;
|
||||
ImVector<char> TempBuffer; // Temporary text buffer
|
||||
char TempKeychordName[64];
|
||||
|
||||
ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
{
|
||||
@ -2235,6 +2286,7 @@ struct ImGuiContext
|
||||
ActiveIdHasBeenPressedBefore = false;
|
||||
ActiveIdHasBeenEditedBefore = false;
|
||||
ActiveIdHasBeenEditedThisFrame = false;
|
||||
ActiveIdFromShortcut = false;
|
||||
ActiveIdClickOffset = ImVec2(-1, -1);
|
||||
ActiveIdWindow = NULL;
|
||||
ActiveIdSource = ImGuiInputSource_None;
|
||||
@ -2257,12 +2309,13 @@ struct ImGuiContext
|
||||
CurrentFocusScopeId = 0;
|
||||
CurrentItemFlags = ImGuiItemFlags_None;
|
||||
DebugShowGroupRects = false;
|
||||
BeginMenuCount = 0;
|
||||
|
||||
NavWindow = NULL;
|
||||
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
|
||||
NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
|
||||
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
|
||||
NavHighlightActivatedId = 0;
|
||||
NavHighlightActivatedTimer = 0.0f;
|
||||
NavJustMovedToKeyMods = ImGuiMod_None;
|
||||
NavInputSource = ImGuiInputSource_Keyboard;
|
||||
NavLayer = ImGuiNavLayer_Main;
|
||||
@ -2290,6 +2343,7 @@ struct ImGuiContext
|
||||
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
|
||||
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
|
||||
NavWindowingToggleLayer = false;
|
||||
NavWindowingToggleKey = ImGuiKey_None;
|
||||
|
||||
DimBgRatio = 0.0f;
|
||||
|
||||
@ -2318,6 +2372,7 @@ struct ImGuiContext
|
||||
MouseStationaryTimer = 0.0f;
|
||||
|
||||
TempInputId = 0;
|
||||
BeginMenuDepth = BeginComboDepth = 0;
|
||||
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
|
||||
ColorEditCurrentID = ColorEditSavedID = 0;
|
||||
ColorEditSavedHue = ColorEditSavedSat = 0.0f;
|
||||
@ -2376,6 +2431,7 @@ struct ImGuiContext
|
||||
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
|
||||
FramerateSecPerFrameAccum = 0.0f;
|
||||
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
|
||||
memset(TempKeychordName, 0, sizeof(TempKeychordName));
|
||||
}
|
||||
};
|
||||
|
||||
@ -2425,6 +2481,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.
|
||||
@ -2528,6 +2585,7 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
|
||||
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
|
||||
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
|
||||
ImGuiWindow* ParentWindowForFocusRoute; // Set to manual link a window to its logical parent so that Shortcut() chain are honoerd (e.g. Tool linked to Document)
|
||||
|
||||
ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.)
|
||||
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
|
||||
@ -2859,7 +2917,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;
|
||||
@ -2941,6 +2999,7 @@ namespace ImGui
|
||||
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size);
|
||||
IMGUI_API void SetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window);
|
||||
inline void SetWindowParentWindowForFocusRoute(ImGuiWindow* window, ImGuiWindow* parent_window) { window->ParentWindowForFocusRoute = parent_window; }
|
||||
inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
|
||||
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
|
||||
inline ImVec2 WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
|
||||
@ -3094,11 +3153,13 @@ namespace ImGui
|
||||
IMGUI_API void NavMoveRequestCancel();
|
||||
IMGUI_API void NavMoveRequestApplyResult();
|
||||
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
||||
IMGUI_API void NavHighlightActivated(ImGuiID id);
|
||||
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
|
||||
IMGUI_API void NavRestoreHighlightAfterMove();
|
||||
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
|
||||
IMGUI_API void SetNavWindow(ImGuiWindow* window);
|
||||
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
||||
IMGUI_API void SetNavFocusScope(ImGuiID focus_scope_id);
|
||||
|
||||
// Focus/Activation
|
||||
// This should be part of a larger set of API: FocusItem(offset = -1), FocusItemByID(id), ActivateItem(offset = -1), ActivateItemByID(id) etc. which are
|
||||
@ -3115,7 +3176,8 @@ namespace ImGui
|
||||
inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; }
|
||||
inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; }
|
||||
inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; }
|
||||
inline ImGuiKeyChord ConvertShortcutMod(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; IM_ASSERT_PARANOID(key_chord & ImGuiMod_Shortcut); return (key_chord & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); }
|
||||
inline bool IsModKey(ImGuiKey key) { return key >= ImGuiKey_LeftCtrl && key <= ImGuiKey_RightSuper; }
|
||||
ImGuiKeyChord FixupKeyChord(ImGuiContext* ctx, ImGuiKeyChord key_chord);
|
||||
inline ImGuiKey ConvertSingleModFlagToKey(ImGuiContext* ctx, ImGuiKey key)
|
||||
{
|
||||
ImGuiContext& g = *ctx;
|
||||
@ -3129,7 +3191,7 @@ namespace ImGui
|
||||
|
||||
IMGUI_API ImGuiKeyData* GetKeyData(ImGuiContext* ctx, ImGuiKey key);
|
||||
inline ImGuiKeyData* GetKeyData(ImGuiKey key) { ImGuiContext& g = *GImGui; return GetKeyData(&g, key); }
|
||||
IMGUI_API const char* GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size);
|
||||
IMGUI_API const char* GetKeyChordName(ImGuiKeyChord key_chord);
|
||||
inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); }
|
||||
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
|
||||
IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down);
|
||||
@ -3186,8 +3248,9 @@ namespace ImGui
|
||||
// - IsKeyChordPressed() compares mods + call IsKeyPressed() -> function has no side-effect.
|
||||
// - Shortcut() submits a route then if currently can be routed calls IsKeyChordPressed() -> function has (desirable) side-effects.
|
||||
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0);
|
||||
IMGUI_API void SetNextItemShortcut(ImGuiKeyChord key_chord);
|
||||
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
|
||||
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
|
||||
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0); // owner_id needs to be explicit and cannot be 0
|
||||
IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);
|
||||
IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord);
|
||||
|
||||
@ -3238,7 +3301,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; }
|
||||
@ -3316,7 +3379,7 @@ namespace ImGui
|
||||
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
|
||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
|
||||
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_None); // Navigation highlight
|
||||
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
|
||||
IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
|
||||
|
||||
@ -3421,7 +3484,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);
|
||||
@ -3448,13 +3510,12 @@ namespace ImGui
|
||||
inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89
|
||||
inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89
|
||||
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister():
|
||||
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)'
|
||||
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
|
||||
// (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))' (WIP)
|
||||
// Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText()
|
||||
inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
|
||||
inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
|
||||
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0'
|
||||
// (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))'
|
||||
//inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
|
||||
//inline void FocusableItemUnregister(ImGuiWindow* window) // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity!
|
||||
|
70
external/imgui/imgui/imgui_tables.cpp
vendored
70
external/imgui/imgui/imgui_tables.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@ -498,7 +498,7 @@ 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;
|
||||
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);
|
||||
@ -1344,7 +1344,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 +1462,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 +1567,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)
|
||||
{
|
||||
@ -2154,6 +2155,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 +2930,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
|
||||
// [SECTION] Tables: Headers
|
||||
//-------------------------------------------------------------------------
|
||||
// - TableGetHeaderRowHeight() [Internal]
|
||||
// - TableGetHeaderAngledMaxLabelWidth() [Internal]
|
||||
// - TableHeadersRow()
|
||||
// - TableHeader()
|
||||
// - TableAngledHeadersRow()
|
||||
@ -2958,7 +2962,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().
|
||||
@ -3082,7 +3086,7 @@ void ImGui::TableHeader(const char* label)
|
||||
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
|
||||
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
|
||||
}
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding);
|
||||
if (held)
|
||||
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
|
||||
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
|
||||
@ -3180,25 +3184,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 header_height = g.FontSize + g.Style.CellPadding.x * 2.0f;
|
||||
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);
|
||||
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 +3213,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 +3237,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);
|
||||
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;
|
||||
|
||||
// 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, 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); }
|
||||
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 = label_r.GetBL();
|
||||
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y) + (flip_label ? (unit_right * clip_width) : ImVec2(header_height, 0.0f));
|
||||
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 +3285,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);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
89
external/imgui/imgui/imgui_widgets.cpp
vendored
89
external/imgui/imgui/imgui_widgets.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.1
|
||||
// dear imgui, v1.90.4
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -477,6 +477,9 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
// Frame N + RepeatDelay + RepeatRate*N true true - true
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// FIXME: For refactor we could output flags, incl mouse hovered vs nav keyboard vs nav triggered etc.
|
||||
// And better standardize how widgets use 'GetColor32((held && hovered) ? ... : hovered ? ...)' vs 'GetColor32(held ? ... : hovered ? ...);'
|
||||
// For mouse feedback we typically prefer the 'held && hovered' test, but for nav feedback not always. Outputting hovered=true on Activation may be misleading.
|
||||
bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -597,9 +600,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
g.NavDisableHighlight = true;
|
||||
}
|
||||
|
||||
// Gamepad/Keyboard navigation
|
||||
// We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse.
|
||||
if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover && (g.ActiveId == 0 || g.ActiveId == id || g.ActiveId == window->MoveId))
|
||||
// Gamepad/Keyboard handling
|
||||
// We report navigated and navigation-activated items as hovered but we don't set g.HoveredId to not interfere with mouse.
|
||||
if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover)
|
||||
if (!(flags & ImGuiButtonFlags_NoHoveredOnFocus))
|
||||
hovered = true;
|
||||
if (g.NavActivateDownId == id)
|
||||
@ -621,8 +624,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
pressed = true;
|
||||
SetActiveID(id, window);
|
||||
g.ActiveIdSource = g.NavInputSource;
|
||||
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
||||
if (!(flags & ImGuiButtonFlags_NoNavFocus) && !(g.NavActivateFlags & ImGuiActivateFlags_FromShortcut))
|
||||
SetFocusID(id, window);
|
||||
if (g.NavActivateFlags & ImGuiActivateFlags_FromShortcut)
|
||||
g.ActiveIdFromShortcut = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -666,13 +671,19 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
// When activated using Nav, we hold on the ActiveID until activation button is released
|
||||
if (g.NavActivateDownId != id)
|
||||
if (g.NavActivateDownId == id)
|
||||
held = true; // hovered == true not true as we are already likely hovered on direct activation.
|
||||
else
|
||||
ClearActiveID();
|
||||
}
|
||||
if (pressed)
|
||||
g.ActiveIdHasBeenPressedBefore = true;
|
||||
}
|
||||
|
||||
// Activation highlight (this may be a remote activation)
|
||||
if (g.NavHighlightActivatedId == id)
|
||||
hovered = true;
|
||||
|
||||
if (out_hovered) *out_hovered = hovered;
|
||||
if (out_held) *out_held = held;
|
||||
|
||||
@ -966,7 +977,6 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// Click position in scrollbar normalized space (0.0f->1.0f)
|
||||
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
||||
SetHoveredID(id);
|
||||
|
||||
bool seek_absolute = false;
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
@ -1774,7 +1784,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
|
||||
// This is essentially a specialized version of BeginPopupEx()
|
||||
char name[16];
|
||||
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth
|
||||
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginComboDepth); // Recycle windows based on depth
|
||||
|
||||
// Set position given a custom constraint (peak into expected window size so we can position it)
|
||||
// FIXME: This might be easier to express with an hypothetical SetNextWindowPosConstraints() function?
|
||||
@ -1801,12 +1811,15 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above
|
||||
return false;
|
||||
}
|
||||
g.BeginComboDepth++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui::EndCombo()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
EndPopup();
|
||||
g.BeginComboDepth--;
|
||||
}
|
||||
|
||||
// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements
|
||||
@ -1982,7 +1995,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*old_getter)(void*
|
||||
// - DataTypeGetInfo()
|
||||
// - DataTypeFormatString()
|
||||
// - DataTypeApplyOp()
|
||||
// - DataTypeApplyOpFromText()
|
||||
// - DataTypeApplyFromText()
|
||||
// - DataTypeCompare()
|
||||
// - DataTypeClamp()
|
||||
// - GetMinimumStepAtDecimalPrecision
|
||||
@ -4175,27 +4188,32 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf);
|
||||
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs)
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf)
|
||||
{
|
||||
// Access state even if we don't own it yet.
|
||||
state = &g.InputTextState;
|
||||
state->CursorAnimReset();
|
||||
state->ReloadUserBuf = false;
|
||||
|
||||
// Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714)
|
||||
InputTextDeactivateHook(state->ID);
|
||||
|
||||
// Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar)
|
||||
// From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
const int buf_len = (int)strlen(buf);
|
||||
if (!init_reload_from_user_buf)
|
||||
{
|
||||
// Take a copy of the initial buffer value.
|
||||
state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->InitialTextA.Data, buf, buf_len + 1);
|
||||
}
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: Since we reworked this on 2022/06, may want to differenciate recycle_cursor vs recycle_undostate?
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
||||
if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
recycle_state = false;
|
||||
|
||||
@ -4220,7 +4238,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
||||
}
|
||||
|
||||
if (!is_multiline)
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
state->Stb.select_start = state->ReloadSelectionStart;
|
||||
state->Stb.cursor = state->Stb.select_end = state->ReloadSelectionEnd;
|
||||
state->CursorClamp();
|
||||
}
|
||||
else if (!is_multiline)
|
||||
{
|
||||
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
||||
select_all = true;
|
||||
@ -4250,6 +4274,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
|
||||
if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory))
|
||||
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
|
||||
SetKeyOwner(ImGuiKey_Enter, id);
|
||||
SetKeyOwner(ImGuiKey_KeypadEnter, id);
|
||||
SetKeyOwner(ImGuiKey_Home, id);
|
||||
SetKeyOwner(ImGuiKey_End, id);
|
||||
if (is_multiline)
|
||||
@ -4259,8 +4285,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
if (is_osx)
|
||||
SetKeyOwner(ImGuiMod_Alt, id);
|
||||
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
|
||||
SetShortcutRouting(ImGuiKey_Tab, id);
|
||||
}
|
||||
|
||||
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function)
|
||||
@ -4389,12 +4413,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// We expect backends to emit a Tab key but some also emit a Tab character which we ignore (#2467, #1336)
|
||||
// (For Tab and Enter: Win32/SFML/Allegro are sending both keys and chars, GLFW and SDL are only sending keys. For Space they all send all threes)
|
||||
if ((flags & ImGuiInputTextFlags_AllowTabInput) && Shortcut(ImGuiKey_Tab, id, ImGuiInputFlags_Repeat) && !is_readonly)
|
||||
if ((flags & ImGuiInputTextFlags_AllowTabInput) && !is_readonly)
|
||||
{
|
||||
if (Shortcut(ImGuiKey_Tab, id, ImGuiInputFlags_Repeat))
|
||||
{
|
||||
unsigned int c = '\t'; // Insert TAB
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
|
||||
state->OnKeyPressed((int)c);
|
||||
}
|
||||
// FIXME: Implement Shift+Tab
|
||||
/*
|
||||
if (Shortcut(ImGuiKey_Tab | ImGuiMod_Shift, id, ImGuiInputFlags_Repeat))
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Process regular text input (before we check for Return because using some IME will effectively send a Return?)
|
||||
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
|
||||
@ -6308,7 +6341,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// Render
|
||||
const ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_TypeThin;
|
||||
ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_Compact;
|
||||
if (display_frame)
|
||||
{
|
||||
// Framed type
|
||||
@ -6611,7 +6644,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
RenderFrame(bb.Min, bb.Max, col, false, 0.0f);
|
||||
}
|
||||
if (g.NavId == id)
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding);
|
||||
|
||||
if (span_all_columns)
|
||||
{
|
||||
@ -7491,6 +7524,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
PopItemFlag();
|
||||
|
||||
bool want_open = false;
|
||||
bool want_open_nav_init = false;
|
||||
bool want_close = false;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
||||
{
|
||||
@ -7533,8 +7567,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
want_open = true;
|
||||
if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
|
||||
{
|
||||
want_open = true;
|
||||
want_open = want_open_nav_init = true;
|
||||
NavMoveRequestCancel();
|
||||
NavRestoreHighlightAfterMove();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -7566,13 +7601,13 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
|
||||
if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
|
||||
{
|
||||
// Don't reopen/recycle same menu level in the same frame, first close the other menu and yield for a frame.
|
||||
// Don't reopen/recycle same menu level in the same frame if it is a different menu ID, first close the other menu and yield for a frame.
|
||||
OpenPopup(label);
|
||||
}
|
||||
else if (want_open)
|
||||
{
|
||||
menu_is_open = true;
|
||||
OpenPopup(label);
|
||||
OpenPopup(label, ImGuiPopupFlags_NoReopen);// | (want_open_nav_init ? ImGuiPopupFlags_NoReopenAlwaysNavInit : 0));
|
||||
}
|
||||
|
||||
if (menu_is_open)
|
||||
@ -7584,6 +7619,14 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
PopStyleVar();
|
||||
if (menu_is_open)
|
||||
{
|
||||
// Implement what ImGuiPopupFlags_NoReopenAlwaysNavInit would do:
|
||||
// Perform an init request in the case the popup was already open (via a previous mouse hover)
|
||||
if (want_open && want_open_nav_init && !g.NavInitRequest)
|
||||
{
|
||||
FocusWindow(g.CurrentWindow, ImGuiFocusRequestFlags_UnlessBelowModal);
|
||||
NavInitWindow(g.CurrentWindow, false);
|
||||
}
|
||||
|
||||
// Restore LastItemData so IsItemXXXX functions can work after BeginMenu()/EndMenu()
|
||||
// (This fixes using IsItemClicked() and IsItemHovered(), but IsItemHovered() also relies on its support for ImGuiItemFlags_NoWindowHoverableCheck)
|
||||
g.LastItemData = last_item_in_parent;
|
||||
|
Loading…
Reference in New Issue
Block a user