Nav: merged SetNavID() and SetNavIDWithRectRel() to improve sanity, moved flags overwrite off them. (#787)

This commit is contained in:
ocornut 2021-03-08 18:52:42 +01:00
parent 1c9cc7c117
commit a64e0eb3a4
3 changed files with 33 additions and 36 deletions

View File

@ -886,6 +886,7 @@ static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb
static ImVec2 NavCalcPreferredRefPos(); static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
static void NavRestoreLayer(ImGuiNavLayer layer);
static int FindWindowFocusIndex(ImGuiWindow* window); static int FindWindowFocusIndex(ImGuiWindow* window);
// Error Checking // Error Checking
@ -8476,9 +8477,8 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// FIXME-NAV: The existence of SetNavID vs SetNavIDWithRectRel vs SetFocusID is incredibly messy and confusing, // FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked.
// and needs some explanation or serious refactoring. void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.NavWindow != NULL); IM_ASSERT(g.NavWindow != NULL);
@ -8487,16 +8487,9 @@ void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
g.NavLayer = (ImGuiNavLayer)nav_layer; g.NavLayer = (ImGuiNavLayer)nav_layer;
g.NavFocusScopeId = focus_scope_id; g.NavFocusScopeId = focus_scope_id;
g.NavWindow->NavLastIds[nav_layer] = id; g.NavWindow->NavLastIds[nav_layer] = id;
}
void ImGui::SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
{
ImGuiContext& g = *GImGui;
SetNavID(id, nav_layer, focus_scope_id);
g.NavWindow->NavRectRel[nav_layer] = rect_rel; g.NavWindow->NavRectRel[nav_layer] = rect_rel;
g.NavMousePosDirty = true; //g.NavDisableHighlight = false;
g.NavDisableHighlight = false; //g.NavDisableMouseHover = g.NavMousePosDirty = true;
g.NavDisableMouseHover = true;
} }
void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
@ -8810,17 +8803,23 @@ static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
return window; return window;
} }
static void NavRestoreLayer(ImGuiNavLayer layer) void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.NavLayer = layer; if (layer == ImGuiNavLayer_Main)
if (layer == 0) g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow);
g.NavWindow = ImGui::NavRestoreLastChildNavWindow(g.NavWindow);
ImGuiWindow* window = g.NavWindow; ImGuiWindow* window = g.NavWindow;
if (window->NavLastIds[layer] != 0) if (window->NavLastIds[layer] != 0)
ImGui::SetNavIDWithRectRel(window->NavLastIds[layer], layer, 0, g.NavWindow->NavRectRel[layer]); {
SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
g.NavDisableHighlight = false;
g.NavDisableMouseHover = g.NavMousePosDirty = true;
}
else else
ImGui::NavInitWindow(window, true); {
g.NavLayer = layer;
NavInitWindow(window, true);
}
} }
static inline void ImGui::NavUpdateAnyRequestFlag() static inline void ImGui::NavUpdateAnyRequestFlag()
@ -8843,7 +8842,7 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer); IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer);
if (init_for_nav) if (init_for_nav)
{ {
SetNavID(0, g.NavLayer, 0); SetNavID(0, g.NavLayer, 0, ImRect());
g.NavInitRequest = true; g.NavInitRequest = true;
g.NavInitRequestFromMove = false; g.NavInitRequestFromMove = false;
g.NavInitResultId = 0; g.NavInitResultId = 0;
@ -8987,13 +8986,11 @@ static void ImGui::NavUpdate()
{ {
// Set mouse position given our knowledge of the navigated item position from last frame // Set mouse position given our knowledge of the navigated item position from last frame
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
{
if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow) if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
{ {
io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos();
io.WantSetMousePos = true; io.WantSetMousePos = true;
} }
}
g.NavMousePosDirty = false; g.NavMousePosDirty = false;
} }
g.NavIdIsAlive = false; g.NavIdIsAlive = false;
@ -9028,12 +9025,9 @@ static void ImGui::NavUpdate()
ImGuiWindow* child_window = g.NavWindow; ImGuiWindow* child_window = g.NavWindow;
ImGuiWindow* parent_window = g.NavWindow->ParentWindow; ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
IM_ASSERT(child_window->ChildId != 0); IM_ASSERT(child_window->ChildId != 0);
ImRect child_rect = child_window->Rect();
FocusWindow(parent_window); FocusWindow(parent_window);
SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0); SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos));
// Reassigning with same value, we're being explicit here.
g.NavIdIsAlive = false; // -V1048
if (g.NavDisableMouseHover)
g.NavMousePosDirty = true;
} }
else if (g.OpenPopupStack.Size > 0) else if (g.OpenPopupStack.Size > 0)
{ {
@ -9202,11 +9196,12 @@ static void ImGui::NavUpdateInitResult()
// Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called)
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name); IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name);
SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
if (g.NavInitRequestFromMove) if (g.NavInitRequestFromMove)
SetNavIDWithRectRel(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel); {
else g.NavDisableHighlight = false;
SetNavID(g.NavInitResultId, g.NavLayer, 0); g.NavDisableMouseHover = g.NavMousePosDirty = true;
g.NavWindow->NavRectRel[g.NavLayer] = g.NavInitResultRectRel; }
} }
// Apply result from previous frame navigation directional move request // Apply result from previous frame navigation directional move request
@ -9269,7 +9264,9 @@ static void ImGui::NavUpdateMoveResult()
g.NavJustMovedToKeyMods = g.NavMoveRequestKeyMods; g.NavJustMovedToKeyMods = g.NavMoveRequestKeyMods;
} }
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name); IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
SetNavIDWithRectRel(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel); SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
g.NavDisableHighlight = false;
g.NavDisableMouseHover = g.NavMousePosDirty = true;
} }
// Handle PageUp/PageDown/Home/End keys // Handle PageUp/PageDown/Home/End keys

View File

@ -2313,8 +2313,7 @@ namespace ImGui
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
IMGUI_API void SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id); IMGUI_API void SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
IMGUI_API void SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
// Focus Scope (WIP) // Focus Scope (WIP)
// This is generally used to identify a selection set (multiple of which may be in the same window), as selection // This is generally used to identify a selection set (multiple of which may be in the same window), as selection

View File

@ -5913,7 +5913,7 @@ void ImGui::TreePop()
if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
if (g.NavIdIsAlive && (window->DC.TreeJumpToParentOnPopMask & tree_depth_mask)) if (g.NavIdIsAlive && (window->DC.TreeJumpToParentOnPopMask & tree_depth_mask))
{ {
SetNavID(window->IDStack.back(), g.NavLayer, 0); SetNavID(window->IDStack.back(), g.NavLayer, 0, ImRect());
NavMoveRequestCancel(); NavMoveRequestCancel();
} }
window->DC.TreeJumpToParentOnPopMask &= tree_depth_mask - 1; window->DC.TreeJumpToParentOnPopMask &= tree_depth_mask - 1;
@ -6101,8 +6101,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
{ {
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent) if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
{ {
SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos));
g.NavDisableHighlight = true; g.NavDisableHighlight = true;
SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent);
} }
} }
if (pressed) if (pressed)
@ -6580,8 +6580,9 @@ void ImGui::EndMenuBar()
const ImGuiNavLayer layer = ImGuiNavLayer_Menu; const ImGuiNavLayer layer = ImGuiNavLayer_Menu;
IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check
FocusWindow(window); FocusWindow(window);
SetNavIDWithRectRel(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.
g.NavDisableMouseHover = g.NavMousePosDirty = true;
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
NavMoveRequestCancel(); NavMoveRequestCancel();
} }