mirror of
https://github.com/ocornut/imgui.git
synced 2025-12-20 05:15:36 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_sdl3.cpp # examples/example_sdl3_vulkan/main.cpp
This commit is contained in:
@@ -138,9 +138,6 @@
|
|||||||
#define GLFW_EXPOSE_NATIVE_X11
|
#define GLFW_EXPOSE_NATIVE_X11
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef GLFW_EXPOSE_NATIVE_WAYLAND
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
|
||||||
#endif
|
|
||||||
#include <GLFW/glfw3native.h>
|
#include <GLFW/glfw3native.h>
|
||||||
#undef Status // X11 headers are leaking this.
|
#undef Status // X11 headers are leaking this.
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-10-22: Fixed Platform_OpenInShellFn() return value (unused in core).
|
||||||
// 2025-09-24: Skip using the SDL_GetGlobalMouseState() state when one of our window is hovered, as the SDL_EVENT_MOUSE_MOTION data is reliable. Fix macOS notch mouse coordinates issue in fullscreen mode + better perf on X11. (#7919, #7786)
|
// 2025-09-24: Skip using the SDL_GetGlobalMouseState() state when one of our window is hovered, as the SDL_EVENT_MOUSE_MOTION data is reliable. Fix macOS notch mouse coordinates issue in fullscreen mode + better perf on X11. (#7919, #7786)
|
||||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||||
// 2025-09-15: Use SDL_GetWindowDisplayScale() on Mac to output DisplayFrameBufferScale. The function is more reliable during resolution changes e.g. going fullscreen. (#8703, #4414)
|
// 2025-09-15: Use SDL_GetWindowDisplayScale() on Mac to output DisplayFrameBufferScale. The function is more reliable during resolution changes e.g. going fullscreen. (#8703, #4414)
|
||||||
@@ -570,7 +571,7 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
||||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url); };
|
||||||
|
|
||||||
// Update monitor a first time during init
|
// Update monitor a first time during init
|
||||||
ImGui_ImplSDL3_UpdateMonitors();
|
ImGui_ImplSDL3_UpdateMonitors();
|
||||||
|
|||||||
@@ -47,19 +47,38 @@ Other Changes:
|
|||||||
result in temporarily incorrect state, which would lead to bugs to side effects
|
result in temporarily incorrect state, which would lead to bugs to side effects
|
||||||
in various locations, e.g. GetContentRegionAvail() calls or using clipper. (#9005)
|
in various locations, e.g. GetContentRegionAvail() calls or using clipper. (#9005)
|
||||||
EndTable() was mistakenly restoring a wrong current table.
|
EndTable() was mistakenly restoring a wrong current table.
|
||||||
|
- InputText: when buffer is not resizable, trying to paste contents that
|
||||||
|
cannot fit will now truncate text instead of ignoring the paste. (#9029)
|
||||||
- InputText: avoid continuously overwriting ownership of ImGuiKey_Enter/_KeypadEnter
|
- InputText: avoid continuously overwriting ownership of ImGuiKey_Enter/_KeypadEnter
|
||||||
keys in order to allow e.g. external Shortcut override behavior. (#9004)
|
keys in order to allow e.g. external Shortcut override behavior. (#9004)
|
||||||
|
- InputText: when using a callback to reduce/manipulate the value of BufTextLen,
|
||||||
|
we do not require anymore that CursorPos be clamped by user code. (#9029)
|
||||||
- InputTextMultiline: fixed a crash when using ImGuiInputTextFlags_WordWrap and
|
- InputTextMultiline: fixed a crash when using ImGuiInputTextFlags_WordWrap and
|
||||||
resizing the parent window while keeping the multi-line field active (which is
|
resizing the parent window while keeping the multi-line field active (which is
|
||||||
most typically achieved when resizing programmatically or via a docking layout
|
most typically achieved when resizing programmatically or via a docking layout
|
||||||
reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut]
|
reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut]
|
||||||
- Backends: Vulkan: added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to
|
- MultiSelect: added ImGuiMultiSelectFlags_NoSelectOnRightClick to disable default
|
||||||
Volk (default to "volk.h"). (#9008, #7722, #6582, #4854) [@mwlasiuk]
|
right-click processing, which selects item on mouse down and is designed for
|
||||||
- Backends: WebGPU: update to compile with Dawn and Emscripten's 4.0.10+
|
context-menus. (#8200, #9015)
|
||||||
'--use-port=emdawnwebgpu' ports. (#8381, #8898) [@brutpitt, @trbabb]
|
- Groups: fixed an issue reporting IsItemEdited() signal after EndGroup() when
|
||||||
When using Emscripten 4.0.10+, backend now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
triggered by some widgets e.g. Checkbox(), Selectable() and many others, which
|
||||||
instead of IMGUI_IMPL_WEBGPU_BACKEND_WGPU, if neither are specified.
|
cleared ActiveId at the same time as editing. (#9028)
|
||||||
(note: examples application were not updated yet)
|
Note that IsItemDeactivatedAfterEdit() was not affected, only IsItemEdited).
|
||||||
|
- Backends:
|
||||||
|
- GLFW: fixed building on Linux platforms where Wayland headers
|
||||||
|
are not available. (#9024, #8969, #8921, #8920) [@jagot]
|
||||||
|
- SDL3: fixed Platform_OpenInShellFn() return value (the return value
|
||||||
|
was unused in core but might be used by a direct caller). (#9027) [@achabense]
|
||||||
|
- Vulkan: added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to
|
||||||
|
Volk (default to "volk.h"). (#9008, #7722, #6582, #4854) [@mwlasiuk]
|
||||||
|
- WebGPU: update to compile with Dawn and Emscripten's 4.0.10+
|
||||||
|
'--use-port=emdawnwebgpu' ports. (#8381, #8898) [@brutpitt, @trbabb]
|
||||||
|
When using Emscripten 4.0.10+, backend now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||||
|
instead of IMGUI_IMPL_WEBGPU_BACKEND_WGPU, if neither are specified.
|
||||||
|
(note: examples application were not updated yet)
|
||||||
|
- Examples:
|
||||||
|
- GLFW+WebGPU: removed unnecessary ImGui_ImplWGPU_InvalidateDeviceObjects() call
|
||||||
|
during surface resize. (#8381)
|
||||||
|
|
||||||
Docking+Viewports Branch:
|
Docking+Viewports Branch:
|
||||||
|
|
||||||
|
|||||||
@@ -180,11 +180,7 @@ int main(int, char**)
|
|||||||
int width, height;
|
int width, height;
|
||||||
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
||||||
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
||||||
{
|
|
||||||
ImGui_ImplWGPU_InvalidateDeviceObjects(); // FIXME-OPT: Why doing this? This seems unnecessary and unoptimal.
|
|
||||||
ResizeSurface(width, height);
|
ResizeSurface(width, height);
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the Dear ImGui frame
|
// Start the Dear ImGui frame
|
||||||
ImGui_ImplWGPU_NewFrame();
|
ImGui_ImplWGPU_NewFrame();
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ int main(int, char**)
|
|||||||
bool CreateDeviceD3D(HWND hWnd)
|
bool CreateDeviceD3D(HWND hWnd)
|
||||||
{
|
{
|
||||||
// Setup swap chain
|
// Setup swap chain
|
||||||
|
// This is a basic setup. Optimally could use e.g. DXGI_SWAP_EFFECT_FLIP_DISCARD and handle fullscreen mode differently. See #8979 for suggestions.
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
sd.BufferCount = 2;
|
sd.BufferCount = 2;
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ int main(int, char**)
|
|||||||
bool CreateDeviceD3D(HWND hWnd)
|
bool CreateDeviceD3D(HWND hWnd)
|
||||||
{
|
{
|
||||||
// Setup swap chain
|
// Setup swap chain
|
||||||
|
// This is a basic setup. Optimally could use e.g. DXGI_SWAP_EFFECT_FLIP_DISCARD and handle fullscreen mode differently. See #8979 for suggestions.
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
sd.BufferCount = 2;
|
sd.BufferCount = 2;
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ int main(int, char**)
|
|||||||
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
||||||
{
|
{
|
||||||
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
||||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_height, fb_height, g_MinImageCount, 0);
|
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0);
|
||||||
g_MainWindowData.FrameIndex = 0;
|
g_MainWindowData.FrameIndex = 0;
|
||||||
g_SwapChainRebuild = false;
|
g_SwapChainRebuild = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ int main(int, char**)
|
|||||||
bool CreateDeviceD3D(HWND hWnd)
|
bool CreateDeviceD3D(HWND hWnd)
|
||||||
{
|
{
|
||||||
// Setup swap chain
|
// Setup swap chain
|
||||||
|
// This is a basic setup. Optimally could use handle fullscreen mode differently. See #8979 for suggestions.
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
sd.BufferCount = 2;
|
sd.BufferCount = 2;
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ int main(int, char**)
|
|||||||
bool CreateDeviceD3D(HWND hWnd)
|
bool CreateDeviceD3D(HWND hWnd)
|
||||||
{
|
{
|
||||||
// Setup swap chain
|
// Setup swap chain
|
||||||
|
// This is a basic setup. Optimally could use e.g. DXGI_SWAP_EFFECT_FLIP_DISCARD and handle fullscreen mode differently. See #8979 for suggestions.
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
sd.BufferCount = 2;
|
sd.BufferCount = 2;
|
||||||
|
|||||||
@@ -332,6 +332,7 @@ int main(int, char**)
|
|||||||
bool CreateDeviceD3D(HWND hWnd)
|
bool CreateDeviceD3D(HWND hWnd)
|
||||||
{
|
{
|
||||||
// Setup swap chain
|
// Setup swap chain
|
||||||
|
// This is a basic setup. Optimally could handle fullscreen mode differently. See #8979 for suggestions.
|
||||||
DXGI_SWAP_CHAIN_DESC1 sd;
|
DXGI_SWAP_CHAIN_DESC1 sd;
|
||||||
{
|
{
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
@@ -545,7 +546,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
DXGI_SWAP_CHAIN_DESC1 desc = {};
|
DXGI_SWAP_CHAIN_DESC1 desc = {};
|
||||||
g_pSwapChain->GetDesc1(&desc);
|
g_pSwapChain->GetDesc1(&desc);
|
||||||
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), desc.Format, desc.Flags);
|
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), desc.Format, desc.Flags);
|
||||||
assert(SUCCEEDED(result) && "Failed to resize swapchain.");
|
IM_ASSERT(SUCCEEDED(result) && "Failed to resize swapchain.");
|
||||||
CreateRenderTarget();
|
CreateRenderTarget();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -12197,6 +12197,7 @@ void ImGui::BeginGroup()
|
|||||||
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
||||||
group_data.BackupHoveredIdIsAlive = g.HoveredId != 0;
|
group_data.BackupHoveredIdIsAlive = g.HoveredId != 0;
|
||||||
group_data.BackupIsSameLine = window->DC.IsSameLine;
|
group_data.BackupIsSameLine = window->DC.IsSameLine;
|
||||||
|
group_data.BackupActiveIdHasBeenEditedThisFrame = g.ActiveIdHasBeenEditedThisFrame;
|
||||||
group_data.BackupDeactivatedIdIsAlive = g.DeactivatedItemData.IsAlive;
|
group_data.BackupDeactivatedIdIsAlive = g.DeactivatedItemData.IsAlive;
|
||||||
group_data.EmitItem = true;
|
group_data.EmitItem = true;
|
||||||
|
|
||||||
@@ -12261,7 +12262,7 @@ void ImGui::EndGroup()
|
|||||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||||
|
|
||||||
// Forward Edited flag
|
// Forward Edited flag
|
||||||
if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame)
|
if (g.ActiveIdHasBeenEditedThisFrame && !group_data.BackupActiveIdHasBeenEditedThisFrame)
|
||||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||||
|
|
||||||
// Forward Deactivated flag
|
// Forward Deactivated flag
|
||||||
|
|||||||
9
imgui.h
9
imgui.h
@@ -29,7 +29,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.92.5 WIP"
|
#define IMGUI_VERSION "1.92.5 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19241
|
#define IMGUI_VERSION_NUM 19242
|
||||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||||
@@ -3132,6 +3132,7 @@ enum ImGuiMultiSelectFlags_
|
|||||||
ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 14, // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
|
ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 14, // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
|
||||||
//ImGuiMultiSelectFlags_RangeSelect2d = 1 << 15, // Shift+Selection uses 2d geometry instead of linear sequence, so possible to use Shift+up/down to select vertically in grid. Analogous to what BoxSelect does.
|
//ImGuiMultiSelectFlags_RangeSelect2d = 1 << 15, // Shift+Selection uses 2d geometry instead of linear sequence, so possible to use Shift+up/down to select vertically in grid. Analogous to what BoxSelect does.
|
||||||
ImGuiMultiSelectFlags_NavWrapX = 1 << 16, // [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one.
|
ImGuiMultiSelectFlags_NavWrapX = 1 << 16, // [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one.
|
||||||
|
ImGuiMultiSelectFlags_NoSelectOnRightClick = 1 << 17, // Disable default right-click processing, which selects item on mouse down, and is designed for context-menus.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Main IO structure returned by BeginMultiSelect()/EndMultiSelect().
|
// Main IO structure returned by BeginMultiSelect()/EndMultiSelect().
|
||||||
@@ -4144,7 +4145,7 @@ struct ImGuiPlatformIO
|
|||||||
void* Platform_ClipboardUserData;
|
void* Platform_ClipboardUserData;
|
||||||
|
|
||||||
// Optional: Open link/folder/file in OS Shell
|
// Optional: Open link/folder/file in OS Shell
|
||||||
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac)
|
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac. expected to return false on failure, but some platforms may always return true)
|
||||||
bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path);
|
bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path);
|
||||||
void* Platform_OpenInShellUserData;
|
void* Platform_OpenInShellUserData;
|
||||||
|
|
||||||
@@ -4235,8 +4236,8 @@ struct ImGuiPlatformIO
|
|||||||
// Functions
|
// Functions
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
void ClearPlatformHandlers(); // Clear all Platform_XXX fields. Typically called on Platform Backend shutdown.
|
IMGUI_API void ClearPlatformHandlers(); // Clear all Platform_XXX fields. Typically called on Platform Backend shutdown.
|
||||||
void ClearRendererHandlers(); // Clear all Renderer_XXX fields. Typically called on Renderer Backend shutdown.
|
IMGUI_API void ClearRendererHandlers(); // Clear all Renderer_XXX fields. Typically called on Renderer Backend shutdown.
|
||||||
};
|
};
|
||||||
|
|
||||||
// (Optional) This is required when enabling multi-viewport. Represent the bounds of each connected monitor/display and their DPI.
|
// (Optional) This is required when enabling multi-viewport. Represent the bounds of each connected monitor/display and their DPI.
|
||||||
|
|||||||
@@ -2731,6 +2731,10 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
|
|||||||
{
|
{
|
||||||
HelpMarker("Selections can be built using Selectable(), TreeNode() or other widgets. Selection state is owned by application code/data.");
|
HelpMarker("Selections can be built using Selectable(), TreeNode() or other widgets. Selection state is owned by application code/data.");
|
||||||
|
|
||||||
|
ImGui::BulletText("Wiki page:");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextLinkOpenURL("imgui/wiki/Multi-Select", "https://github.com/ocornut/imgui/wiki/Multi-Select");
|
||||||
|
|
||||||
// Without any fancy API: manage single-selection yourself.
|
// Without any fancy API: manage single-selection yourself.
|
||||||
IMGUI_DEMO_MARKER("Widgets/Selection State/Single-Select");
|
IMGUI_DEMO_MARKER("Widgets/Selection State/Single-Select");
|
||||||
if (ImGui::TreeNode("Single-Select"))
|
if (ImGui::TreeNode("Single-Select"))
|
||||||
@@ -3264,6 +3268,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
|
|||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoSelect", &flags, ImGuiMultiSelectFlags_NoAutoSelect);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoSelect", &flags, ImGuiMultiSelectFlags_NoAutoSelect);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClearOnReselect", &flags, ImGuiMultiSelectFlags_NoAutoClearOnReselect);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClearOnReselect", &flags, ImGuiMultiSelectFlags_NoAutoClearOnReselect);
|
||||||
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoSelectOnRightClick", &flags, ImGuiMultiSelectFlags_NoSelectOnRightClick);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect1d", &flags, ImGuiMultiSelectFlags_BoxSelect1d);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect1d", &flags, ImGuiMultiSelectFlags_BoxSelect1d);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect2d", &flags, ImGuiMultiSelectFlags_BoxSelect2d);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect2d", &flags, ImGuiMultiSelectFlags_BoxSelect2d);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelectNoScroll", &flags, ImGuiMultiSelectFlags_BoxSelectNoScroll);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelectNoScroll", &flags, ImGuiMultiSelectFlags_BoxSelectNoScroll);
|
||||||
|
|||||||
@@ -1184,6 +1184,7 @@ struct IMGUI_API ImGuiGroupData
|
|||||||
ImVec2 BackupCurrLineSize;
|
ImVec2 BackupCurrLineSize;
|
||||||
float BackupCurrLineTextBaseOffset;
|
float BackupCurrLineTextBaseOffset;
|
||||||
ImGuiID BackupActiveIdIsAlive;
|
ImGuiID BackupActiveIdIsAlive;
|
||||||
|
bool BackupActiveIdHasBeenEditedThisFrame;
|
||||||
bool BackupDeactivatedIdIsAlive;
|
bool BackupDeactivatedIdIsAlive;
|
||||||
bool BackupHoveredIdIsAlive;
|
bool BackupHoveredIdIsAlive;
|
||||||
bool BackupIsSameLine;
|
bool BackupIsSameLine;
|
||||||
|
|||||||
@@ -4148,21 +4148,23 @@ static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
|||||||
obj->TextLen -= n;
|
obj->TextLen -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
static int STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
||||||
{
|
{
|
||||||
const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||||
const int text_len = obj->TextLen;
|
const int text_len = obj->TextLen;
|
||||||
IM_ASSERT(pos <= text_len);
|
IM_ASSERT(pos <= text_len);
|
||||||
|
|
||||||
if (!is_resizable && (new_text_len + obj->TextLen + 1 > obj->BufCapacity))
|
// We support partial insertion (with a mod in stb_textedit.h)
|
||||||
return false;
|
const int avail = obj->BufCapacity - 1 - obj->TextLen;
|
||||||
|
if (!is_resizable && new_text_len > avail)
|
||||||
|
new_text_len = avail; // 0
|
||||||
|
if (new_text_len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Grow internal buffer if needed
|
// Grow internal buffer if needed
|
||||||
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
||||||
if (new_text_len + text_len + 1 > obj->TextA.Size)
|
if (text_len + new_text_len + 1 > obj->TextA.Size && is_resizable)
|
||||||
{
|
{
|
||||||
if (!is_resizable)
|
|
||||||
return false;
|
|
||||||
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
|
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
|
||||||
obj->TextSrc = obj->TextA.Data;
|
obj->TextSrc = obj->TextA.Data;
|
||||||
}
|
}
|
||||||
@@ -4176,7 +4178,7 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
|
|||||||
obj->TextLen += new_text_len;
|
obj->TextLen += new_text_len;
|
||||||
obj->TextA[obj->TextLen] = '\0';
|
obj->TextA[obj->TextLen] = '\0';
|
||||||
|
|
||||||
return true;
|
return new_text_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols)
|
// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols)
|
||||||
@@ -4211,7 +4213,8 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
|
|||||||
state->cursor = state->select_start = state->select_end = 0;
|
state->cursor = state->select_start = state->select_end = 0;
|
||||||
if (text_len <= 0)
|
if (text_len <= 0)
|
||||||
return;
|
return;
|
||||||
if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len))
|
int text_len_inserted = ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len);
|
||||||
|
if (text_len_inserted > 0)
|
||||||
{
|
{
|
||||||
state->cursor = state->select_start = state->select_end = text_len;
|
state->cursor = state->select_start = state->select_end = text_len;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@@ -4306,15 +4309,20 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
|||||||
ImGuiContext& g = *Ctx;
|
ImGuiContext& g = *Ctx;
|
||||||
ImGuiInputTextState* obj = &g.InputTextState;
|
ImGuiInputTextState* obj = &g.InputTextState;
|
||||||
IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID);
|
IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID);
|
||||||
|
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||||
|
const bool is_readonly = (Flags & ImGuiInputTextFlags_ReadOnly) != 0;
|
||||||
|
int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
|
||||||
|
|
||||||
|
// We support partial insertion (with a mod in stb_textedit.h)
|
||||||
|
const int avail = BufSize - 1 - BufTextLen;
|
||||||
|
if (!is_resizable && new_text_len > avail)
|
||||||
|
new_text_len = avail; // 0
|
||||||
|
if (new_text_len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Grow internal buffer if needed
|
// Grow internal buffer if needed
|
||||||
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && is_resizable && !is_readonly)
|
||||||
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
|
|
||||||
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && (Flags & ImGuiInputTextFlags_ReadOnly) == 0)
|
|
||||||
{
|
{
|
||||||
if (!is_resizable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
IM_ASSERT(Buf == obj->TextA.Data);
|
IM_ASSERT(Buf == obj->TextA.Data);
|
||||||
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
|
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
|
||||||
obj->TextA.resize(new_buf_size + 1);
|
obj->TextA.resize(new_buf_size + 1);
|
||||||
@@ -5268,10 +5276,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
callback_data.BufTextLen = state->TextLen;
|
callback_data.BufTextLen = state->TextLen;
|
||||||
callback_data.BufSize = state->BufCapacity;
|
callback_data.BufSize = state->BufCapacity;
|
||||||
callback_data.BufDirty = false;
|
callback_data.BufDirty = false;
|
||||||
|
callback_data.CursorPos = state->Stb->cursor;
|
||||||
const int utf8_cursor_pos = callback_data.CursorPos = state->Stb->cursor;
|
callback_data.SelectionStart = state->Stb->select_start;
|
||||||
const int utf8_selection_start = callback_data.SelectionStart = state->Stb->select_start;
|
callback_data.SelectionEnd = state->Stb->select_end;
|
||||||
const int utf8_selection_end = callback_data.SelectionEnd = state->Stb->select_end;
|
|
||||||
|
|
||||||
// Call user code
|
// Call user code
|
||||||
callback(&callback_data);
|
callback(&callback_data);
|
||||||
@@ -5281,11 +5288,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields
|
IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields
|
||||||
IM_ASSERT(callback_data.BufSize == state->BufCapacity);
|
IM_ASSERT(callback_data.BufSize == state->BufCapacity);
|
||||||
IM_ASSERT(callback_data.Flags == flags);
|
IM_ASSERT(callback_data.Flags == flags);
|
||||||
const bool buf_dirty = callback_data.BufDirty;
|
if (callback_data.BufDirty || callback_data.CursorPos != state->Stb->cursor)
|
||||||
if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb->cursor = callback_data.CursorPos; state->CursorFollow = true; }
|
state->CursorFollow = true;
|
||||||
if (callback_data.SelectionStart != utf8_selection_start || buf_dirty) { state->Stb->select_start = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb->cursor : callback_data.SelectionStart; }
|
state->Stb->cursor = ImClamp(callback_data.CursorPos, 0, callback_data.BufTextLen);
|
||||||
if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb->select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb->select_start : callback_data.SelectionEnd; }
|
state->Stb->select_start = ImClamp(callback_data.SelectionStart, 0, callback_data.BufTextLen);
|
||||||
if (buf_dirty)
|
state->Stb->select_end = ImClamp(callback_data.SelectionEnd, 0, callback_data.BufTextLen);
|
||||||
|
if (callback_data.BufDirty)
|
||||||
{
|
{
|
||||||
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||||
IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||||
@@ -8219,8 +8227,8 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Right-click handling.
|
// Right-click handling.
|
||||||
// FIXME-MULTISELECT: Currently filtered out by ImGuiMultiSelectFlags_NoAutoSelect but maybe should be moved to Selectable(). See https://github.com/ocornut/imgui/pull/5816
|
// FIXME-MULTISELECT: Maybe should be moved to Selectable()? Also see #5816, #8200, #9015
|
||||||
if (hovered && IsMouseClicked(1) && (flags & ImGuiMultiSelectFlags_NoAutoSelect) == 0)
|
if (hovered && IsMouseClicked(1) && (flags & (ImGuiMultiSelectFlags_NoAutoSelect | ImGuiMultiSelectFlags_NoSelectOnRightClick)) == 0)
|
||||||
{
|
{
|
||||||
if (g.ActiveId != 0 && g.ActiveId != id)
|
if (g.ActiveId != 0 && g.ActiveId != id)
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||||
// - Added name to struct or it may be forward declared in our code.
|
// - Added name to struct or it may be forward declared in our code.
|
||||||
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
|
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// - Changed STB_TEXTEDIT_INSERTCHARS() to return inserted count (instead of 0/1 bool), allowing partial insertion.
|
||||||
|
// Grep for [DEAR IMGUI] to find some changes.
|
||||||
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||||
|
|
||||||
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
//
|
//
|
||||||
// VERSION HISTORY
|
// VERSION HISTORY
|
||||||
//
|
//
|
||||||
|
// !!!! (2025-10-23) changed STB_TEXTEDIT_INSERTCHARS() to return inserted count (instead of 0/1 bool), allowing partial insertion.
|
||||||
// 1.14 (2021-07-11) page up/down, various fixes
|
// 1.14 (2021-07-11) page up/down, various fixes
|
||||||
// 1.13 (2019-02-07) fix bug in undo size management
|
// 1.13 (2019-02-07) fix bug in undo size management
|
||||||
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
||||||
@@ -147,7 +149,8 @@
|
|||||||
// as manually wordwrapping for end-of-line positioning
|
// as manually wordwrapping for end-of-line positioning
|
||||||
//
|
//
|
||||||
// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i
|
// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i
|
||||||
// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*)
|
// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) try to insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*)
|
||||||
|
// returns number of characters actually inserted. [DEAR IMGUI]
|
||||||
//
|
//
|
||||||
// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key
|
// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key
|
||||||
//
|
//
|
||||||
@@ -775,7 +778,8 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
|
|||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
stb_textedit_delete_selection(str,state);
|
stb_textedit_delete_selection(str,state);
|
||||||
// try to insert the characters
|
// try to insert the characters
|
||||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
|
len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len);
|
||||||
|
if (len) {
|
||||||
stb_text_makeundo_insert(state, state->cursor, len);
|
stb_text_makeundo_insert(state, state->cursor, len);
|
||||||
state->cursor += len;
|
state->cursor += len;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@@ -800,13 +804,15 @@ static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* sta
|
|||||||
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
||||||
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
||||||
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
||||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
text_len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len);
|
||||||
|
if (text_len) {
|
||||||
state->cursor += text_len;
|
state->cursor += text_len;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stb_textedit_delete_selection(str, state); // implicitly clamps
|
stb_textedit_delete_selection(str, state); // implicitly clamps
|
||||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
text_len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len);
|
||||||
|
if (text_len) {
|
||||||
stb_text_makeundo_insert(state, state->cursor, text_len);
|
stb_text_makeundo_insert(state, state->cursor, text_len);
|
||||||
state->cursor += text_len;
|
state->cursor += text_len;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@@ -1352,7 +1358,7 @@ static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
// check type of recorded action:
|
// check type of recorded action:
|
||||||
if (u.insert_length) {
|
if (u.insert_length) {
|
||||||
// easy case: was a deletion, so we need to insert n characters
|
// easy case: was a deletion, so we need to insert n characters
|
||||||
STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
|
u.insert_length = STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
|
||||||
s->undo_char_point -= u.insert_length;
|
s->undo_char_point -= u.insert_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1403,7 +1409,7 @@ static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
|
|
||||||
if (r.insert_length) {
|
if (r.insert_length) {
|
||||||
// easy case: need to insert n characters
|
// easy case: need to insert n characters
|
||||||
STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
|
r.insert_length = STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
|
||||||
s->redo_char_point += r.insert_length;
|
s->redo_char_point += r.insert_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user