From 587506dd575cb230bf7379be4ed9b233f75dfabd Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Dec 2018 11:27:02 +0100 Subject: [PATCH 1/4] Tests: Changed prototype of ImGuiTestEngineHook_ItemAdd to match functions called in same spot. Made ButtonBehavior submit fallback item info if ItemAdd() was not called (for resize grips, resize borders, scrollbar, columns, etc.) --- imgui.cpp | 2 +- imgui_internal.h | 2 +- imgui_widgets.cpp | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6fcbc85d..447f78a1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2630,7 +2630,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None; #ifdef IMGUI_ENABLE_TEST_ENGINE - ImGuiTestEngineHook_ItemAdd(id, bb); + ImGuiTestEngineHook_ItemAdd(bb, id); #endif // Clipping test diff --git a/imgui_internal.h b/imgui_internal.h index 033888ef..ab0691d1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1427,7 +1427,7 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch #ifdef IMGUI_ENABLE_TEST_ENGINE extern void ImGuiTestEngineHook_PreNewFrame(); extern void ImGuiTestEngineHook_PostNewFrame(); -extern void ImGuiTestEngineHook_ItemAdd(ImGuiID id, const ImRect& bb); +extern void ImGuiTestEngineHook_ItemAdd(const ImRect& bb, ImGuiID id); extern void ImGuiTestEngineHook_ItemInfo(ImGuiID id, const char* label, int flags); #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(_ID, _LABEL, _FLAGS) // Register status flags #else diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 672fa5ca..3bc83441 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -396,6 +396,11 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) g.HoveredWindow = window; +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (window->DC.LastItemId != id) + ImGuiTestEngineHook_ItemAdd(bb, id); +#endif + bool pressed = false; bool hovered = ItemHoverable(bb, id); From f1c75964098f81cf66c0d42653dc258ce5eaaf02 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Dec 2018 16:24:59 +0100 Subject: [PATCH 2/4] Internals: Popup related comments. Renamed the misleading internal ClosePopup() function. Added bool* test to BeginPopupModal in demo. --- imgui.cpp | 35 +++++++++++++++++------------------ imgui.h | 18 +++++++++++++----- imgui_demo.cpp | 12 +++++++++--- imgui_internal.h | 3 +-- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 447f78a1..da10a1e6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6520,12 +6520,13 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window) // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. // Don't close our own child popup windows. - int n = 0; + int popup_count_to_keep = 0; if (ref_window) { - for (; n < g.OpenPopupStack.Size; n++) + // Find the highest popup which is a descendant of the reference window (generally reference window = NavWindow) + for (; popup_count_to_keep < g.OpenPopupStack.Size; popup_count_to_keep++) { - ImGuiPopupRef& popup = g.OpenPopupStack[n]; + ImGuiPopupRef& popup = g.OpenPopupStack[popup_count_to_keep]; if (!popup.Window) continue; IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); @@ -6533,15 +6534,19 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window) continue; // Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow) - bool has_focus = false; - for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) - has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow); - if (!has_focus) + bool popup_or_descendent_has_focus = false; + for (int m = popup_count_to_keep; m < g.OpenPopupStack.Size && !popup_or_descendent_has_focus; m++) + if (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow) + popup_or_descendent_has_focus = true; + if (!popup_or_descendent_has_focus) break; } } - if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below - ClosePopupToLevel(n); + if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below + { + //IMGUI_DEBUG_LOG("ClosePopupsOverWindow(%s) -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep); + ClosePopupToLevel(popup_count_to_keep); + } } void ImGui::ClosePopupToLevel(int remaining) @@ -6556,14 +6561,6 @@ void ImGui::ClosePopupToLevel(int remaining) g.OpenPopupStack.resize(remaining); } -void ImGui::ClosePopup(ImGuiID id) -{ - if (!IsPopupOpen(id)) - return; - ImGuiContext& g = *GImGui; - ClosePopupToLevel(g.OpenPopupStack.Size - 1); -} - // Close the popup we have begin-ed into. void ImGui::CloseCurrentPopup() { @@ -6610,6 +6607,8 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags); } +// If 'p_open' is specified for a modal popup window, the popup will have a regular close button which will close the popup. +// Note that popup visibility status is owned by imgui (and manipulated with e.g. OpenPopup) so the actual value of *p_open is meaningless here. bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; @@ -6632,7 +6631,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla { EndPopup(); if (is_open) - ClosePopup(id); + ClosePopupToLevel(g.CurrentPopupStack.Size); return false; } return is_open; diff --git a/imgui.h b/imgui.h index ebe00640..b4ea2d89 100644 --- a/imgui.h +++ b/imgui.h @@ -226,7 +226,8 @@ namespace ImGui // which clicking will set the boolean to false when clicked. // - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting // anything to the window. Always call a matching End() for each Begin() call, regardless of its return value! - // [this is due to legacy reason and is inconsistent with most other functions such as BeginMenu/EndMenu, BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function returned true.] + // [this is due to legacy reason and is inconsistent with most other functions such as BeginMenu/EndMenu, BeginPopup/EndPopup, etc. + // where the EndXXX call should only be called if the corresponding BeginXXX function returned true.] // - Note that the bottom of window stack always contains a window called "Debug". IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); IMGUI_API void End(); @@ -511,7 +512,14 @@ namespace ImGui IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); - // Popups + // Popups, Modals + // The properties of popups windows are: + // - They block normal mouse hovering detection outside them. (*) + // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - Their visibility state (~bool) is held internally by imgui instead of being held by the programmer as we are used to with regular Begin() calls. + // User can manipulate the visibility state by calling OpenPopup(). + // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even when normally blocked by a popup. + // Those three properties are connected. The library needs to hold their visibility state because it can close popups at any time. IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! @@ -520,11 +528,11 @@ namespace ImGui IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors). return true when just opened. - IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open + IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open at the current begin-ed level of the popup stack. IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. // Columns - // You can also use SameLine(pos_x) for simplified columns. The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!) + // You can also use SameLine(pos_x) to mimic simplified columns. The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!) IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished IMGUI_API int GetColumnIndex(); // get current column index @@ -543,7 +551,7 @@ namespace ImGui IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name. // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. - IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty + IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty (stdout) IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard IMGUI_API void LogFinish(); // stop logging (close file, etc.) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d9eabfd3..3e382ddd 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1981,12 +1981,13 @@ static void ShowDemoWindowPopups() if (!ImGui::CollapsingHeader("Popups & Modal windows")) return; - // Popups are windows with a few special properties: + // The properties of popups windows are: // - They block normal mouse hovering detection outside them. (*) // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. // - Their visibility state (~bool) is held internally by imgui instead of being held by the programmer as we are used to with regular Begin() calls. + // User can manipulate the visibility state by calling OpenPopup(). // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even when normally blocked by a popup. - // Those three properties are intimately connected. The library needs to hold their visibility state because it can close popups at any time. + // Those three properties are connected. The library needs to hold their visibility state because it can close popups at any time. // Typical use for regular windows: // bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End(); @@ -2115,6 +2116,7 @@ static void ShowDemoWindowPopups() if (ImGui::Button("Delete..")) ImGui::OpenPopup("Delete?"); + if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); @@ -2147,7 +2149,11 @@ static void ShowDemoWindowPopups() if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); - if (ImGui::BeginPopupModal("Stacked 2")) + + // Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which will close the popup. + // Note that the visibility state of popups is owned by imgui, so the input value of the bool actually doesn't matter here. + bool dummy_open = true; + if (ImGui::BeginPopupModal("Stacked 2", &dummy_open)) { ImGui::Text("Hello from Stacked The Second!"); if (ImGui::Button("Close")) diff --git a/imgui_internal.h b/imgui_internal.h index ab0691d1..aa5b5c38 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1297,10 +1297,9 @@ namespace ImGui // Popups, Modals, Tooltips IMGUI_API void OpenPopupEx(ImGuiID id); - IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API void ClosePopupToLevel(int remaining); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window); - IMGUI_API bool IsPopupOpen(ImGuiID id); + IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack! IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); IMGUI_API ImGuiWindow* GetFrontMostPopupModal(); From f6f5c511063d53256fadaf1ce0575a3d684a53ba Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Dec 2018 18:42:11 +0100 Subject: [PATCH 3/4] Internals: Popups: EndMenu() calls ClosePopupToLevel(g.CurrentPopupStack.Size) which is more correct. --- imgui_widgets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 3bc83441..d3edd7bf 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5687,14 +5687,14 @@ bool ImGui::BeginMenu(const char* label, bool enabled) void ImGui::EndMenu() { - // Nav: When a left move request _within our child menu_ failed, close the menu. + // Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu). // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. // However, it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) { - ClosePopupToLevel(g.OpenPopupStack.Size - 1); + ClosePopupToLevel(g.CurrentPopupStack.Size); NavMoveRequestCancel(); } From 65dac021712f99ba954392734ceafe43392efe59 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Dec 2018 18:44:17 +0100 Subject: [PATCH 4/4] Internals: Popups: Renamed CurrentPopupStack to BeginPopupStack which is much less ambiguous. --- imgui.cpp | 38 +++++++++++++++++++------------------- imgui_internal.h | 2 +- imgui_widgets.cpp | 14 +++++++------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index da10a1e6..3d019dbc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3299,7 +3299,7 @@ void ImGui::NewFrame() // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. g.CurrentWindowStack.resize(0); - g.CurrentPopupStack.resize(0); + g.BeginPopupStack.resize(0); ClosePopupsOverWindow(g.NavWindow); // Create implicit/fallback window - which we will only render it if the user has added something to it. @@ -3373,7 +3373,7 @@ void ImGui::Shutdown(ImGuiContext* context) g.StyleModifiers.clear(); g.FontStack.clear(); g.OpenPopupStack.clear(); - g.CurrentPopupStack.clear(); + g.BeginPopupStack.clear(); g.DrawDataBuilder.ClearFreeMemory(); g.OverlayDrawList.ClearFreeMemory(); g.PrivateClipboard.clear(); @@ -3942,8 +3942,8 @@ ImVec2 ImGui::GetMousePos() ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() { ImGuiContext& g = *GImGui; - if (g.CurrentPopupStack.Size > 0) - return g.OpenPopupStack[g.CurrentPopupStack.Size-1].OpenMousePos; + if (g.BeginPopupStack.Size > 0) + return g.OpenPopupStack[g.BeginPopupStack.Size-1].OpenMousePos; return g.IO.MousePos; } @@ -4224,7 +4224,7 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) short* p_backup = &window->DC.StackSizesBackup[0]; { int current = window->IDStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop() { int current = window->DC.GroupStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup() - { int current = g.CurrentPopupStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup() + { int current = g.BeginPopupStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup() // For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them. { int current = g.ColorModifiers.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup >= current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() { int current = g.StyleModifiers.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup >= current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() @@ -4638,7 +4638,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesForResize > 0); if (flags & ImGuiWindowFlags_Popup) { - ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed window_just_activated_by_user |= (window != popup_ref.Window); } @@ -4652,9 +4652,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) CheckStacksSize(window, true); if (flags & ImGuiWindowFlags_Popup) { - ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; popup_ref.Window = window; - g.CurrentPopupStack.push_back(popup_ref); + g.BeginPopupStack.push_back(popup_ref); window->PopupId = popup_ref.PopupId; } @@ -4829,7 +4829,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->Pos = g.CurrentPopupStack.back().OpenPopupPos; + window->Pos = g.BeginPopupStack.back().OpenPopupPos; } // Position child window @@ -5232,7 +5232,7 @@ void ImGui::End() // Pop from window stack g.CurrentWindowStack.pop_back(); if (window->Flags & ImGuiWindowFlags_Popup) - g.CurrentPopupStack.pop_back(); + g.BeginPopupStack.pop_back(); CheckStacksSize(window, false); SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); } @@ -6428,13 +6428,13 @@ void ImGui::SetTooltip(const char* fmt, ...) bool ImGui::IsPopupOpen(ImGuiID id) { ImGuiContext& g = *GImGui; - return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; + return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id; } bool ImGui::IsPopupOpen(const char* str_id) { ImGuiContext& g = *GImGui; - return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); + return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); } ImGuiWindow* ImGui::GetFrontMostPopupModal() @@ -6461,7 +6461,7 @@ void ImGui::OpenPopupEx(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = g.CurrentWindow; - int current_stack_size = g.CurrentPopupStack.Size; + int current_stack_size = g.BeginPopupStack.Size; ImGuiPopupRef popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. popup_ref.PopupId = id; popup_ref.Window = NULL; @@ -6565,8 +6565,8 @@ void ImGui::ClosePopupToLevel(int remaining) void ImGui::CloseCurrentPopup() { ImGuiContext& g = *GImGui; - int popup_idx = g.CurrentPopupStack.Size - 1; - if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) + int popup_idx = g.BeginPopupStack.Size - 1; + if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.BeginPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) return; while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) popup_idx--; @@ -6584,7 +6584,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) char name[20]; if (extra_flags & ImGuiWindowFlags_ChildMenu) - ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth + ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginPopupStack.Size); // 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 @@ -6598,7 +6598,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; - if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance + if (g.OpenPopupStack.Size <= g.BeginPopupStack.Size) // Early out for performance { g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; @@ -6631,7 +6631,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla { EndPopup(); if (is_open) - ClosePopupToLevel(g.CurrentPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size); return false; } return is_open; @@ -6641,7 +6641,7 @@ void ImGui::EndPopup() { ImGuiContext& g = *GImGui; (void)g; IM_ASSERT(g.CurrentWindow->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls - IM_ASSERT(g.CurrentPopupStack.Size > 0); + IM_ASSERT(g.BeginPopupStack.Size > 0); // Make all menus and popups wrap around for now, may need to expose that policy. NavMoveRequestTryWrapping(g.CurrentWindow, ImGuiNavMoveFlags_LoopY); diff --git a/imgui_internal.h b/imgui_internal.h index aa5b5c38..53408f12 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -743,7 +743,7 @@ struct ImGuiContext ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector FontStack; // Stack for PushFont()/PopFont() ImVector OpenPopupStack; // Which popups are open (persistent) - ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) + ImVector BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions ImGuiCond NextTreeNodeOpenCond; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d3edd7bf..367c4df9 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1337,7 +1337,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF } char name[16]; - ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth + ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth // Peak into expected window size so we can position it if (ImGuiWindow* popup_window = FindWindowByName(name)) @@ -5563,7 +5563,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool pressed; bool menu_is_open = IsPopupOpen(id); - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].OpenParentId == window->IDStack.back()); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].OpenParentId == window->IDStack.back()); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) @@ -5604,9 +5604,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled) { // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. bool moving_within_opened_triangle = false; - if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar)) + if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].ParentWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar)) { - if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window) + if (ImGuiWindow* next_window = g.OpenPopupStack[g.BeginPopupStack.Size].Window) { ImRect next_window_rect = next_window->Rect(); ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; @@ -5657,11 +5657,11 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; if (want_close && IsPopupOpen(id)) - ClosePopupToLevel(g.CurrentPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); - if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) + if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) { // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. OpenPopup(label); @@ -5694,7 +5694,7 @@ void ImGui::EndMenu() ImGuiWindow* window = g.CurrentWindow; if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) { - ClosePopupToLevel(g.CurrentPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size); NavMoveRequestCancel(); }