Explorar o código

Merge remote-tracking branch 'upstream/master'

Branimir Karadžić %!s(int64=10) %!d(string=hai) anos
pai
achega
123fd73c8c
Modificáronse 2 ficheiros con 42 adicións e 24 borrados
  1. 40 23
      imgui.cpp
  2. 2 1
      imgui.h

+ 40 - 23
imgui.cpp

@@ -1252,8 +1252,9 @@ struct ImGuiState
     ImGuiID                 ActiveId;                           // Active widget
     ImGuiID                 ActiveIdPreviousFrame;
     bool                    ActiveIdIsAlive;
-    bool                    ActiveIdIsJustActivated;            // Set when 
-    bool                    ActiveIdIsFocusedOnly;              // Set only by active widget. Denote focus but no active interaction.
+    bool                    ActiveIdIsJustActivated;            // Set at the time of activation for one frame
+    bool                    ActiveIdIsFocusedOnly;              // Set only by active widget. Denote focus but no active interaction
+    ImGuiWindow*            ActiveIdWindow;
     ImGuiWindow*            MovedWindow;                        // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window.
     float                   SettingsDirtyTimer;
     ImVector<ImGuiIniData>  Settings;
@@ -1468,12 +1469,13 @@ static inline ImGuiWindow* GetParentWindow()
     return g.CurrentWindowStack[g.CurrentWindowStack.size() - 2];
 }
 
-static void SetActiveId(ImGuiID id) 
+static void SetActiveId(ImGuiID id, ImGuiWindow* window = NULL) 
 {
     ImGuiState& g = *GImGui;
     g.ActiveId = id; 
     g.ActiveIdIsFocusedOnly = false;
     g.ActiveIdIsJustActivated = true;
+    g.ActiveIdWindow = window;
 }
 
 static void RegisterAliveId(ImGuiID id)
@@ -2377,16 +2379,19 @@ void ImGui::Render()
         // Click to focus window and start moving (after we're done with all our widgets)
         if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0])
         {
-            if (g.HoveredRootWindow != NULL)
+            if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear
             {
-                IM_ASSERT(g.MovedWindow == NULL);
-                g.MovedWindow = g.HoveredWindow;
-                SetActiveId(g.HoveredRootWindow->MoveID);
-            }
-            else if (g.FocusedWindow != NULL)
-            {
-                // Clicking on void disable focus
-                FocusWindow(NULL);
+                if (g.HoveredRootWindow != NULL)
+                {
+                    IM_ASSERT(g.MovedWindow == NULL);
+                    g.MovedWindow = g.HoveredWindow;
+                    SetActiveId(g.HoveredRootWindow->MoveID, g.HoveredRootWindow);
+                }
+                else if (g.FocusedWindow != NULL)
+                {
+                    // Clicking on void disable focus
+                    FocusWindow(NULL);
+                }
             }
         }
 
@@ -3180,14 +3185,23 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int button)
     return ImGui::BeginPopup(str_id);
 }
 
-bool ImGui::BeginPopupContextWindow(const char* str_id, bool void_only, int button)
+bool ImGui::BeginPopupContextWindow(bool in_empty_space_only, const char* str_id, int button)
 {
+    if (!str_id) str_id = "window_context_menu";
     if (ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(button))
-        if (!void_only || !ImGui::IsAnyItemHovered())
+        if (!in_empty_space_only || !ImGui::IsAnyItemHovered())
             ImGui::OpenPopup(str_id);
     return ImGui::BeginPopup(str_id);
 }
 
+bool ImGui::BeginPopupContextVoid(const char* str_id, int button)
+{
+    if (!str_id) str_id = "void_context_menu";
+    if (!ImGui::IsMouseHoveringAnyWindow() && ImGui::IsMouseClicked(button))
+        ImGui::OpenPopup(str_id);
+    return ImGui::BeginPopup(str_id);
+}
+
 bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
 {
     ImGuiState& g = *GImGui;
@@ -4015,6 +4029,11 @@ static void FocusWindow(ImGuiWindow* window)
     if (window->RootWindow)
         window = window->RootWindow;
 
+    // Steal focus on active widgets
+    if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it..
+        if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window)
+            SetActiveId(0);
+
     if (g.Windows.back() == window)
         return;
 
@@ -4889,7 +4908,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
                 }
                 else
                 {
-                    SetActiveId(id);
+                    SetActiveId(id, window);
                 }
                 FocusWindow(window);
             }
@@ -5539,7 +5558,7 @@ static bool SliderFloatAsInputText(const char* label, float* v, ImGuiID id, int
     char text_buf[64];
     ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
 
-    SetActiveId(g.ScalarAsInputTextId);
+    SetActiveId(g.ScalarAsInputTextId, window);
     g.HoveredId = 0;
 
     // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen)
@@ -5769,7 +5788,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
     const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id);
     if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
     {
-        SetActiveId(id);
+        SetActiveId(id, window);
         FocusWindow(window);
 
         const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -5827,7 +5846,7 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
 
     if (hovered && g.IO.MouseClicked[0])
     {
-        SetActiveId(id);
+        SetActiveId(id, window);
         FocusWindow(window);
     }
 
@@ -6073,7 +6092,7 @@ bool ImGui::DragFloat(const char* label, float *v, float v_speed, float v_min, f
     const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id);
     if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0])))
     {
-        SetActiveId(id);
+        SetActiveId(id, window);
         FocusWindow(window);
 
         if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0])
@@ -6786,11 +6805,11 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
 // Edit a string of text
 bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)
 {
-    ImGuiState& g = *GImGui;
     ImGuiWindow* window = GetCurrentWindow();
     if (window->SkipItems)
         return false;
 
+    ImGuiState& g = *GImGui;
     const ImGuiIO& io = g.IO;
     const ImGuiStyle& style = g.Style;
 
@@ -6857,16 +6876,14 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
             if (focus_requested_by_tab || (user_clicked && is_ctrl_down))
                 select_all = true;
         }
-        SetActiveId(id);
+        SetActiveId(id, window);
         FocusWindow(window);
     }
     else if (io.MouseClicked[0])
     {
         // Release focus when we click outside
         if (g.ActiveId == id)
-        {
             SetActiveId(0);
-        }
     }
 
     // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.

+ 2 - 1
imgui.h

@@ -170,7 +170,8 @@ namespace ImGui
     IMGUI_API void          OpenPopup(const char* str_id);                                      // mark popup as open. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). close childs popups if any. will close popup when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
     IMGUI_API bool          BeginPopup(const char* str_id);                                     // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true!
     IMGUI_API bool          BeginPopupContextItem(const char* str_id, int button = 1);          // open popup when clicked on last item
-    IMGUI_API bool          BeginPopupContextWindow(const char* str_id = "window_context_menu", bool void_only = false, int button = 1);  // open popup when clicked on current window
+    IMGUI_API bool          BeginPopupContextWindow(bool in_empty_space_only = false, const char* str_id = "window_context_menu", int button = 1);  // open popup when clicked on current window
+    IMGUI_API bool          BeginPopupContextVoid(const char* str_id = "void_context_menu", int button = 1);                                        // open popup when clicked in void (no window)
     IMGUI_API void          EndPopup();
     IMGUI_API void          CloseCurrentPopup();                                                // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup.