1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-11 00:04:24 +00:00

Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
#	imgui.h
#	imgui_demo.cpp
#	imgui_widgets.cpp
This commit is contained in:
ocornut 2024-10-18 18:59:27 +02:00
commit 4e2126ee44
14 changed files with 421 additions and 286 deletions

238
imgui.cpp
View file

@ -438,6 +438,7 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2024/10/18 (1.91.4) - renamed ImGuiCol_NavHighlight to ImGuiCol_NavCursor (for consistency with newly exposed and reworked features). Kept inline redirection enum (will obsolete).
- 2024/10/14 (1.91.4) - moved ImGuiConfigFlags_NavEnableSetMousePos to standalone io.ConfigNavMoveSetMousePos bool.
moved ImGuiConfigFlags_NavNoCaptureKeyboard to standalone io.ConfigNavCaptureKeyboard bool (note the inverted value!).
kept legacy names (will obsolete) + code that copies settings once the first time. Dynamically changing the old value won't work. Switch to using the new value!
@ -1426,6 +1427,15 @@ ImGuiIO::ImGuiIO()
FontAllowUserScaling = false;
DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
// Keyboard/Gamepad Navigation options
ConfigNavSwapGamepadButtons = false;
ConfigNavMoveSetMousePos = false;
ConfigNavCaptureKeyboard = true;
ConfigNavEscapeClearFocusItem = true;
ConfigNavEscapeClearFocusWindow = false;
ConfigNavCursorVisibleAuto = true;
ConfigNavCursorVisibleAlways = false;
// Docking options (when ImGuiConfigFlags_DockingEnable is set)
ConfigDockingNoSplit = false;
ConfigDockingWithShift = false;
@ -1445,10 +1455,6 @@ ImGuiIO::ImGuiIO()
#else
ConfigMacOSXBehaviors = false;
#endif
ConfigNavSwapGamepadButtons = false;
ConfigNavMoveSetMousePos = false;
ConfigNavCaptureKeyboard = true;
ConfigNavEscapeClearFocusWindow = false;
ConfigInputTrickleEventQueue = true;
ConfigInputTextCursorBlink = true;
ConfigInputTextEnterKeepActive = false;
@ -3558,7 +3564,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
case ImGuiCol_TextLink: return "TextLink";
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
case ImGuiCol_DragDropTarget: return "DragDropTarget";
case ImGuiCol_NavHighlight: return "NavHighlight";
case ImGuiCol_NavCursor: return "NavCursor";
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg";
@ -3763,26 +3769,26 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
}
}
void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags)
void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags)
{
ImGuiContext& g = *GImGui;
if (id != g.NavId)
return;
if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw))
if (!g.NavCursorVisible && !(flags & ImGuiNavRenderCursorFlags_AlwaysDraw))
return;
if (id == g.LastItemData.ID && (g.LastItemData.InFlags & ImGuiItemFlags_NoNav))
if (id == g.LastItemData.ID && (g.LastItemData.ItemFlags & ImGuiItemFlags_NoNav))
return;
ImGuiWindow* window = g.CurrentWindow;
if (window->DC.NavHideHighlightOneFrame)
return;
float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding;
float rounding = (flags & ImGuiNavRenderCursorFlags_NoRounding) ? 0.0f : g.Style.FrameRounding;
ImRect display_rect = bb;
display_rect.ClipWith(window->ClipRect);
const float thickness = 2.0f;
if (flags & ImGuiNavHighlightFlags_Compact)
if (flags & ImGuiNavRenderCursorFlags_Compact)
{
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, 0, thickness);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
}
else
{
@ -3791,7 +3797,7 @@ void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFl
bool fully_visible = window->ClipRect.Contains(display_rect);
if (!fully_visible)
window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, 0, thickness);
window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
if (!fully_visible)
window->DrawList->PopClipRect();
}
@ -3976,8 +3982,13 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
ViewportCreatedCount = PlatformWindowsCreatedCount = 0;
ViewportFocusedStampCount = 0;
NavCursorVisible = false;
NavHighlightItemUnderNav = false;
NavMousePosDirty = false;
NavIdIsAlive = false;
NavId = 0;
NavWindow = NULL;
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
NavLayer = ImGuiNavLayer_Main;
NavNextActivateId = 0;
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
@ -3985,10 +3996,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
NavHighlightActivatedTimer = 0.0f;
NavInputSource = ImGuiInputSource_Keyboard;
NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
NavIdIsAlive = false;
NavMousePosDirty = false;
NavDisableHighlight = true;
NavDisableMouseHover = false;
NavCursorHideFrames = 0;
NavAnyRequest = false;
NavInitRequest = false;
@ -4064,7 +4072,6 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
DragSpeedDefaultRatio = 1.0f / 100.0f;
DisabledAlphaBackup = 0.0f;
DisabledStackSize = 0;
LockMarkEdited = 0;
TooltipOverrideCount = 0;
TooltipPreviousWindow = NULL;
@ -4474,10 +4481,10 @@ ImGuiID ImGui::GetHoveredID()
void ImGui::MarkItemEdited(ImGuiID id)
{
// This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit().
// This marking is to be able to provide info for IsItemDeactivatedAfterEdit().
// ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need to fill the data.
ImGuiContext& g = *GImGui;
if (g.LockMarkEdited > 0)
if (g.LastItemData.ItemFlags & ImGuiItemFlags_NoMarkEdited)
return;
if (g.ActiveId == id || g.ActiveId == 0)
{
@ -4551,11 +4558,11 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT_USER_ERROR((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0, "Invalid flags for IsItemHovered()!");
if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
if (g.NavHighlightItemUnderNav && g.NavCursorVisible && !(flags & ImGuiHoveredFlags_NoNavOverride))
{
if (!IsItemFocused())
return false;
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
if ((g.LastItemData.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
return false;
if (flags & ImGuiHoveredFlags_ForTooltip)
@ -4590,11 +4597,11 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// Test if interactions on this window are blocked by an active popup or modal.
// The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here.
if (!IsWindowContentHoverable(window, flags) && !(g.LastItemData.InFlags & ImGuiItemFlags_NoWindowHoverableCheck))
if (!IsWindowContentHoverable(window, flags) && !(g.LastItemData.ItemFlags & ImGuiItemFlags_NoWindowHoverableCheck))
return false;
// Test if the item is disabled
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
if ((g.LastItemData.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
return false;
// Special handling for calling after Begin() which represent the title bar or tab.
@ -4604,7 +4611,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false;
// Test if using AllowOverlap and overlapped
if ((g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap) && id != 0)
if ((g.LastItemData.ItemFlags & ImGuiItemFlags_AllowOverlap) && id != 0)
if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0)
if (g.HoveredIdPreviousFrame != g.LastItemData.ID)
return false;
@ -4637,7 +4644,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// (this does not rely on LastItemData it can be called from a ButtonBehavior() call not following an ItemAdd() call)
// FIXME-LEGACY: the 'ImGuiItemFlags item_flags' parameter was added on 2023-06-28.
// If you used this in your legacy/custom widgets code:
// - Commonly: if your ItemHoverable() call comes after an ItemAdd() call: pass 'item_flags = g.LastItemData.InFlags'.
// - Commonly: if your ItemHoverable() call comes after an ItemAdd() call: pass 'item_flags = g.LastItemData.ItemFlags'.
// - Rare: otherwise you may pass 'item_flags = 0' (ImGuiItemFlags_None) unless you want to benefit from special behavior handled by ItemHoverable.
bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags)
{
@ -4722,7 +4729,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
}
#endif
if (g.NavDisableMouseHover && (item_flags & ImGuiItemFlags_NoNavDisableMouseHover) == 0)
if (g.NavHighlightItemUnderNav && (item_flags & ImGuiItemFlags_NoNavDisableMouseHover) == 0)
return false;
return true;
@ -4747,7 +4754,7 @@ void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemS
{
ImGuiContext& g = *GImGui;
g.LastItemData.ID = item_id;
g.LastItemData.InFlags = in_flags;
g.LastItemData.ItemFlags = in_flags;
g.LastItemData.StatusFlags = item_flags;
g.LastItemData.Rect = g.LastItemData.NavRect = item_rect;
}
@ -4923,7 +4930,8 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
ImGuiContext& g = *GImGui;
FocusWindow(window);
SetActiveID(window->MoveId, window);
g.NavDisableHighlight = true;
if (g.IO.ConfigNavCursorVisibleAuto)
g.NavCursorVisible = false;
g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - window->RootWindowDockTree->Pos;
g.ActiveIdNoClearOnFocusLoss = true;
SetActiveIdUsingAllKeyboardKeys();
@ -5027,12 +5035,13 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
}
}
// Initiate moving window when clicking on empty space or title bar.
// Initiate focusing and moving window when clicking on empty space or title bar.
// Initiate focusing window when clicking on a disabled item.
// Handle left-click and right-click focus.
void ImGui::UpdateMouseMovingWindowEndFrame()
{
ImGuiContext& g = *GImGui;
if (g.ActiveId != 0 || g.HoveredId != 0)
if (g.ActiveId != 0 || (g.HoveredId != 0 && !g.HoveredIdIsDisabled))
return;
// Unless we just made a window/popup appear
@ -5058,7 +5067,8 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL;
// Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already)
// Cancel moving if clicked over an item which was disabled or inhibited by popups
// (when g.HoveredIdIsDisabled == true && g.HoveredId == 0 we are inhibited by popups, when g.HoveredIdIsDisabled == true && g.HoveredId != 0 we are over a disabled item)0 already)
if (g.HoveredIdIsDisabled)
g.MovingWindow = NULL;
}
@ -5072,7 +5082,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
// With right mouse button we close popups without changing focus based on where the mouse is aimed
// Instead, focus will be restored to the window under the bottom-most closed popup.
// (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger)
if (g.IO.MouseClicked[1])
if (g.IO.MouseClicked[1] && g.HoveredId == 0)
{
// Find the top-most window between HoveredWindow and the top-most Modal Window.
// This is where we can trim the popup stack.
@ -5376,7 +5386,7 @@ void ImGui::NewFrame()
//IM_ASSERT(g.IO.KeyAlt == IsKeyDown(ImGuiKey_LeftAlt) || IsKeyDown(ImGuiKey_RightAlt));
//IM_ASSERT(g.IO.KeySuper == IsKeyDown(ImGuiKey_LeftSuper) || IsKeyDown(ImGuiKey_RightSuper));
// Update gamepad/keyboard navigation
// Update keyboard/gamepad navigation
NavUpdate();
// Update mouse input state
@ -6103,7 +6113,7 @@ bool ImGui::IsAnyItemActive()
bool ImGui::IsAnyItemFocused()
{
ImGuiContext& g = *GImGui;
return g.NavId != 0 && !g.NavDisableHighlight;
return g.NavId != 0 && g.NavCursorVisible;
}
bool ImGui::IsItemVisible()
@ -6335,11 +6345,11 @@ void ImGui::EndChild()
if ((child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY) && !nav_flattened)
{
ItemAdd(bb, child_window->ChildId);
RenderNavHighlight(bb, child_window->ChildId);
RenderNavCursor(bb, child_window->ChildId);
// When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
if (child_window->DC.NavLayersActiveMask == 0 && child_window == g.NavWindow)
RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_Compact);
RenderNavCursor(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavRenderCursorFlags_Compact);
}
else
{
@ -6899,7 +6909,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
g.NavWindowingAccumDeltaSize += nav_resize_dir * resize_step;
g.NavWindowingAccumDeltaSize = ImMax(g.NavWindowingAccumDeltaSize, clamp_rect.Min - window->Pos - window->Size); // We need Pos+Size >= clmap_rect.Min, so Size >= clmap_rect.Min - Pos, so size_delta >= clmap_rect.Min - window->Pos - window->Size
g.NavWindowingToggleLayer = false;
g.NavDisableMouseHover = true;
g.NavHighlightItemUnderNav = true;
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
ImVec2 accum_floored = ImTrunc(g.NavWindowingAccumDeltaSize);
if (accum_floored.x != 0.0f || accum_floored.y != 0.0f)
@ -7001,7 +7011,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
// Title bar only
const float backup_border_size = style.FrameBorderSize;
g.Style.FrameBorderSize = window->WindowBorderSize;
ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && g.NavCursorVisible) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
if (window->ViewportOwned)
title_bar_col |= IM_COL32_A_MASK; // No alpha (we don't support is_docking_transparent_payload here because simpler and less meaningful, but could with a bit of code shuffle/reuse)
RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding);
@ -8418,7 +8428,7 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
if (g.NavWindow != window)
{
SetNavWindow(window);
if (window && g.NavDisableMouseHover)
if (window && g.NavHighlightItemUnderNav)
g.NavMousePosDirty = true;
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
g.NavLayer = ImGuiNavLayer_Main;
@ -9186,7 +9196,7 @@ void ImGui::FocusItem()
return;
}
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavHighlight | ImGuiNavMoveFlags_NoSelect;
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavCursorVisible | ImGuiNavMoveFlags_NoSelect;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
SetNavWindow(window);
NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags);
@ -9221,7 +9231,7 @@ void ImGui::SetKeyboardFocusHere(int offset)
SetNavWindow(window);
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavHighlight;
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavCursorVisible;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
if (offset == -1)
@ -10406,9 +10416,9 @@ static void ImGui::UpdateMouseInputs()
g.MouseStationaryTimer = mouse_stationary ? (g.MouseStationaryTimer + io.DeltaTime) : 0.0f;
//IMGUI_DEBUG_LOG("%.4f\n", g.MouseStationaryTimer);
// If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
// If mouse moved we re-enable mouse hovering in case it was disabled by keyboard/gamepad. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)
g.NavDisableMouseHover = false;
g.NavHighlightItemUnderNav = false;
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
@ -10448,9 +10458,9 @@ static void ImGui::UpdateMouseInputs()
// We provide io.MouseDoubleClicked[] as a legacy service
io.MouseDoubleClicked[i] = (io.MouseClickedCount[i] == 2);
// Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation
// Clicking any mouse button reactivate mouse hovering which may have been deactivated by keyboard/gamepad navigation
if (io.MouseClicked[i])
g.NavDisableMouseHover = false;
g.NavHighlightItemUnderNav = false;
}
}
@ -10918,7 +10928,7 @@ bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiInputFlags flags, Im
void ImGui::SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags)
{
ImGuiContext& g = *GImGui;
g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasShortcut;
g.NextItemData.HasFlags |= ImGuiNextItemDataFlags_HasShortcut;
g.NextItemData.Shortcut = key_chord;
g.NextItemData.ShortcutFlags = flags;
}
@ -10930,7 +10940,7 @@ void ImGui::ItemHandleShortcut(ImGuiID id)
ImGuiInputFlags flags = g.NextItemData.ShortcutFlags;
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetNextItemShortcut) == 0); // Passing flags not supported by SetNextItemShortcut()!
if (g.LastItemData.InFlags & ImGuiItemFlags_Disabled)
if (g.LastItemData.ItemFlags & ImGuiItemFlags_Disabled)
return;
if (flags & ImGuiInputFlags_Tooltip)
{
@ -11461,7 +11471,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
g.LastItemData.ID = id;
g.LastItemData.Rect = bb;
g.LastItemData.NavRect = nav_bb_arg ? *nav_bb_arg : bb;
g.LastItemData.InFlags = g.CurrentItemFlags | g.NextItemData.ItemFlags | extra_flags;
g.LastItemData.ItemFlags = g.CurrentItemFlags | g.NextItemData.ItemFlags | extra_flags;
g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None;
// Note: we don't copy 'g.NextItemData.SelectionUserData' to an hypothetical g.LastItemData.SelectionUserData: since the former is not cleared.
@ -11479,7 +11489,7 @@ 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).
// 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 (!(g.LastItemData.InFlags & ImGuiItemFlags_NoNav))
if (!(g.LastItemData.ItemFlags & ImGuiItemFlags_NoNav))
{
// FIMXE-NAV: investigate changing the window tests into a simple 'if (g.NavFocusScopeId == g.CurrentFocusScopeId)' test.
window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent);
@ -11489,12 +11499,12 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
NavProcessItem();
}
if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasShortcut)
if (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasShortcut)
ItemHandleShortcut(id);
}
// Lightweight clear of SetNextItemXXX data.
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
g.NextItemData.HasFlags = ImGuiNextItemDataFlags_None;
g.NextItemData.ItemFlags = ImGuiItemFlags_None;
#ifdef IMGUI_ENABLE_TEST_ENGINE
@ -11524,7 +11534,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
}
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
//if ((g.LastItemData.InFlags & ImGuiItemFlags_NoNav) == 0)
//if ((g.LastItemData.ItemFlags & ImGuiItemFlags_NoNav) == 0)
// window->DrawList->AddRect(g.LastItemData.NavRect.Min, g.LastItemData.NavRect.Max, IM_COL32(255,255,0,255)); // [DEBUG]
#endif
@ -11723,7 +11733,7 @@ void ImGui::Unindent(float indent_w)
void ImGui::SetNextItemWidth(float item_width)
{
ImGuiContext& g = *GImGui;
g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasWidth;
g.NextItemData.HasFlags |= ImGuiNextItemDataFlags_HasWidth;
g.NextItemData.Width = item_width;
}
@ -11734,7 +11744,7 @@ void ImGui::PushItemWidth(float item_width)
ImGuiWindow* window = g.CurrentWindow;
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width
window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width);
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
g.NextItemData.HasFlags &= ~ImGuiNextItemDataFlags_HasWidth;
}
void ImGui::PushMultiItemsWidths(int components, float w_full)
@ -11753,7 +11763,7 @@ void ImGui::PushMultiItemsWidths(int components, float w_full)
prev_split = next_split;
}
window->DC.ItemWidth = ImMax(prev_split, 1.0f);
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
g.NextItemData.HasFlags &= ~ImGuiNextItemDataFlags_HasWidth;
}
void ImGui::PopItemWidth()
@ -11776,7 +11786,7 @@ float ImGui::CalcItemWidth()
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
float w;
if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth)
if (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasWidth)
w = g.NextItemData.Width;
else
w = window->DC.ItemWidth;
@ -12878,7 +12888,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET_MOUSE * scale;
ImRect r_avoid;
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !g.IO.ConfigNavMoveSetMousePos)
if (g.NavCursorVisible && g.NavHighlightItemUnderNav && !g.IO.ConfigNavMoveSetMousePos)
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
else
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
@ -12898,6 +12908,23 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// In our terminology those should be interchangeable, yet right now this is super confusing.
// Those two functions are merely a legacy artifact, so at minimum naming should be clarified.
void ImGui::SetNavCursorVisible(bool visible)
{
ImGuiContext& g = *GImGui;
if (g.IO.ConfigNavCursorVisibleAlways)
visible = true;
g.NavCursorVisible = visible;
}
// (was called NavRestoreHighlightAfterMove() before 1.91.4)
void ImGui::SetNavCursorVisibleAfterMove()
{
ImGuiContext& g = *GImGui;
if (g.IO.ConfigNavCursorVisibleAuto)
g.NavCursorVisible = true;
g.NavHighlightItemUnderNav = g.NavMousePosDirty = true;
}
void ImGui::SetNavWindow(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
@ -12959,9 +12986,9 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
window->NavRectRel[nav_layer] = WindowRectAbsToRel(window, g.LastItemData.NavRect);
if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
g.NavDisableMouseHover = true;
else
g.NavDisableHighlight = true;
g.NavHighlightItemUnderNav = true;
else if (g.IO.ConfigNavCursorVisibleAuto)
g.NavCursorVisible = false;
// Clear preferred scoring position (NavMoveRequestApplyResult() will tend to restore it)
NavClearPreferredPosForAxis(ImGuiAxis_X);
@ -12984,7 +13011,7 @@ static float inline NavScoreItemDistInterval(float cand_min, float cand_max, flo
return 0.0f;
}
// Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057
// Scoring function for keyboard/gamepad directional navigation. Based on https://gist.github.com/rygorous/6981057
static bool ImGui::NavScoreItem(ImGuiNavItemData* result)
{
ImGuiContext& g = *GImGui;
@ -13133,9 +13160,9 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
result->Window = window;
result->ID = g.LastItemData.ID;
result->FocusScopeId = g.CurrentFocusScopeId;
result->InFlags = g.LastItemData.InFlags;
result->ItemFlags = g.LastItemData.ItemFlags;
result->RectRel = WindowRectAbsToRel(window, g.LastItemData.NavRect);
if (result->InFlags & ImGuiItemFlags_HasSelectionUserData)
if (result->ItemFlags & ImGuiItemFlags_HasSelectionUserData)
{
IM_ASSERT(g.NextItemData.SelectionUserData != ImGuiSelectionUserData_Invalid);
result->SelectionUserData = g.NextItemData.SelectionUserData; // INTENTIONAL: At this point this field is not cleared in NextItemData. Avoid unnecessary copy to LastItemData.
@ -13158,7 +13185,7 @@ static void ImGui::NavProcessItem()
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
const ImGuiID id = g.LastItemData.ID;
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
const ImGuiItemFlags item_flags = g.LastItemData.ItemFlags;
// When inside a container that isn't scrollable with Left<>Right, clip NavRect accordingly (#2221)
if (window->DC.NavIsScrollPushableX == false)
@ -13220,7 +13247,7 @@ static void ImGui::NavProcessItem()
SetNavFocusScope(g.CurrentFocusScopeId); // Will set g.NavFocusScopeId AND store g.NavFocusScopePath
g.NavFocusScopeId = g.CurrentFocusScopeId;
g.NavIdIsAlive = true;
if (g.LastItemData.InFlags & ImGuiItemFlags_HasSelectionUserData)
if (g.LastItemData.ItemFlags & ImGuiItemFlags_HasSelectionUserData)
{
IM_ASSERT(g.NextItemData.SelectionUserData != ImGuiSelectionUserData_Invalid);
g.NavLastValidSelectionUserData = g.NextItemData.SelectionUserData; // INTENTIONAL: At this point this field is not cleared in NextItemData. Avoid unnecessary copy to LastItemData.
@ -13341,7 +13368,7 @@ void ImGui::NavMoveRequestResolveWithPastTreeNode(ImGuiNavItemData* result, ImGu
ImGuiContext& g = *GImGui;
g.NavMoveScoringItems = false;
g.LastItemData.ID = tree_node_data->ID;
g.LastItemData.InFlags = tree_node_data->InFlags & ~ImGuiItemFlags_HasSelectionUserData; // Losing SelectionUserData, recovered next-frame (cheaper).
g.LastItemData.ItemFlags = tree_node_data->ItemFlags & ~ImGuiItemFlags_HasSelectionUserData; // Losing SelectionUserData, recovered next-frame (cheaper).
g.LastItemData.NavRect = tree_node_data->NavRect;
NavApplyItemToResult(result); // Result this instead of implementing a NavApplyPastTreeNodeToResult()
NavClearPreferredPosForAxis(ImGuiAxis_Y);
@ -13427,13 +13454,6 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
}
}
void ImGui::NavRestoreHighlightAfterMove()
{
ImGuiContext& g = *GImGui;
g.NavDisableHighlight = false;
g.NavDisableMouseHover = g.NavMousePosDirty = true;
}
static inline void ImGui::NavUpdateAnyRequestFlag()
{
ImGuiContext& g = *GImGui;
@ -13482,7 +13502,7 @@ static ImGuiInputSource ImGui::NavCalcPreferredRefPosSource()
const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID;
// Testing for !activated_shortcut here could in theory be removed if we decided that activating a remote shortcut altered one of the g.NavDisableXXX flag.
if ((g.NavDisableHighlight || !g.NavDisableMouseHover || !window) && !activated_shortcut)
if ((!g.NavCursorVisible || !g.NavHighlightItemUnderNav || !window) && !activated_shortcut)
return ImGuiInputSource_Mouse;
else
return ImGuiInputSource_Keyboard; // or Nav in general
@ -13586,11 +13606,14 @@ static void ImGui::NavUpdate()
NavMoveRequestApplyResult();
g.NavTabbingCounter = 0;
g.NavMoveSubmitted = g.NavMoveScoringItems = false;
if (g.NavCursorHideFrames > 0)
if (--g.NavCursorHideFrames == 0)
g.NavCursorVisible = true;
// Schedule mouse position update (will be done at the bottom of this function, after 1) processing all move requests and 2) updating scrolling)
bool set_mouse_pos = false;
if (g.NavMousePosDirty && g.NavIdIsAlive)
if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
if (g.NavCursorVisible && g.NavHighlightItemUnderNav && g.NavWindow)
set_mouse_pos = true;
g.NavMousePosDirty = false;
IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu);
@ -13606,7 +13629,7 @@ static void ImGui::NavUpdate()
// Set output flags for user application
io.NavActive = (nav_keyboard_active || nav_gamepad_active) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs);
io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL);
io.NavVisible = (io.NavActive && g.NavId != 0 && g.NavCursorVisible) || (g.NavWindowingTarget != NULL);
// Process NavCancel input (to close a popup, get back to parent, clear focus)
NavUpdateCancelRequest();
@ -13614,7 +13637,7 @@ static void ImGui::NavUpdate()
// Process manual activation request
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = 0;
g.NavActivateFlags = ImGuiActivateFlags_None;
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
if (g.NavId != 0 && g.NavCursorVisible && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
{
const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space, ImGuiKeyOwner_NoOwner)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_NoOwner));
const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, 0, ImGuiKeyOwner_NoOwner)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, 0, ImGuiKeyOwner_NoOwner)));
@ -13639,7 +13662,9 @@ static void ImGui::NavUpdate()
}
}
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
g.NavDisableHighlight = true;
g.NavCursorVisible = false;
else if (g.IO.ConfigNavCursorVisibleAlways && g.NavCursorHideFrames == 0)
g.NavCursorVisible = true;
if (g.NavActivateId != 0)
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
@ -13696,8 +13721,8 @@ static void ImGui::NavUpdate()
// Always prioritize mouse highlight if navigation is disabled
if (!nav_keyboard_active && !nav_gamepad_active)
{
g.NavDisableHighlight = true;
g.NavDisableMouseHover = set_mouse_pos = false;
g.NavCursorVisible = false;
g.NavHighlightItemUnderNav = set_mouse_pos = false;
}
// Update mouse position if requested
@ -13732,7 +13757,7 @@ void ImGui::NavInitRequestApplyResult()
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
g.NavJustMovedToKeyMods = 0;
g.NavJustMovedToIsTabbing = false;
g.NavJustMovedToHasSelectionData = (result->InFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
g.NavJustMovedToHasSelectionData = (result->ItemFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
}
// Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called)
@ -13743,7 +13768,7 @@ void ImGui::NavInitRequestApplyResult()
if (result->SelectionUserData != ImGuiSelectionUserData_Invalid)
g.NavLastValidSelectionUserData = result->SelectionUserData;
if (g.NavInitRequestFromMove)
NavRestoreHighlightAfterMove();
SetNavCursorVisibleAfterMove();
}
// Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position
@ -13840,7 +13865,8 @@ void ImGui::NavUpdateCreateMoveRequest()
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", window ? window->Name : "<NULL>", g.NavLayer);
g.NavInitRequest = g.NavInitRequestFromMove = true;
g.NavInitResult.ID = 0;
g.NavDisableHighlight = false;
if (g.IO.ConfigNavCursorVisibleAuto)
g.NavCursorVisible = true;
}
// When using gamepad, we project the reference nav bounding box into window visible area.
@ -13904,7 +13930,7 @@ void ImGui::NavUpdateCreateTabbingRequest()
// See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping.
const bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
if (nav_keyboard_active)
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1;
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavCursorVisible == false && g.ActiveId == 0) ? 0 : +1;
else
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1;
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate;
@ -13936,9 +13962,9 @@ void ImGui::NavMoveRequestApplyResult()
if (result == NULL)
{
if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing)
g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight;
if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0)
NavRestoreHighlightAfterMove();
g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavCursorVisible;
if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavCursorVisible) == 0)
SetNavCursorVisibleAfterMove();
NavClearPreferredPosForAxis(axis); // On a failed move, clear preferred pos for this axis.
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n");
return;
@ -13991,7 +14017,7 @@ void ImGui::NavMoveRequestApplyResult()
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
g.NavJustMovedToKeyMods = g.NavMoveKeyMods;
g.NavJustMovedToIsTabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0;
g.NavJustMovedToHasSelectionData = (result->InFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
g.NavJustMovedToHasSelectionData = (result->ItemFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
//IMGUI_DEBUG_LOG_NAV("[nav] NavJustMovedFromFocusScopeId = 0x%08X, NavJustMovedToFocusScopeId = 0x%08X\n", g.NavJustMovedFromFocusScopeId, g.NavJustMovedToFocusScopeId);
}
@ -14011,7 +14037,7 @@ void ImGui::NavMoveRequestApplyResult()
}
// Tabbing: Activates Inputable, otherwise only Focus
if ((g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0)
if ((g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && (result->ItemFlags & ImGuiItemFlags_Inputable) == 0)
g.NavMoveFlags &= ~ImGuiNavMoveFlags_Activate;
// Activate
@ -14023,9 +14049,9 @@ void ImGui::NavMoveRequestApplyResult()
g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState | ImGuiActivateFlags_FromTabbing;
}
// Enable nav highlight
if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0)
NavRestoreHighlightAfterMove();
// Make nav cursor visible
if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavCursorVisible) == 0)
SetNavCursorVisibleAfterMove();
}
// Process Escape/NavCancel input (to close a popup, get back to parent, clear focus)
@ -14049,7 +14075,7 @@ static void ImGui::NavUpdateCancelRequest()
{
// Leave the "menu" layer
NavRestoreLayer(ImGuiNavLayer_Main);
NavRestoreHighlightAfterMove();
SetNavCursorVisibleAfterMove();
}
else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow)
{
@ -14059,7 +14085,7 @@ static void ImGui::NavUpdateCancelRequest()
IM_ASSERT(child_window->ChildId != 0);
FocusWindow(parent_window);
SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_window->Rect()));
NavRestoreHighlightAfterMove();
SetNavCursorVisibleAfterMove();
}
else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
{
@ -14070,11 +14096,13 @@ static void ImGui::NavUpdateCancelRequest()
{
// Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
// FIXME-NAV: This should happen on window appearing.
if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup)))// || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
g.NavWindow->NavLastIds[0] = 0;
if (g.IO.ConfigNavEscapeClearFocusItem || g.IO.ConfigNavEscapeClearFocusWindow)
if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup)))// || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
g.NavWindow->NavLastIds[0] = 0;
// Clear nav focus
g.NavId = 0;
if (g.IO.ConfigNavEscapeClearFocusItem || g.IO.ConfigNavEscapeClearFocusWindow)
g.NavId = 0;
if (g.IO.ConfigNavEscapeClearFocusWindow)
FocusWindow(NULL);
}
@ -14408,7 +14436,7 @@ static void ImGui::NavUpdateWindowing()
const float NAV_MOVE_SPEED = 800.0f;
const float move_step = NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
g.NavWindowingAccumDeltaPos += nav_move_dir * move_step;
g.NavDisableMouseHover = true;
g.NavHighlightItemUnderNav = true;
ImVec2 accum_floored = ImTrunc(g.NavWindowingAccumDeltaPos);
if (accum_floored.x != 0.0f || accum_floored.y != 0.0f)
{
@ -14426,7 +14454,7 @@ static void ImGui::NavUpdateWindowing()
// Investigate for each of them: ClearActiveID(), NavRestoreHighlightAfterMove(), NavRestoreLastChildNavWindow(), ClosePopupsOverWindow(), NavInitWindow()
ImGuiViewport* previous_viewport = g.NavWindow ? g.NavWindow->Viewport : NULL;
ClearActiveID();
NavRestoreHighlightAfterMove();
SetNavCursorVisibleAfterMove();
ClosePopupsOverWindow(apply_focus_window, false);
FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild);
apply_focus_window = g.NavWindow;
@ -14478,7 +14506,7 @@ static void ImGui::NavUpdateWindowing()
if (new_nav_layer == ImGuiNavLayer_Menu && !preserve_layer_1_nav_id)
g.NavWindow->NavLastIds[new_nav_layer] = 0;
NavRestoreLayer(new_nav_layer);
NavRestoreHighlightAfterMove();
SetNavCursorVisibleAfterMove();
}
}
}
@ -14619,7 +14647,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
// Rely on keeping other window->LastItemXXX fields intact.
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
KeepAliveID(source_id);
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id, g.LastItemData.InFlags);
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id, g.LastItemData.ItemFlags);
if (is_hovered && g.IO.MouseClicked[mouse_button])
{
SetActiveID(source_id, window);
@ -16181,7 +16209,7 @@ static void ImGui::WindowSelectViewport(ImGuiWindow* window)
// We need to take account of the possibility that mouse may become invalid.
// Popups/Tooltip always set ViewportAllowPlatformMonitorExtend so GetWindowAllowedExtentRect() will return full monitor bounds.
ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.BeginPopupStack.back().OpenMousePos;
bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow);
bool use_mouse_ref = (!g.NavCursorVisible || !g.NavHighlightItemUnderNav || !g.NavWindow);
bool mouse_valid = IsMousePosValid(&mouse_ref);
if ((window->Appearing || (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_ChildMenu))) && (!use_mouse_ref || mouse_valid))
window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos());
@ -21558,7 +21586,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
Text("NavActivateId/DownId/PressedId: %08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId);
Text("NavActivateFlags: %04X", g.NavActivateFlags);
Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
Text("NavCursorVisible: %d, NavHighlightItemUnderNav: %d", g.NavCursorVisible, g.NavHighlightItemUnderNav);
Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId);
Text("NavFocusRoute[] = ");
for (int path_n = g.NavFocusRoute.Size - 1; path_n >= 0; path_n--)
@ -21698,7 +21726,7 @@ bool ImGui::DebugBreakButton(const char* label, const char* description_of_locat
ColorConvertRGBtoHSV(col4f.x, col4f.y, col4f.z, hsv.x, hsv.y, hsv.z);
ColorConvertHSVtoRGB(hsv.x + 0.20f, hsv.y, hsv.z, col4f.x, col4f.y, col4f.z);
RenderNavHighlight(bb, id);
RenderNavCursor(bb, id);
RenderFrame(bb.Min, bb.Max, GetColorU32(col4f), true, g.Style.FrameRounding);
RenderTextClipped(bb.Min, bb.Max, label, NULL, &label_size, g.Style.ButtonTextAlign, &bb);