When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. This function closes any popups that are over 'ref_window'.
| 12343 | // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. |
| 12344 | // This function closes any popups that are over 'ref_window'. |
| 12345 | void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup) |
| 12346 | { |
| 12347 | ImGuiContext& g = *GImGui; |
| 12348 | if (g.OpenPopupStack.Size == 0) |
| 12349 | return; |
| 12350 | |
| 12351 | // Don't close our own child popup windows. |
| 12352 | //IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupsOverWindow(\"%s\") restore_under=%d\n", ref_window ? ref_window->Name : "<NULL>", restore_focus_to_window_under_popup); |
| 12353 | int popup_count_to_keep = 0; |
| 12354 | if (ref_window) |
| 12355 | { |
| 12356 | // Find the highest popup which is a descendant of the reference window (generally reference window = NavWindow) |
| 12357 | for (; popup_count_to_keep < g.OpenPopupStack.Size; popup_count_to_keep++) |
| 12358 | { |
| 12359 | ImGuiPopupData& popup = g.OpenPopupStack[popup_count_to_keep]; |
| 12360 | if (!popup.Window) |
| 12361 | continue; |
| 12362 | IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); |
| 12363 | |
| 12364 | // Trim the stack unless the popup is a direct parent of the reference window (the reference window is often the NavWindow) |
| 12365 | // - Clicking/Focusing Window2 won't close Popup1: |
| 12366 | // Window -> Popup1 -> Window2(Ref) |
| 12367 | // - Clicking/focusing Popup1 will close Popup2 and Popup3: |
| 12368 | // Window -> Popup1(Ref) -> Popup2 -> Popup3 |
| 12369 | // - Each popups may contain child windows, which is why we compare ->RootWindow! |
| 12370 | // Window -> Popup1 -> Popup1_Child -> Popup2 -> Popup2_Child |
| 12371 | // We step through every popup from bottom to top to validate their position relative to reference window. |
| 12372 | bool ref_window_is_descendant_of_popup = false; |
| 12373 | for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++) |
| 12374 | if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window) |
| 12375 | if (IsWindowWithinBeginStackOf(ref_window, popup_window)) |
| 12376 | { |
| 12377 | ref_window_is_descendant_of_popup = true; |
| 12378 | break; |
| 12379 | } |
| 12380 | if (!ref_window_is_descendant_of_popup) |
| 12381 | break; |
| 12382 | } |
| 12383 | } |
| 12384 | if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below |
| 12385 | { |
| 12386 | IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupsOverWindow(\"%s\")\n", ref_window ? ref_window->Name : "<NULL>"); |
| 12387 | ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup); |
| 12388 | } |
| 12389 | } |
| 12390 | |
| 12391 | void ImGui::ClosePopupsExceptModals() |
| 12392 | { |
nothing calls this directly
no outgoing calls
no test coverage detected