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.
This commit is contained in:
ocornut 2022-09-29 17:26:52 +02:00
parent e74a50f525
commit d5d705069d
3 changed files with 19 additions and 9 deletions

View File

@ -3584,6 +3584,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false; return false;
IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function 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) // 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) // [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 // [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; return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max)) if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false; return false;
// Done with rectangle culling so we can perform heavier checks now.
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
{ {
g.HoveredIdDisabled = true; g.HoveredIdDisabled = true;

View File

@ -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 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 ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressedEx() typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressedEx()
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests
@ -758,7 +758,10 @@ struct ImDrawDataBuilder
// [SECTION] Widgets support: flags, enums, data structures // [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. // This is going to be exposed in imgui.h when stabilized enough.
enum ImGuiItemFlags_ enum ImGuiItemFlags_
{ {
@ -774,10 +777,11 @@ enum ImGuiItemFlags_
ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
// Controlled by widget code // 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_ enum ImGuiItemStatusFlags_
{ {
ImGuiItemStatusFlags_None = 0, ImGuiItemStatusFlags_None = 0,
@ -2650,7 +2654,7 @@ namespace ImGui
IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API ImVec2 GetContentRegionMaxAbs();
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); 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 PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag(); IMGUI_API void PopItemFlag();

View File

@ -7018,6 +7018,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
ImVec2 label_size = CalcTextSize(label, NULL, true); 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) // 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(); const bool menuset_is_open = IsRootOfOpenMenuSet();
ImGuiWindow* backed_nav_window = g.NavWindow; ImGuiWindow* backed_nav_window = g.NavWindow;
if (menuset_is_open) if (menuset_is_open)
@ -7156,7 +7157,8 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
if (menu_is_open) 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 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(); PopStyleVar();
@ -7177,7 +7179,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
void ImGui::EndMenu() void ImGui::EndMenu()
{ {
// Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ 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. // 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. // 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. // FIXME: This doesn't work if the parent BeginMenu() is not on a menu.
ImGuiContext& g = *GImGui; 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 pos = window->DC.CursorPos;
ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 label_size = CalcTextSize(label, NULL, true);
// See BeginMenuEx() for comments about this.
const bool menuset_is_open = IsRootOfOpenMenuSet(); const bool menuset_is_open = IsRootOfOpenMenuSet();
ImGuiWindow* backed_nav_window = g.NavWindow; ImGuiWindow* backed_nav_window = g.NavWindow;
if (menuset_is_open) if (menuset_is_open)