Jelajahi Sumber

Popups: Fixed right-click to close popups not handling modal windows properly. (~#439)

omar 8 tahun lalu
induk
melakukan
6ab737a4bb
2 mengubah file dengan 24 tambahan dan 5 penghapusan
  1. 22 5
      imgui.cpp
  2. 2 0
      imgui_demo.cpp

+ 22 - 5
imgui.cpp

@@ -2802,7 +2802,23 @@ void ImGui::EndFrame()
             // With right mouse button we close popups without changing focus
             // (The left mouse button path calls FocusWindow which will lead NewFrame->CloseInactivePopups to trigger)
             if (g.IO.MouseClicked[1])
-                CloseInactivePopups(g.HoveredWindow);
+            {
+                // Find the top-most window between HoveredWindow and the front most Modal Window.
+                // This is where we can trim the popup stack.
+                ImGuiWindow* modal = GetFrontMostModalRootWindow();
+                bool hovered_window_above_modal = false;
+                if (modal == NULL)
+                    hovered_window_above_modal = true;
+                for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
+                {
+                    ImGuiWindow* window = g.Windows[i];
+                    if (window == modal)
+                        break;
+                    if (window == g.HoveredWindow)
+                        hovered_window_above_modal = true;
+                }
+                CloseInactivePopups(hovered_window_above_modal ? g.HoveredWindow : modal);
+            }
         }
     }
 
@@ -3588,7 +3604,7 @@ static void CloseInactivePopups(ImGuiWindow* ref_window)
         return;
 
     // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
-    // Don't close our own child popup windows
+    // Don't close our own child popup windows.
     int n = 0;
     if (ref_window)
     {
@@ -3601,6 +3617,7 @@ static void CloseInactivePopups(ImGuiWindow* ref_window)
             if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow)
                 continue;
 
+            // Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow)
             bool has_focus = false;
             for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++)
                 has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow);
@@ -3616,9 +3633,9 @@ static ImGuiWindow* GetFrontMostModalRootWindow()
 {
     ImGuiContext& g = *GImGui;
     for (int n = g.OpenPopupStack.Size-1; n >= 0; n--)
-        if (ImGuiWindow* front_most_popup = g.OpenPopupStack.Data[n].Window)
-            if (front_most_popup->Flags & ImGuiWindowFlags_Modal)
-                return front_most_popup;
+        if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window)
+            if (popup->Flags & ImGuiWindowFlags_Modal)
+                return popup;
     return NULL;
 }
 

+ 2 - 0
imgui_demo.cpp

@@ -1453,6 +1453,8 @@ void ImGui::ShowTestWindow(bool* p_open)
                 ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDarkening] for darkening.");
                 static int item = 1;
                 ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
+                static float color[4] = { 0.4f,0.7f,0.0f,0.5f };
+                ImGui::ColorEdit4("color", color);  // This is to test behavior of stacked regular popups over a modal
 
                 if (ImGui::Button("Add another modal.."))
                     ImGui::OpenPopup("Stacked 2");