From d5d705069dafc8f26b9d8b0e4a16a54321f56376 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 29 Sep 2022 17:26:52 +0200 Subject: [PATCH] Various comments As it turns out, functions like IsItemHovered() won't work on an open BeginMenu() because LastItemData is overriden by BeginPopup(). Probably an easy fix. --- imgui.cpp | 3 +++ imgui_internal.h | 16 ++++++++++------ imgui_widgets.cpp | 9 ++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 04b43a315..8867192ab 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3584,6 +3584,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) return false; IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function + // Done with rectangle culling so we can perform heavier checks now // Test if we are hovering the right window (our window could be behind another window) // [2021/03/02] Reworked / reverted the revert, finally. Note we want e.g. BeginGroup/ItemAdd/EndGroup to work as well. (#3851) // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable @@ -3648,6 +3649,8 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) return false; if (!IsMouseHoveringRect(bb.Min, bb.Max)) return false; + + // Done with rectangle culling so we can perform heavier checks now. if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) { g.HoveredIdDisabled = true; diff --git a/imgui_internal.h b/imgui_internal.h index 6f591478f..a866fb8f6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -149,8 +149,8 @@ typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // E typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressedEx() -typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() -typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags +typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags +typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests @@ -758,7 +758,10 @@ struct ImDrawDataBuilder // [SECTION] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- -// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). +// Flags used by upcoming items +// - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags. +// - output: stored in g.LastItemData.InFlags +// Current window shared by all windows. // This is going to be exposed in imgui.h when stabilized enough. enum ImGuiItemFlags_ { @@ -774,10 +777,11 @@ enum ImGuiItemFlags_ ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. // Controlled by widget code - ImGuiItemFlags_Inputable = 1 << 8, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. + ImGuiItemFlags_Inputable = 1 << 10, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. }; -// Storage for LastItem data +// Status flags for an already submitted item +// - output: stored in g.LastItemData.StatusFlags enum ImGuiItemStatusFlags_ { ImGuiItemStatusFlags_None = 0, @@ -2650,7 +2654,7 @@ namespace ImGui IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); - // Parameter stacks + // Parameter stacks (shared) IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 44518881e..049df88fa 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7018,6 +7018,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) ImVec2 label_size = CalcTextSize(label, NULL, true); // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window) + // This is only done for items for the menu set and not the full parent window. const bool menuset_is_open = IsRootOfOpenMenuSet(); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) @@ -7156,9 +7157,10 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (menu_is_open) { - SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos. + // FIXME: This technically breaks functions relying on LastItemData, somehow nobody complained yet. Should backup/restore LastItemData. + SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos. PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding - menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) PopStyleVar(); } else @@ -7177,7 +7179,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) void ImGui::EndMenu() { // 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. + // A menu doesn't close itself because EndMenuBar() wants to 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. // FIXME: This doesn't work if the parent BeginMenu() is not on a menu. ImGuiContext& g = *GImGui; @@ -7203,6 +7205,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); + // See BeginMenuEx() for comments about this. const bool menuset_is_open = IsRootOfOpenMenuSet(); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open)