From 8cbb693f4764f19983588d5f1b9ddd92a7873c8f Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Sat, 25 Jan 2020 23:49:23 +0300 Subject: [PATCH 01/10] Emscripten: Allow filesystem support. (#3005) Filesystem functions perfectly work for Emscripten platform. This changes remove extra changes added by #2734. You can still disable filesystem functions by defining IMGUI_DISABLE_FILE_FUNCTIONS. --- docs/CHANGELOG.txt | 3 ++- imgui_internal.h | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ebd82d44..6f73c077 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -85,6 +85,7 @@ Other Changes: - Misc: Added misc/single_file/imgui_single_file.h, We use this to validate compiling all *.cpp files in a same compilation unit. Actual users of that technique (also called "Unity builds") can generally provide this themselves, so we don't really recommend you use this. [@rokups] +- CI: Added PVS-Studio static analysis on the continuous-integration server. [@rokups] - Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups] - Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups] - Backends: SDL: Wayland: use SDL_GetMouseState (because there is no global mouse state available @@ -98,7 +99,7 @@ Other Changes: the later may be problematic if compiling with recent Windows SDK and you want your app to run on Windows 7. You can instead try linking with Xinput9_1_0.lib instead. (#2716) - Backends: Glut: Improved FreeGLUT support for MinGW. (#3004) [@podsvirov] -- CI: Added PVS-Studio static analysis on the continuous-integration server. [@rokups] +- Backends: Emscripten: Avoid forcefully setting IMGUI_DISABLE_FILE_FUNCTIONS. (#3005) [@podsvirov] - Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking settings (otherwise if another loader such as Glew is accessible, the OpenGL3 backend might automatically use it). (#2919, #2798) diff --git a/imgui_internal.h b/imgui_internal.h index b1eb00d4..18b960a4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -270,9 +270,6 @@ static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) #endif // Helpers: File System -#if defined(__EMSCRIPTEN__) && !defined(IMGUI_DISABLE_FILE_FUNCTIONS) -#define IMGUI_DISABLE_FILE_FUNCTIONS -#endif #ifdef IMGUI_DISABLE_FILE_FUNCTIONS #define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS typedef void* ImFileHandle; From 05a49f0413232d2483e902089d2e9e99b40ce3b2 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 30 Jan 2020 17:15:11 +0100 Subject: [PATCH 02/10] Examples: Emscripten: Demonstrating embedding fonts in Makefile and code. (#2953) [@Oipo] --- docs/CHANGELOG.txt | 5 ++-- examples/example_emscripten/Makefile | 39 +++++++++++++++++++++------- examples/example_emscripten/main.cpp | 13 ++++++---- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6f73c077..9ee78e80 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -100,12 +100,13 @@ Other Changes: on Windows 7. You can instead try linking with Xinput9_1_0.lib instead. (#2716) - Backends: Glut: Improved FreeGLUT support for MinGW. (#3004) [@podsvirov] - Backends: Emscripten: Avoid forcefully setting IMGUI_DISABLE_FILE_FUNCTIONS. (#3005) [@podsvirov] -- Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking +- Examples: OpenGL: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking settings (otherwise if another loader such as Glew is accessible, the OpenGL3 backend might automatically use it). (#2919, #2798) +- Examples: OpenGL: Added support for glbindings OpenGL loader. (#2870) [@rokups] +- Examples: Emscripten: Demonstrating embedding fonts in Makefile and code. (#2953) [@Oipo] - Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed even if underlying system event loop gets paused due to app nap. (#2910, #2917) [@bear24rw] -- Examples: Added support for glbindings OpenGL loader. (#2870) [@rokups] ----------------------------------------------------------------------- diff --git a/examples/example_emscripten/Makefile b/examples/example_emscripten/Makefile index f5b7369a..9833270e 100644 --- a/examples/example_emscripten/Makefile +++ b/examples/example_emscripten/Makefile @@ -1,8 +1,10 @@ # # Makefile to use with emscripten # See https://emscripten.org/docs/getting_started/downloads.html -# for installation instructions. This Makefile assumes you have -# loaded emscripten's environment. +# for installation instructions. +# +# This Makefile assumes you have loaded emscripten's environment. +# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead) # # Running `make` will produce three files: # - example_emscripten.html @@ -13,7 +15,6 @@ CC = emcc CXX = em++ - EXE = example_emscripten.html SOURCES = main.cpp SOURCES += ../imgui_impl_sdl.cpp ../imgui_impl_opengl3.cpp @@ -21,21 +22,41 @@ SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) -EMS = -s USE_SDL=2 -s WASM=1 +##--------------------------------------------------------------------- +## EMSCRIPTEN OPTIONS +##--------------------------------------------------------------------- + +EMS += -s USE_SDL=2 -s WASM=1 EMS += -s ALLOW_MEMORY_GROWTH=1 EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0 EMS += -s ASSERTIONS=1 -EMS += -s NO_FILESYSTEM=1 -DIMGUI_DISABLE_FILE_FUNCTIONS -# Uncomment next line to fix possible rendering bugs with emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877) + +# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877) #EMS += -s BINARYEN_TRAP_MODE=clamp #EMS += -s SAFE_HEAP=1 ## Adds overhead -CPPFLAGS = -I../ -I../../ +# Emscripten allows preloading a file or folder to be accessible at runtime. +# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts" +# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html +# (Default value is 0. Set to 1 to enable file-system and include the misc/fonts/ folder as part of the build.) +USE_FILE_SYSTEM ?= 0 +ifeq ($(USE_FILE_SYSTEM), 0) +EMS += -s NO_FILESYSTEM=1 -DIMGUI_DISABLE_FILE_FUNCTIONS +endif +ifeq ($(USE_FILE_SYSTEM), 1) +LDFLAGS += --no-heap-copy --preload-file ../../misc/fonts@/fonts +endif + +##--------------------------------------------------------------------- +## FINAL BUILD FLAGS +##--------------------------------------------------------------------- + +CPPFLAGS += -I../ -I../../ #CPPFLAGS += -g CPPFLAGS += -Wall -Wformat -Os CPPFLAGS += $(EMS) -LIBS = $(EMS) -LDFLAGS = --shell-file shell_minimal.html +LIBS += $(EMS) +LDFLAGS += --shell-file shell_minimal.html ##--------------------------------------------------------------------- ## BUILD RULES diff --git a/examples/example_emscripten/main.cpp b/examples/example_emscripten/main.cpp index d9a6406d..f0eb3a2b 100644 --- a/examples/example_emscripten/main.cpp +++ b/examples/example_emscripten/main.cpp @@ -83,13 +83,16 @@ int main(int, char**) // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - Read 'docs/FONTS.txt' for more instructions and details. // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + // - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details. //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); - //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); +#ifndef IMGUI_DISABLE_FILE_FUNCTIONS + io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); +#endif // This function call won't return, and will engage in an infinite loop, processing events from the browser, and dispatching them. emscripten_set_main_loop_arg(main_loop, NULL, 0, true); From 9cff4d6e5e76dd18d9c4ee7a1560563da2059a44 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Wed, 29 Jan 2020 16:14:58 +0200 Subject: [PATCH 03/10] Columns: ImDrawList::Channels* functions now work inside columns. Use a private splitter in columns, paving way for removal of obsolete ImDrawList::Channels* functions. --- docs/CHANGELOG.txt | 2 ++ imgui.h | 7 +++++-- imgui_draw.cpp | 2 +- imgui_internal.h | 1 + imgui_widgets.cpp | 14 +++++++------- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9ee78e80..1c952838 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -79,6 +79,8 @@ Other Changes: In the current branch they are essentially the same as AddCircle(), AddCircleFilled() but as we will rework the circle rendering functions to use textures and automatic segment count selection, those new api can fill a gap. [@ShironekoBen] +- Columns: ImDrawList::Channels* functions now work inside columns. Added extra comments to + suggest using user-owned ImDrawListSplitter instead of ImDrawList functions. [@rokups] - Misc: Added ImGuiMouseCursor_NotAllowed enum so it can be used by more shared widgets. [@rokups] - Misc: Disable format checks when using stb_printf, to allow using extra formats. Made IMGUI_USE_STB_SPRINTF a properly documented imconfig.h flag. (#2954) [@loicmolinari] diff --git a/imgui.h b/imgui.h index 55c9b2bb..4cbe196e 100644 --- a/imgui.h +++ b/imgui.h @@ -1987,8 +1987,11 @@ struct ImDrawList IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer. // Advanced: Channels - // - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives) - // - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end) + // - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives) + // - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end) + // - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place! + // Prefer using your own persistent copy of ImDrawListSplitter as you can stack them. + // Using the ImDrawList::ChannelsXXXX you cannot stack a split over another. inline void ChannelsSplit(int count) { _Splitter.Split(this, count); } inline void ChannelsMerge() { _Splitter.Merge(this); } inline void ChannelsSetCurrent(int n) { _Splitter.SetCurrentChannel(this, n); } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2f3370e0..b457b532 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1307,7 +1307,7 @@ void ImDrawListSplitter::ClearFreeMemory() void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count) { - IM_ASSERT(_Current == 0 && _Count <= 1); + IM_ASSERT(_Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter."); int old_channels_count = _Channels.Size; if (old_channels_count < channels_count) _Channels.resize(channels_count); diff --git a/imgui_internal.h b/imgui_internal.h index 18b960a4..6df52433 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -843,6 +843,7 @@ struct ImGuiColumns ImRect HostClipRect; // Backup of ClipRect at the time of BeginColumns() ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns() ImVector Columns; + ImDrawListSplitter Splitter; ImGuiColumns() { Clear(); } void Clear() diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 099673f3..d5eed2cd 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7400,7 +7400,7 @@ void ImGui::PushColumnsBackground() ImGuiColumns* columns = window->DC.CurrentColumns; if (columns->Count == 1) return; - window->DrawList->ChannelsSetCurrent(0); + columns->Splitter.SetCurrentChannel(window->DrawList, 0); int cmd_size = window->DrawList->CmdBuffer.Size; PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false); IM_UNUSED(cmd_size); @@ -7413,7 +7413,7 @@ void ImGui::PopColumnsBackground() ImGuiColumns* columns = window->DC.CurrentColumns; if (columns->Count == 1) return; - window->DrawList->ChannelsSetCurrent(columns->Current + 1); + columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1); PopClipRect(); } @@ -7504,8 +7504,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag if (columns->Count > 1) { - window->DrawList->ChannelsSplit(1 + columns->Count); - window->DrawList->ChannelsSetCurrent(1); + columns->Splitter.Split(window->DrawList, 1 + columns->Count); + columns->Splitter.SetCurrentChannel(window->DrawList, 1); PushColumnClipRect(0); } @@ -7544,14 +7544,14 @@ void ImGui::NextColumn() // Columns 1+ ignore IndentX (by canceling it out) // FIXME-COLUMNS: Unnecessary, could be locked? window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding; - window->DrawList->ChannelsSetCurrent(columns->Current + 1); + columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1); } else { // New row/line // Column 0 honor IndentX window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); - window->DrawList->ChannelsSetCurrent(1); + columns->Splitter.SetCurrentChannel(window->DrawList, 1); columns->Current = 0; columns->LineMinY = columns->LineMaxY; } @@ -7581,7 +7581,7 @@ void ImGui::EndColumns() if (columns->Count > 1) { PopClipRect(); - window->DrawList->ChannelsMerge(); + columns->Splitter.Merge(window->DrawList); } const ImGuiColumnsFlags flags = columns->Flags; From 47fab0e166fe91966a16855fbcbecffcaaee5fd2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 12:27:57 +0100 Subject: [PATCH 04/10] Misc renaming, comments. Docs: add missing spacing to Changelog. --- docs/CHANGELOG.txt | 11 +++++++++++ imgui.cpp | 15 ++++++++------- imgui_demo.cpp | 6 +++--- imgui_internal.h | 6 +++--- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1c952838..165e46bb 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -8,6 +8,7 @@ Changes to the examples/bindings are included within the individual .cpp files i RELEASE NOTES: https://github.com/ocornut/imgui/releases REPORT ISSUES, ASK QUESTIONS: https://github.com/ocornut/imgui/issues COMMITS HISTORY: https://github.com/ocornut/imgui/commits/master +FAQ https://www.dearimgui.org/faq/ WHEN TO UPDATE? @@ -34,6 +35,7 @@ HOW TO UPDATE? ----------------------------------------------------------------------- Breaking Changes: + - Removed redirecting functions/enums names that were marked obsolete in 1.53 (December 2017): - ShowTestWindow() -> use ShowDemoWindow() - IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow) @@ -63,6 +65,7 @@ Breaking Changes: adding multiple points into it, you may need to fix your initial value. Other Changes: + - Inputs: Added ImGuiMouseButton enum for convenience (e.g. ImGuiMouseButton_Right=1). We forever guarantee that the existing value will not changes so existing code is free to use 0/1/2. - ColorEdit: Fix label alignment when using ImGuiColorEditFlags_NoInputs. (#2955) [@rokups] @@ -118,6 +121,7 @@ Other Changes: Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.74 Breaking Changes: + - Removed redirecting functions/enums names that were marked obsolete in 1.52 (October 2017): - Begin() [old 5 args version] -> use Begin() [3 args], use SetNextWindowSize() SetNextWindowBgAlpha() if needed - IsRootWindowOrAnyChildHovered() -> use IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows) @@ -142,6 +146,7 @@ Breaking Changes: The value is unused in master branch but will be used by the multi-viewport feature. (#2851) [@obfuscate] Other Changes: + - InputText, Nav: Fixed Home/End key broken when activating Keyboard Navigation. (#787) - InputText: Filter out ASCII 127 (DEL) emitted by low-level OSX layer, as we are using the Key value. (#2578) - Layout: Fixed a couple of subtle bounding box vertical positioning issues relating to the handling of text @@ -274,6 +279,7 @@ Other Changes: Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.72 Breaking Changes: + - Removed redirecting functions/enums names that were marked obsolete in 1.51 (June 2017): - ImGuiCol_Column*, ImGuiSetCond_* enums. - IsItemHoveredRect(), IsPosHoveringAnyWindow(), IsMouseHoveringAnyWindow(), IsMouseHoveringWindow() functions. @@ -285,6 +291,7 @@ Breaking Changes: Kept redirection function (will obsolete). (#581, #324) Other Changes: + - Scrolling: Made mouse-wheel scrolling lock the underlying window until the mouse is moved again or until a short delay expires (~2 seconds). This allow uninterrupted scroll even if child windows are passing under the mouse cursor. (#2604) @@ -357,6 +364,7 @@ Other Changes: Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.71 Breaking Changes: + - IO: changed AddInputCharacter(unsigned short c) signature to AddInputCharacter(unsigned int c). - Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). - Window: rendering of child windows outer decorations (e.g. bg color, border, scrollbars) is now @@ -367,6 +375,7 @@ Breaking Changes: to the creation of overlapping child windows. Please reach out if you are affected by this change! Other Changes: + - Window: clarified behavior of SetNextWindowContentSize(). Content size is defined as the size available after removal of WindowPadding on each sides. So SetNextWindowContentSize(ImVec2(100,100)) + auto-resize will always allow submitting a 100x100 item without creating a scrollbar, regarding of WindowPadding. @@ -439,6 +448,7 @@ Other Changes: Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.70 Breaking Changes: + - ImDrawList: Improved algorithm for mitre joints on thick lines, preserving correct thickness up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines, they will appear a little thicker now. (#2518) [@rmitton] @@ -451,6 +461,7 @@ Breaking Changes: on them but it is possible you have!). Other Changes: + - ImDrawList: Added ImDrawCallback_ResetRenderState, a special ImDrawList::AddCallback() value to request the renderer back-end to reset its render state. (#2037, #1639, #2452) Examples: Added support for ImDrawCallback_ResetRenderState in all renderer back-ends. Each diff --git a/imgui.cpp b/imgui.cpp index 899a323b..3fa63e0d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3766,7 +3766,7 @@ void ImGui::NewFrame() window->Active = false; window->WriteAccessed = false; - // Garbage collect (this is totally functional but we may need decide if the side-effects are desirable) + // Garbage collect transient buffers of recently unused windows if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) GcCompactTransientWindowBuffers(window); } @@ -3887,7 +3887,7 @@ void ImGui::Shutdown(ImGuiContext* context) IM_DELETE(g.Windows[i]); g.Windows.clear(); g.WindowsFocusOrder.clear(); - g.WindowsSortBuffer.clear(); + g.WindowsTempSortBuffer.clear(); g.CurrentWindow = NULL; g.CurrentWindowStack.clear(); g.WindowsById.Clear(); @@ -4123,19 +4123,19 @@ void ImGui::EndFrame() // Sort the window list so that all child windows are after their parent // We cannot do that on FocusWindow() because childs may not exist yet - g.WindowsSortBuffer.resize(0); - g.WindowsSortBuffer.reserve(g.Windows.Size); + g.WindowsTempSortBuffer.resize(0); + g.WindowsTempSortBuffer.reserve(g.Windows.Size); for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it continue; - AddWindowToSortBuffer(&g.WindowsSortBuffer, window); + AddWindowToSortBuffer(&g.WindowsTempSortBuffer, window); } // This usually assert if there is a mismatch between the ImGuiWindowFlags_ChildWindow / ParentWindow values and DC.ChildWindows[] in parents, aka we've done something wrong. - IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); - g.Windows.swap(g.WindowsSortBuffer); + IM_ASSERT(g.Windows.Size == g.WindowsTempSortBuffer.Size); + g.Windows.swap(g.WindowsTempSortBuffer); g.IO.MetricsActiveWindows = g.WindowsActiveCount; // Unlock font atlas @@ -10119,6 +10119,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) }; Funcs::NodeWindows(g.Windows, "Windows"); + //Funcs::NodeWindows(g.WindowsFocusOrder, "WindowsFocusOrder"); if (ImGui::TreeNode("DrawLists", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) { for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6bee207b..54b3a9f6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1790,7 +1790,7 @@ static void ShowDemoWindowLayout() // Child 1: no border, enable horizontal scrollbar { ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0); - ImGui::BeginChild("Child1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags); + ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags); for (int i = 0; i < 100; i++) { ImGui::Text("%04d: scrollable region", i); @@ -1808,7 +1808,7 @@ static void ShowDemoWindowLayout() { ImGuiWindowFlags window_flags = (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0) | (disable_menu ? 0 : ImGuiWindowFlags_MenuBar); ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("Child2", ImVec2(0, 260), true, window_flags); + ImGui::BeginChild("ChildR", ImVec2(0, 260), true, window_flags); if (!disable_menu && ImGui::BeginMenuBar()) { if (ImGui::BeginMenu("Menu")) @@ -1841,7 +1841,7 @@ static void ShowDemoWindowLayout() { ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10); ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100)); - ImGui::BeginChild("blah", ImVec2(200, 100), true, ImGuiWindowFlags_None); + ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None); for (int n = 0; n < 50; n++) ImGui::Text("Some test %d", n); ImGui::EndChild(); diff --git a/imgui_internal.h b/imgui_internal.h index 6df52433..46221159 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1006,8 +1006,8 @@ struct ImGuiContext // Windows state ImVector Windows; // Windows, sorted in display order, back to front - ImVector WindowsFocusOrder; // Windows, sorted in focus order, back to front - ImVector WindowsSortBuffer; + ImVector WindowsFocusOrder; // Windows, sorted in focus order, back to front. (FIXME: We could only store root windows here! Need to sort out the Docking equivalent which is RootWindowDockStop and is unfortunately a little more dynamic) + ImVector WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child ImVector CurrentWindowStack; ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* int WindowsActiveCount; // Number of unique windows submitted by frame @@ -1424,7 +1424,7 @@ struct IMGUI_API ImGuiWindowTempData // Storage for one window struct IMGUI_API ImGuiWindow { - char* Name; + char* Name; // Window name, owned by the window. ImGuiID ID; // == ImHashStr(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ ImVec2 Pos; // Position (always rounded-up to nearest pixel) From d19297e2fa930f4bbcfd0d586c6dabea4988154a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 14:10:43 +0100 Subject: [PATCH 05/10] InputTextMultiline: Provide label to BeginChildEx so internal window name hold a little more context. --- imgui_widgets.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d5eed2cd..a5aa86b1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3458,14 +3458,23 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ EndGroup(); return false; } - if (!BeginChildFrame(id, frame_bb.GetSize())) + + // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. + PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding); + PopStyleVar(3); + PopStyleColor(); + if (!child_visible) { - EndChildFrame(); + EndChild(); EndGroup(); return false; } draw_window = g.CurrentWindow; // Child window - draw_window->DC.NavLayerActiveMaskNext |= draw_window->DC.NavLayerCurrentMask; // This is to ensure that EndChild() will display a navigation highlight + draw_window->DC.NavLayerActiveMaskNext |= draw_window->DC.NavLayerCurrentMask; // This is to ensure that EndChild() will display a navigation highlight so we can "enter" into it. inner_size.x -= draw_window->ScrollbarSizes.x; } else @@ -4151,7 +4160,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (is_multiline) { Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line - EndChildFrame(); + EndChild(); EndGroup(); } From d9bca0d8531b8c6fca08cf883781fc0776418222 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 14:17:43 +0100 Subject: [PATCH 06/10] Nav: Fixed a bug where the initial CTRL-Tab press while in a child window sometimes selected the current root window instead of always selecting the previous root window. (#787) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 165e46bb..30a2a780 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -68,6 +68,8 @@ Other Changes: - Inputs: Added ImGuiMouseButton enum for convenience (e.g. ImGuiMouseButton_Right=1). We forever guarantee that the existing value will not changes so existing code is free to use 0/1/2. +- Nav: Fixed a bug where the initial CTRL-Tab press while in a child window sometimes selected + the current root window instead of always selecting the previous root window. (#787) - ColorEdit: Fix label alignment when using ImGuiColorEditFlags_NoInputs. (#2955) [@rokups] - ColorEdit: In HSV display of a RGB stored value, attempt to locally preserve Saturation when Value==0.0 (similar to changes done in 1.73 for Hue). Removed Hue editing lock since diff --git a/imgui.cpp b/imgui.cpp index 3fa63e0d..0d13896e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8766,7 +8766,7 @@ static void ImGui::NavUpdateWindowing() if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) { - g.NavWindowingTarget = g.NavWindowingTargetAnim = window; + g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // FIXME-DOCK: Will need to use RootWindowDockStop g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true; g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_NavKeyboard : ImGuiInputSource_NavGamepad; From fb257eef3e63dd589325a1db66478c5dfbe3dbe7 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 17:43:35 +0100 Subject: [PATCH 07/10] Internals: Update ->RootWindow and other links before applying the SetNextWindowXXX stuff. This is so FocusWindow() can always assume that ->RootWindow != NULL. --- imgui.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0d13896e..fac95013 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5402,6 +5402,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window_just_appearing_after_hidden_for_resize && !(flags & ImGuiWindowFlags_ChildWindow)) window->NavLastIds[0] = 0; + // Update ->RootWindow and others pointers (before any possible call to FocusWindow) + if (first_begin_of_the_frame) + UpdateWindowParentAndRootLinks(window, flags, parent_window); + // Process SetNextWindow***() calls bool window_pos_set_by_api = false; bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; @@ -5443,8 +5447,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Initialize const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) - UpdateWindowParentAndRootLinks(window, flags, parent_window); - window->Active = true; window->HasCloseButton = (p_open != NULL); window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); @@ -6037,8 +6039,8 @@ void ImGui::FocusWindow(ImGuiWindow* window) return; // Move the root window to the top of the pile - if (window->RootWindow) - window = window->RootWindow; + IM_ASSERT(window->RootWindow != NULL); + window = window->RootWindow; // Steal focus on active widgets if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it.. @@ -7823,7 +7825,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) // [SECTION] KEYBOARD/GAMEPAD NAVIGATION //----------------------------------------------------------------------------- -// FIXME-NAV: The existance of SetNavID vs SetNavIDWithRectRel vs SetFocusID is incredibly messy and confusing, +// FIXME-NAV: The existence of SetNavID vs SetNavIDWithRectRel vs SetFocusID is incredibly messy and confusing, // and needs some explanation or serious refactoring. void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id) { @@ -8295,7 +8297,8 @@ static void ImGui::NavUpdate() if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); #endif - // Set input source as Gamepad when buttons are pressed before we map Keyboard (some features differs when used with Gamepad vs Keyboard) + // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard) + // (do it before we map Keyboard input!) bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; bool nav_gamepad_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (g.IO.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; if (nav_gamepad_active) From fc41839cabb173b07897726abb9187061e3a44fa Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 18:27:40 +0100 Subject: [PATCH 08/10] Focus: Reworking FocusWindow() so in Docking branch we can fix CTRL+Tab being out of order on Docked windows because WindowsFocusOreder is poorly maintained. When merging this and d9bca0d8 in Docking we'll replace two ocurrences of RootWindow with RootWindowDockStop. --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fac95013..6d44419d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6040,17 +6040,18 @@ void ImGui::FocusWindow(ImGuiWindow* window) // Move the root window to the top of the pile IM_ASSERT(window->RootWindow != NULL); - window = window->RootWindow; + ImGuiWindow* focus_front_window = window->RootWindow; // NB: In docking branch this is window->RootWindowDockStop + ImGuiWindow* display_front_window = window->RootWindow; // Steal focus on active widgets - if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it.. - if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window) + if (focus_front_window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement may be unnecessary? Need further testing before removing it.. + if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window) ClearActiveID(); // Bring to front - BringWindowToFocusFront(window); - if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) - BringWindowToDisplayFront(window); + BringWindowToFocusFront(focus_front_window); + if ((display_front_window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayFront(display_front_window); } void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window) From fc42528f134a3aec1f6c34daec6f26390e7b29b5 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 31 Jan 2020 18:28:25 +0100 Subject: [PATCH 09/10] When testing for the presence of the ImGuiWindowFlags_NoBringToFrontOnFocus flag we test both the focused/clicked window (which could be a child window) and the root window. --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 30a2a780..099f8f08 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -78,6 +78,8 @@ Other Changes: - ColorEdit: "Copy As" content-menu tool shows hex values both with/without alpha when available. - MenuBar: Fix minor clipping issue where occasionally a menu text can overlap the right-most border. - Window: Fix SetNextWindowBgAlpha(1.0f) failing to override alpha component. (#3007) [@Albog] +- Window: When testing for the presence of the ImGuiWindowFlags_NoBringToFrontOnFocus flag we + test both the focused/clicked window (which could be a child window) and the root window. - ImDrawList: AddCircle(), AddCircleFilled() API can now auto-tessellate when provided a segment count of zero. Alter tessellation quality with 'style.CircleSegmentMaxError'. [@ShironekoBen] - ImDrawList: Add AddNgon(), AddNgonFilled() API with a guarantee on the explicit segment count. diff --git a/imgui.cpp b/imgui.cpp index 6d44419d..4f2993b4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6050,7 +6050,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) // Bring to front BringWindowToFocusFront(focus_front_window); - if ((display_front_window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + if (((window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) BringWindowToDisplayFront(display_front_window); } From 5a437f198ce39b923dc1a04c7fbfe7c64a283e25 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 2 Feb 2020 21:01:22 +0100 Subject: [PATCH 10/10] Internals: GetItemStatusFlags(). Added Comments. --- imgui_internal.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 46221159..85dcce20 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1258,7 +1258,7 @@ struct ImGuiContext NavInitResultId = 0; NavMoveFromClampedRefRect = false; NavMoveRequest = false; - NavMoveRequestFlags = 0; + NavMoveRequestFlags = ImGuiNavMoveFlags_None; NavMoveRequestForward = ImGuiNavForward_None; NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; @@ -1277,11 +1277,11 @@ struct ImGuiContext MouseCursor = ImGuiMouseCursor_Arrow; DragDropActive = DragDropWithinSourceOrTarget = false; - DragDropSourceFlags = 0; + DragDropSourceFlags = ImGuiDragDropFlags_None; DragDropSourceFrameCount = -1; DragDropMouseButton = -1; DragDropTargetId = 0; - DragDropAcceptFlags = 0; + DragDropAcceptFlags = ImGuiDragDropFlags_None; DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptFrameCount = -1; @@ -1395,7 +1395,7 @@ struct IMGUI_API ImGuiWindowTempData GroupOffset = ImVec1(0.0f); LastItemId = 0; - LastItemStatusFlags = 0; + LastItemStatusFlags = ImGuiItemStatusFlags_None; LastItemRect = LastItemDisplayRect = ImRect(); NavLayerActiveMask = NavLayerActiveMaskNext = 0x00; @@ -1570,7 +1570,7 @@ struct ImGuiTabItem float Width; // Width currently displayed float ContentWidth; // Width of actual contents, stored during BeginTabItem() call - ImGuiTabItem() { ID = 0; Flags = 0; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; } + ImGuiTabItem() { ID = 0; Flags = ImGuiTabItemFlags_None; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; } }; // Storage for a tab bar (sizeof() 92~96 bytes) @@ -1617,6 +1617,7 @@ struct ImGuiTabBar namespace ImGui { + // Windows // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) // If this ever crash because g.CurrentWindow is NULL it means that either // - ImGui::NewFrame() has never been called, which is illegal. @@ -1625,11 +1626,6 @@ namespace ImGui inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); - IMGUI_API void FocusWindow(ImGuiWindow* window); - IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window); - IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); - IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); - IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); @@ -1638,9 +1634,15 @@ namespace ImGui IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0); - IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); - IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); + // Windows: Display Order and Focus Order + IMGUI_API void FocusWindow(ImGuiWindow* window); + IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window); + IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); + + // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); ImGuiContext& g = *GImGui; return &g.ForegroundDrawList; } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches. @@ -1672,6 +1674,7 @@ namespace ImGui // Basic Accessors inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemId; } + inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemStatusFlags; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); @@ -1680,7 +1683,7 @@ namespace ImGui IMGUI_API ImGuiID GetHoveredID(); IMGUI_API void SetHoveredID(ImGuiID id); IMGUI_API void KeepAliveID(ImGuiID id); - IMGUI_API void MarkItemEdited(ImGuiID id); + IMGUI_API void MarkItemEdited(ImGuiID id); // Mark data associated to given item as "edited", used by IsItemDeactivatedAfterEdit() function. IMGUI_API void PushOverrideID(ImGuiID id); // Push given value at the top of the ID stack (whereas PushID combines old and new hashes) // Basic Helpers for widget code @@ -1749,7 +1752,7 @@ namespace ImGui IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); - // New Columns API (FIXME-WIP) + // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables api) IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index); @@ -1852,6 +1855,10 @@ namespace ImGui IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); + // Garbage collection + IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); + IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); + // Debug Tools inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, col); } inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }