Nav, Internals: wrap changes to g.NavWindow into a helper function to help track/log changes.

Amend 076d8fc. Eventually we should REALLY clean up the SetNavWindow SetNavID SetFocusID FocusWindow fiasco.
This commit is contained in:
ocornut 2022-06-13 17:15:27 +02:00
parent 1d6e34f3f9
commit 2ed9e21eba
3 changed files with 36 additions and 21 deletions

View File

@ -113,6 +113,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- layout: (R&D) local multi-pass layout mode. - layout: (R&D) local multi-pass layout mode.
- layout: (R&D) bind authored layout data (created by an off-line tool), items fetch their pos/size at submission, self-optimize data structures to stable linear access. - layout: (R&D) bind authored layout data (created by an off-line tool), items fetch their pos/size at submission, self-optimize data structures to stable linear access.
- tables: see https://github.com/ocornut/imgui/issues/2957#issuecomment-569726095
- group: BeginGroup() needs a border option. (~#1496) - group: BeginGroup() needs a border option. (~#1496)
- group: IsHovered() after EndGroup() covers whole AABB rather than the intersection of individual items. Is that desirable? - group: IsHovered() after EndGroup() covers whole AABB rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550) - group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)

View File

@ -6784,16 +6784,13 @@ void ImGui::FocusWindow(ImGuiWindow* window)
if (g.NavWindow != window) if (g.NavWindow != window)
{ {
IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\")\n", window ? window->Name : "<NULL>"); SetNavWindow(window);
g.NavWindow = window;
if (window && g.NavDisableMouseHover) if (window && g.NavDisableMouseHover)
g.NavMousePosDirty = true; g.NavMousePosDirty = true;
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
g.NavLayer = ImGuiNavLayer_Main;
g.NavFocusScopeId = 0; g.NavFocusScopeId = 0;
g.NavIdIsAlive = false; g.NavIdIsAlive = false;
g.NavLayer = ImGuiNavLayer_Main;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
} }
// Close popups if any // Close popups if any
@ -7387,8 +7384,7 @@ void ImGui::SetKeyboardFocusHere(int offset)
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(offset >= -1); // -1 is allowed but not below IM_ASSERT(offset >= -1); // -1 is allowed but not below
g.NavWindow = window; SetNavWindow(window);
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
@ -9561,8 +9557,22 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked. // FIXME-NAV: The existence of SetNavID vs SetFocusID vs FocusWindow() needs to be clarified/reworked.
// In our terminology those should be interchangeable. Those two functions are merely a legacy artifact, so at minimum naming should be clarified. // 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::SetNavWindow(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (g.NavWindow != window)
{
IMGUI_DEBUG_LOG_FOCUS("[focus] SetNavWindow(\"%s\")\n", window ? window->Name : "<NULL>");
g.NavWindow = window;
}
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel) void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -9580,15 +9590,12 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(id != 0); IM_ASSERT(id != 0);
if (g.NavWindow != window)
SetNavWindow(window);
// Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and window->DC.NavFocusScopeIdCurrent are valid. // Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and window->DC.NavFocusScopeIdCurrent are valid.
// Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text) // Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text)
const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent; const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
if (g.NavWindow != window)
{
g.NavWindow = window;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavId = id; g.NavId = id;
g.NavLayer = nav_layer; g.NavLayer = nav_layer;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
@ -9837,11 +9844,7 @@ static void ImGui::NavProcessItem()
if (g.NavId == id) if (g.NavId == id)
{ {
if (g.NavWindow != window) if (g.NavWindow != window)
{ SetNavWindow(window); // Always refresh g.NavWindow, because some operations such as FocusItem() may not have a window.
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavLayer = window->DC.NavLayerCurrent; g.NavLayer = window->DC.NavLayerCurrent;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
g.NavIdIsAlive = true; g.NavIdIsAlive = true;
@ -9990,7 +9993,12 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (layer == ImGuiNavLayer_Main) if (layer == ImGuiNavLayer_Main)
{
ImGuiWindow* prev_nav_window = g.NavWindow;
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests? g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests?
if (prev_nav_window)
IMGUI_DEBUG_LOG_FOCUS("[focus] NavRestoreLayer: from \"%s\" to SetNavWindow(\"%s\")\n", prev_nav_window->Name, g.NavWindow->Name);
}
ImGuiWindow* window = g.NavWindow; ImGuiWindow* window = g.NavWindow;
if (window->NavLastIds[layer] != 0) if (window->NavLastIds[layer] != 0)
{ {
@ -10527,7 +10535,11 @@ void ImGui::NavMoveRequestApplyResult()
} }
} }
if (g.NavWindow != result->Window)
{
IMGUI_DEBUG_LOG_FOCUS("[focus] NavMoveRequest: SetNavWindow(\"%s\")\n", result->Window->Name);
g.NavWindow = result->Window; g.NavWindow = result->Window;
}
if (g.ActiveId != result->ID) if (g.ActiveId != result->ID)
ClearActiveID(); ClearActiveID();
if (g.NavId != result->ID) if (g.NavId != result->ID)

View File

@ -2671,6 +2671,7 @@ namespace ImGui
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiNavReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiNavReadMode 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 SetNavWindow(ImGuiWindow* window);
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
// Focus Scope (WIP) // Focus Scope (WIP)