Internals: using ItemAdd() consistently for internal items: windows & tables resize grips/borders, ScrollbarEx().

This put an extra flag check in ItemAdd() but essentially reduce inconsistency with windows decorations not using this. Useful for debugging.
It however buries the info/blurs the line about what it means to not use ItemAdd() since they are now doing it much less.
This commit is contained in:
ocornut 2022-10-24 22:45:05 +02:00
parent 178aee4b1c
commit 431fc6a7f6
4 changed files with 19 additions and 22 deletions

View File

@ -5874,7 +5874,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x); if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x);
if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID() ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID()
KeepAliveID(resize_grip_id); ItemAdd(resize_rect, resize_grip_id, NULL, ImGuiItemFlags_NoNav);
ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
//GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
if (hovered || held) if (hovered || held)
@ -5910,7 +5910,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
bool hovered, held; bool hovered, held;
ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING); ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING);
ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID() ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID()
KeepAliveID(border_id); ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav);
ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
//GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
@ -8650,11 +8650,14 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
// to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick). // to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick).
// We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null. // We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null.
// If we crash on a NULL g.NavWindow we need to fix the bug elsewhere. // If we crash on a NULL g.NavWindow we need to fix the bug elsewhere.
window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent); if (!(g.LastItemData.InFlags & ImGuiItemFlags_NoNav))
if (g.NavId == id || g.NavAnyRequest) {
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent);
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) if (g.NavId == id || g.NavAnyRequest)
NavProcessItem(); if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
NavProcessItem();
}
// [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something". // [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something".
// Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something". // Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something".
@ -10172,7 +10175,7 @@ static void ImGui::NavProcessItem()
if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi)) if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi))
NavProcessItemForTabbingRequest(id); NavProcessItemForTabbingRequest(id);
} }
else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & ImGuiItemFlags_Disabled))
{ {
ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
if (!is_tabbing) if (!is_tabbing)

View File

@ -850,7 +850,7 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags)
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold, ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease, ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease,

View File

@ -1171,8 +1171,8 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent); ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent);
ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit); ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit);
ItemAdd(hit_rect, column_id, NULL, ImGuiItemFlags_NoNav);
//GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100)); //GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100));
KeepAliveID(column_id);
bool hovered = false, held = false; bool hovered = false, held = false;
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus); bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
@ -4022,8 +4022,7 @@ void ImGui::EndColumns()
const ImGuiID column_id = columns->ID + ImGuiID(n); const ImGuiID column_id = columns->ID + ImGuiID(n);
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
KeepAliveID(column_id); if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav))
if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test
continue; continue;
bool hovered = false, held = false; bool hovered = false, held = false;

View File

@ -925,8 +925,6 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
if (window->SkipItems) if (window->SkipItems)
return false; return false;
KeepAliveID(id);
const float bb_frame_width = bb_frame.GetWidth(); const float bb_frame_width = bb_frame.GetWidth();
const float bb_frame_height = bb_frame.GetHeight(); const float bb_frame_height = bb_frame.GetHeight();
if (bb_frame_width <= 0.0f || bb_frame_height <= 0.0f) if (bb_frame_width <= 0.0f || bb_frame_height <= 0.0f)
@ -958,6 +956,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
bool held = false; bool held = false;
bool hovered = false; bool hovered = false;
ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav);
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v); const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v);
@ -1477,11 +1476,7 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags; if (!ItemAdd(bb, id, NULL, ImGuiItemFlags_NoNav))
g.CurrentItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
bool item_add = ItemAdd(bb, id);
g.CurrentItemFlags = item_flags_backup;
if (!item_add)
return false; return false;
bool hovered, held; bool hovered, held;
@ -6834,7 +6829,7 @@ void ImGui::EndMenuBar()
// To do so we claim focus back, restore NavId and then process the movement request for yet another frame. // To do so we claim focus back, restore NavId and then process the movement request for yet another frame.
// This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering)
const ImGuiNavLayer layer = ImGuiNavLayer_Menu; const ImGuiNavLayer layer = ImGuiNavLayer_Menu;
IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check (FIXME: Seems unnecessary)
FocusWindow(window); FocusWindow(window);
SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
@ -8059,7 +8054,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
if (p_open && !*p_open) if (p_open && !*p_open)
{ {
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav);
return false; return false;
} }
@ -8131,7 +8126,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'. // and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
if (tab_appearing && (!tab_bar_appearing || tab_is_new)) if (tab_appearing && (!tab_bar_appearing || tab_is_new))
{ {
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav);
if (is_tab_button) if (is_tab_button)
return false; return false;
return tab_contents_visible; return tab_contents_visible;