diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a6c0c7a5..9c750599 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? @@ -103,6 +104,7 @@ Other changes: ----------------------------------------------------------------------- Breaking Changes: + - Removed redirecting functions/enums names that were marked obsolete in 1.53 (December 2017): - ShowTestWindow() -> use ShowDemoWindow() - IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow) @@ -132,8 +134,11 @@ 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. +- 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 @@ -142,18 +147,23 @@ 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. 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] - 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 @@ -167,13 +177,14 @@ 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] -- Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking +- Backends: Emscripten: Avoid forcefully setting IMGUI_DISABLE_FILE_FUNCTIONS. (#3005) [@podsvirov] +- 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] ----------------------------------------------------------------------- @@ -183,6 +194,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) @@ -207,6 +219,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 @@ -339,6 +352,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. @@ -350,6 +364,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) @@ -422,6 +437,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 @@ -432,6 +448,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. @@ -504,6 +521,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] @@ -516,6 +534,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/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 e8231000..7ee4640d 100644 --- a/examples/example_emscripten/main.cpp +++ b/examples/example_emscripten/main.cpp @@ -84,13 +84,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); diff --git a/imgui.cpp b/imgui.cpp index ca718d74..f24d040d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3992,7 +3992,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); } @@ -4138,7 +4138,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(); @@ -4445,19 +4445,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 @@ -5883,6 +5883,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; @@ -5926,8 +5930,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); @@ -6714,18 +6716,19 @@ void ImGui::FocusWindow(ImGuiWindow* window) window->DockNode->TabBar->SelectedTabId = window->DockNode->TabBar->NextSelectedTabId = window->ID; // Move the root window to the top of the pile - if (window->RootWindow) - window = window->RootWindow; + IM_ASSERT(window->RootWindow != NULL); + 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 (((window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayFront(display_front_window); } void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window) @@ -8580,7 +8583,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) { @@ -9057,7 +9060,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) @@ -9528,7 +9532,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; @@ -15319,6 +15323,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) }; Funcs::NodeWindows(g.Windows, "Windows"); + //Funcs::NodeWindows(g.WindowsFocusOrder, "WindowsFocusOrder"); if (ImGui::TreeNode("Viewport", "Viewports (%d)", g.Viewports.Size)) { ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); diff --git a/imgui.h b/imgui.h index 9530ef93..1c370380 100644 --- a/imgui.h +++ b/imgui.h @@ -2090,8 +2090,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_demo.cpp b/imgui_demo.cpp index 3e2fbef5..254da598 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1848,7 +1848,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); @@ -1866,7 +1866,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")) @@ -1899,7 +1899,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_draw.cpp b/imgui_draw.cpp index 228df410..29e4f040 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1313,7 +1313,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 4f21d646..d55ea709 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -281,9 +281,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; @@ -862,6 +859,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() @@ -1159,8 +1157,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 @@ -1430,7 +1428,7 @@ struct ImGuiContext NavInitResultId = 0; NavMoveFromClampedRefRect = false; NavMoveRequest = false; - NavMoveRequestFlags = 0; + NavMoveRequestFlags = ImGuiNavMoveFlags_None; NavMoveRequestForward = ImGuiNavForward_None; NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; @@ -1447,11 +1445,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; @@ -1568,7 +1566,7 @@ struct IMGUI_API ImGuiWindowTempData GroupOffset = ImVec1(0.0f); LastItemId = 0; - LastItemStatusFlags = 0; + LastItemStatusFlags = ImGuiItemStatusFlags_None; LastItemRect = LastItemDisplayRect = ImRect(); NavLayerActiveMask = NavLayerActiveMaskNext = 0x00; @@ -1597,7 +1595,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, FlagsPreviousFrame; // See enum ImGuiWindowFlags_ ImGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass() @@ -1768,7 +1766,7 @@ struct ImGuiTabItem float Width; // Width currently displayed float ContentWidth; // Width of actual contents, stored during BeginTabItem() call - ImGuiTabItem() { ID = 0; Flags = 0; Window = NULL; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; } + ImGuiTabItem() { ID = 0; Flags = ImGuiTabItemFlags_None; Window = NULL; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; } }; // Storage for a tab bar (sizeof() 92~96 bytes) @@ -1817,6 +1815,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. @@ -1825,11 +1824,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); @@ -1838,9 +1832,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) { return GetForegroundDrawList(window->Viewport); } @@ -1879,6 +1879,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); @@ -1887,7 +1888,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 @@ -2000,7 +2001,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); @@ -2108,6 +2109,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; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a038eb0d..b787903a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3465,14 +3465,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 @@ -4161,7 +4170,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(); } @@ -7519,7 +7528,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); @@ -7532,7 +7541,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(); } @@ -7623,8 +7632,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); } @@ -7663,14 +7672,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; } @@ -7700,7 +7709,7 @@ void ImGui::EndColumns() if (columns->Count > 1) { PopClipRect(); - window->DrawList->ChannelsMerge(); + columns->Splitter.Merge(window->DrawList); } const ImGuiColumnsFlags flags = columns->Flags;