瀏覽代碼

Fixed SetNextWindowPosCenter() being processed too early for windows that are still measuring their size (for #249)

ocornut 10 年之前
父節點
當前提交
d171e48b20
共有 1 個文件被更改,包括 13 次插入6 次删除
  1. 13 6
      imgui.cpp

+ 13 - 6
imgui.cpp

@@ -1426,6 +1426,7 @@ struct ImGuiWindow
     int                     SetWindowPosAllowFlags;             // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. 
     int                     SetWindowPosAllowFlags;             // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. 
     int                     SetWindowSizeAllowFlags;            // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. 
     int                     SetWindowSizeAllowFlags;            // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. 
     int                     SetWindowCollapsedAllowFlags;       // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. 
     int                     SetWindowCollapsedAllowFlags;       // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. 
+    bool                    SetWindowPosCenterWanted;
 
 
     ImGuiDrawContext        DC;                                 // Temporary per-window data, reset at the beginning of the frame
     ImGuiDrawContext        DC;                                 // Temporary per-window data, reset at the beginning of the frame
     ImVector<ImGuiID>       IDStack;                            // ID stack. ID are hashes seeded with the value at the top of the stack
     ImVector<ImGuiID>       IDStack;                            // ID stack. ID are hashes seeded with the value at the top of the stack
@@ -1787,6 +1788,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
     AutoPosLastDirection = -1;
     AutoPosLastDirection = -1;
     HiddenFrames = 0;
     HiddenFrames = 0;
     SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing;
     SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing;
+    SetWindowPosCenterWanted = false;
 
 
     LastFrameDrawn = -1;
     LastFrameDrawn = -1;
     ItemWidthDefault = 0.0f;
     ItemWidthDefault = 0.0f;
@@ -3562,16 +3564,20 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
 
 
     // Process SetNextWindow***() calls
     // Process SetNextWindow***() calls
     bool window_pos_set_by_api = false, window_size_set_by_api = false;
     bool window_pos_set_by_api = false, window_size_set_by_api = false;
-    bool window_pos_center = false;
     if (g.SetNextWindowPosCond)
     if (g.SetNextWindowPosCond)
     {
     {
         const ImVec2 backup_cursor_pos = window->DC.CursorPos;                  // FIXME: not sure of the exact reason of this anymore :( need to look into that.
         const ImVec2 backup_cursor_pos = window->DC.CursorPos;                  // FIXME: not sure of the exact reason of this anymore :( need to look into that.
         if (!window_was_visible) window->SetWindowPosAllowFlags |= ImGuiSetCond_Appearing;
         if (!window_was_visible) window->SetWindowPosAllowFlags |= ImGuiSetCond_Appearing;
         window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0;
         window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0;
         if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f)
         if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f)
-            window_pos_center = true;
+        {
+            window->SetWindowPosCenterWanted = true;                            // May be processed on the next frame if this is our first frame and we are measuring size
+            window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing);
+        }
         else
         else
+        {
             ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond);
             ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond);
+        }
         window->DC.CursorPos = backup_cursor_pos;
         window->DC.CursorPos = backup_cursor_pos;
         g.SetNextWindowPosCond = 0;
         g.SetNextWindowPosCond = 0;
     }
     }
@@ -3738,12 +3744,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
             window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user.
             window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user.
         }
         }
 
 
-        // Position popup
-        if ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_appearing_after_being_hidden)
-            window_pos_center = true;
-
+        bool window_pos_center = false;
+        window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0);
+        window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_appearing_after_being_hidden);
         if (window_pos_center)
         if (window_pos_center)
         {
         {
+            // Center (any sort of window)
             ImRect fullscreen_rect(GetVisibleRect());
             ImRect fullscreen_rect(GetVisibleRect());
             SetWindowPos(ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f));
             SetWindowPos(ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f));
         }
         }
@@ -4485,6 +4491,7 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond co
     if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
     if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
         return;
         return;
     window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing);
     window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing);
+    window->SetWindowPosCenterWanted = false;
 
 
     // Set
     // Set
     const ImVec2 old_pos = window->Pos;
     const ImVec2 old_pos = window->Pos;