Skip to content

Commit

Permalink
Shortcut()/SetShortcutRouting(): focus route testing now use ParentWi…
Browse files Browse the repository at this point in the history
…ndowForFocusRoute. Automatically set on child-window, manually configurable otherwise. (#6798, #2637, #456)
  • Loading branch information
ocornut committed Jan 15, 2024
1 parent 4b20a02 commit e0c8c80
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
26 changes: 14 additions & 12 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,7 @@ struct IMGUI_API ImGuiWindow
ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
ImGuiWindow* ParentWindowForFocusRoute; // Set to manual link a window to its logical parent so that Shortcut() chain are honoerd (e.g. Tool linked to Document)

ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.)
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
Expand Down

0 comments on commit e0c8c80

Please sign in to comment.