From 6cefd4fd88c47884933c828e3ad725f7675c52f7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 3 Jun 2024 16:41:19 +0200 Subject: [PATCH 01/66] Scrollbar: fixed miscalculation of vertical scrollbar visibility when required solely by the presence of an horizontal scrollbar. (#1574) Initially fixed by 2d9d7a10c, and broken back by a0994d74c2 (v1.71, wow). --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 +- imgui.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3b4ff8238..0c5550f99 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,6 +47,8 @@ Other changes: responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899) - Scrollbar: made scrolling logic more standard: clicking above or below the grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) +- Scrollbar: fixed miscalculation of vertical scrollbar visibility when required + solely by the presence of an horizontal scrollbar. (#1574) - Combo: simplified Combo() API uses a list clipper (due to its api it wasn't previously trivial before we added clipper.IncludeItemByIndex() function). - Disabled: nested tooltips or other non-child window within a BeginDisabled() diff --git a/imgui.cpp b/imgui.cpp index a4a578c6f..96a0ca118 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6926,7 +6926,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); // Amend the partially filled window->DecorationXXX values. diff --git a/imgui.h b/imgui.h index 689604ba4..477cf4b5f 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.8 WIP" -#define IMGUI_VERSION_NUM 19073 +#define IMGUI_VERSION_NUM 19074 #define IMGUI_HAS_TABLE /* From 68a05e3f0400442e9af743e7555b5ae552e66ed3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 3 Jun 2024 17:16:28 +0200 Subject: [PATCH 02/66] Tables: fixed a bug where after disabling the ScrollY flag for a table, previous scrollbar width would be accounted for. (#5920) Amend 317b33d6 --- docs/CHANGELOG.txt | 2 ++ imgui_tables.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 0c5550f99..cd71c6d9f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,8 @@ Other changes: grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) - Scrollbar: fixed miscalculation of vertical scrollbar visibility when required solely by the presence of an horizontal scrollbar. (#1574) +- Tables: fixed a bug where after disabling the ScrollY flag for a table, + previous scrollbar width would be accounted for. (#5920) - Combo: simplified Combo() API uses a list clipper (due to its api it wasn't previously trivial before we added clipper.IncludeItemByIndex() function). - Disabled: nested tooltips or other non-child window within a BeginDisabled() diff --git a/imgui_tables.cpp b/imgui_tables.cpp index d5848cb50..99d09c6df 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -437,6 +437,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // For non-scrolling tables, WorkRect == OuterRect == InnerRect. // But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable(). table->WorkRect = table->OuterRect = table->InnerRect = outer_rect; + table->HasScrollbarYPrev = table->HasScrollbarYCurr = false; } // Push a standardized ID for both child-using and not-child-using tables @@ -1490,9 +1491,10 @@ void ImGui::EndTable() } else if (temp_data->UserOuterSize.x <= 0.0f) { + const float inner_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; // Slightly misleading name but used for code symmetry with inner_content_max_y 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)); + outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, inner_content_max_x + decoration_size - temp_data->UserOuterSize.x); + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x)); } else { From f8de9fec8c5dc72fca6c35fc6052a8bb9813f5fc Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 3 Jun 2024 18:25:58 +0200 Subject: [PATCH 03/66] Backends: SDL3: Update for SDL_SYSTEM_CURSOR_xxx api renames. (#7653) --- backends/imgui_impl_sdl3.cpp | 18 +++++++++--------- docs/CHANGELOG.txt | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 083876611..3da22f9b5 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -413,15 +413,15 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void 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); - bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); - bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); - bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); + bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT); + bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE); + bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE); + bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE); + bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE); + bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE); + bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER); + bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED); // Set platform dependent data in viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index cd71c6d9f..2f74efc98 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,7 @@ Other changes: - Disabled: nested tooltips or other non-child window within a BeginDisabled() block disable the disabled state. (#211, #7640) - Misc: made ImGuiDir and ImGuiSortDirection stronger-typed enums. +- Backends: SDL3: Update for SDL_SYSTEM_CURSOR_xxx api renames. (#7653) ----------------------------------------------------------------------- From a31aa683ff91077a1a701d40acd55e3181fa2f4d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 3 Jun 2024 19:02:28 +0200 Subject: [PATCH 04/66] Tables: fixed an issue where ideal size reported to parent container wouldn't correctly take account of inner scrollbar. (#7651) --- docs/CHANGELOG.txt | 3 +++ imgui_tables.cpp | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 2f74efc98..7f3be8b0d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,9 @@ Other changes: grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) - Scrollbar: fixed miscalculation of vertical scrollbar visibility when required solely by the presence of an horizontal scrollbar. (#1574) +- Tables: fixed an issue where ideal size reported to parent container wouldn't + correctly take account of inner scrollbar, affecting potential auto-resize of + parent container. (#7651) - Tables: fixed a bug where after disabling the ScrollY flag for a table, previous scrollbar width would be accounted for. (#5920) - Combo: simplified Combo() API uses a list clipper (due to its api it wasn't diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 99d09c6df..34ab36e6e 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1491,10 +1491,13 @@ void ImGui::EndTable() } else if (temp_data->UserOuterSize.x <= 0.0f) { + // Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block + // - Checking for ImGuiTableFlags_ScrollX/ScrollY flag makes us a frame ahead when disabling those flags. + // - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback. const float inner_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; // Slightly misleading name but used for code symmetry with inner_content_max_y - 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_ScrollY) ? inner_window->ScrollbarSizes.x : 0.0f); outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, inner_content_max_x + decoration_size - temp_data->UserOuterSize.x); - outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x)); + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x + decoration_size)); } else { @@ -1502,9 +1505,9 @@ void ImGui::EndTable() } if (temp_data->UserOuterSize.y <= 0.0f) { - const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f; + const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.y : 0.0f; outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y); - outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y)); + outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y + decoration_size)); } else { From 209edcc2477ca6bfa0cb6436b775c7fccbf145c2 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Tue, 4 Jun 2024 17:35:18 +0300 Subject: [PATCH 05/66] Fixed incorrect order of arguments in IsMouseClicked(). (#7657, #456) Amend 85513de24 --- docs/CHANGELOG.txt | 4 ++++ imgui.cpp | 2 +- imgui.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7f3be8b0d..9578f87cb 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,10 @@ Breaking changes: Other changes: +- Inputs: Fixed IsMouseClicked(..., repeat=true); broken on 2024/05/22. + (due to an internal api parameter swap, repeat wouldn't be honored and + ownership would be accidently checked even though this api is meant to not + check ownership). (#7657) [@korenkonder] - Windows: fixed altering FramePadding mid-frame not correctly affecting logic responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899) - Scrollbar: made scrolling logic more standard: clicking above or below the diff --git a/imgui.cpp b/imgui.cpp index 96a0ca118..cb01836d8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8900,7 +8900,7 @@ bool ImGui::IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id) bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) { - return IsMouseClicked(button, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); + return IsMouseClicked(button, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any); } bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id) diff --git a/imgui.h b/imgui.h index 477cf4b5f..69a53b017 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.8 WIP" -#define IMGUI_VERSION_NUM 19074 +#define IMGUI_VERSION_NUM 19075 #define IMGUI_HAS_TABLE /* From b95b2b4574dea80f38edce3477d5e15ef1f9a2ee Mon Sep 17 00:00:00 2001 From: jungnitz <24437335+jungnitz@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:18:23 +0200 Subject: [PATCH 06/66] Fixed (harmless) incorrect order of arguments in IsKeyChordPressed (#7657) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index cb01836d8..92ea44cd7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9725,7 +9725,7 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) // This is the only public API until we expose owner_id versions of the API as replacements. bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord) { - return IsKeyChordPressed(key_chord, 0, ImGuiInputFlags_None); + return IsKeyChordPressed(key_chord, ImGuiInputFlags_None, ImGuiKeyOwner_Any); } // This is equivalent to comparing KeyMods + doing a IsKeyPressed() From 219c6adc58221df4f1cf6c7033d9fcbca1962411 Mon Sep 17 00:00:00 2001 From: Kenneth Rapp Date: Wed, 5 Jun 2024 07:50:24 -0500 Subject: [PATCH 07/66] Examples: SDL3+SDLRenderer3: Update SDL_SetRenderDrawColorFloat() call. (#7658) --- examples/example_sdl3_sdlrenderer3/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_sdl3_sdlrenderer3/main.cpp b/examples/example_sdl3_sdlrenderer3/main.cpp index baa7cd76e..98b9666ea 100644 --- a/examples/example_sdl3_sdlrenderer3/main.cpp +++ b/examples/example_sdl3_sdlrenderer3/main.cpp @@ -160,7 +160,7 @@ int main(int, char**) // Rendering ImGui::Render(); //SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); - SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255)); + SDL_SetRenderDrawColorFloat(renderer, clear_color.x, clear_color.y, clear_color.z, clear_color.w); SDL_RenderClear(renderer); ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer); SDL_RenderPresent(renderer); From 0561d708baa268dbb9da333d6fab1924dd017f8a Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 5 Jun 2024 15:47:21 +0200 Subject: [PATCH 08/66] Modals, Popups: fixed an issue preventing to close a popup opened over a modal by clicking over void. (#7654) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 6 +++++- imgui_demo.cpp | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9578f87cb..6b2f0f042 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,8 @@ Other changes: check ownership). (#7657) [@korenkonder] - Windows: fixed altering FramePadding mid-frame not correctly affecting logic responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899) +- Popups: fixed an issue preventing to close a popup opened over a modal by clicking + over void (it required clicking over the visible part of the modal). (#7654) - Scrollbar: made scrolling logic more standard: clicking above or below the grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) - Scrollbar: fixed miscalculation of vertical scrollbar visibility when required diff --git a/imgui.cpp b/imgui.cpp index 92ea44cd7..ffd055aec 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7378,9 +7378,13 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) { + // This block would typically be reached in two situations: + // - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag. + // - User clicking on void or anything behind a modal while a modal is open (window == NULL) IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) - BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal. + BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?) + ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals return; } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8183ee1ae..de657be45 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3875,7 +3875,7 @@ static void ShowDemoWindowPopups() static int item = 1; static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - ImGui::ColorEdit4("color", color); + ImGui::ColorEdit4("Color", color); if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); @@ -3887,6 +3887,7 @@ static void ShowDemoWindowPopups() if (ImGui::BeginPopupModal("Stacked 2", &unused_open)) { ImGui::Text("Hello from Stacked The Second!"); + ImGui::ColorEdit4("Color", color); // Allow opening another nested popup if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); From 3460014e055cb0bd70676edfe7ea42cab8b6a9ec Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 15:53:05 +0200 Subject: [PATCH 09/66] Internals: avoid using bitfields in ImGuiNextItemData as it leads to extraneous packing. rename ImGuiDataTypeTempStorage to ImGuiDataTypeStorage. moved DataType section above Widgets. --- imgui_internal.h | 72 +++++++++++++++++++++++------------------------ imgui_widgets.cpp | 6 ++-- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 0d5cd43a6..a5784af0b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -14,8 +14,8 @@ Index of this file: // [SECTION] Macros // [SECTION] Generic helpers // [SECTION] ImDrawList support -// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Data types support +// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Popup support // [SECTION] Inputs support // [SECTION] Clipper support @@ -798,6 +798,40 @@ struct ImDrawDataBuilder ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); } }; +//----------------------------------------------------------------------------- +// [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 ImGuiDataTypeStorage +{ + ImU8 Data[8]; // Opaque storage to 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] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- @@ -1189,7 +1223,7 @@ struct ImGuiNextItemData ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut() ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut() bool OpenVal; // Set by SetNextItemOpen() - ImGuiCond OpenCond : 8; + ImU8 OpenCond; // Set by SetNextItemOpen() ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! @@ -1263,40 +1297,6 @@ 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 //----------------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 277588e47..2cc09294e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2150,7 +2150,7 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); - ImGuiDataTypeTempStorage data_backup; + ImGuiDataTypeStorage data_backup; memcpy(&data_backup, p_data, type_info->Size); // Sanitize format @@ -3471,7 +3471,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG { // Backup old value size_t data_type_size = type_info->Size; - ImGuiDataTypeTempStorage data_backup; + ImGuiDataTypeStorage data_backup; memcpy(&data_backup, p_data, data_type_size); // Apply new value (or operations) then clamp @@ -6497,7 +6497,7 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond) return; g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen; g.NextItemData.OpenVal = is_open; - g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always; + g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always); } // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag). From 47db0698d2ac88f10cc2cf0085e14f83b3d4c868 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 16:39:25 +0200 Subject: [PATCH 10/66] InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal, ImGuiInputTextFlags_DisplayEmptyRefVal. (#7305) --- docs/CHANGELOG.txt | 4 ++++ imgui.h | 2 ++ imgui_demo.cpp | 28 ++++++++++++++++------------ imgui_internal.h | 6 +++++- imgui_widgets.cpp | 32 ++++++++++++++++++++++---------- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6b2f0f042..74cb0a35c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,6 +62,10 @@ Other changes: previous scrollbar width would be accounted for. (#5920) - Combo: simplified Combo() API uses a list clipper (due to its api it wasn't previously trivial before we added clipper.IncludeItemByIndex() function). +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal + to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut] +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal + to display a zero-value as empty. (#7305) [@supermerill, @ocornut] - Disabled: nested tooltips or other non-child window within a BeginDisabled() block disable the disabled state. (#211, #7640) - Misc: made ImGuiDir and ImGuiSortDirection stronger-typed enums. diff --git a/imgui.h b/imgui.h index 69a53b017..b03f7143c 100644 --- a/imgui.h +++ b/imgui.h @@ -1104,6 +1104,8 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 21, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value. + ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 22, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal. // Obsolete names //ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior diff --git a/imgui_demo.cpp b/imgui_demo.cpp index de657be45..6b7630ec7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2273,20 +2273,24 @@ static void ShowDemoWindowWidgets() IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs"); static bool inputs_step = true; + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None; ImGui::SeparatorText("Inputs"); ImGui::Checkbox("Show step buttons", &inputs_step); - ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); - ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X"); - ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); - ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X"); - ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); - ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); - ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); - ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", &flags, ImGuiInputTextFlags_ParseEmptyRefVal); + ImGui::CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", &flags, ImGuiInputTextFlags_DisplayEmptyRefVal); + ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X", flags); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", flags); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL, NULL, NULL, flags); ImGui::TreePop(); } diff --git a/imgui_internal.h b/imgui_internal.h index a5784af0b..6bd89c2b9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1211,6 +1211,7 @@ enum ImGuiNextItemDataFlags_ ImGuiNextItemDataFlags_HasWidth = 1 << 0, ImGuiNextItemDataFlags_HasOpen = 1 << 1, ImGuiNextItemDataFlags_HasShortcut = 1 << 2, + ImGuiNextItemDataFlags_HasRefVal = 1 << 3, }; struct ImGuiNextItemData @@ -1224,6 +1225,7 @@ struct ImGuiNextItemData ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut() bool OpenVal; // Set by SetNextItemOpen() ImU8 OpenCond; // Set by SetNextItemOpen() + ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! @@ -2154,6 +2156,7 @@ struct ImGuiContext ImGuiInputTextDeactivatedState InputTextDeactivatedState; ImFont InputTextPasswordFont; ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types int BeginMenuDepth; int BeginComboDepth; ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets @@ -2376,6 +2379,7 @@ struct ImGuiContext MouseStationaryTimer = 0.0f; TempInputId = 0; + memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue)); BeginMenuDepth = BeginComboDepth = 0; ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; ColorEditCurrentID = ColorEditSavedID = 0; @@ -3458,7 +3462,7 @@ namespace ImGui IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); - IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format); + IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 2cc09294e..5f73e2817 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2141,18 +2141,25 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const // User can input math operators (e.g. +100) to edit a numerical values. // NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. -bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) +bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty) { - while (ImCharIsBlankA(*buf)) - buf++; - if (!buf[0]) - return false; - // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); ImGuiDataTypeStorage data_backup; memcpy(&data_backup, p_data, type_info->Size); + while (ImCharIsBlankA(*buf)) + buf++; + if (!buf[0]) + { + if (p_data_when_empty != NULL) + { + memcpy(p_data, p_data_when_empty, type_info->Size); + return memcmp(&data_backup, p_data, type_info->Size) != 0; + } + return false; + } + // Sanitize format // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. @@ -3475,7 +3482,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG memcpy(&data_backup, p_data, data_type_size); // Apply new value (or operations) then clamp - DataTypeApplyFromText(data_buf, data_type, p_data, format); + DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL); if (p_clamp_min || p_clamp_max) { if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0) @@ -3505,8 +3512,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; + void* p_data_default = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue; + char buf[64]; - DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); + if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0) + buf[0] = 0; + else + DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. flags |= (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint; @@ -3515,7 +3527,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if (p_step == NULL) { if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); } else { @@ -3525,7 +3537,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data PushID(label); SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable); // Step buttons From f1eaf8d7c0150ebfc20a63adec3ed1adf0287ca0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 17:00:50 +0200 Subject: [PATCH 11/66] Internals: added SetNextItemRefVal(). (#7305) --- imgui_internal.h | 1 + imgui_widgets.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index 6bd89c2b9..7d1b1b2c0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3473,6 +3473,7 @@ namespace ImGui IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active + IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data); // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5f73e2817..725172349 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3498,6 +3498,13 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG return value_changed; } +void ImGui::SetNextItemRefVal(ImGuiDataType data_type, void* p_data) +{ + ImGuiContext& g = *GImGui; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasRefVal; + memcpy(&g.NextItemData.RefVal, p_data, DataTypeGetInfo(data_type)->Size); +} + // Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional. // Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) From 2a418f054d8ea38c95f5ee894a8c4f2947514dab Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 17:13:37 +0200 Subject: [PATCH 12/66] InputText: reordered all flags. (ABI breaking) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 1 + imgui.h | 51 ++++++++++++++++++++++++++-------------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 74cb0a35c..3726422c8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,6 +41,9 @@ HOW TO UPDATE? Breaking changes: +- Reordered various ImGuiInputTextFlags values. This should not be breaking unless + you are using generated headers that have values not matching the main library. + Other changes: - Inputs: Fixed IsMouseClicked(..., repeat=true); broken on 2024/05/22. diff --git a/imgui.cpp b/imgui.cpp index ffd055aec..8295cb0cf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,7 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. - 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022): - old: CaptureKeyboardFromApp(bool) - new: SetNextFrameWantCaptureKeyboard(bool) diff --git a/imgui.h b/imgui.h index b03f7143c..7acc9e69e 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.8 WIP" -#define IMGUI_VERSION_NUM 19075 +#define IMGUI_VERSION_NUM 19076 #define IMGUI_HAS_TABLE /* @@ -1082,30 +1082,37 @@ enum ImGuiChildFlags_ // (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigInputTextCursorBlink and io.ConfigInputTextEnterKeepActive) enum ImGuiInputTextFlags_ { + // Basic filters (also see ImGuiInputTextFlags_CallbackCharFilter) ImGuiInputTextFlags_None = 0, ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef - ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z - ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs - ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus - ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. - ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling) - ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer. - ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. - ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field - ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). - ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally - ImGuiInputTextFlags_AlwaysOverwrite = 1 << 13, // Overwrite mode - ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode - ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_CharsScientific = 1 << 2, // Allow 0123456789.+-*/eE (Scientific notation input) + ImGuiInputTextFlags_CharsUppercase = 1 << 3, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 4, // Filter out spaces, tabs + + // Inputs + ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. + ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter). + + // Other options + ImGuiInputTextFlags_ReadOnly = 1 << 9, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 10, // Password mode, display all characters as '*', disable copy + ImGuiInputTextFlags_AlwaysOverwrite = 1 << 11, // Overwrite mode + ImGuiInputTextFlags_AutoSelectAll = 1 << 12, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 13, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value. + ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 14, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal. + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 15, // Disable following the cursor horizontally ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). - ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) - ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) - ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) - ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) - ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 21, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value. - ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 22, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal. + + // Callback features + ImGuiInputTextFlags_CallbackCompletion = 1 << 17, // Callback on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 18, // Callback on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 19, // Callback on each iteration. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 20, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. + ImGuiInputTextFlags_CallbackResize = 1 << 21, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) + ImGuiInputTextFlags_CallbackEdit = 1 << 22, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) // Obsolete names //ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior @@ -1125,7 +1132,7 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow. IMPORTANT: node can still be marked open/close if you don't set the _Leaf flag! - ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node. ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode. ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area). ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text. From 67d886fd637641ab2d7b0f2a5c1b186a54f795b6 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 17:20:32 +0200 Subject: [PATCH 13/66] Removed ImGuiButtonFlags_MouseButtonDefault_. --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 1 + imgui.h | 8 +++----- imgui_widgets.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3726422c8..30261158e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,8 @@ Breaking changes: - Reordered various ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. +- Removed ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft + from imgui.h, was mostly unused and misleading. Other changes: diff --git a/imgui.cpp b/imgui.cpp index 8295cb0cf..60a686a1e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -431,6 +431,7 @@ CODE You can read releases logs https://github.com/ocornut/imgui/releases for more details. - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. + - 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading. - 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022): - old: CaptureKeyboardFromApp(bool) - new: SetNextFrameWantCaptureKeyboard(bool) diff --git a/imgui.h b/imgui.h index 7acc9e69e..a5d0845bd 100644 --- a/imgui.h +++ b/imgui.h @@ -1657,10 +1657,8 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default) ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button - - // [Internal] - ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, - ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal] + //ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, }; // Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() @@ -3265,7 +3263,7 @@ namespace ImGui static inline void PopAllowKeyboardFocus() { PopTabStop(); } // OBSOLETED in 1.89 (from August 2022) IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Use new ImageButton() signature (explicit item id, regular FramePadding) - // OBSOLETED in 1.87 (from February 2022) + // OBSOLETED in 1.87 (from February 2022 but more formally obsoleted April 2024) IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value! //static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 725172349..c286b2d7a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -488,7 +488,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool // Default only reacts to left mouse button if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) - flags |= ImGuiButtonFlags_MouseButtonDefault_; + flags |= ImGuiButtonFlags_MouseButtonLeft; // Default behavior requires click + release inside bounding box if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) From 6f7b5d0ee2fe9948ab871a530888a6dc5c960700 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 6 Jun 2024 17:29:19 +0200 Subject: [PATCH 14/66] Version 1.90.8 --- docs/CHANGELOG.txt | 22 ++++++++++++---------- imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 30261158e..77b0842dc 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,30 +36,36 @@ HOW TO UPDATE? - Please report any issue! ----------------------------------------------------------------------- - VERSION 1.90.8 WIP (In Progress) + VERSION 1.90.8 (Released 2024-06-06) ----------------------------------------------------------------------- +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.8 + Breaking changes: -- Reordered various ImGuiInputTextFlags values. This should not be breaking unless +- Reordered various ImGuiInputTextFlags values. This should NOT be breaking unless you are using generated headers that have values not matching the main library. - Removed ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft from imgui.h, was mostly unused and misleading. Other changes: -- Inputs: Fixed IsMouseClicked(..., repeat=true); broken on 2024/05/22. +- Inputs: fixed IsMouseClicked(..., repeat=true); broken in 1.90.7 on 2024/05/22. (due to an internal api parameter swap, repeat wouldn't be honored and - ownership would be accidently checked even though this api is meant to not + ownership would be accidentally checked even though this api is meant to not check ownership). (#7657) [@korenkonder] - Windows: fixed altering FramePadding mid-frame not correctly affecting logic responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899) -- Popups: fixed an issue preventing to close a popup opened over a modal by clicking - over void (it required clicking over the visible part of the modal). (#7654) - Scrollbar: made scrolling logic more standard: clicking above or below the grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) - Scrollbar: fixed miscalculation of vertical scrollbar visibility when required solely by the presence of an horizontal scrollbar. (#1574) +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal + to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut] +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal + to display a zero-value as empty. (#7305) [@supermerill, @ocornut] +- Popups: fixed an issue preventing to close a popup opened over a modal by clicking + over void (it required clicking over the visible part of the modal). (#7654) - Tables: fixed an issue where ideal size reported to parent container wouldn't correctly take account of inner scrollbar, affecting potential auto-resize of parent container. (#7651) @@ -67,10 +73,6 @@ Other changes: previous scrollbar width would be accounted for. (#5920) - Combo: simplified Combo() API uses a list clipper (due to its api it wasn't previously trivial before we added clipper.IncludeItemByIndex() function). -- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal - to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut] -- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal - to display a zero-value as empty. (#7305) [@supermerill, @ocornut] - Disabled: nested tooltips or other non-child window within a BeginDisabled() block disable the disabled state. (#211, #7640) - Misc: made ImGuiDir and ImGuiSortDirection stronger-typed enums. diff --git a/imgui.cpp b/imgui.cpp index 60a686a1e..f9a48e14c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index a5d0845bd..271c47dc2 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (headers) // Help: @@ -27,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.8 WIP" -#define IMGUI_VERSION_NUM 19076 +#define IMGUI_VERSION "1.90.8" +#define IMGUI_VERSION_NUM 19080 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6b7630ec7..febb58058 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ac31f618e..31465f529 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 7d1b1b2c0..d5e6d95e0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (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. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 34ab36e6e..24263bd85 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index c286b2d7a..55d264d1a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (widgets code) /* From 7260bb51cfc129fa5e46817dfd30632a9c1f2ff7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 7 Jun 2024 16:57:01 +0200 Subject: [PATCH 15/66] Version 1.90.9 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 77b0842dc..62377c7b6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,15 @@ 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.9 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking changes: + +Other changes: + + ----------------------------------------------------------------------- VERSION 1.90.8 (Released 2024-06-06) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index f9a48e14c..76da8c68d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 271c47dc2..d3a74704a 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (headers) // Help: @@ -27,7 +27,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.8" +#define IMGUI_VERSION "1.90.9 WIP" #define IMGUI_VERSION_NUM 19080 #define IMGUI_HAS_TABLE diff --git a/imgui_demo.cpp b/imgui_demo.cpp index febb58058..b2f0f4a14 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 31465f529..171889f2c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index d5e6d95e0..27e0bfeb2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (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. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 24263bd85..778d27afd 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 55d264d1a..4c3b1c046 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 +// dear imgui, v1.90.9 WIP // (widgets code) /* From d46a0aa06939c5a754bb2cab0e7c464ecb36ce06 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 10 Jun 2024 13:59:46 +0200 Subject: [PATCH 16/66] Internals: renamed HoveredIdDisabled to HoveredIdIsDisabled for consistency. --- imgui.cpp | 8 ++++---- imgui_internal.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 76da8c68d..d4d3a8a76 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4172,7 +4172,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag // Done with rectangle culling so we can perform heavier checks now. if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) { - g.HoveredIdDisabled = true; + g.HoveredIdIsDisabled = true; return false; } @@ -4207,7 +4207,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag // Release active id if turning disabled if (g.ActiveId == id && id != 0) ClearActiveID(); - g.HoveredIdDisabled = true; + g.HoveredIdIsDisabled = true; return false; } @@ -4510,7 +4510,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() g.MovingWindow = NULL; // Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already) - if (g.HoveredIdDisabled) + if (g.HoveredIdIsDisabled) g.MovingWindow = NULL; } else if (root_window == NULL && g.NavWindow != NULL) @@ -4704,7 +4704,7 @@ void ImGui::NewFrame() g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; - g.HoveredIdDisabled = false; + g.HoveredIdIsDisabled = false; // Clear ActiveID if the item is not alive anymore. // In 1.87, the common most call to KeepAliveID() was moved from GetID() to ItemAdd(). diff --git a/imgui_internal.h b/imgui_internal.h index 27e0bfeb2..9dc832d97 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1971,7 +1971,7 @@ struct ImGuiContext float HoveredIdTimer; // Measure contiguous hovering time float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active bool HoveredIdAllowOverlap; - bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. + bool HoveredIdIsDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. bool ItemUnclipByLog; // Disable ItemAdd() clipping, essentially a memory-locality friendly copy of LogEnabled ImGuiID ActiveId; // Active widget ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame) @@ -2279,7 +2279,7 @@ struct ImGuiContext DebugHookIdInfo = 0; HoveredId = HoveredIdPreviousFrame = 0; HoveredIdAllowOverlap = false; - HoveredIdDisabled = false; + HoveredIdIsDisabled = false; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; ItemUnclipByLog = false; ActiveId = 0; From a47bfb1b5b1b9d62676ccb31d7c8a441d8eb2686 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 10 Jun 2024 15:02:43 +0200 Subject: [PATCH 17/66] Examples: GLFW+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR (#7671) --- docs/CHANGELOG.txt | 3 +++ examples/example_glfw_vulkan/main.cpp | 17 +++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 62377c7b6..19b9cd36a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,9 @@ Breaking changes: Other changes: +- Examples: GLFW+Vulkan: handle swap chain resize even without Vulkan returning + VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego] + ----------------------------------------------------------------------- VERSION 1.90.8 (Released 2024-06-06) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index b6e53ed8d..26012065a 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -485,17 +485,14 @@ int main(int, char**) glfwPollEvents(); // Resize swap chain? - if (g_SwapChainRebuild) + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height)) { - int width, height; - glfwGetFramebufferSize(window, &width, &height); - if (width > 0 && height > 0) - { - ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); - ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); - g_MainWindowData.FrameIndex = 0; - g_SwapChainRebuild = false; - } + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; } // Start the Dear ImGui frame From 7538ca6f405952cb25e42ff7cc22857e2c0b3c14 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 10 Jun 2024 15:04:40 +0200 Subject: [PATCH 18/66] Examples: SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR (#7671) --- docs/CHANGELOG.txt | 5 +++-- examples/example_sdl2_vulkan/main.cpp | 17 +++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 19b9cd36a..8db7c1f9e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,8 +43,9 @@ Breaking changes: Other changes: -- Examples: GLFW+Vulkan: handle swap chain resize even without Vulkan returning - VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego] +- Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan + returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) + [@AndreiNego, @ocornut] ----------------------------------------------------------------------- diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index df0db4d1e..7f8fd0abb 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -494,17 +494,14 @@ int main(int, char**) } // Resize swap chain? - if (g_SwapChainRebuild) + int fb_width, fb_height; + SDL_GetWindowSize(window, &fb_width, &fb_height); + if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height)) { - int width, height; - SDL_GetWindowSize(window, &width, &height); - if (width > 0 && height > 0) - { - ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); - ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); - g_MainWindowData.FrameIndex = 0; - g_SwapChainRebuild = false; - } + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; } // Start the Dear ImGui frame From 22d65c7949d6e78b5f4933733cedf4e0d6a3d11d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 10 Jun 2024 17:42:08 +0200 Subject: [PATCH 19/66] Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 14 +++++++------- imgui.h | 28 +++++++++++++++++----------- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 8db7c1f9e..b5caca628 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,6 +41,9 @@ HOW TO UPDATE? Breaking changes: +- Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to + ImGuiStoragePair (simpler for many languages). No significant nested type left. + Other changes: - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan diff --git a/imgui.cpp b/imgui.cpp index d4d3a8a76..e16dea2ac 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,7 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/10 (1.90.9) - removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. - 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading. - 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022): @@ -2502,15 +2503,14 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& //----------------------------------------------------------------------------- // std::lower_bound but without the bullshit -static ImGuiStorage::ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID key) +static ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID key) { - ImGuiStorage::ImGuiStoragePair* first = data.Data; - ImGuiStorage::ImGuiStoragePair* last = data.Data + data.Size; - size_t count = (size_t)(last - first); - while (count > 0) + ImGuiStoragePair* first = data.Data; + ImGuiStoragePair* last = data.Data + data.Size; + for (size_t count = (size_t)(last - first); count > 0; ) { size_t count2 = count >> 1; - ImGuiStorage::ImGuiStoragePair* mid = first + count2; + ImGuiStoragePair* mid = first + count2; if (mid->key < key) { first = ++mid; @@ -15419,7 +15419,7 @@ void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) { if (!TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) return; - for (const ImGuiStorage::ImGuiStoragePair& p : storage->Data) + for (const ImGuiStoragePair& p : storage->Data) BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer. TreePop(); } diff --git a/imgui.h b/imgui.h index d3a74704a..c48fd4c75 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19080 +#define IMGUI_VERSION_NUM 19081 #define IMGUI_HAS_TABLE /* @@ -178,7 +178,8 @@ struct ImGuiOnceUponAFrame; // Helper for running a block of code not mo struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiPlatformImeData; // Platform IME data for io.SetPlatformImeDataFn() function. struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use) -struct ImGuiStorage; // Helper for key->value storage +struct ImGuiStorage; // Helper for key->value storage (container sorted by key) +struct ImGuiStoragePair; // Helper for key->value storage (pair) struct ImGuiStyle; // Runtime data for styling/colors struct ImGuiTableSortSpecs; // Sorting specifications for a table (often handling sort specs for a single column, occasionally more) struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table @@ -2460,6 +2461,16 @@ struct ImGuiTextBuffer IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); }; +// [Internal] Key+Value for ImGuiStorage +struct ImGuiStoragePair +{ + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; + ImGuiStoragePair(ImGuiID _key, int _val) { key = _key; val_i = _val; } + ImGuiStoragePair(ImGuiID _key, float _val) { key = _key; val_f = _val; } + ImGuiStoragePair(ImGuiID _key, void* _val) { key = _key; val_p = _val; } +}; + // Helper: Key->Value storage // Typically you don't have to worry about this since a storage is held within each Window. // We use it to e.g. store collapse state for a tree (Int 0/1) @@ -2471,15 +2482,6 @@ struct ImGuiTextBuffer struct ImGuiStorage { // [Internal] - struct ImGuiStoragePair - { - ImGuiID key; - union { int val_i; float val_f; void* val_p; }; - ImGuiStoragePair(ImGuiID _key, int _val) { key = _key; val_i = _val; } - ImGuiStoragePair(ImGuiID _key, float _val) { key = _key; val_f = _val; } - ImGuiStoragePair(ImGuiID _key, void* _val) { key = _key; val_p = _val; } - }; - ImVector Data; // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) @@ -2508,6 +2510,10 @@ struct ImGuiStorage IMGUI_API void BuildSortByKey(); // Obsolete: use on your own storage if you know only integer are being stored (open/close all tree nodes) IMGUI_API void SetAllInt(int val); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //typedef ::ImGuiStoragePair ImGuiStoragePair; // 1.90.8: moved type outside struct +#endif }; // Helper: Manually clip large list of items. From 8caf7afbad61cd4ce7fff5bb3f29b35d64865e63 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 10 Jun 2024 19:20:12 +0200 Subject: [PATCH 20/66] Internals: made ImLowerBound() accessible in internals + take a span. + rearrange child/popup/tooltips section. Because upcoming rework of ImGuiSelectionBasicStorage will want to do a lower bound on a span. --- imgui.cpp | 40 +++++++++++++++++++--------------------- imgui_internal.h | 17 ++++++++++++----- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e16dea2ac..f4545ec55 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2503,17 +2503,16 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& //----------------------------------------------------------------------------- // std::lower_bound but without the bullshit -static ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID key) +ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key) { - ImGuiStoragePair* first = data.Data; - ImGuiStoragePair* last = data.Data + data.Size; - for (size_t count = (size_t)(last - first); count > 0; ) + ImGuiStoragePair* in_p = in_begin; + for (size_t count = (size_t)(in_end - in_p); count > 0; ) { size_t count2 = count >> 1; - ImGuiStoragePair* mid = first + count2; + ImGuiStoragePair* mid = in_p + count2; if (mid->key < key) { - first = ++mid; + in_p = ++mid; count -= count2 + 1; } else @@ -2521,7 +2520,7 @@ static ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID ke count = count2; } } - return first; + return in_p; } // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. @@ -2542,7 +2541,7 @@ void ImGuiStorage::BuildSortByKey() int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { - ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return default_val; return it->val_i; @@ -2555,7 +2554,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { - ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return default_val; return it->val_f; @@ -2563,7 +2562,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const void* ImGuiStorage::GetVoidPtr(ImGuiID key) const { - ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return NULL; return it->val_p; @@ -2572,7 +2571,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_i; @@ -2585,7 +2584,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_f; @@ -2593,7 +2592,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_p; @@ -2602,7 +2601,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) void ImGuiStorage::SetInt(ImGuiID key, int val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -2616,7 +2615,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val) void ImGuiStorage::SetFloat(ImGuiID key, float val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -2625,7 +2624,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val) void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -11238,8 +11237,8 @@ void ImGui::CloseCurrentPopup() window->DC.NavHideHighlightOneFrame = true; } -// Attention! BeginPopup() adds default flags which BeginPopupEx()! -bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) +// Attention! BeginPopup() adds default flags when calling BeginPopupEx()! +bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags) { ImGuiContext& g = *GImGui; if (!IsPopupOpen(id, ImGuiPopupFlags_None)) @@ -11249,13 +11248,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) } char name[20]; - if (flags & ImGuiWindowFlags_ChildMenu) + if (extra_window_flags & ImGuiWindowFlags_ChildMenu) ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuDepth); // Recycle windows based on depth else ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame - flags |= ImGuiWindowFlags_Popup; - bool is_open = Begin(name, NULL, flags); + bool is_open = Begin(name, NULL, extra_window_flags | ImGuiWindowFlags_Popup); if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); diff --git a/imgui_internal.h b/imgui_internal.h index 9dc832d97..244cda1a2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -348,6 +348,7 @@ namespace ImStb // - Helper: ImPool<> // - Helper: ImChunkStream<> // - Helper: ImGuiTextIndex +// - Helper: ImGuiStorage //----------------------------------------------------------------------------- // Helpers: Hashing @@ -722,7 +723,7 @@ struct ImChunkStream void swap(ImChunkStream& rhs) { rhs.Buf.swap(Buf); } }; -// Helper: ImGuiTextIndex<> +// Helper: ImGuiTextIndex // Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API. struct ImGuiTextIndex { @@ -736,6 +737,8 @@ struct ImGuiTextIndex void append(const char* base, int old_size, int new_size); }; +// Helper: ImGuiStorage +IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key); //----------------------------------------------------------------------------- // [SECTION] ImDrawList support //----------------------------------------------------------------------------- @@ -3143,16 +3146,16 @@ namespace ImGui IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); - // Popups, Modals, Tooltips + // Childs IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags); + + // Popups, Modals + IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags); IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None); IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsExceptModals(); IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags); - IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); - IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); - IMGUI_API bool BeginTooltipHidden(); IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal(); @@ -3160,6 +3163,10 @@ namespace ImGui IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); + // Tooltips + IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); + IMGUI_API bool BeginTooltipHidden(); + // Menus IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true); From b902fa4c4490ddffb713f8153d1a65e1940e58d1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 11 Jun 2024 14:15:13 +0200 Subject: [PATCH 21/66] IO: do not disable io.ConfigWindowsResizeFromEdges when ImGuiBackendFlags_HasMouseCursors is not set by backend. Amend 42bf149ac --- docs/CHANGELOG.txt | 6 ++++++ imgui.cpp | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b5caca628..4c680cf74 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,6 +46,12 @@ Breaking changes: Other changes: +- IO: do not disable io.ConfigWindowsResizeFromEdges (which allow resizing from borders + and lower-left corner) when ImGuiBackendFlags_HasMouseCursors is not set by backend. + The initial reasoning is that resizing from borders feels better when correct mouse cursor + shape change as honored by backends. Keeping this enabling will hopefully increase pressure + on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of + ImGui::GetMouseCursor() value. (#1495) - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index f4545ec55..6f4398298 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9919,10 +9919,6 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); #endif - - // Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly. - if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors)) - g.IO.ConfigWindowsResizeFromEdges = false; } static void ImGui::ErrorCheckEndFrameSanityChecks() From 1b9593e88946b4cc364b74e95c228f2b4b2661b9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Jun 2024 16:51:48 -0700 Subject: [PATCH 22/66] Style: (Breaking) renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected. Amend #261, #351 --- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 9 +++++---- imgui.h | 20 +++++++++++++------- imgui_draw.cpp | 24 ++++++++++++------------ imgui_widgets.cpp | 4 ++-- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4c680cf74..ed71de843 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,11 @@ Breaking changes: - Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). No significant nested type left. +- Style: renamed tab colors for clarity and consistency with other changes: (#261, #351) + - ImGuiCol_TabActive -> ImGuiCol_TabSelected + - ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed + - ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected + Kept inline redirecting enums (will obsolete). Other changes: diff --git a/imgui.cpp b/imgui.cpp index 6f4398298..363c1b8ae 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,7 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/18 (1.90.9) - style: renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected. - 2024/06/10 (1.90.9) - removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. - 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading. @@ -3318,11 +3319,11 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_ResizeGrip: return "ResizeGrip"; case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; - case ImGuiCol_Tab: return "Tab"; case ImGuiCol_TabHovered: return "TabHovered"; - case ImGuiCol_TabActive: return "TabActive"; - case ImGuiCol_TabUnfocused: return "TabUnfocused"; - case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive"; + case ImGuiCol_Tab: return "Tab"; + case ImGuiCol_TabSelected: return "TabSelected"; + case ImGuiCol_TabDimmed: return "TabDimmed"; + case ImGuiCol_TabDimmedSelected: return "TabDimmedSelected"; case ImGuiCol_PlotLines: return "PlotLines"; case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; case ImGuiCol_PlotHistogram: return "PlotHistogram"; diff --git a/imgui.h b/imgui.h index c48fd4c75..268cb5d28 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19081 +#define IMGUI_VERSION_NUM 19082 #define IMGUI_HAS_TABLE /* @@ -1582,11 +1582,11 @@ enum ImGuiCol_ ImGuiCol_ResizeGrip, // Resize grip in lower-right and lower-left corners of windows. ImGuiCol_ResizeGripHovered, ImGuiCol_ResizeGripActive, - ImGuiCol_Tab, // TabItem in a TabBar - ImGuiCol_TabHovered, - ImGuiCol_TabActive, - ImGuiCol_TabUnfocused, - ImGuiCol_TabUnfocusedActive, + ImGuiCol_TabHovered, // Tab background, when hovered + ImGuiCol_Tab, // Tab background, tab-bar is focused, tab is unselected + ImGuiCol_TabSelected, // Tab background, tab-bar is focused, tab is selected + ImGuiCol_TabDimmed, // Tab background, tab-bar is unfocused, tab is unselected + ImGuiCol_TabDimmedSelected, // Tab background, tab-bar is unfocused, tab is selected ImGuiCol_PlotLines, ImGuiCol_PlotLinesHovered, ImGuiCol_PlotHistogram, @@ -1602,7 +1602,13 @@ enum ImGuiCol_ ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active - ImGuiCol_COUNT + ImGuiCol_COUNT, + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiCol_TabActive = ImGuiCol_TabSelected, // [renamed in 1.90.9] + ImGuiCol_TabUnfocused = ImGuiCol_TabDimmed, // [renamed in 1.90.9] + ImGuiCol_TabUnfocusedActive = ImGuiCol_TabDimmedSelected, // [renamed in 1.90.9] +#endif }; // Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 171889f2c..1c048ef58 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -211,11 +211,11 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); - colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); - colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); + colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -271,11 +271,11 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); - colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); - colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); - colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); + colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -332,11 +332,11 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); - colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); - colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f); + colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 4c3b1c046..46ef59bb1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7975,7 +7975,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG // Draw separator // (it would be misleading to draw this in EndTabBar() suggesting that it may be drawn over tabs, as tab bar are appendable) - const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive); + const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected); if (g.Style.TabBarBorderSize > 0.0f) { const float y = tab_bar->BarRect.Max.y; @@ -8835,7 +8835,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, // Render tab shape ImDrawList* display_draw_list = window->DrawList; - const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabUnfocused)); + const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed)); TabItemBackground(display_draw_list, bb, flags, tab_col); RenderNavHighlight(bb, id); From 21bda2ed994fdf2a1dc9a3cf474dac883971f408 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Jun 2024 16:52:56 -0700 Subject: [PATCH 23/66] TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline and ImGuiCol_TabSelectedOverline, ImGuiCol_TabDimmedSelectedOverline. --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 2 ++ imgui.h | 15 +++++++++------ imgui_demo.cpp | 6 +++++- imgui_draw.cpp | 6 ++++++ imgui_widgets.cpp | 12 +++++++++++- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ed71de843..63104ce8c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -57,6 +57,9 @@ Other changes: shape change as honored by backends. Keeping this enabling will hopefully increase pressure on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of ImGui::GetMouseCursor() value. (#1495) +- TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal + line over selected tabs to increase visibility. This is used by docking. + Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index 363c1b8ae..472093bc7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3322,8 +3322,10 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_TabHovered: return "TabHovered"; case ImGuiCol_Tab: return "Tab"; case ImGuiCol_TabSelected: return "TabSelected"; + case ImGuiCol_TabSelectedOverline: return "TabSelectedOverline"; case ImGuiCol_TabDimmed: return "TabDimmed"; case ImGuiCol_TabDimmedSelected: return "TabDimmedSelected"; + case ImGuiCol_TabDimmedSelectedOverline: return "TabDimmedSelectedOverline"; case ImGuiCol_PlotLines: return "PlotLines"; case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; case ImGuiCol_PlotHistogram: return "PlotHistogram"; diff --git a/imgui.h b/imgui.h index 268cb5d28..8c4bd25eb 100644 --- a/imgui.h +++ b/imgui.h @@ -1212,8 +1212,9 @@ enum ImGuiTabBarFlags_ ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 3, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You may handle this behavior manually on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false. ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4, // Disable scrolling buttons (apply when fitting policy is ImGuiTabBarFlags_FittingPolicyScroll) ImGuiTabBarFlags_NoTooltip = 1 << 5, // Disable tooltips when hovering a tab - ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 6, // Resize tabs when they don't fit - ImGuiTabBarFlags_FittingPolicyScroll = 1 << 7, // Add scroll buttons when tabs don't fit + ImGuiTabBarFlags_DrawSelectedOverline = 1 << 6, // Draw selected overline markers over selected tab + ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 7, // Resize tabs when they don't fit + ImGuiTabBarFlags_FittingPolicyScroll = 1 << 8, // Add scroll buttons when tabs don't fit ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_FittingPolicyScroll, ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown, }; @@ -1583,10 +1584,12 @@ enum ImGuiCol_ ImGuiCol_ResizeGripHovered, ImGuiCol_ResizeGripActive, ImGuiCol_TabHovered, // Tab background, when hovered - ImGuiCol_Tab, // Tab background, tab-bar is focused, tab is unselected - ImGuiCol_TabSelected, // Tab background, tab-bar is focused, tab is selected - ImGuiCol_TabDimmed, // Tab background, tab-bar is unfocused, tab is unselected - ImGuiCol_TabDimmedSelected, // Tab background, tab-bar is unfocused, tab is selected + ImGuiCol_Tab, // Tab background, when tab-bar is focused & tab is unselected + ImGuiCol_TabSelected, // Tab background, when tab-bar is focused & tab is selected + ImGuiCol_TabSelectedOverline, // Tab horizontal overline, when tab-bar is focused & tab is selected + ImGuiCol_TabDimmed, // Tab background, when tab-bar is unfocused & tab is unselected + ImGuiCol_TabDimmedSelected, // Tab background, when tab-bar is unfocused & tab is selected + ImGuiCol_TabDimmedSelectedOverline,//..horizontal overline, when tab-bar is unfocused & tab is selected ImGuiCol_PlotLines, ImGuiCol_PlotLinesHovered, ImGuiCol_PlotHistogram, diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b2f0f4a14..3548cc6cb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1730,6 +1730,7 @@ static void ShowDemoWindowWidgets() ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs); ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton); + ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline); if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_; if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) @@ -1738,11 +1739,13 @@ static void ShowDemoWindowWidgets() tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); // Tab Bar + ImGui::AlignTextToFramePadding(); + ImGui::Text("Opened:"); const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" }; static bool opened[4] = { true, true, true, true }; // Persistent user state for (int n = 0; n < IM_ARRAYSIZE(opened); n++) { - if (n > 0) { ImGui::SameLine(); } + ImGui::SameLine(); ImGui::Checkbox(names[n], &opened[n]); } @@ -8617,6 +8620,7 @@ void ShowExampleAppDocuments(bool* p_open) // Submit Tab Bar and Tabs { ImGuiTabBarFlags tab_bar_flags = (opt_fitting_flags) | (opt_reorderable ? ImGuiTabBarFlags_Reorderable : 0); + tab_bar_flags |= ImGuiTabBarFlags_DrawSelectedOverline; if (ImGui::BeginTabBar("##tabs", tab_bar_flags)) { if (opt_reorderable) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1c048ef58..c8499441e 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -214,8 +214,10 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -274,8 +276,10 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_TabDimmedSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -335,8 +339,10 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f); colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.26f, 0.59f, 1.00f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 46ef59bb1..927cb2b98 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7921,7 +7921,9 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) tab_bar->ID = id; tab_bar->SeparatorMinX = tab_bar->BarRect.Min.x - IM_TRUNC(window->WindowPadding.x * 0.5f); tab_bar->SeparatorMaxX = tab_bar->BarRect.Max.x + IM_TRUNC(window->WindowPadding.x * 0.5f); - return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused); + //if (g.NavWindow && IsWindowChildOf(g.NavWindow, window, false, false)) + flags |= ImGuiTabBarFlags_IsFocused; + return BeginTabBarEx(tab_bar, tab_bar_bb, flags); } bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImGuiTabBarFlags flags) @@ -8837,6 +8839,14 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImDrawList* display_draw_list = window->DrawList; const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed)); TabItemBackground(display_draw_list, bb, flags, tab_col); + if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline)) + { + float x_offset = IM_TRUNC(0.4f * style.TabRounding); + if (x_offset < 2.0f * g.CurrentDpiScale) + x_offset = 0.0f; + float y_offset = 1.0f * g.CurrentDpiScale; + display_draw_list->AddLine(bb.GetTL() + ImVec2(x_offset, y_offset), bb.GetTR() + ImVec2(-x_offset, y_offset), GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline), 2.0f * g.CurrentDpiScale); + } RenderNavHighlight(bb, id); // Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget. From 32a037c030f84c8c755c16ff45c12f66562b810d Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 13:36:58 -0700 Subject: [PATCH 24/66] Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern. (#143) Amend 0c6e260f7 --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 63104ce8c..20c943827 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,8 @@ Other changes: - TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal line over selected tabs to increase visibility. This is used by docking. Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. +- Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets + active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index 472093bc7..6d2c557e2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13234,6 +13234,8 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) window = NULL; source_id = ImHashStr("#SourceExtern"); source_drag_active = true; + KeepAliveID(source_id); + SetActiveID(source_id, NULL); } IM_ASSERT(g.DragDropWithinTarget == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget() From 8c517fee357460a39acd7ca3fe9abb917cc1ec94 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 14:19:55 -0700 Subject: [PATCH 25/66] Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame. --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 20c943827..e42e5d6ce 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,6 +62,9 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) +- Drag and Drop: Fixes an issue when elapsing payload would be based on last payload + frame instead of last drag source frame, which makes a difference if not resubmitting + payload every frame. - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index 6d2c557e2..41d1cfacd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5136,7 +5136,7 @@ void ImGui::EndFrame() if (g.DragDropActive) { bool is_delivered = g.DragDropPayload.Delivery; - bool is_elapsed = (g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton)); + bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton)); if (is_delivered || is_elapsed) ClearDragDrop(); } @@ -13306,7 +13306,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long"); IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); - IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() + IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) { From 37c243bb35a09c0732325a624c344c6c1d3eab5f Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 17:53:34 -0700 Subject: [PATCH 26/66] Internals: added ImGuiContext::ContextName optionally used by debug log and to facilitate debugging. --- imgui.cpp | 5 ++++- imgui_internal.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 41d1cfacd..443ce9eb3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -15606,7 +15606,10 @@ void ImGui::DebugLogV(const char* fmt, va_list args) { ImGuiContext& g = *GImGui; const int old_size = g.DebugLogBuf.size(); - g.DebugLogBuf.appendf("[%05d] ", g.FrameCount); + if (g.ContextName[0] != 0) + g.DebugLogBuf.appendf("[%s] [%05d] ", g.ContextName, g.FrameCount); + else + g.DebugLogBuf.appendf("[%05d] ", g.FrameCount); g.DebugLogBuf.appendfv(fmt, args); g.DebugLogIndex.append(g.DebugLogBuf.c_str(), old_size, g.DebugLogBuf.size()); if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY) diff --git a/imgui_internal.h b/imgui_internal.h index 244cda1a2..f2940d211 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1939,6 +1939,7 @@ struct ImGuiContext bool GcCompactAll; // Request full GC bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() void* TestEngine; // Test engine user data + char ContextName[16]; // Storage for a context name (to facilitate debugging multi-context setups) // Inputs ImVector InputEventsQueue; // Input events which will be trickled/written into IO structure. @@ -2266,6 +2267,7 @@ struct ImGuiContext GcCompactAll = false; TestEngineHookItems = false; TestEngine = NULL; + memset(ContextName, 0, sizeof(ContextName)); InputEventsNextMouseSource = ImGuiMouseSource_Mouse; InputEventsNextEventId = 1; From 413c056359b2ec7d70725d94bb9c4e522bbbd9f0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 17:55:54 -0700 Subject: [PATCH 27/66] Drag and Drop: comments, debug log entries. --- imgui.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 443ce9eb3..505afa030 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5141,7 +5141,11 @@ void ImGui::EndFrame() ClearDragDrop(); } - // Drag and Drop: Fallback for source tooltip. This is not ideal but better than nothing. + // Drag and Drop: Fallback for missing source tooltip. This is not ideal but better than nothing. + // If you want to handle source item disappearing: instead of submitting your description tooltip + // in the BeginDragDropSource() block of the dragged item, you can submit them from a safe single spot + // (e.g. end of your item loop, or before EndFrame) by reading payload data. + // In the typical case, the contents of drag tooltip should be possible to infer solely from payload data. if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) { g.DragDropWithinSource = true; @@ -13231,6 +13235,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) } else { + // When ImGuiDragDropFlags_SourceExtern is set: window = NULL; source_id = ImHashStr("#SourceExtern"); source_drag_active = true; @@ -13247,7 +13252,8 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) { IM_ASSERT(source_id != 0); ClearDragDrop(); - IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] BeginDragDropSource() DragDropActive = true, source_id = %08X\n", source_id); + IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] BeginDragDropSource() DragDropActive = true, source_id = 0x%08X%s\n", + source_id, (flags & ImGuiDragDropFlags_SourceExtern) ? " (EXTERN)" : ""); ImGuiPayload& payload = g.DragDropPayload; payload.SourceId = source_id; payload.SourceParentId = source_parent_id; @@ -13437,7 +13443,8 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; - //IMGUI_DEBUG_LOG("AcceptDragDropPayload(): %08X: return payload\n", g.DragDropTargetId); + if (payload.Delivery) + IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] AcceptDragDropPayload(): 0x%08X: payload delivery\n", g.DragDropTargetId); return &payload; } From 50709454b3f62c0c12bf56a89ca8bab90fcd16be Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 19:02:51 -0700 Subject: [PATCH 28/66] Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern assume a mouse button being pressed. (#143) --- docs/CHANGELOG.txt | 4 +++- imgui.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e42e5d6ce..252f954a1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,9 +62,11 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) +- Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume + a mouse button being pressed. Facilitate implementing cross-context drag and drop. (#143) - Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame, which makes a difference if not resubmitting - payload every frame. + payload every frame. (#143) - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index 505afa030..01beb6bf4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5136,7 +5136,7 @@ void ImGui::EndFrame() if (g.DragDropActive) { bool is_delivered = g.DragDropPayload.Delivery; - bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton)); + bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || g.DragDropMouseButton == -1 || !IsMouseDown(g.DragDropMouseButton)); if (is_delivered || is_elapsed) ClearDragDrop(); } @@ -13239,6 +13239,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) window = NULL; source_id = ImHashStr("#SourceExtern"); source_drag_active = true; + mouse_button = g.IO.MouseDown[0] ? 0 : -1; KeepAliveID(source_id); SetActiveID(source_id, NULL); } @@ -13439,7 +13440,10 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop RenderDragDropTargetRect(r, g.DragDropTargetClipRect); g.DragDropAcceptFrameCount = g.FrameCount; - payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() + if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1) + payload.Delivery = was_accepted_previously && (g.DragDropSourceFrameCount < g.FrameCount); + else + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; From 8c318dc77021a74075c496e211ce36cd7aa5e863 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 20 Jun 2024 11:24:54 -0700 Subject: [PATCH 29/66] Drag and Drop: (Breaking) renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. (#1725, #143) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 3 ++- imgui.h | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 252f954a1..030f648a8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -48,6 +48,8 @@ Breaking changes: - ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed - ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected Kept inline redirecting enums (will obsolete). +- Drag and Drop: renamed ImGuiDragDropFlags_SourceAutoExpirePayload to + ImGuiDragDropFlags_PayloadAutoExpire. Kept inline redirecting enum (will obsolete). (#1725, #143). Other changes: diff --git a/imgui.cpp b/imgui.cpp index 01beb6bf4..f45fd6411 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,7 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/20 (1.90.9) - renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. - 2024/06/18 (1.90.9) - style: renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected. - 2024/06/10 (1.90.9) - removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. @@ -5136,7 +5137,7 @@ void ImGui::EndFrame() if (g.DragDropActive) { bool is_delivered = g.DragDropPayload.Delivery; - bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || g.DragDropMouseButton == -1 || !IsMouseDown(g.DragDropMouseButton)); + bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_PayloadAutoExpire) || g.DragDropMouseButton == -1 || !IsMouseDown(g.DragDropMouseButton)); if (is_delivered || is_elapsed) ClearDragDrop(); } diff --git a/imgui.h b/imgui.h index 8c4bd25eb..64b163625 100644 --- a/imgui.h +++ b/imgui.h @@ -1296,12 +1296,16 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of dear imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. - ImGuiDragDropFlags_SourceAutoExpirePayload = 1 << 5, // Automatically expire the payload if the source cease to be submitted (otherwise payloads are persisting while being dragged) + ImGuiDragDropFlags_PayloadAutoExpire = 1 << 5, // Automatically expire the payload if the source cease to be submitted (otherwise payloads are persisting while being dragged) // AcceptDragDropPayload() flags ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, // Request hiding the BeginDragDropSource tooltip from the BeginDragDropTarget site. ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect, // For peeking ahead and inspecting the payload before delivery. + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiDragDropFlags_SourceAutoExpirePayload = ImGuiDragDropFlags_PayloadAutoExpire, // Renamed in 1.90.9 +#endif }; // Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui. From 77d9f80754e3ae7efb476f11dd16bb17cb0eeda7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 20 Jun 2024 11:26:45 -0700 Subject: [PATCH 30/66] Drag and Drop: Added ImGuiDragDropFlags_PayloadNoCrossContext and ImGuiDragDropFlags_PayloadNoCrossProcess flags. --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 5 +++++ imgui.h | 2 ++ 3 files changed, 10 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 030f648a8..06d34933e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,9 @@ Other changes: active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume a mouse button being pressed. Facilitate implementing cross-context drag and drop. (#143) +- Drag and Drop: Added ImGuiDragDropFlags_PayloadNoCrossContext/_PayloadNoCrossProcess flags + as metadata to specify that a payload may not be copied outside the context/process by + some logic aiming to copy payloads around. - Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame, which makes a difference if not resubmitting payload every frame. (#143) diff --git a/imgui.cpp b/imgui.cpp index f45fd6411..7480a8df1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -14569,6 +14569,11 @@ void ImGui::ShowMetricsWindow(bool* p_open) // Basic info Text("Dear ImGui %s", GetVersion()); + if (g.ContextName[0] != NULL) + { + SameLine(); + Text("(Context Name: \"%s\")", g.ContextName); + } Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3); Text("%d visible windows, %d current allocations", io.MetricsRenderWindows, g.DebugAllocInfo.TotalAllocCount - g.DebugAllocInfo.TotalFreeCount); diff --git a/imgui.h b/imgui.h index 64b163625..a7c5a3a88 100644 --- a/imgui.h +++ b/imgui.h @@ -1297,6 +1297,8 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of dear imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. ImGuiDragDropFlags_PayloadAutoExpire = 1 << 5, // Automatically expire the payload if the source cease to be submitted (otherwise payloads are persisting while being dragged) + ImGuiDragDropFlags_PayloadNoCrossContext = 1 << 6, // Hint to specify that the payload may not be copied outside current dear imgui context. + ImGuiDragDropFlags_PayloadNoCrossProcess = 1 << 7, // Hint to specify that the payload may not be copied outside current process. // AcceptDragDropPayload() flags ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. From 7e7c97ac5f9c0137f9f2547deb46dca2dd12abda Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 20 Jun 2024 14:34:42 -0700 Subject: [PATCH 31/66] Ignore .ini file with other suffixes. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 64b5e1221..f632636e0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ ## Dear ImGui artifacts imgui.ini +imgui*.ini ## General build artifacts *.o From 21581cf70cef16db7e9a7095703f3233997596ff Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 20 Jun 2024 17:45:09 -0700 Subject: [PATCH 32/66] Fixed build warning. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 7480a8df1..6f90d94ef 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -14569,7 +14569,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) // Basic info Text("Dear ImGui %s", GetVersion()); - if (g.ContextName[0] != NULL) + if (g.ContextName[0] != 0) { SameLine(); Text("(Context Name: \"%s\")", g.ContextName); From 8067d05f744a91821a93e4ead34435143bb79db3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 21 Jun 2024 10:01:53 -0700 Subject: [PATCH 33/66] IO: added ClearInputMouse(). made ClearInputKeys() not clear mouse data. (#4921) Amend 6aa408c6a --- docs/CHANGELOG.txt | 9 ++++++--- imgui.cpp | 21 +++++++++++++++++++-- imgui.h | 9 +++++---- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 06d34933e..0961b555f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -48,6 +48,8 @@ Breaking changes: - ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed - ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected Kept inline redirecting enums (will obsolete). +- IO: io.ClearInputKeys() (first exposed in 1.89.8) doesn't clear mouse data. + Newly added io.ClearInputMouse() does. (#4921) - Drag and Drop: renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. Kept inline redirecting enum (will obsolete). (#1725, #143). @@ -59,6 +61,7 @@ Other changes: shape change as honored by backends. Keeping this enabling will hopefully increase pressure on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of ImGui::GetMouseCursor() value. (#1495) +- IO: Added io.ClearInputMouse() to clear mouse state. (#4921) - TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal line over selected tabs to increase visibility. This is used by docking. Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. @@ -842,7 +845,7 @@ Breaking changes: - IO: Obsoleted io.ClearInputCharacters() (added in 1.47) as it now ambiguous and often incorrect/misleading considering the existence of a higher-level - input queue. This is automatically cleared by io.ClearInputsKeys(). (#4921) + input queue. This is automatically cleared by io.ClearInputKeys(). (#4921) - ImDrawData: CmdLists[] array is now owned, changed from 'ImDrawList**' to 'ImVector'. Majority of users shouldn't be affected, but you cannot compare to NULL nor reassign manually anymore. @@ -880,10 +883,10 @@ Other changes: will slightly reduce scrollbar size. Generally we tried to make it that window border size has no incidence on layout but this can't work with thick borders. (#2522) - IO: Added io.ClearEventsQueue() to clear incoming inputs events. (#4921) - May be useful in conjunction with io.ClearInputsKeys() if you need to clear + May be useful in conjunction with io.ClearInputKeys() if you need to clear both current inputs state and queued events (e.g. when using blocking native dialogs such as Windows's ::MessageBox() or ::GetOpenFileName()). -- IO: Changed io.ClearInputsKeys() specs to also clear current frame character buffer +- IO: Changed io.ClearInputKeys() specs to also clear current frame character buffer (what now obsoleted io.ClearInputCharacters() did), as this is effectively the desirable behavior. - Misc: Added IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION config macro to disable diff --git a/imgui.cpp b/imgui.cpp index 6f90d94ef..48c73dc31 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,7 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/21 (1.90.9) - io: ClearInputKeys() (first exposed in 1.89.8) doesn't clear mouse data, newly added ClearInputMouse() does. - 2024/06/20 (1.90.9) - renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. - 2024/06/18 (1.90.9) - style: renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected. - 2024/06/10 (1.90.9) - removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). @@ -1453,7 +1454,7 @@ void ImGuiIO::ClearEventsQueue() g.InputEventsQueue.clear(); } -// Clear current keyboard/mouse/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons. +// Clear current keyboard/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons. void ImGuiIO::ClearInputKeys() { #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO @@ -1461,12 +1462,26 @@ void ImGuiIO::ClearInputKeys() #endif for (int n = 0; n < IM_ARRAYSIZE(KeysData); n++) { + if (ImGui::IsMouseKey((ImGuiKey)(n + ImGuiKey_KeysData_OFFSET))) + continue; KeysData[n].Down = false; KeysData[n].DownDuration = -1.0f; KeysData[n].DownDurationPrev = -1.0f; } KeyCtrl = KeyShift = KeyAlt = KeySuper = false; KeyMods = ImGuiMod_None; + InputQueueCharacters.resize(0); // Behavior of old ClearInputCharacters(). +} + +void ImGuiIO::ClearInputMouse() +{ + for (ImGuiKey key = ImGuiKey_Mouse_BEGIN; key < ImGuiKey_Mouse_END; key = (ImGuiKey)(key + 1)) + { + ImGuiKeyData* key_data = &KeysData[key - ImGuiKey_KeysData_OFFSET]; + key_data->Down = false; + key_data->DownDuration = -1.0f; + key_data->DownDurationPrev = -1.0f; + } MousePos = ImVec2(-FLT_MAX, -FLT_MAX); for (int n = 0; n < IM_ARRAYSIZE(MouseDown); n++) { @@ -1474,7 +1489,6 @@ void ImGuiIO::ClearInputKeys() MouseDownDuration[n] = MouseDownDurationPrev[n] = -1.0f; } MouseWheel = MouseWheelH = 0.0f; - InputQueueCharacters.resize(0); // Behavior of old ClearInputCharacters(). } // Removed this as it is ambiguous/misleading and generally incorrect to use with the existence of a higher-level input queue. @@ -9632,7 +9646,10 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) // - we clear in EndFrame() and not now in order allow application/user code polling this flag // (e.g. custom backend may want to clear additional data, custom widgets may want to react with a "canceling" event). if (g.IO.AppFocusLost) + { g.IO.ClearInputKeys(); + g.IO.ClearInputMouse(); + } } ImGuiID ImGui::GetKeyOwner(ImGuiKey key) diff --git a/imgui.h b/imgui.h index a7c5a3a88..e8c1a1a5e 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19082 +#define IMGUI_VERSION_NUM 19083 #define IMGUI_HAS_TABLE /* @@ -1535,7 +1535,7 @@ enum ImGuiConfigFlags_ ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. - ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information set by the backend. + ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse interactions. ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui) @@ -2198,7 +2198,7 @@ struct ImGuiIO // Option to deactivate io.AddFocusEvent(false) handling. // - May facilitate interactions with a debugger when focus loss leads to clearing inputs data. // - Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them. - bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys() in input processing. + bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys()/io.ClearInputMouse() in input processing. // Options to audit .ini data bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower) @@ -2247,7 +2247,8 @@ struct ImGuiIO IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode. IMGUI_API void SetAppAcceptingEvents(bool accepting_events); // Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen. IMGUI_API void ClearEventsQueue(); // Clear all incoming events. - IMGUI_API void ClearInputKeys(); // Clear current keyboard/mouse/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons. + IMGUI_API void ClearInputKeys(); // Clear current keyboard/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons. + IMGUI_API void ClearInputMouse(); // Clear current mouse state. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS IMGUI_API void ClearInputCharacters(); // [Obsoleted in 1.89.8] Clear the current frame text input buffer. Now included within ClearInputKeys(). #endif From e3971079cf5a16088caa381bd5d05dfbdc51b353 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 21 Jun 2024 10:08:07 -0700 Subject: [PATCH 34/66] IO: added ImGuiConfigFlags_NoKeyboard for consistency and convenience. (#4921) # Conflicts: # imgui.h # imgui_demo.cpp --- imgui.cpp | 9 ++++++++- imgui.h | 3 ++- imgui_demo.cpp | 13 ++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 48c73dc31..5efd63505 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4577,7 +4577,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() if (modal_window && g.HoveredWindow && !IsWindowWithinBeginStackOf(g.HoveredWindow->RootWindow, modal_window)) clear_hovered_windows = true; - // Disabled mouse? + // Disabled mouse hovering (we don't currently clear MousePos, we could) if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) clear_hovered_windows = true; @@ -9136,6 +9136,9 @@ static void ImGui::UpdateKeyboardInputs() ImGuiContext& g = *GImGui; ImGuiIO& io = g.IO; + if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) + io.ClearInputKeys(); + // Import legacy keys or verify they are not used #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO if (io.BackendUsingLegacyKeyArrays == 0) @@ -9582,6 +9585,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) else if (e->Type == ImGuiInputEventType_Key) { // Trickling Rule: Stop processing queued events if we got multiple action on the same button + if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) + continue; ImGuiKey key = e->Key.Key; IM_ASSERT(key != ImGuiKey_None); ImGuiKeyData* key_data = GetKeyData(key); @@ -9602,6 +9607,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) } else if (e->Type == ImGuiInputEventType_Text) { + if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) + continue; // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with if (trickle_fast_inputs && ((key_changed && trickle_interleaved_keys_and_text) || mouse_button_changed != 0 || mouse_moved || mouse_wheeled)) break; diff --git a/imgui.h b/imgui.h index e8c1a1a5e..71ef3cc00 100644 --- a/imgui.h +++ b/imgui.h @@ -1535,8 +1535,9 @@ enum ImGuiConfigFlags_ ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. - ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse interactions. + ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions. ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. + ImGuiConfigFlags_NoKeyboard = 1 << 6, // Instruct dear imgui to disable keyboard inputs and interactions. This is done by ignoring keyboard events and clearing existing states. // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui) ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3548cc6cb..de442f518 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -462,19 +462,26 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse); + ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable mouse inputs and interactions."); + + // The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it: if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) { - // The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it: if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f) { ImGui::SameLine(); ImGui::Text("<>"); } - if (ImGui::IsKeyPressed(ImGuiKey_Space)) + // Prevent both being checked + if (ImGui::IsKeyPressed(ImGuiKey_Space) || (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard)) io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; } - ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); + + ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility."); + ImGui::CheckboxFlags("io.ConfigFlags: NoKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NoKeyboard); + ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable keyboard inputs and interactions."); + ImGui::Checkbox("io.ConfigInputTrickleEventQueue", &io.ConfigInputTrickleEventQueue); ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates."); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); From 7f20a4b041546fb975dccb2b5d93a8930ad16cf4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 21 Jun 2024 10:16:15 -0700 Subject: [PATCH 35/66] Nav: CTRL+Tab overlay display context name if any. --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 5efd63505..517df51eb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13135,6 +13135,8 @@ void ImGui::NavUpdateWindowingOverlay() SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f); Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings); + if (g.ContextName[0] != 0) + SeparatorText(g.ContextName); for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--) { ImGuiWindow* window = g.WindowsFocusOrder[n]; From 2c8cc58fd16819c56a4eb36edebc591dc9878d83 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 21 Jun 2024 14:45:30 -0700 Subject: [PATCH 36/66] Internals: storing HoveredWindowBeforeClear for use by multi-context compositor drag and drop propagation. # Conflicts: # imgui.cpp # imgui_internal.h --- imgui.cpp | 1 + imgui_internal.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 517df51eb..8822dd934 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4571,6 +4571,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. bool clear_hovered_windows = false; FindHoveredWindowEx(g.IO.MousePos, false, &g.HoveredWindow, &g.HoveredWindowUnderMovingWindow); + g.HoveredWindowBeforeClear = g.HoveredWindow; // Modal windows prevents mouse from hovering behind them. ImGuiWindow* modal_window = GetTopMostPopupModal(); diff --git a/imgui_internal.h b/imgui_internal.h index f2940d211..a02f01b85 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1959,6 +1959,7 @@ struct ImGuiContext ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set. + ImGuiWindow* HoveredWindowBeforeClear; // Window the mouse is hovering. Filled even with _NoMouse. This is currently useful for multi-context compositors. ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow. ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window. ImVec2 WheelingWindowRefMousePos; @@ -2276,6 +2277,7 @@ struct ImGuiContext CurrentWindow = NULL; HoveredWindow = NULL; HoveredWindowUnderMovingWindow = NULL; + HoveredWindowBeforeClear = NULL; MovingWindow = NULL; WheelingWindow = NULL; WheelingWindowStartFrame = WheelingWindowScrolledFrame = -1; From 755bf2b8c2effb4bb8ce28c7ce8a7dbc3d40dd95 Mon Sep 17 00:00:00 2001 From: cfillion Date: Wed, 12 Jun 2024 18:28:24 -0400 Subject: [PATCH 37/66] (Breaking) Move ImGuiWindowFlags_NavFlattened to ImGuiChildFlags_NavFlattened. (#7687) --- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 27 +++++++++++++++------------ imgui.h | 3 ++- imgui_demo.cpp | 4 ++-- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 0961b555f..5170ea6b3 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,11 @@ Breaking changes: - Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). No significant nested type left. +- BeginChild: added ImGuiChildFlags_NavFlattened as a replacement for the window + flag ImGuiWindowFlags_NavFlattened: the feature only ever made sense for + BeginChild() calls anyhow. (#7687) [@cfillion] + - old: BeginChild("Name", size, 0, ImGuiWindowFlags_NavFlattened); + - new: BeginChild("Name", size, ImGuiChildFlags_NavFlattened, 0) - Style: renamed tab colors for clarity and consistency with other changes: (#261, #351) - ImGuiCol_TabActive -> ImGuiCol_TabSelected - ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed diff --git a/imgui.cpp b/imgui.cpp index 8822dd934..fd6521288 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,9 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/06/21 (1.90.9) - BeginChild: added ImGuiChildFlags_NavFlattened as a replacement for the window flag ImGuiWindowFlags_NavFlattened: the feature only ever made sense for BeginChild() anyhow. + - old: BeginChild("Name", size, 0, ImGuiWindowFlags_NavFlattened); + - new: BeginChild("Name", size, ImGuiChildFlags_NavFlattened, 0); - 2024/06/21 (1.90.9) - io: ClearInputKeys() (first exposed in 1.89.8) doesn't clear mouse data, newly added ClearInputMouse() does. - 2024/06/20 (1.90.9) - renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. - 2024/06/18 (1.90.9) - style: renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected. @@ -5533,7 +5536,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I IM_ASSERT(id != 0); // Sanity check as it is likely that some user will accidentally pass ImGuiWindowFlags into the ImGuiChildFlags argument. - const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle; + const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle | ImGuiChildFlags_NavFlattened; IM_UNUSED(ImGuiChildFlags_SupportedMask_); IM_ASSERT((child_flags & ~ImGuiChildFlags_SupportedMask_) == 0 && "Illegal ImGuiChildFlags value. Did you pass ImGuiWindowFlags values instead of ImGuiChildFlags?"); IM_ASSERT((window_flags & ImGuiWindowFlags_AlwaysAutoResize) == 0 && "Cannot specify ImGuiWindowFlags_AlwaysAutoResize for BeginChild(). Use ImGuiChildFlags_AlwaysAutoResize!"); @@ -5545,6 +5548,8 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS if (window_flags & ImGuiWindowFlags_AlwaysUseWindowPadding) child_flags |= ImGuiChildFlags_AlwaysUseWindowPadding; + if (window_flags & ImGuiWindowFlags_NavFlattened) + child_flags |= ImGuiChildFlags_NavFlattened; #endif if (child_flags & ImGuiChildFlags_AutoResizeX) child_flags &= ~ImGuiChildFlags_ResizeX; @@ -5623,7 +5628,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id); if (g.ActiveId == temp_id_for_activation) ClearActiveID(); - if (g.NavActivateId == id && !(window_flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY)) + if (g.NavActivateId == id && !(child_flags & ImGuiChildFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY)) { FocusWindow(child_window); NavInitWindow(child_window, false); @@ -5649,7 +5654,8 @@ void ImGui::EndChild() ImGuiWindow* parent_window = g.CurrentWindow; ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + child_size); ItemSize(child_size); - if ((child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY) && !(child_window->Flags & ImGuiWindowFlags_NavFlattened)) + const bool nav_flattened = (child_window->ChildFlags & ImGuiChildFlags_NavFlattened) != 0; + if ((child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY) && !nav_flattened) { ItemAdd(bb, child_window->ChildId); RenderNavHighlight(bb, child_window->ChildId); @@ -5666,7 +5672,7 @@ void ImGui::EndChild() ItemAdd(bb, child_window->ChildId, NULL, ImGuiItemFlags_NoNav); // But when flattened we directly reach items, adjust active layer mask accordingly - if (child_window->Flags & ImGuiWindowFlags_NavFlattened) + if (nav_flattened) parent_window->DC.NavLayersActiveMaskNext |= child_window->DC.NavLayersActiveMaskNext; } if (g.HoveredWindow == child_window) @@ -6440,7 +6446,7 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags window->RootWindowPopupTree = parent_window->RootWindowPopupTree; if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) window->RootWindowForTitleBarHighlight = parent_window->RootWindowForTitleBarHighlight; - while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened) + while (window->RootWindowForNav->ChildFlags & ImGuiChildFlags_NavFlattened) { IM_ASSERT(window->RootWindowForNav->ParentWindow != NULL); window->RootWindowForNav = window->RootWindowForNav->ParentWindow; @@ -6536,9 +6542,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if ((flags & ImGuiWindowFlags_NoInputs) == ImGuiWindowFlags_NoInputs) flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - if (flags & ImGuiWindowFlags_NavFlattened) - IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); - const int current_frame = g.FrameCount; const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); window->IsFallbackWindow = (g.CurrentWindowStack.Size == 0 && g.WithinFrameScopeWithImplicitWindow); @@ -6603,7 +6606,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Add to focus scope stack - PushFocusScope((flags & ImGuiWindowFlags_NavFlattened) ? g.CurrentFocusScopeId : window->ID); + PushFocusScope((window->ChildFlags & ImGuiChildFlags_NavFlattened) ? g.CurrentFocusScopeId : window->ID); window->NavRootFocusScopeId = g.CurrentFocusScopeId; // Add to popup stacks: update OpenPopupStack[] data, push to BeginPopupStack[] @@ -7199,7 +7202,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Child window can be out of sight and have "negative" clip windows. // Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar). IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); - const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + const bool nav_request = (window->ChildFlags & ImGuiChildFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); if (!g.LogEnabled && !nav_request) if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y) { @@ -10189,7 +10192,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent); if (g.NavId == id || g.NavAnyRequest) if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) - if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) + if (window == g.NavWindow || ((window->ChildFlags | g.NavWindow->ChildFlags) & ImGuiChildFlags_NavFlattened)) NavProcessItem(); } @@ -11678,7 +11681,7 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result) // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring if (window->ParentWindow == g.NavWindow) { - IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened); + IM_ASSERT((window->ChildFlags | g.NavWindow->ChildFlags) & ImGuiChildFlags_NavFlattened); if (!window->ClipRect.Overlaps(cand)) return false; cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window diff --git a/imgui.h b/imgui.h index 71ef3cc00..e3c4db777 100644 --- a/imgui.h +++ b/imgui.h @@ -1044,7 +1044,6 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, // [Internal] - ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] On child window: share focus scope, allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows. ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() @@ -1054,6 +1053,7 @@ enum ImGuiWindowFlags_ // Obsolete names #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30, // Obsoleted in 1.90: Use ImGuiChildFlags_AlwaysUseWindowPadding in BeginChild() call. + ImGuiWindowFlags_NavFlattened = 1 << 31, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call. #endif }; @@ -1077,6 +1077,7 @@ enum ImGuiChildFlags_ ImGuiChildFlags_AutoResizeY = 1 << 5, // Enable auto-resizing height. Read "IMPORTANT: Size measurement" details above. ImGuiChildFlags_AlwaysAutoResize = 1 << 6, // Combined with AutoResizeX/AutoResizeY. Always measure size even when child is hidden, always return true, always disable clipping optimization! NOT RECOMMENDED. ImGuiChildFlags_FrameStyle = 1 << 7, // Style the child window like a framed item: use FrameBg, FrameRounding, FrameBorderSize, FramePadding instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding. + ImGuiChildFlags_NavFlattened = 1 << 8, // Share focus scope, allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows. }; // Flags for ImGui::InputText() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index de442f518..fba72951a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6851,7 +6851,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) "Right-click to open edit options menu."); ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10), ImVec2(FLT_MAX, FLT_MAX)); - ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); + ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar); ImGui::PushItemWidth(ImGui::GetFontSize() * -12); for (int i = 0; i < ImGuiCol_COUNT; i++) { @@ -7251,7 +7251,7 @@ struct ExampleAppConsole // Reserve enough left-over height for 1 separator + 1 input text const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); - if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NavFlattened)) + if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_HorizontalScrollbar)) { if (ImGui::BeginPopupContextWindow()) { From 48e7e7bfe8521af8802eda2ec26546a6069e5573 Mon Sep 17 00:00:00 2001 From: Gary Geng Date: Sun, 23 Jun 2024 17:26:52 -0500 Subject: [PATCH 38/66] Backends: SDL3: Follow SDL3 removal of keysym field in SDL_KeyboardEvent (#7729) --- backends/imgui_impl_sdl3.cpp | 6 +++--- docs/CHANGELOG.txt | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 3da22f9b5..8b210b223 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -326,10 +326,10 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: { - ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); - ImGuiKey key = ImGui_ImplSDL3_KeycodeToImGuiKey(event->key.keysym.sym); + ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod); + ImGuiKey key = ImGui_ImplSDL3_KeycodeToImGuiKey(event->key.key); io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN)); - io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. + io.SetKeyEventNativeData(key, event->key.key, event->key.scancode, event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. return true; } case SDL_EVENT_WINDOW_MOUSE_ENTER: diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5170ea6b3..35694f47e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -83,6 +83,7 @@ Other changes: - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] +- Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) ----------------------------------------------------------------------- From aab27130a6159a08026e1c3dc809c212999b7f88 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Jun 2024 12:57:39 -0700 Subject: [PATCH 39/66] Demo: Style Editor: clarify how _CalcCircleAutoSegmentCount() doesn't always get exact final segment count. (#7731) --- imgui_demo.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fba72951a..7bc4281cf 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6932,10 +6932,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos()); if (show_samples && ImGui::BeginTooltip()) { - ImGui::TextUnformatted("(R = radius, N = number of segments)"); + ImGui::TextUnformatted("(R = radius, N = approx number of segments)"); ImGui::Spacing(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x; + const float min_widget_width = ImGui::CalcTextSize("R: MMM\nN: MMM").x; for (int n = 0; n < 8; n++) { const float RAD_MIN = 5.0f; @@ -6944,6 +6944,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::BeginGroup(); + // N is not always exact here due to how PathArcTo() function work internally ImGui::Text("R: %.f\nN: %d", rad, draw_list->_CalcCircleAutoSegmentCount(rad)); const float canvas_width = IM_MAX(min_widget_width, rad * 2.0f); From a18fb406ace8163309a27f948acb85309dfbd312 Mon Sep 17 00:00:00 2001 From: Martin Ejdestig Date: Sat, 22 Jun 2024 13:54:21 +0200 Subject: [PATCH 40/66] Backends: Vulkan: Remove Volk/ from volk.h #include directives (#7722, #6582, #4854) --- backends/imgui_impl_vulkan.h | 2 +- docs/CHANGELOG.txt | 4 +++- examples/example_glfw_vulkan/main.cpp | 2 +- examples/example_sdl2_vulkan/main.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index c174a6ca1..fb98bfbc4 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -55,7 +55,7 @@ // Vulkan includes #ifdef IMGUI_IMPL_VULKAN_USE_VOLK -#include +#include #else #include #endif diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 35694f47e..eea03be61 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -80,10 +80,12 @@ Other changes: - Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame, which makes a difference if not resubmitting payload every frame. (#143) +- Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) +- Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) + [@martin-ejdestig] - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] -- Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) ----------------------------------------------------------------------- diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 26012065a..e1f099e3d 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -25,7 +25,7 @@ // Volk headers #ifdef IMGUI_IMPL_VULKAN_USE_VOLK #define VOLK_IMPLEMENTATION -#include +#include #endif // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index 7f8fd0abb..afcebf1b9 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -24,7 +24,7 @@ // Volk headers #ifdef IMGUI_IMPL_VULKAN_USE_VOLK #define VOLK_IMPLEMENTATION -#include +#include #endif //#define APP_USE_UNLIMITED_FRAME_RATE From eb1cc4b8b4ebe4a10ad0d422fe8d5751a6ebf9a3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 12:17:22 +0200 Subject: [PATCH 41/66] Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index eea03be61..3c3c6ad3c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -80,6 +80,7 @@ Other changes: - Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame, which makes a difference if not resubmitting payload every frame. (#143) +- Debug Tools: Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] diff --git a/imgui.cpp b/imgui.cpp index fd6521288..0fe364f6a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -15466,7 +15466,10 @@ void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) if (!TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) return; for (const ImGuiStoragePair& p : storage->Data) + { BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer. + DebugLocateItemOnHover(p.key); + } TreePop(); } From 32f9dfc1261e4b8dd4a026588ee966c200b7f3f0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 14:32:48 +0200 Subject: [PATCH 42/66] Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends. --- backends/imgui_impl_glfw.cpp | 15 ++++++++------- backends/imgui_impl_osx.mm | 4 +++- backends/imgui_impl_sdl2.cpp | 17 +++++++++-------- backends/imgui_impl_sdl3.cpp | 2 +- backends/imgui_impl_win32.cpp | 3 ++- docs/CHANGELOG.txt | 2 ++ imgui.h | 3 ++- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 883917875..3c95f1786 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -145,7 +145,7 @@ struct ImGui_ImplGlfw_Data GLFWcharfun PrevUserCallbackChar; GLFWmonitorfun PrevUserCallbackMonitor; #ifdef _WIN32 - WNDPROC GlfwWndProc; + WNDPROC PrevWndProc; #endif ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); } @@ -497,7 +497,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo()); break; } - return ::CallWindowProcW(bd->GlfwWndProc, hWnd, msg, wParam, lParam); + return ::CallWindowProcW(bd->PrevWndProc, hWnd, msg, wParam, lParam); } #endif @@ -612,6 +612,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw // Set platform dependent data in viewport ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)bd->Window; #ifdef _WIN32 main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window); #elif defined(__APPLE__) @@ -622,8 +623,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw // Windows: register a WndProc hook so we can intercept some messages. #ifdef _WIN32 - bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC); - IM_ASSERT(bd->GlfwWndProc != nullptr); + bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC); + IM_ASSERT(bd->PrevWndProc != nullptr); ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc); #endif @@ -661,11 +662,11 @@ void ImGui_ImplGlfw_Shutdown() for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(bd->MouseCursors[cursor_n]); - // Windows: register a WndProc hook so we can intercept some messages. + // Windows: restore our WndProc hook #ifdef _WIN32 ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc); - bd->GlfwWndProc = nullptr; + ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc); + bd->PrevWndProc = nullptr; #endif io.BackendPlatformName = nullptr; diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 322798022..14cdd85cd 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -133,7 +133,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view); - (void)updateImePosWithView:(NSView *)view { - NSWindow *window = view.window; + NSWindow* window = view.window; if (!window) return; NSRect contentRect = [window contentRectForFrameRect:window.frame]; @@ -402,6 +402,8 @@ bool ImGui_ImplOSX_Init(NSView* view) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) bd->Observer = [ImGuiObserver new]; + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window; // Load cursors. Some of them are undocumented. bd->MouseCursorHidden = false; diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 892fe9050..a18c013fd 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -397,7 +397,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) return false; } -static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) +static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) { ImGuiIO& io = ImGui::GetIO(); IMGUI_CHECKVERSION(); @@ -448,6 +448,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) // Set platform dependent data in viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)window; main_viewport->PlatformHandleRaw = nullptr; SDL_SysWMinfo info; SDL_VERSION(&info.version); @@ -481,13 +482,13 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); #endif + (void)sdl_gl_context; // Unused in 'master' branch. return true; } bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) { - IM_UNUSED(sdl_gl_context); // Viewport branch will need this. - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context); } bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) @@ -495,7 +496,7 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) #if !SDL_HAS_VULKAN IM_ASSERT(0 && "Unsupported"); #endif - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) @@ -503,22 +504,22 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) #if !defined(_WIN32) IM_ASSERT(0 && "Unsupported"); #endif - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) { - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer) { - return ImGui_ImplSDL2_Init(window, renderer); + return ImGui_ImplSDL2_Init(window, renderer, nullptr); } bool ImGui_ImplSDL2_InitForOther(SDL_Window* window) { - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } static void ImGui_ImplSDL2_CloseGamepads(); diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 8b210b223..189c6f412 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -365,7 +365,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Window* window) { - IM_UNUSED(window); + viewport->PlatformHandle = window; viewport->PlatformHandleRaw = nullptr; #if defined(__WIN32__) && !defined(__WINRT__) viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", nullptr); diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 3e59b62e3..b0f694057 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -169,7 +169,8 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) ImGui_ImplWin32_UpdateKeyboardCodePage(); // Set platform dependent data in viewport - ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd; + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd; IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch // Dynamically load XInput library diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3c3c6ad3c..ed4c1d718 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -81,6 +81,8 @@ Other changes: frame instead of last drag source frame, which makes a difference if not resubmitting payload every frame. (#143) - Debug Tools: Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. +- Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for + use by backends. - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] diff --git a/imgui.h b/imgui.h index e3c4db777..95506954b 100644 --- a/imgui.h +++ b/imgui.h @@ -2202,7 +2202,7 @@ struct ImGuiIO // - Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them. bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys()/io.ClearInputMouse() in input processing. - // Options to audit .ini data + // Option to audit .ini data bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower) //------------------------------------------------------------------ @@ -3240,6 +3240,7 @@ struct ImGuiViewport ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size) // Platform/Backend Dependent Data + void* PlatformHandle; // void* to hold higher-level, platform window handle (e.g. HWND, GLFWWindow*, SDL_Window*) void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms) ImGuiViewport() { memset(this, 0, sizeof(*this)); } From 7c2476986b5b01ecfab85eca064568634194d13a Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 14:41:21 +0200 Subject: [PATCH 43/66] Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (#7735) --- backends/imgui_impl_sdl3.cpp | 25 ++++++++++++++++++------- docs/CHANGELOG.txt | 1 + examples/imgui_examples.sln | 10 ++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 189c6f412..f8e2c5510 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -22,6 +22,10 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-06-26: Update for SDL3 api changes: SDL_StartTextInput()/SDL_StopTextInput()/SDL_SetTextInputRect() functions signatures. +// 2024-06-24: Update for SDL3 api changes: SDL_EVENT_KEY_DOWN/SDL_EVENT_KEY_UP contents. +// 2024-06-03; Update for SDL3 api changes: SDL_SYSTEM_CURSOR_ renames. +// 2024-05-15: Update for SDL3 api changes: SDLK_ renames. // 2024-04-15: Inputs: Re-enable calling SDL_StartTextInput()/SDL_StopTextInput() as SDL3 no longer enables it by default and should play nicer with IME. // 2024-02-13: Inputs: Fixed gamepad support. Handle gamepad disconnection. Added ImGui_ImplSDL3_SetGamepadMode(). // 2023-11-13: Updated for recent SDL3 API changes. @@ -76,6 +80,9 @@ struct ImGui_ImplSDL3_Data Uint64 Time; char* ClipboardTextData; + // IME handling + SDL_Window* ImeWindow; + // Mouse handling Uint32 MouseWindowID; int MouseButtonsDown; @@ -116,8 +123,15 @@ static void ImGui_ImplSDL3_SetClipboardText(void*, const char* text) SDL_SetClipboardText(text); } -static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data) +static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlatformImeData* data) { + ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData(); + SDL_Window* window = (SDL_Window*)viewport->PlatformHandle; + if ((data->WantVisible == false || bd->ImeWindow != window) && bd->ImeWindow != NULL) + { + SDL_StopTextInput(bd->ImeWindow); + bd->ImeWindow = nullptr; + } if (data->WantVisible) { SDL_Rect r; @@ -125,12 +139,9 @@ static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeDa r.y = (int)data->InputPos.y; r.w = 1; r.h = (int)data->InputLineHeight; - SDL_SetTextInputRect(&r); - SDL_StartTextInput(); - } - else - { - SDL_StopTextInput(); + SDL_SetTextInputRect(window, &r); + SDL_StartTextInput(window); + bd->ImeWindow = window; } } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ed4c1d718..eba73bb2b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -84,6 +84,7 @@ Other changes: - Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends. - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) +- Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (#7735) - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan diff --git a/examples/imgui_examples.sln b/examples/imgui_examples.sln index 071bcbd63..cf1e7d75f 100644 --- a/examples/imgui_examples.sln +++ b/examples/imgui_examples.sln @@ -29,6 +29,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_opengl3", "ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl2_sdlrenderer2", "example_sdl2_sdlrenderer2\example_sdl2_sdlrenderer2.vcxproj", "{0C0B2BEA-311F-473C-9652-87923EF639E3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -141,6 +143,14 @@ Global {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|Win32.Build.0 = Release|Win32 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.ActiveCfg = Release|x64 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.Build.0 = Release|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.Build.0 = Debug|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.ActiveCfg = Debug|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.Build.0 = Debug|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.ActiveCfg = Release|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 22b36bef9e6ec315f16eff98d11d2b853bf31f80 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 14:59:00 +0200 Subject: [PATCH 44/66] Examples: undo adding SDL3 example to Visual Studio sln. --- examples/imgui_examples.sln | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/imgui_examples.sln b/examples/imgui_examples.sln index cf1e7d75f..071bcbd63 100644 --- a/examples/imgui_examples.sln +++ b/examples/imgui_examples.sln @@ -29,8 +29,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_opengl3", "ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl2_sdlrenderer2", "example_sdl2_sdlrenderer2\example_sdl2_sdlrenderer2.vcxproj", "{0C0B2BEA-311F-473C-9652-87923EF639E3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -143,14 +141,6 @@ Global {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|Win32.Build.0 = Release|Win32 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.ActiveCfg = Release|x64 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.Build.0 = Release|x64 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.Build.0 = Debug|Win32 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.ActiveCfg = Debug|x64 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.Build.0 = Debug|x64 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.ActiveCfg = Release|Win32 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64 - {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 0c2650e8339213398c28625f3d1d91fc9bf6db6b Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 16:23:27 +0200 Subject: [PATCH 45/66] Backends: OSX: build fix. Amend 32f9dfc --- backends/imgui_impl_osx.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 14cdd85cd..fdd407f3e 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -80,6 +80,7 @@ struct ImGui_ImplOSX_Data KeyEventResponder* KeyEventResponder; NSTextInputContext* InputContext; id Monitor; + NSWindow* Window; ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); } }; @@ -402,6 +403,7 @@ bool ImGui_ImplOSX_Init(NSView* view) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) bd->Observer = [ImGuiObserver new]; + bd->Window = view.window ?: NSApp.orderedWindows.firstObject; ImGuiViewport* main_viewport = ImGui::GetMainViewport(); main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window; From dbffb702f836f4c9bcbac97ab7e80fcb63b2e123 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 18:57:14 +0200 Subject: [PATCH 46/66] ImGuiStorage: tweak impl for BuildSortByKey(). --- imgui.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0fe364f6a..520590206 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2542,20 +2542,18 @@ ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_ return in_p; } +static int IMGUI_CDECL PairComparerByID(const void* lhs, const void* rhs) +{ + // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. + ImGuiID lhs_v = ((const ImGuiStoragePair*)lhs)->key; + ImGuiID rhs_v = ((const ImGuiStoragePair*)rhs)->key; + return (lhs_v > rhs_v ? +1 : lhs_v < rhs_v ? -1 : 0); +} + // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. void ImGuiStorage::BuildSortByKey() { - struct StaticFunc - { - static int IMGUI_CDECL PairComparerByID(const void* lhs, const void* rhs) - { - // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. - if (((const ImGuiStoragePair*)lhs)->key > ((const ImGuiStoragePair*)rhs)->key) return +1; - if (((const ImGuiStoragePair*)lhs)->key < ((const ImGuiStoragePair*)rhs)->key) return -1; - return 0; - } - }; - ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairComparerByID); + ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), PairComparerByID); } int ImGuiStorage::GetInt(ImGuiID key, int default_val) const From fbb903e15808d6a36034d65649e10b6976d0cdb9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 27 Jun 2024 16:37:33 +0200 Subject: [PATCH 47/66] Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block bypassing the disabled state. (#7726) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 9 ++++++++- imgui.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index eba73bb2b..85bcfbb13 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -67,6 +67,8 @@ Other changes: on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of ImGui::GetMouseCursor() value. (#1495) - IO: Added io.ClearInputMouse() to clear mouse state. (#4921) +- Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block bypassing + the disabled state. (#7726) - TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal line over selected tabs to increase visibility. This is used by docking. Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. diff --git a/imgui.cpp b/imgui.cpp index 520590206..72f1f1871 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4214,6 +4214,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag } // Display shortcut (only works with mouse) + // (ImGuiItemStatusFlags_HasShortcut in LastItemData denotes we want a tooltip) if (id == g.LastItemData.ID && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasShortcut)) if (IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_DelayNormal)) SetTooltip("%s", GetKeyChordName(g.LastItemData.Shortcut)); @@ -9793,12 +9794,15 @@ void ImGui::SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags) g.NextItemData.ShortcutFlags = flags; } +// Called from within ItemAdd: at this point we can read from NextItemData and write to LastItemData void ImGui::ItemHandleShortcut(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiInputFlags flags = g.NextItemData.ShortcutFlags; IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetNextItemShortcut) == 0); // Passing flags not supported by SetNextItemShortcut()! + if (g.LastItemData.InFlags & ImGuiItemFlags_Disabled) + return; if (flags & ImGuiInputFlags_Tooltip) { g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasShortcut; @@ -9822,7 +9826,7 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags) bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) { - //ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; //IMGUI_DEBUG_LOG("Shortcut(%s, flags=%X, owner_id=0x%08X)\n", GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), flags, owner_id); // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any. @@ -9834,6 +9838,9 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID own if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_NoOwner) owner_id = GetRoutingIdFromOwnerId(owner_id); + if (g.CurrentItemFlags & ImGuiItemFlags_Disabled) + return false; + // Submit route if (!SetShortcutRouting(key_chord, flags, owner_id)) return false; diff --git a/imgui.h b/imgui.h index 95506954b..7617addc4 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19083 +#define IMGUI_VERSION_NUM 19084 #define IMGUI_HAS_TABLE /* From 953d40c929fc56ad719845ad1788aa046ef9ee33 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 27 Jun 2024 17:17:54 +0200 Subject: [PATCH 48/66] Tables: moved TableGetHoveredColumn() to public API. (#7715, #3740) --- docs/CHANGELOG.txt | 2 ++ imgui.h | 3 ++- imgui_internal.h | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 85bcfbb13..acb2f3202 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -72,6 +72,8 @@ Other changes: - TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal line over selected tabs to increase visibility. This is used by docking. Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. +- Tables: added TableGetHoveredColumn() to public API, as an alternative to testing for + 'TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered' on each column. (#3740) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume diff --git a/imgui.h b/imgui.h index 7617addc4..ff8778c03 100644 --- a/imgui.h +++ b/imgui.h @@ -779,7 +779,7 @@ namespace ImGui // - TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row! // - TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear! // - 5. Call EndTable() - IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f); + IMGUI_API bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f); IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true! IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row. IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible. @@ -812,6 +812,7 @@ namespace ImGui IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column. IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column. IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change user accessible enabled/disabled state of a column. Set to false to hide the column. User can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody) + IMGUI_API int TableGetHoveredColumn(); // return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. Can also use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details. // Legacy Columns API (prefer using Tables!) diff --git a/imgui_internal.h b/imgui_internal.h index a02f01b85..9bbbc5eca 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3332,7 +3332,6 @@ namespace ImGui IMGUI_API void TableOpenContextMenu(int column_n = -1); IMGUI_API void TableSetColumnWidth(int column_n, float width); IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); - IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. IMGUI_API int TableGetHoveredRow(); // Retrieve *PREVIOUS FRAME* hovered row. This difference with TableGetHoveredColumn() is the reason why this is not public yet. IMGUI_API float TableGetHeaderRowHeight(); IMGUI_API float TableGetHeaderAngledMaxLabelWidth(); From 77d582fa37b4958a284421432aec18ba84f138bc Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 27 Jun 2024 18:04:24 +0200 Subject: [PATCH 49/66] Windows: BeginChild(): fixed a glitch when during a resize of a child window which is tightly close to the boundaries of its parent. (#7706) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index acb2f3202..4b9b12c79 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -69,6 +69,9 @@ Other changes: - IO: Added io.ClearInputMouse() to clear mouse state. (#4921) - Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block bypassing the disabled state. (#7726) +- Windows: BeginChild(): fixed a glitch when during a resize of a child window which is + tightly close to the boundaries of its parent (e.g. with zero WindowPadding), the child + position could have temporarily be moved around by erroneous padding application. (#7706) - TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline option to draw an horizontal line over selected tabs to increase visibility. This is used by docking. Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. diff --git a/imgui.cpp b/imgui.cpp index 72f1f1871..114aeee25 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6140,12 +6140,13 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si border_target = ImClamp(border_target, clamp_min, clamp_max); if (flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent { - ImGuiWindowFlags parent_flags = window->ParentWindow->Flags; - ImRect border_limit_rect = window->ParentWindow->InnerRect; - border_limit_rect.Expand(ImVec2(-ImMax(window->WindowPadding.x, window->WindowBorderSize), -ImMax(window->WindowPadding.y, window->WindowBorderSize))); - if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar)) + ImGuiWindow* parent_window = window->ParentWindow; + ImGuiWindowFlags parent_flags = parent_window->Flags; + ImRect border_limit_rect = parent_window->InnerRect; + border_limit_rect.Expand(ImVec2(-ImMax(parent_window->WindowPadding.x, parent_window->WindowBorderSize), -ImMax(parent_window->WindowPadding.y, parent_window->WindowBorderSize))); + if ((axis == ImGuiAxis_X) && ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar))) border_target.x = ImClamp(border_target.x, border_limit_rect.Min.x, border_limit_rect.Max.x); - if (parent_flags & ImGuiWindowFlags_NoScrollbar) + if ((axis == ImGuiAxis_Y) && (parent_flags & ImGuiWindowFlags_NoScrollbar)) border_target.y = ImClamp(border_target.y, border_limit_rect.Min.y, border_limit_rect.Max.y); } if (!ignore_resize) From 0582f7678a4447d9d36e3f2385d990f4885d44e1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 27 Jun 2024 19:05:47 +0200 Subject: [PATCH 50/66] Nav: store NavJustMovedToIsTabbing + shuffle a few nav related fields. (for usage by multi-select) --- imgui.cpp | 5 +++++ imgui_internal.h | 26 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 114aeee25..25423664a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12393,6 +12393,8 @@ void ImGui::NavInitRequestApplyResult() g.NavJustMovedToId = result->ID; g.NavJustMovedToFocusScopeId = result->FocusScopeId; g.NavJustMovedToKeyMods = 0; + g.NavJustMovedToIsTabbing = false; + g.NavJustMovedToHasSelectionData = (result->InFlags & ImGuiItemFlags_HasSelectionUserData) != 0; } // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) @@ -12649,6 +12651,9 @@ void ImGui::NavMoveRequestApplyResult() g.NavJustMovedToId = result->ID; g.NavJustMovedToFocusScopeId = result->FocusScopeId; g.NavJustMovedToKeyMods = g.NavMoveKeyMods; + g.NavJustMovedToIsTabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0; + g.NavJustMovedToHasSelectionData = (result->InFlags & ImGuiItemFlags_HasSelectionUserData) != 0; + //IMGUI_DEBUG_LOG_NAV("[nav] NavJustMovedFromFocusScopeId = 0x%08X, NavJustMovedToFocusScopeId = 0x%08X\n", g.NavJustMovedFromFocusScopeId, g.NavJustMovedToFocusScopeId); } // Apply new NavID/Focus diff --git a/imgui_internal.h b/imgui_internal.h index 9bbbc5eca..b75f9a324 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1599,7 +1599,7 @@ struct ImGuiNavItemData float DistBox; // Move // Best candidate box distance to current NavId float DistCenter; // Move // Best candidate center distance to current NavId float DistAxial; // Move // Best candidate axial distance to current NavId - ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. + ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionUserData() value. Valid if (InFlags & ImGuiItemFlags_HasSelectionUserData) ImGuiNavItemData() { Clear(); } void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } @@ -2044,6 +2044,7 @@ struct ImGuiContext ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' ImGuiID NavId; // Focused item for navigation ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope) + ImGuiNavLayer NavLayer; // Focused layer (main scrolling layer, or menu/title bar layer) 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) @@ -2051,13 +2052,9 @@ struct ImGuiContext ImVector NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain. 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; ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. ImGuiActivateFlags NavNextActivateFlags; ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse - ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data. bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) @@ -2088,6 +2085,14 @@ struct ImGuiContext ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy + // Navigation: record of last move request + ImGuiID NavJustMovedFromFocusScopeId; // Just navigated from this focus scope id (result of a successfully MoveRequest). + 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; + bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags. + bool NavJustMovedToHasSelectionData; // Copy of move result's InFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData. + // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828) ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab on OS X) @@ -2324,18 +2329,18 @@ struct ImGuiContext NavWindow = NULL; NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0; - NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; + NavLayer = ImGuiNavLayer_Main; + NavNextActivateId = 0; NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None; NavHighlightActivatedId = 0; NavHighlightActivatedTimer = 0.0f; - NavJustMovedToKeyMods = ImGuiMod_None; NavInputSource = ImGuiInputSource_Keyboard; - NavLayer = ImGuiNavLayer_Main; NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid; NavIdIsAlive = false; NavMousePosDirty = false; NavDisableHighlight = true; NavDisableMouseHover = false; + NavAnyRequest = false; NavInitRequest = false; NavInitRequestFromMove = false; @@ -2350,6 +2355,11 @@ struct ImGuiContext NavTabbingDir = 0; NavTabbingCounter = 0; + NavJustMovedFromFocusScopeId = NavJustMovedToId = NavJustMovedToFocusScopeId = 0; + NavJustMovedToKeyMods = ImGuiMod_None; + NavJustMovedToIsTabbing = false; + NavJustMovedToHasSelectionData = false; + // All platforms use Ctrl+Tab but Ctrl<>Super are swapped on Mac... // FIXME: Because this value is stored, it annoyingly interfere with toggling io.ConfigMacOSXBehaviors updating this.. ConfigNavWindowingKeyNext = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiKey_Tab); From 404af57004917e4b7cb763d416a78f2acf990055 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 28 Jun 2024 15:04:52 +0200 Subject: [PATCH 51/66] Backends: OpenGL2, OpenGL3: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) Analogous to change to Vulkan backend in 1.90. --- backends/imgui_impl_opengl2.cpp | 3 +++ backends/imgui_impl_opengl3.cpp | 3 +++ docs/CHANGELOG.txt | 2 ++ 3 files changed, 8 insertions(+) diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 3eb092afd..7f1ea325a 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748) // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). @@ -113,6 +114,8 @@ void ImGui_ImplOpenGL2_NewFrame() if (!bd->FontTexture) ImGui_ImplOpenGL2_CreateDeviceObjects(); + if (!bd->FontTexture) + ImGui_ImplOpenGL2_CreateFontsTexture(); } static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index 58603a047..bbe96c420 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) // 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562) // 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447) // 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink. @@ -402,6 +403,8 @@ void ImGui_ImplOpenGL3_NewFrame() if (!bd->ShaderHandle) ImGui_ImplOpenGL3_CreateDeviceObjects(); + if (!bd->FontTexture) + ImGui_ImplOpenGL3_CreateFontsTexture(); } static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4b9b12c79..18871c060 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -90,6 +90,8 @@ Other changes: - Debug Tools: Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. - Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends. +- Backends: OpenGL2, OpenGL3: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it + has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) [@mlauss2] - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (#7735) - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) From c7df9c71214a16790eaa2d202a5fd7b9f164578f Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 28 Jun 2024 15:48:08 +0200 Subject: [PATCH 52/66] Backends: Win32: Fixed warning with old MinGW/GCC versions. --- backends/imgui_impl_win32.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index b0f694057..9241f8edb 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -98,6 +98,7 @@ typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*); #endif #if defined(__GNUC__) #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader) #endif From 0403096a9d3574d6c07eda91daf79d45e3fbf927 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 28 Jun 2024 15:54:40 +0200 Subject: [PATCH 53/66] Drags: added ImGuisliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (#7749) --- docs/CHANGELOG.txt | 1 + imgui.h | 5 +++-- imgui_demo.cpp | 12 ++++++++---- imgui_widgets.cpp | 37 +++++++++++++++++++++++++------------ 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 18871c060..d3f328494 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -77,6 +77,7 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Tables: added TableGetHoveredColumn() to public API, as an alternative to testing for 'TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered' on each column. (#3740) +- Drags: added ImGuisliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (#7749) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume diff --git a/imgui.h b/imgui.h index ff8778c03..1ba242aa0 100644 --- a/imgui.h +++ b/imgui.h @@ -1732,8 +1732,9 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_None = 0, ImGuiSliderFlags_AlwaysClamp = 1 << 4, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits. - ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits) - ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget + ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits). + ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget. + ImGuisliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions for now. ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. // Obsolete names diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7bc4281cf..745258617 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -720,18 +720,19 @@ static void ShowDemoWindowWidgets() { IMGUI_DEMO_MARKER("Widgets/Basic/DragInt, DragFloat"); - static int i1 = 50, i2 = 42; + static int i1 = 50, i2 = 42, i3 = 128; ImGui::DragInt("drag int", &i1, 1); ImGui::SameLine(); HelpMarker( "Click and drag to edit value.\n" "Hold SHIFT/ALT for faster/slower edit.\n" "Double-click or CTRL+click to input value."); - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp); + ImGui::DragInt("drag int wrap 100..200", &i3, 1, 100, 200, "%d", ImGuisliderFlags_WrapAround); static float f1 = 1.00f, f2 = 0.0067f; ImGui::DragFloat("drag float", &f1, 0.005f); ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + //ImGui::DragFloat("drag wrap -1..1", &f3, 0.005f, -1.0f, 1.0f, NULL, ImGuisliderFlags_WrapAround); } ImGui::SeparatorText("Sliders"); @@ -2145,6 +2146,8 @@ static void ShowDemoWindowWidgets() ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); + ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuisliderFlags_WrapAround); + ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)"); // Drags static float drag_f = 0.5f; @@ -2159,9 +2162,10 @@ static void ShowDemoWindowWidgets() // Sliders static float slider_f = 0.5f; static int slider_i = 50; + const ImGuiSliderFlags flags_for_sliders = flags & ~ImGuisliderFlags_WrapAround; ImGui::Text("Underlying float value: %f", slider_f); - ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags); - ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags); + ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags_for_sliders); + ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags_for_sliders); ImGui::TreePop(); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 927cb2b98..41a14bf3d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2305,12 +2305,13 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const { ImGuiContext& g = *GImGui; const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; - const bool is_clamped = (v_min < v_max); + const bool is_bounded = (v_min < v_max); + const bool is_wrapped = is_bounded && (flags & ImGuisliderFlags_WrapAround); const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0; const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); // Default tweak speed - if (v_speed == 0.0f && is_clamped && (v_max - v_min < FLT_MAX)) + if (v_speed == 0.0f && is_bounded && (v_max - v_min < FLT_MAX)) v_speed = (float)((v_max - v_min) * g.DragSpeedDefaultRatio); // Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings @@ -2344,8 +2345,8 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const // Clear current value on activation // Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300. - bool is_just_activated = g.ActiveIdIsJustActivated; - bool is_already_past_limits_and_pushing_outward = is_clamped && ((*v >= v_max && adjust_delta > 0.0f) || (*v <= v_min && adjust_delta < 0.0f)); + const bool is_just_activated = g.ActiveIdIsJustActivated; + const bool is_already_past_limits_and_pushing_outward = is_bounded && !is_wrapped && ((*v >= v_max && adjust_delta > 0.0f) || (*v <= v_min && adjust_delta < 0.0f)); if (is_just_activated || is_already_past_limits_and_pushing_outward) { g.DragCurrentAccum = 0.0f; @@ -2403,13 +2404,24 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const if (v_cur == (TYPE)-0) v_cur = (TYPE)0; - // Clamp values (+ handle overflow/wrap-around for integer types) - if (*v != v_cur && is_clamped) + if (*v != v_cur && is_bounded) { - if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_floating_point)) - v_cur = v_min; - if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_floating_point)) - v_cur = v_max; + if (is_wrapped) + { + // Wrap values + if (v_cur < v_min) + v_cur += v_max - v_min + (is_floating_point ? 0 : 1); + if (v_cur > v_max) + v_cur -= v_max - v_min + (is_floating_point ? 0 : 1); + } + else + { + // Clamp values + handle overflow/wrap-around for integer types. + if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_floating_point)) + v_cur = v_min; + if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_floating_point)) + v_cur = v_max; + } } // Apply result @@ -2422,7 +2434,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. - IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); ImGuiContext& g = *GImGui; if (g.ActiveId == id) @@ -3015,7 +3027,8 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb) { // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. - IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + IM_ASSERT((flags & ImGuisliderFlags_WrapAround) == 0); // Not supported by SliderXXX(), only by DragXXX() switch (data_type) { From 372eebbeb2975096a8b59a1aed9dc178512e77dd Mon Sep 17 00:00:00 2001 From: Kevin Coghlan Date: Fri, 28 Jun 2024 17:06:16 +0100 Subject: [PATCH 54/66] Fix typo, rename ImGuisliderFlags_WrapAround flag to ImGuiSliderFlags_WrapAround. (#7752, #7749) --- docs/CHANGELOG.txt | 2 +- imgui.h | 2 +- imgui_demo.cpp | 8 ++++---- imgui_widgets.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d3f328494..0a01f1b9d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -77,7 +77,7 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Tables: added TableGetHoveredColumn() to public API, as an alternative to testing for 'TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered' on each column. (#3740) -- Drags: added ImGuisliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (#7749) +- Drags: added ImGuiSliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (#7749) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume diff --git a/imgui.h b/imgui.h index 1ba242aa0..4d9083c0e 100644 --- a/imgui.h +++ b/imgui.h @@ -1734,7 +1734,7 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits. ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits). ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget. - ImGuisliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions for now. + ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions for now. ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. // Obsolete names diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 745258617..838b44380 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -727,12 +727,12 @@ static void ShowDemoWindowWidgets() "Hold SHIFT/ALT for faster/slower edit.\n" "Double-click or CTRL+click to input value."); ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp); - ImGui::DragInt("drag int wrap 100..200", &i3, 1, 100, 200, "%d", ImGuisliderFlags_WrapAround); + ImGui::DragInt("drag int wrap 100..200", &i3, 1, 100, 200, "%d", ImGuiSliderFlags_WrapAround); static float f1 = 1.00f, f2 = 0.0067f; ImGui::DragFloat("drag float", &f1, 0.005f); ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); - //ImGui::DragFloat("drag wrap -1..1", &f3, 0.005f, -1.0f, 1.0f, NULL, ImGuisliderFlags_WrapAround); + //ImGui::DragFloat("drag wrap -1..1", &f3, 0.005f, -1.0f, 1.0f, NULL, ImGuiSliderFlags_WrapAround); } ImGui::SeparatorText("Sliders"); @@ -2146,7 +2146,7 @@ static void ShowDemoWindowWidgets() ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); - ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuisliderFlags_WrapAround); + ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround); ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)"); // Drags @@ -2162,7 +2162,7 @@ static void ShowDemoWindowWidgets() // Sliders static float slider_f = 0.5f; static int slider_i = 50; - const ImGuiSliderFlags flags_for_sliders = flags & ~ImGuisliderFlags_WrapAround; + const ImGuiSliderFlags flags_for_sliders = flags & ~ImGuiSliderFlags_WrapAround; ImGui::Text("Underlying float value: %f", slider_f); ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags_for_sliders); ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags_for_sliders); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 41a14bf3d..18a94bffe 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2306,7 +2306,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const ImGuiContext& g = *GImGui; const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; const bool is_bounded = (v_min < v_max); - const bool is_wrapped = is_bounded && (flags & ImGuisliderFlags_WrapAround); + const bool is_wrapped = is_bounded && (flags & ImGuiSliderFlags_WrapAround); const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0; const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); @@ -3028,7 +3028,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type { // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); - IM_ASSERT((flags & ImGuisliderFlags_WrapAround) == 0); // Not supported by SliderXXX(), only by DragXXX() + IM_ASSERT((flags & ImGuiSliderFlags_WrapAround) == 0); // Not supported by SliderXXX(), only by DragXXX() switch (data_type) { From c47928ffc0f42bd08e5643eb1d788812cba1ac3e Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 28 Jun 2024 18:33:57 +0200 Subject: [PATCH 55/66] Checkbox: minor tidying up to simplify work on multi-select branch. --- imgui_widgets.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 18a94bffe..715f236c2 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1132,7 +1132,8 @@ bool ImGui::Checkbox(const char* label, bool* v) const ImVec2 pos = window->DC.CursorPos; const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f)); ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, id)) + const bool is_visible = ItemAdd(total_bb, id); + if (!is_visible) { IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); return false; @@ -1147,27 +1148,29 @@ bool ImGui::Checkbox(const char* label, bool* v) } const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); - RenderNavHighlight(total_bb, id); - RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); - ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); - bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; - if (mixed_value) + const bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; + if (is_visible) { - // Undocumented tristate/mixed/indeterminate checkbox (#2644) - // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) - ImVec2 pad(ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)), ImMax(1.0f, IM_TRUNC(square_sz / 3.6f))); - window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); + RenderNavHighlight(total_bb, id); + RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); + if (mixed_value) + { + // Undocumented tristate/mixed/indeterminate checkbox (#2644) + // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) + ImVec2 pad(ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)), ImMax(1.0f, IM_TRUNC(square_sz / 3.6f))); + window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); + } + else if (*v) + { + const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f)); + RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); + } } - else if (*v) - { - const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f)); - RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); - } - - ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); + const ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); if (g.LogEnabled) LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]"); - if (label_size.x > 0.0f) + if (is_visible && label_size.x > 0.0f) RenderText(label_pos, label); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); From f2c07ed7175c79ab6e2999d14bb694c39510ad41 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Sun, 30 Jun 2024 14:25:51 -0700 Subject: [PATCH 56/66] Backends: Allegro5: Correctly handle unstable bit in version checks (#7755) --- backends/imgui_impl_allegro5.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 03a457082..db366fa74 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -62,8 +62,8 @@ #ifdef _WIN32 #include #endif -#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12 -#define ALLEGRO_HAS_DRAW_INDEXED_PRIM (ALLEGRO_VERSION_INT >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5 +#define ALLEGRO_HAS_CLIPBOARD ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12 +#define ALLEGRO_HAS_DRAW_INDEXED_PRIM ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5 // Visual Studio warnings #ifdef _MSC_VER From 751bbf38ba5aed4122462e11cd7f838567c2040e Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 12:04:36 +0200 Subject: [PATCH 57/66] Backends: SDLRenderer3: Update for SDL_RenderGeometryRaw() API changes. --- backends/imgui_impl_sdlrenderer3.cpp | 29 +++++++++++++++++++++++++--- docs/CHANGELOG.txt | 1 + 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index ae75b7c8b..8ba262548 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -20,6 +20,7 @@ // - Introduction, links and more at the top of imgui.cpp // CHANGELOG +// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009). // 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter. // 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly. // 2023-05-30: Initial version. @@ -44,8 +45,10 @@ // SDL_Renderer data struct ImGui_ImplSDLRenderer3_Data { - SDL_Renderer* Renderer; // Main viewport's renderer - SDL_Texture* FontTexture; + SDL_Renderer* Renderer; // Main viewport's renderer + SDL_Texture* FontTexture; + ImVector ColorBuffer; + ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); } }; @@ -106,8 +109,28 @@ void ImGui_ImplSDLRenderer3_NewFrame() ImGui_ImplSDLRenderer3_CreateDeviceObjects(); } +// https://github.com/libsdl-org/SDL/issues/9009 +static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVector& colors_out, SDL_Texture* texture, const float* xy, int xy_stride, const SDL_Color* color, int color_stride, const float* uv, int uv_stride, int num_vertices, const void* indices, int num_indices, int size_indices) +{ + const Uint8* color2 = (const Uint8*)color; + colors_out.resize(num_vertices); + SDL_FColor* color3 = colors_out.Data; + for (int i = 0; i < num_vertices; i++) + { + color3[i].r = color->r / 255.0f; + color3[i].g = color->g / 255.0f; + color3[i].b = color->b / 255.0f; + color3[i].a = color->a / 255.0f; + color2 += color_stride; + color = (const SDL_Color*)color2; + } + return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color3, sizeof(*color3), uv, uv_stride, num_vertices, indices, num_indices, size_indices); +} + void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer) { + ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); + // If there's a scale factor set by the user, use that instead // If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here. @@ -183,7 +206,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* // Bind texture, Draw SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); - SDL_RenderGeometryRaw(renderer, tex, + SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex, xy, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert), uv, (int)sizeof(ImDrawVert), diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 0a01f1b9d..0ceb01215 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -95,6 +95,7 @@ Other changes: has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) [@mlauss2] - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (#7735) +- Backends: SDLRenderer3: Update for SDL_RenderGeometryRaw() API changes. (SDL#9009). - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan From ccf3ee674a063a85653056a80fafc9e398c7dd68 Mon Sep 17 00:00:00 2001 From: Max Ortner Date: Sun, 30 Jun 2024 16:28:53 -0600 Subject: [PATCH 58/66] Backends: SDL3: update for SDL_SetTextInputRect() -> SDL_SetTextInputArea() api change. (#7760, #7754) --- backends/imgui_impl_sdl3.cpp | 3 ++- docs/CHANGELOG.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index f8e2c5510..c90455f61 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-07-01: Update for SDL3 api changes: SDL_SetTextInputRect() changed to SDL_SetTextInputArea(). // 2024-06-26: Update for SDL3 api changes: SDL_StartTextInput()/SDL_StopTextInput()/SDL_SetTextInputRect() functions signatures. // 2024-06-24: Update for SDL3 api changes: SDL_EVENT_KEY_DOWN/SDL_EVENT_KEY_UP contents. // 2024-06-03; Update for SDL3 api changes: SDL_SYSTEM_CURSOR_ renames. @@ -139,7 +140,7 @@ static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlat r.y = (int)data->InputPos.y; r.w = 1; r.h = (int)data->InputLineHeight; - SDL_SetTextInputRect(window, &r); + SDL_SetTextInputArea(window, &r, 0); SDL_StartTextInput(window); bd->ImeWindow = window; } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 0ceb01215..359c89fb6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -95,6 +95,7 @@ Other changes: has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) [@mlauss2] - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (#7735) +- Backends: SDL3: Update for SDL_SetTextInputRect() API rename. (#7760, #7754) [@maxortner01] - Backends: SDLRenderer3: Update for SDL_RenderGeometryRaw() API changes. (SDL#9009). - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] From 67216910fb0f6b3818fe04fa8c07c5237fff92a3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 12:10:54 +0200 Subject: [PATCH 59/66] Examples: SDL3: Remove use of SDL_HINT_IME_NATIVE_UI. --- docs/CHANGELOG.txt | 2 ++ examples/example_sdl3_opengl3/main.cpp | 3 --- examples/example_sdl3_sdlrenderer3/main.cpp | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 359c89fb6..66896b294 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -99,6 +99,8 @@ Other changes: - Backends: SDLRenderer3: Update for SDL_RenderGeometryRaw() API changes. (SDL#9009). - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] +- Examples: SDL3: Remove use of SDL_HINT_IME_NATIVE_UI since new SDL_HINT_IME_IMPLEMENTED_UI + values has a more suitable default for our case case. - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/examples/example_sdl3_opengl3/main.cpp b/examples/example_sdl3_opengl3/main.cpp index da12589f8..7ce36b4e8 100644 --- a/examples/example_sdl3_opengl3/main.cpp +++ b/examples/example_sdl3_opengl3/main.cpp @@ -57,9 +57,6 @@ int main(int, char**) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif - // Enable native IME. - SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); - // Create window with graphics context SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); diff --git a/examples/example_sdl3_sdlrenderer3/main.cpp b/examples/example_sdl3_sdlrenderer3/main.cpp index 98b9666ea..607d00b6b 100644 --- a/examples/example_sdl3_sdlrenderer3/main.cpp +++ b/examples/example_sdl3_sdlrenderer3/main.cpp @@ -31,9 +31,6 @@ int main(int, char**) return -1; } - // Enable native IME. - SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); - // Create window with SDL_Renderer graphics context Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags); From dd5c30d2d75b1038486468638729a5fed5ed3f84 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 14:32:11 +0200 Subject: [PATCH 60/66] Disabled: Reworked 1.90.8 behavior of Begin() not inheriting current BeginDisabled() state. Only tooltip are clearing that state. (#211, #7640) --- docs/CHANGELOG.txt | 6 ++++-- imgui.cpp | 2 +- imgui.h | 1 + imgui_demo.cpp | 3 +-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 66896b294..bd5caffd2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -67,8 +67,6 @@ Other changes: on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of ImGui::GetMouseCursor() value. (#1495) - IO: Added io.ClearInputMouse() to clear mouse state. (#4921) -- Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block bypassing - the disabled state. (#7726) - Windows: BeginChild(): fixed a glitch when during a resize of a child window which is tightly close to the boundaries of its parent (e.g. with zero WindowPadding), the child position could have temporarily be moved around by erroneous padding application. (#7706) @@ -77,6 +75,10 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Tables: added TableGetHoveredColumn() to public API, as an alternative to testing for 'TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered' on each column. (#3740) +- Disabled, Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block + bypassing the disabled state. (#7726) +- Disabled: Reworked 1.90.8 behavior of Begin() not inheriting current BeginDisabled() state, + to make it that only tooltip windows are temporarily clearing it. (#211, #7640) - Drags: added ImGuiSliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (#7749) - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) diff --git a/imgui.cpp b/imgui.cpp index 25423664a..cb0da9398 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6589,7 +6589,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window_stack_data.Window = window; window_stack_data.ParentLastItemDataBackup = g.LastItemData; window_stack_data.StackSizesOnBegin.SetToContextState(&g); - window_stack_data.DisabledOverrideReenable = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; + window_stack_data.DisabledOverrideReenable = (flags & ImGuiWindowFlags_Tooltip) && (g.CurrentItemFlags & ImGuiItemFlags_Disabled); g.CurrentWindowStack.push_back(window_stack_data); if (flags & ImGuiWindowFlags_ChildMenu) g.BeginMenuDepth++; diff --git a/imgui.h b/imgui.h index 4d9083c0e..d6dfd538a 100644 --- a/imgui.h +++ b/imgui.h @@ -861,6 +861,7 @@ namespace ImGui // Disabling [BETA API] // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors) // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) + // - Tooltips windows by exception are opted out of disabling. // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. IMGUI_API void BeginDisabled(bool disabled = true); IMGUI_API void EndDisabled(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 838b44380..72ac77982 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -889,12 +889,11 @@ static void ShowDemoWindowWidgets() // Using ImGuiHoveredFlags_ForTooltip will pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav', // which default value include the ImGuiHoveredFlags_AllowWhenDisabled flag. - // As a result, Set ImGui::BeginDisabled(); ImGui::Button("Disabled item", sz); - ImGui::EndDisabled(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) ImGui::SetTooltip("I am a a tooltip for a disabled item."); + ImGui::EndDisabled(); ImGui::TreePop(); } From 50a0f18e6aeeaee2ed3de67bd6e312577af5084d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 14:57:33 +0200 Subject: [PATCH 61/66] imgui_freetype: fixed divide by zero while handling FT_PIXEL_MODE_BGRA glyphs. (#7267, #3369) --- docs/CHANGELOG.txt | 1 + misc/freetype/imgui_freetype.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index bd5caffd2..5f35dc15a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -93,6 +93,7 @@ Other changes: - Debug Tools: Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. - Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends. +- imgui_freetype: Fixed divide by zero while handling FT_PIXEL_MODE_BGRA glyphs. (#7267, #3369) - Backends: OpenGL2, OpenGL3: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) [@mlauss2] - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index a5acab32d..68e38ed95 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -357,7 +357,7 @@ namespace case FT_PIXEL_MODE_BGRA: { // FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good. - #define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f) + #define DE_MULTIPLY(color, alpha) ImMin((ImU32)(255.0f * (float)color / (float)(alpha + FLT_MIN) + 0.5f), 255u) if (multiply_table == nullptr) { for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) From c554c402d307e6fde50e895adad009e23343ed26 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 16:13:38 +0200 Subject: [PATCH 62/66] IO: do not claim io.WantCaptureMouse=true on the mouse release frame of a button which was pressed over void. (#1392) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 2 +- imgui.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5f35dc15a..889ce554e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,9 @@ Other changes: shape change as honored by backends. Keeping this enabling will hopefully increase pressure on third-party backends to set ImGuiBackendFlags_HasMouseCursors and honor changes of ImGui::GetMouseCursor() value. (#1495) +- IO: do not claim io.WantCaptureMouse=true on the mouse release frame of a button + which was pressed over void/underlying app, which is consistent/needed to allow the + mouse up event of a drag over void/underlying app to catch release. (#1392) [@Moka42] - IO: Added io.ClearInputMouse() to clear mouse state. (#4921) - Windows: BeginChild(): fixed a glitch when during a resize of a child window which is tightly close to the boundaries of its parent (e.g. with zero WindowPadding), the child diff --git a/imgui.cpp b/imgui.cpp index cb0da9398..8d8d7b64a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4598,7 +4598,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() io.MouseDownOwnedUnlessPopupClose[i] = (g.HoveredWindow != NULL) || has_open_modal; } mouse_any_down |= io.MouseDown[i]; - if (io.MouseDown[i]) + if (io.MouseDown[i] || io.MouseReleased[i]) // Increase release frame for our evaluation of earliest button (#1392) if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down]) mouse_earliest_down = i; } diff --git a/imgui.h b/imgui.h index d6dfd538a..b93c0d947 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19084 +#define IMGUI_VERSION_NUM 19085 #define IMGUI_HAS_TABLE /* From cb16be3a3fc1f9cd146ae24d52b615f8a05fa93d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 16:50:03 +0200 Subject: [PATCH 63/66] Version 1.90.9 --- docs/CHANGELOG.txt | 7 +++++-- imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 889ce554e..16fc04d39 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,9 +36,11 @@ HOW TO UPDATE? - Please report any issue! ----------------------------------------------------------------------- - VERSION 1.90.9 WIP (In Progress) + VERSION 1.90.9 (Released 2024-07-01) ----------------------------------------------------------------------- +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.9 + Breaking changes: - Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to @@ -48,6 +50,7 @@ Breaking changes: BeginChild() calls anyhow. (#7687) [@cfillion] - old: BeginChild("Name", size, 0, ImGuiWindowFlags_NavFlattened); - new: BeginChild("Name", size, ImGuiChildFlags_NavFlattened, 0) + Kept inline redirection flag (will obsolete). - Style: renamed tab colors for clarity and consistency with other changes: (#261, #351) - ImGuiCol_TabActive -> ImGuiCol_TabSelected - ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed @@ -56,7 +59,7 @@ Breaking changes: - IO: io.ClearInputKeys() (first exposed in 1.89.8) doesn't clear mouse data. Newly added io.ClearInputMouse() does. (#4921) - Drag and Drop: renamed ImGuiDragDropFlags_SourceAutoExpirePayload to - ImGuiDragDropFlags_PayloadAutoExpire. Kept inline redirecting enum (will obsolete). (#1725, #143). + ImGuiDragDropFlags_PayloadAutoExpire. Kept inline redirecting enum (will obsolete). (#1725, #143) Other changes: diff --git a/imgui.cpp b/imgui.cpp index 8d8d7b64a..31220bdf2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index b93c0d947..a22e7ae9c 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (headers) // Help: @@ -27,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.9 WIP" -#define IMGUI_VERSION_NUM 19085 +#define IMGUI_VERSION "1.90.9" +#define IMGUI_VERSION_NUM 19090 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 72ac77982..955f3d1db 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c8499441e..51974604b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index b75f9a324..cb7b7319e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (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. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 778d27afd..dc69f9462 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 715f236c2..d261ba8ff 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 WIP +// dear imgui, v1.90.9 // (widgets code) /* From 84cc72f37209fae8cf4ab440f6aa9851254ba5f8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 1 Jul 2024 19:00:44 +0200 Subject: [PATCH 64/66] Version 1.91.0 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 12 ++++++------ imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 16fc04d39..75e10acce 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,15 @@ HOW TO UPDATE? and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.91.0 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking changes: + +Other changes: + + ----------------------------------------------------------------------- VERSION 1.90.9 (Released 2024-07-01) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 31220bdf2..4cfa2e1a0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index a22e7ae9c..2ec9aad26 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (headers) // Help: @@ -27,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.9" -#define IMGUI_VERSION_NUM 19090 +#define IMGUI_VERSION "1.91.0 WIP" +#define IMGUI_VERSION_NUM 19091 #define IMGUI_HAS_TABLE /* @@ -1660,11 +1660,11 @@ enum ImGuiStyleVar_ ImGuiStyleVar_TabRounding, // float TabRounding ImGuiStyleVar_TabBorderSize, // float TabBorderSize ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize - ImGuiStyleVar_TableAngledHeadersAngle, // float TableAngledHeadersAngle - ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign + ImGuiStyleVar_TableAngledHeadersAngle, // float TableAngledHeadersAngle + ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign - ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize + ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign ImGuiStyleVar_SeparatorTextPadding, // ImVec2 SeparatorTextPadding ImGuiStyleVar_COUNT diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 955f3d1db..6ea0e47d7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 51974604b..7ef0f2c6a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index cb7b7319e..29ed03bca 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (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. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index dc69f9462..8b392fc3c 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d261ba8ff..b40dcce11 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.9 +// dear imgui, v1.91.0 WIP // (widgets code) /* From 12f92518bc51194e6eb096a2863690f7fd2efcc4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 2 Jul 2024 11:32:46 +0200 Subject: [PATCH 65/66] Backends: SDL3: Update for API changes: SDLK_x renames and SDLK_KP_x removals (#7761, #7762) Also updated function signature in SDL2 backend to match and because it is expected we will use that data (as per #7672) --- backends/imgui_impl_sdl2.cpp | 5 +- backends/imgui_impl_sdl3.cpp | 96 +++++++++++++++++++----------------- docs/CHANGELOG.txt | 2 + 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index a18c013fd..5a319b930 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -163,8 +163,9 @@ static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeDa } } -static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) +static ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode) { + IM_UNUSED(scancode); switch (keycode) { case SDLK_TAB: return ImGuiKey_Tab; @@ -361,7 +362,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) case SDL_KEYUP: { ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); - ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); + ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode); io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. return true; diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index c90455f61..bbca11388 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-07-02: Update for SDL3 api changes: SDLK_x renames and SDLK_KP_x removals (#7761, #7762). // 2024-07-01: Update for SDL3 api changes: SDL_SetTextInputRect() changed to SDL_SetTextInputArea(). // 2024-06-26: Update for SDL3 api changes: SDL_StartTextInput()/SDL_StopTextInput()/SDL_SetTextInputRect() functions signatures. // 2024-06-24: Update for SDL3 api changes: SDL_EVENT_KEY_DOWN/SDL_EVENT_KEY_UP contents. @@ -146,8 +147,29 @@ static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlat } } -static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode) +static ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode) { + // Keypad doesn't have individual key values in SDL3 + switch (scancode) + { + case SDL_SCANCODE_KP_0: return ImGuiKey_Keypad0; + case SDL_SCANCODE_KP_1: return ImGuiKey_Keypad1; + case SDL_SCANCODE_KP_2: return ImGuiKey_Keypad2; + case SDL_SCANCODE_KP_3: return ImGuiKey_Keypad3; + case SDL_SCANCODE_KP_4: return ImGuiKey_Keypad4; + case SDL_SCANCODE_KP_5: return ImGuiKey_Keypad5; + case SDL_SCANCODE_KP_6: return ImGuiKey_Keypad6; + case SDL_SCANCODE_KP_7: return ImGuiKey_Keypad7; + case SDL_SCANCODE_KP_8: return ImGuiKey_Keypad8; + case SDL_SCANCODE_KP_9: return ImGuiKey_Keypad9; + case SDL_SCANCODE_KP_PERIOD: return ImGuiKey_KeypadDecimal; + case SDL_SCANCODE_KP_DIVIDE: return ImGuiKey_KeypadDivide; + case SDL_SCANCODE_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; + case SDL_SCANCODE_KP_MINUS: return ImGuiKey_KeypadSubtract; + case SDL_SCANCODE_KP_PLUS: return ImGuiKey_KeypadAdd; + case SDL_SCANCODE_KP_ENTER: return ImGuiKey_KeypadEnter; + case SDL_SCANCODE_KP_EQUALS: return ImGuiKey_KeypadEqual; + } switch (keycode) { case SDLK_TAB: return ImGuiKey_Tab; @@ -181,23 +203,6 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode) case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock; case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen; case SDLK_PAUSE: return ImGuiKey_Pause; - case SDLK_KP_0: return ImGuiKey_Keypad0; - case SDLK_KP_1: return ImGuiKey_Keypad1; - case SDLK_KP_2: return ImGuiKey_Keypad2; - case SDLK_KP_3: return ImGuiKey_Keypad3; - case SDLK_KP_4: return ImGuiKey_Keypad4; - case SDLK_KP_5: return ImGuiKey_Keypad5; - case SDLK_KP_6: return ImGuiKey_Keypad6; - case SDLK_KP_7: return ImGuiKey_Keypad7; - case SDLK_KP_8: return ImGuiKey_Keypad8; - case SDLK_KP_9: return ImGuiKey_Keypad9; - case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal; - case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide; - case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; - case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract; - case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd; - case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter; - case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual; case SDLK_LCTRL: return ImGuiKey_LeftCtrl; case SDLK_LSHIFT: return ImGuiKey_LeftShift; case SDLK_LALT: return ImGuiKey_LeftAlt; @@ -217,32 +222,32 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode) case SDLK_7: return ImGuiKey_7; case SDLK_8: return ImGuiKey_8; case SDLK_9: return ImGuiKey_9; - case SDLK_a: return ImGuiKey_A; - case SDLK_b: return ImGuiKey_B; - case SDLK_c: return ImGuiKey_C; - case SDLK_d: return ImGuiKey_D; - case SDLK_e: return ImGuiKey_E; - case SDLK_f: return ImGuiKey_F; - case SDLK_g: return ImGuiKey_G; - case SDLK_h: return ImGuiKey_H; - case SDLK_i: return ImGuiKey_I; - case SDLK_j: return ImGuiKey_J; - case SDLK_k: return ImGuiKey_K; - case SDLK_l: return ImGuiKey_L; - case SDLK_m: return ImGuiKey_M; - case SDLK_n: return ImGuiKey_N; - case SDLK_o: return ImGuiKey_O; - case SDLK_p: return ImGuiKey_P; - case SDLK_q: return ImGuiKey_Q; - case SDLK_r: return ImGuiKey_R; - case SDLK_s: return ImGuiKey_S; - case SDLK_t: return ImGuiKey_T; - case SDLK_u: return ImGuiKey_U; - case SDLK_v: return ImGuiKey_V; - case SDLK_w: return ImGuiKey_W; - case SDLK_x: return ImGuiKey_X; - case SDLK_y: return ImGuiKey_Y; - case SDLK_z: return ImGuiKey_Z; + case SDLK_A: return ImGuiKey_A; + case SDLK_B: return ImGuiKey_B; + case SDLK_C: return ImGuiKey_C; + case SDLK_D: return ImGuiKey_D; + case SDLK_E: return ImGuiKey_E; + case SDLK_F: return ImGuiKey_F; + case SDLK_G: return ImGuiKey_G; + case SDLK_H: return ImGuiKey_H; + case SDLK_I: return ImGuiKey_I; + case SDLK_J: return ImGuiKey_J; + case SDLK_K: return ImGuiKey_K; + case SDLK_L: return ImGuiKey_L; + case SDLK_M: return ImGuiKey_M; + case SDLK_N: return ImGuiKey_N; + case SDLK_O: return ImGuiKey_O; + case SDLK_P: return ImGuiKey_P; + case SDLK_Q: return ImGuiKey_Q; + case SDLK_R: return ImGuiKey_R; + case SDLK_S: return ImGuiKey_S; + case SDLK_T: return ImGuiKey_T; + case SDLK_U: return ImGuiKey_U; + case SDLK_V: return ImGuiKey_V; + case SDLK_W: return ImGuiKey_W; + case SDLK_X: return ImGuiKey_X; + case SDLK_Y: return ImGuiKey_Y; + case SDLK_Z: return ImGuiKey_Z; case SDLK_F1: return ImGuiKey_F1; case SDLK_F2: return ImGuiKey_F2; case SDLK_F3: return ImGuiKey_F3; @@ -338,8 +343,9 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: { + //IMGUI_DEBUG_LOG("SDL_EVENT_KEY_%d: key=%d, scancode=%d, mod=%X\n", (event->type == SDL_EVENT_KEY_DOWN) ? "DOWN" : "UP", event->key.key, event->key.scancode, event->key.mod); ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod); - ImGuiKey key = ImGui_ImplSDL3_KeycodeToImGuiKey(event->key.key); + ImGuiKey key = ImGui_ImplSDL3_KeyEventToImGuiKey(event->key.key, event->key.scancode); io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN)); io.SetKeyEventNativeData(key, event->key.key, event->key.scancode, event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. return true; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 75e10acce..75ec36df6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,8 @@ Breaking changes: Other changes: +- Backends: SDL3: Update for API changes: SDLK_x renames and SDLK_KP_x removals (#7761, #7762) + ----------------------------------------------------------------------- VERSION 1.90.9 (Released 2024-07-01) From a489585f8435cea7e9b24be37351a229789591c5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 2 Jul 2024 11:37:18 +0200 Subject: [PATCH 66/66] Backends: SDL3: Updated comments (IME seems fixed in SDL3). Added SDL3 examples to Visual Studio solution. --- backends/imgui_impl_sdl3.cpp | 5 ++--- backends/imgui_impl_sdl3.h | 5 ++--- examples/imgui_examples.sln | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index bbca11388..bc56a51a9 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -1,7 +1,8 @@ // dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*) // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) // (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) -// (IMPORTANT: SDL 3.0.0 is NOT YET RELEASED. IT IS POSSIBLE THAT ITS SPECS/API WILL CHANGE BEFORE RELEASE) + +// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN**) // Implemented features: // [X] Platform: Clipboard support. @@ -9,8 +10,6 @@ // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// Missing features: -// [ ] Platform: IME SUPPORT IS BROKEN IN SDL3 BECAUSE INPUTS GETS SENT TO BOTH APP AND IME + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_sdl3.h b/backends/imgui_impl_sdl3.h index eafb34749..f1c06db5d 100644 --- a/backends/imgui_impl_sdl3.h +++ b/backends/imgui_impl_sdl3.h @@ -1,7 +1,8 @@ // dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*) // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) // (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) -// (IMPORTANT: SDL 3.0.0 is NOT YET RELEASED. IT IS POSSIBLE THAT ITS SPECS/API WILL CHANGE BEFORE RELEASE) + +// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN**) // Implemented features: // [X] Platform: Clipboard support. @@ -9,8 +10,6 @@ // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// Missing features: -// [ ] Platform: IME SUPPORT IS BROKEN IN SDL3 BECAUSE INPUTS GETS SENT TO BOTH APP AND IME + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/examples/imgui_examples.sln b/examples/imgui_examples.sln index 071bcbd63..9aee4a99e 100644 --- a/examples/imgui_examples.sln +++ b/examples/imgui_examples.sln @@ -29,6 +29,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_opengl3", "ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl2_sdlrenderer2", "example_sdl2_sdlrenderer2\example_sdl2_sdlrenderer2.vcxproj", "{0C0B2BEA-311F-473C-9652-87923EF639E3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_opengl3", "example_sdl3_opengl3\example_sdl3_opengl3.vcxproj", "{84AAA301-84FE-428B-9E3E-817BC8123C0C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -141,6 +145,22 @@ Global {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|Win32.Build.0 = Release|Win32 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.ActiveCfg = Release|x64 {0C0B2BEA-311F-473C-9652-87923EF639E3}.Release|x64.Build.0 = Release|x64 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|Win32.ActiveCfg = Debug|Win32 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|Win32.Build.0 = Debug|Win32 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|x64.ActiveCfg = Debug|x64 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|x64.Build.0 = Debug|x64 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|Win32.ActiveCfg = Release|Win32 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|Win32.Build.0 = Release|Win32 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|x64.ActiveCfg = Release|x64 + {84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|x64.Build.0 = Release|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|Win32.Build.0 = Debug|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.ActiveCfg = Debug|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Debug|x64.Build.0 = Debug|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.ActiveCfg = Release|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64 + {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE