From 7260bb51cfc129fa5e46817dfd30632a9c1f2ff7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 7 Jun 2024 16:57:01 +0200 Subject: [PATCH 1/9] 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 2/9] 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 3/9] 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 4/9] 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 5/9] 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 6/9] 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 7/9] 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 8/9] 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 9/9] 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.