Shortcut()/SetShortcutRouting(): focus route testing now use ParentWindowForFocusRoute. Automatically set on child-window, manually configurable otherwise. (#6798, #2637, #456)

This commit is contained in:
ocornut
2024-01-15 14:18:10 +01:00
parent 4b20a0217e
commit e0c8c80ada
2 changed files with 15 additions and 12 deletions

View File

@ -6432,13 +6432,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
UpdateWindowParentAndRootLinks(window, flags, parent_window);
window->ParentWindowInBeginStack = parent_window_in_stack;
// There's little point to expose a flag to set this: because the interesting cases won't be using parent_window_in_stack,
// e.g. linking a tool window in a standalone viewport to a document window, regardless of their Begin() stack parenting. (#6798)
window->ParentWindowForFocusRoute = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window_in_stack : NULL;
}
// Add to focus scope stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
if ((flags & ImGuiWindowFlags_NavFlattened) == 0)
PushFocusScope(window->ID);
window->NavRootFocusScopeId = g.CurrentFocusScopeId;
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
g.CurrentWindow = NULL;
// Add to popup stack
@ -8325,25 +8330,19 @@ static int CalcRoutingScore(ImGuiWindow* location, ImGuiID owner_id, ImGuiInputF
if (owner_id != 0 && g.ActiveId == owner_id)
return 1;
// Early out when not in focus stack
if (focused == NULL || focused->RootWindow != location->RootWindow)
return 255;
// Score based on distance to focused window (lower is better)
// Assuming both windows are submitting a routing request,
// - When Window....... is focused -> Window scores 3 (best), Window/ChildB scores 255 (no match)
// - When Window/ChildB is focused -> Window scores 4, Window/ChildB scores 3 (best)
// Assuming only WindowA is submitting a routing request,
// - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score.
for (int next_score = 3; focused != NULL; next_score++)
{
// FIXME: This could be later abstracted as a focus path
for (int next_score = 3; focused != NULL; next_score++, focused = focused->ParentWindowForFocusRoute)
if (focused == location)
{
IM_ASSERT(next_score < 255);
return next_score;
}
focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path
}
return 255;
}
@ -10780,6 +10779,8 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display)
EndPopup();
//g.CurrentWindow->FocusRouteParentWindow = g.CurrentWindow->ParentWindowInBeginStack;
return is_open;
}
@ -14995,9 +14996,10 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label)
for (int layer = 0; layer < ImGuiNavLayer_COUNT; layer++)
BulletText("NavPreferredScoringPosRel[%d] = {%.1f,%.1f)", layer, (pr[layer].x == FLT_MAX ? -99999.0f : pr[layer].x), (pr[layer].y == FLT_MAX ? -99999.0f : pr[layer].y)); // Display as 99999.0f so it looks neater.
BulletText("NavLayersActiveMask: %X, NavLastChildNavWindow: %s", window->DC.NavLayersActiveMask, window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL");
if (window->RootWindow != window) { DebugNodeWindow(window->RootWindow, "RootWindow"); }
if (window->ParentWindow != NULL) { DebugNodeWindow(window->ParentWindow, "ParentWindow"); }
if (window->DC.ChildWindows.Size > 0) { DebugNodeWindowsList(&window->DC.ChildWindows, "ChildWindows"); }
if (window->RootWindow != window) { DebugNodeWindow(window->RootWindow, "RootWindow"); }
if (window->ParentWindow != NULL) { DebugNodeWindow(window->ParentWindow, "ParentWindow"); }
if (window->ParentWindowForFocusRoute != NULL) { DebugNodeWindow(window->ParentWindowForFocusRoute, "ParentWindowForFocusRoute"); }
if (window->DC.ChildWindows.Size > 0) { DebugNodeWindowsList(&window->DC.ChildWindows, "ChildWindows"); }
if (window->ColumnsStorage.Size > 0 && TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size))
{
for (ImGuiOldColumns& columns : window->ColumnsStorage)