瀏覽代碼

MultiSelect: Box-Select: Fixed initial drag from not claiming hovered id, preventing window behind to move for a frame.

ocornut 1 年之前
父節點
當前提交
9337151a01
共有 2 個文件被更改,包括 12 次插入2 次删除
  1. 3 2
      imgui_demo.cpp
  2. 9 0
      imgui_widgets.cpp

+ 3 - 2
imgui_demo.cpp

@@ -3086,7 +3086,7 @@ static void ShowDemoWindowMultiSelect()
 
                 ImGuiListClipper clipper;
                 clipper.Begin(ITEMS_COUNT);
-                if (ms_io->RangeSrcItem > 0)
+                if (ms_io->RangeSrcItem != -1)
                     clipper.IncludeItemByIndex((int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
                 while (clipper.Step())
                 {
@@ -3210,6 +3210,7 @@ static void ShowDemoWindowMultiSelect()
             if (ImGui::CheckboxFlags("ImGuiMultiSelectFlags_ScopeRect", &flags, ImGuiMultiSelectFlags_ScopeRect) && (flags & ImGuiMultiSelectFlags_ScopeRect))
                 flags &= ~ImGuiMultiSelectFlags_ScopeWindow;
             ImGui::CheckboxFlags("ImGuiMultiSelectFlags_ClearOnClickVoid", &flags, ImGuiMultiSelectFlags_ClearOnClickVoid);
+            ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect", &flags, ImGuiMultiSelectFlags_BoxSelect);
 
             for (int selection_scope_n = 0; selection_scope_n < SCOPES_COUNT; selection_scope_n++)
             {
@@ -3336,7 +3337,7 @@ static void ShowDemoWindowMultiSelect()
                     clipper.Begin(items.Size);
                     if (item_curr_idx_to_focus != -1)
                         clipper.IncludeItemByIndex(item_curr_idx_to_focus); // Ensure focused item is not clipped.
-                    if (ms_io->RangeSrcItem > 0)
+                    if (ms_io->RangeSrcItem != -1)
                         clipper.IncludeItemByIndex((int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
                 }
 

+ 9 - 0
imgui_widgets.cpp

@@ -7176,6 +7176,7 @@ bool ImGui::BeginBoxSelect(ImGuiWindow* window, ImGuiID box_select_id, ImGuiMult
     // IsStarting is set by MultiSelectItemFooter() when considering a possible box-select. We validate it here and lock geometry.
     if (bs->IsStarting && IsMouseDragPastThreshold(0))
     {
+        IMGUI_DEBUG_LOG_SELECTION("[selection] BeginBoxSelect() 0X%08X: Started.\n", box_select_id);
         bs->IsActive = true;
         bs->Window = window;
         bs->IsStarting = false;
@@ -7187,7 +7188,10 @@ bool ImGui::BeginBoxSelect(ImGuiWindow* window, ImGuiID box_select_id, ImGuiMult
     {
         bs->IsActive = bs->IsStarting = false;
         if (g.ActiveId == bs->ID)
+        {
+            IMGUI_DEBUG_LOG_SELECTION("[selection] BeginBoxSelect() 0X%08X: Ended.\n", box_select_id);
             ClearActiveID();
+        }
         bs->ID = 0;
     }
     if (!bs->IsActive)
@@ -7424,8 +7428,13 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect()
     if (scope_hovered && g.HoveredId == 0 && g.ActiveId == 0)
     {
         if (ms->Flags & ImGuiMultiSelectFlags_BoxSelect)
+        {
             if (!g.BoxSelectState.IsActive && !g.BoxSelectState.IsStarting && g.IO.MouseClickedCount[0] == 1)
                 BoxSelectStartDrag(ms->BoxSelectId, ImGuiSelectionUserData_Invalid);
+            SetHoveredID(ms->BoxSelectId);
+            if (ms->Flags & ImGuiMultiSelectFlags_ScopeRect)
+                SetNavID(0, ImGuiNavLayer_Main, ms->FocusScopeId, ImRect(g.IO.MousePos, g.IO.MousePos)); // Automatically switch FocusScope for initial click from outside to box-select.
+        }
 
         if (ms->Flags & ImGuiMultiSelectFlags_ClearOnClickVoid)
             if (IsMouseReleased(0) && IsMouseDragPastThreshold(0) == false && g.IO.KeyMods == ImGuiMod_None)