Browse Source

MultiSelect: reworked comments in imgui.h now that we have our own section.

ocornut 1 year ago
parent
commit
51fe0bfcf6
3 changed files with 91 additions and 86 deletions
  1. 75 67
      imgui.h
  2. 14 17
      imgui_demo.cpp
  3. 2 2
      imgui_widgets.cpp

+ 75 - 67
imgui.h

@@ -673,7 +673,7 @@ namespace ImGui
     // Multi-selection system for Selectable() and TreeNode() functions.
     // - This enables standard multi-selection/range-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
     // - ImGuiSelectionUserData is often used to store your item index.
-    // - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State' for demo.
+    // - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State & Multi-Select' for demo.
     IMGUI_API ImGuiMultiSelectIO*   BeginMultiSelect(ImGuiMultiSelectFlags flags);
     IMGUI_API ImGuiMultiSelectIO*   EndMultiSelect();
     IMGUI_API void                  SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
@@ -2726,46 +2726,24 @@ struct ImColor
 
 #define IMGUI_HAS_MULTI_SELECT      // Multi-Select/Range-Select WIP branch // <-- This is currently _not_ in the top of imgui.h to prevent merge conflicts.
 
-// Flags for BeginMultiSelect().
-// (we provide 'ImGuiMultiSelectFlags_SingleSelect' for consistency and flexiblity to allow a single-selection to use same code/logic, but it essentially disable the biggest purpose of BeginMultiSelect().
-//  If you use 'ImGuiMultiSelectFlags_SingleSelect' you can handle single-selection in a simpler way by just calling Selectable()/TreeNode() and reacting on clicks).
-enum ImGuiMultiSelectFlags_
-{
-    ImGuiMultiSelectFlags_None                  = 0,
-    ImGuiMultiSelectFlags_SingleSelect          = 1 << 0,   // Disable selecting more than one item. This is available to allow single-selection code to use same code/logic is desired, but may not be very useful.
-    ImGuiMultiSelectFlags_NoSelectAll           = 1 << 1,   // Disable CTRL+A shortcut to set RequestSelectAll
-    ImGuiMultiSelectFlags_BoxSelect             = 1 << 2,   // Enable box-selection. Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space.
-    ImGuiMultiSelectFlags_NoBoxSelectScroll     = 1 << 3,   // Disable scrolling when box-selecting near edges of scope.
-    ImGuiMultiSelectFlags_ClearOnEscape         = 1 << 4,   // Clear selection when pressing Escape while scope is focused.
-    ImGuiMultiSelectFlags_ClearOnClickVoid      = 1 << 5,   // Clear selection when clicking on empty location within scope.
-    ImGuiMultiSelectFlags_ScopeWindow           = 1 << 6,   // Scope for _ClearOnClickVoid and _BoxSelect is whole window (Default). Use if (use if BeginMultiSelect() covers a whole window.
-    ImGuiMultiSelectFlags_ScopeRect             = 1 << 7,   // Scope for _ClearOnClickVoid and _BoxSelect is rectangle covering submitted items. Use if multiple BeginMultiSelect() are used in the same host window.
-    ImGuiMultiSelectFlags_SelectOnClick         = 1 << 8,   // Apply selection on mouse down when clicking on unselected item. (Default)
-    ImGuiMultiSelectFlags_SelectOnClickRelease  = 1 << 9,   // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
-};
-
 // Multi-selection system
-// - Refer to 'Demo->Widgets->Selection State' for references using this.
+// - Refer to 'Demo->Widgets->Selection State & Multi-Select' for references using this.
 // - This system implements standard multi-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc)
-//   and supports a clipper being used. Handling this manually and correctly i tricky, this is why we provide
+//   and supports a clipper being used. Handling this manually and correctly is tricky, this is why we provide
 //   the functionality. If you don't need SHIFT+Mouse/Keyboard range-select + clipping, you can implement a
 //   simple form of multi-selection yourself, by reacting to click/presses on Selectable() items.
 // - TreeNode() and Selectable() are supported but custom widgets may use it as well.
 // - In the spirit of Dear ImGui design, your code owns actual selection data.
 //   This is designed to allow all kinds of selection storage you may use in your application:
-//   e.g. set/map/hash (store only selected items), instructive selection (store a bool inside each object),
-//   external array (store an array in your view data, next to your objects) etc.
+//   e.g. set/map/hash (store selected items), instructive selection (store a bool inside each object), etc.
 // - The work involved to deal with multi-selection differs whether you want to only submit visible items and
 //   clip others, or submit all items regardless of their visibility. Clipping items is more efficient and will
 //   allow you to deal with large lists (1k~100k items). See "Usage flow" section below for details.
 //   If you are not sure, always start without clipping! You can work your way to the optimized version afterwards.
-// About ImGuiSelectionBasicStorage:
-// - This is an optional helper to store a selection state and apply selection requests.
-// - It is used by our demos and provided as a convenience if you want to quickly implement multi-selection.
 // About ImGuiSelectionUserData:
-// - This is your application-defined identifier in a selection set:
-//   - For each item is it submitted by your call to SetNextItemSelectionUserData().
-//   - In return we store them into RangeSrcItem/RangeFirstItem/RangeLastItem and other fields in ImGuiMultiSelectIO.
+// - This can store an application-defined identifier (e.g. index or pointer).
+// - For each item is it submitted by your call to SetNextItemSelectionUserData().
+// - In return we store them into RangeSrcItem/RangeFirstItem/RangeLastItem and other fields in ImGuiMultiSelectIO.
 // - Most applications will store an object INDEX, hence the chosen name and type.
 //   Storing an integer index is the easiest thing to do, as RequestSetRange requests will give you two end-points
 //   and you will need to iterate/interpolate between them to honor range selection.
@@ -2778,15 +2756,33 @@ enum ImGuiMultiSelectFlags_
 // Usage flow:
 //   BEGIN - (1) Call BeginMultiSelect() and retrieve the ImGuiMultiSelectIO* result.
 //         - (2) [If using clipper] Honor request list (Clear/SelectAll/SetRange requests) by updating your selection data. Same code as Step 6.
-//         - (3) [If using clipper] You need to make sure RangeSrcItem is always submitted. Calculate its index and pass to clipper.IncludeIndex(). If already using indices in ImGuiSelectionUserData, it is as simple as clipper.IncludeIndex((int)ms_io->RangeSrcItem);
+//         - (3) [If using clipper] You need to make sure RangeSrcItem is always submitted. Calculate its index and pass to clipper.IncludeItemByIndex(). If storing indices in ImGuiSelectionUserData, a simple clipper.IncludeItemByIndex(ms_io->RangeSrcItem) call will work.
 //   LOOP  - (4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls.
 //   END   - (5) Call EndMultiSelect() and retrieve the ImGuiMultiSelectIO* result.
 //         - (6) Honor request list (Clear/SelectAll/SetRange requests) by updating your selection data. Same code as Step 2.
-//   If you submit all items (no clipper), Step 2 and 3 and will be handled by Selectable()/TreeNode on a per-item basis.
-//   However it is perfectly fine to honor all steps even if you don't use a clipper.
+//   If you submit all items (no clipper), Step 2 and 3 are optional and will be handled by each item themselves. It is perfectly fine if you honor those steps without a clipper.
+// About ImGuiSelectionBasicStorage:
+// - This is an optional helper to store a selection state and apply selection requests.
+// - It is used by our demos and provided as a convenience if you want to quickly implement multi-selection.
 // Advanced:
 // - Deletion: If you need to handle items deletion: more work if needed for post-deletion focus and scrolling to be correct.
-//   Refer to 'Demo->Widgets->Selection State' for demos supporting deletion.
+//   Refer to 'Demo->Widgets->Selection State & Multi-Select' for demos supporting deletion.
+
+// Flags for BeginMultiSelect().
+enum ImGuiMultiSelectFlags_
+{
+    ImGuiMultiSelectFlags_None                  = 0,
+    ImGuiMultiSelectFlags_SingleSelect          = 1 << 0,   // Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho!
+    ImGuiMultiSelectFlags_NoSelectAll           = 1 << 1,   // Disable CTRL+A shortcut sending a SelectAll request.
+    ImGuiMultiSelectFlags_BoxSelect             = 1 << 2,   // Enable box-selection. Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space.
+    ImGuiMultiSelectFlags_NoBoxSelectScroll     = 1 << 3,   // Disable scrolling when box-selecting near edges of scope.
+    ImGuiMultiSelectFlags_ClearOnEscape         = 1 << 4,   // Clear selection when pressing Escape while scope is focused.
+    ImGuiMultiSelectFlags_ClearOnClickVoid      = 1 << 5,   // Clear selection when clicking on empty location within scope.
+    ImGuiMultiSelectFlags_ScopeWindow           = 1 << 6,   // Scope for _ClearOnClickVoid and _BoxSelect is whole window (Default). Use if BeginMultiSelect() covers a whole window.
+    ImGuiMultiSelectFlags_ScopeRect             = 1 << 7,   // Scope for _ClearOnClickVoid and _BoxSelect is rectangle covering submitted items. Use if multiple BeginMultiSelect() are used in the same host window.
+    ImGuiMultiSelectFlags_SelectOnClick         = 1 << 8,   // Apply selection on mouse down when clicking on unselected item. (Default)
+    ImGuiMultiSelectFlags_SelectOnClickRelease  = 1 << 9,   // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
+};
 
 enum ImGuiSelectionRequestType
 {
@@ -2814,58 +2810,70 @@ struct ImGuiSelectionRequest
 struct ImGuiMultiSelectIO
 {
     //------------------------------------------// BeginMultiSelect / EndMultiSelect
-    ImVector<ImGuiSelectionRequest> Requests;   //  ms:w, app:r     /  ms:w  app:r   // Requests
+    ImVector<ImGuiSelectionRequest> Requests;   //  ms:w, app:r     /  ms:w  app:r   // Requests to apply to your selection data.
     ImGuiSelectionUserData      RangeSrcItem;   //  ms:w  app:r     /                // (If using clipper) Begin: Source item (generally the first selected item when multi-selecting, which is used as a reference point) must never be clipped!
     ImGuiSelectionUserData      NavIdItem;      //  ms:w, app:r     /                // (If using deletion) Last known SetNextItemSelectionUserData() value for NavId (if part of submitted items).
     bool                        NavIdSelected;  //  ms:w, app:r     /        app:r   // (If using deletion) Last known selection state for NavId (if part of submitted items).
     bool                        RangeSrcReset;  //        app:w     /  ms:r          // (If using deletion) Set before EndMultiSelect() to reset ResetSrcItem (e.g. if deleted selection).
 };
 
-// Helper struct to store multi-selection state + apply multi-selection requests.
-// - Used by our demos and provided as a convenience if you want to quickly implement multi-selection.
-// - Provide an abstraction layer for the purpose of the demo showcasing different forms of underlying selection data.
-// - USING THIS IS NOT MANDATORY. This is only a helper and is not part of the main API. Advanced users are likely to implement their own.
-// To store a single-selection, you only need a single variable and don't need any of this!
+// Optional helper struct to store multi-selection state + apply multi-selection requests.
+// - Used by our demos and provided as a convenience to easily implement basic multi-selection.
+// - USING THIS IS NOT MANDATORY. This is only a helper and not a required API. Advanced users are likely to implement their own.
 // To store a multi-selection, in your real application you could:
 // - A) Use this helper as a convenience. We use our simple key->value ImGuiStorage as a std::set<ImGuiID> replacement.
-// - B) Use your own external storage: e.g. std::set<MyObjectId>, std::vector<MyObjectId>, std::set<index>, interval trees, etc.
-//      are generally appropriate. Even a large array of bool might work for you...
-// - C) Use intrusively stored selection (e.g. 'bool IsSelected' inside your object). Not recommended because:
-//      - it means you cannot have multiple simultaneous views over your objects.
-//      - some of our features requires you to provide the selection _size_, which with this specific strategy require additional work.
+// - B) Use your own external storage: e.g. std::set<MyObjectId>, std::vector<MyObjectId>, interval trees, etc.
+// - C) Use intrusively stored selection (e.g. 'bool IsSelected' inside objects). Not recommended because you can't have multiple views
+//      over same objects. Also some features requires to provide selection _size_, which with this strategy requires additional work.
 // Our BeginMultiSelect() api/system doesn't make assumption about:
-// - how you want to identify items in multi-selection API?     Indices(*) / Custom Identifiers    / Pointers ?
-// - how you want to store persistent selection data?           Indices    / Custom Identifiers(*) / Pointers ?
-// (*) This is the suggested solution: pass indices to API (because easy to iterate/interpolate) + persist your custom identifiers inside selection data.
+// - how you want to identify items in multi-selection API?     Indices(*) or Custom Ids    or Pointers -> Indices is better (easy to iterate/interpolate)
+// - how you want to store persistent selection data?           Indices    or Custom Ids(*) or Pointers -> Custom ids is better (as selection can persist)
 // In ImGuiSelectionBasicStorage we:
 // - always use indices in the multi-selection API (passed to SetNextItemSelectionUserData(), retrieved in ImGuiMultiSelectIO)
-// - use a little extra indirection layer in order to abstract how persistent selection data is derived from an index.
-//   - in some cases we use Index as custom identifier (default, not ideal)
+// - use the AdapterIndexToStorageId() indirection layer to abstract how persistent selection data is derived from an index.
+//   - in some cases we use Index as custom identifier (default implementation returns Index casted as Identifier): only valid for a never changing item list.
 //   - in some cases we read an ID from some custom item data structure (better, and closer to what you would do in your codebase)
 // Many combinations are possible depending on how you prefer to store your items and how you prefer to store your selection.
-// WHEN YOUR APPLICATION SETTLES ON A CHOICE, YOU WILL PROBABLY PREFER TO GET RID OF THE UNNECESSARY 'AdapterIndexToStorageId()' INDIRECTION LOGIC.
+// When your application settles on a choice, you may want to get rid of this indirection layer and do your own thing.
+// Minimum pseudo-code example using this helper:
+// {
+//     static vector<MyItem> items;                  // Your items
+//     static ImGuiSelectionBasicStorage selection;  // Your selection
+//     selection.AdapterData = (void*)&items;        // Setup adapter so selection.ApplyRequests() function can convert indexes to identifiers.
+//     selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((vector<MyItem>*)self->AdapterData))[idx].ID; };
+//
+//     ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(ImGuiMultiSelectFlags_None);
+//     selection.ApplyRequests(ms_io, items.Size);
+//     for (int idx = 0; idx < items.Size; idx++)
+//     {
+//         bool item_is_selected = selection.Contains(items[idx].ID);
+//         ImGui::SetNextItemSelectionUserData(idx);
+//         ImGui::Selectable(label, item_is_selected);
+//     }
+//     ms_io = ImGui::EndMultiSelect();
+//     selection.ApplyRequests(ms_io, items.Size);
+// }
 // In theory, for maximum abstraction, this class could contains AdapterIndexToUserData() and AdapterUserDataToIndex() functions as well,
-// but because we always use indices in SetNextItemSelectionUserData() in the demo, we omit that for clarify.
+// but because we always use indices in SetNextItemSelectionUserData() in the demo, we omit that indirection for clarity.
 struct ImGuiSelectionBasicStorage
 {
-    ImGuiStorage    Storage;                // [Internal] Selection set. Think of this as similar to e.g. std::set<ImGuiID>
-    int             Size;                   // Number of selected items (== number of 1 in the Storage, maintained by this class).
-
-    // Adapter to convert item index to item identifier
-    void*           AdapterData;                                                            // e.g. selection.AdapterData = (void*)my_items;
+    // Members
+    ImGuiStorage    Storage;        // [Internal] Selection set. Think of this as similar to e.g. std::set<ImGuiID>
+    int             Size;           // Number of selected items (== number of 1 in the Storage, maintained by this class).
+    void*           AdapterData;    // Adapter to convert item index to item identifier     // e.g. selection.AdapterData = (void*)my_items;
     ImGuiID         (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx);  // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->AdapterData)[idx]->ID; };
 
-    // Selection storage
-    ImGuiSelectionBasicStorage()            { Clear(); AdapterData = NULL; AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; }
-    void Clear()                            { Storage.Data.resize(0); Size = 0; }
-    void Swap(ImGuiSelectionBasicStorage& r){ Storage.Data.swap(r.Storage.Data); }
-    bool Contains(ImGuiID key) const        { return Storage.GetInt(key, 0) != 0; }
-    void AddItem(ImGuiID key)               { int* p_int = Storage.GetIntRef(key, 0); if (*p_int != 0) return; *p_int = 1; Size++; }
-    void RemoveItem(ImGuiID key)            { int* p_int = Storage.GetIntRef(key, 0); if (*p_int == 0) return; *p_int = 0; Size--; }
-    void UpdateItem(ImGuiID key, bool v)    { if (v) { AddItem(key); } else { RemoveItem(key); } }
-    int  GetSize() const                    { return Size; }
-
-    // Request handling (apply requests coming from BeginMultiSelect() and EndMultiSelect() functions)
+    // Methods: selection storage
+    ImGuiSelectionBasicStorage()                { Clear(); AdapterData = NULL; AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; }
+    void    Clear()                             { Storage.Data.resize(0); Size = 0; }
+    void    Swap(ImGuiSelectionBasicStorage& r) { Storage.Data.swap(r.Storage.Data); }
+    bool    Contains(ImGuiID key) const         { return Storage.GetInt(key, 0) != 0; }
+    void    AddItem(ImGuiID key)                { int* p_int = Storage.GetIntRef(key, 0); if (*p_int != 0) return; *p_int = 1; Size++; }
+    void    RemoveItem(ImGuiID key)             { int* p_int = Storage.GetIntRef(key, 0); if (*p_int == 0) return; *p_int = 0; Size--; }
+    void    UpdateItem(ImGuiID key, bool v)     { if (v) { AddItem(key); } else { RemoveItem(key); } }
+    int     GetSize() const                     { return Size; }
+
+    // Methods: apply selection requests (that are coming from BeginMultiSelect() and EndMultiSelect() functions)
     IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io, int items_count);
 };
 

+ 14 - 17
imgui_demo.cpp

@@ -2783,7 +2783,7 @@ struct ExampleSelectionStorageWithDeletion : ImGuiSelectionBasicStorage
     // - We cannot provide this logic in core Dear ImGui because we don't have access to selection data.
     // - We don't actually manipulate the ImVector<> here, only in ApplyDeletionPostLoop(), but using similar API for consistency and flexibility.
     // - Important: Deletion only works if the underlying ImGuiID for your items are stable: aka not depend on their index, but on e.g. item id/ptr.
-    // FIXME-MULTISELECT: Doesn't take account of the possibility focus target will be moved during deletion. Need refocus or offset.
+    // FIXME-MULTISELECT: Doesn't take account of the possibility focus target will be moved during deletion. Need refocus or scroll offset.
     int ApplyDeletionPreLoop(ImGuiMultiSelectIO* ms_io, int items_count)
     {
         QueueDeletion = false;
@@ -2890,7 +2890,7 @@ struct ExampleDualListBox
     }
     void Show()
     {
-        ImGui::Checkbox("Sorted", &OptKeepSorted);
+        //ImGui::Checkbox("Sorted", &OptKeepSorted);
         if (ImGui::BeginTable("split", 3, ImGuiTableFlags_None))
         {
             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);    // Left side
@@ -2964,13 +2964,15 @@ struct ExampleDualListBox
             if (request_move_selected != -1)
                 MoveSelected(request_move_selected, request_move_selected ^ 1);
 
-            // FIXME-MULTISELECT: action from outside
+            // FIXME-MULTISELECT: Support action from outside
+            /*
             if (OptKeepSorted == false)
             {
                 ImGui::NewLine();
                 if (ImGui::ArrowButton("MoveUp", ImGuiDir_Up)) {}
                 if (ImGui::ArrowButton("MoveDown", ImGuiDir_Down)) {}
             }
+            */
 
             ImGui::EndTable();
         }
@@ -3025,20 +3027,19 @@ static void ShowDemoWindowMultiSelect()
         IMGUI_DEMO_MARKER("Widgets/Selection State/Multi-Select");
         if (ImGui::TreeNode("Multi-Select"))
         {
-            // Use default selection.Adapter: Pass index to SetNextItemSelectionUserData(), store index in Selection
-            static ImGuiSelectionBasicStorage selection;
-
-            ImGui::Text("Tips: Use 'Debug Log->Selection' to see selection requests as they happen.");
-
             ImGui::Text("Supported features:");
             ImGui::BulletText("Keyboard navigation (arrows, page up/down, home/end, space).");
             ImGui::BulletText("Ctrl modifier to preserve and toggle selection.");
             ImGui::BulletText("Shift modifier for range selection.");
             ImGui::BulletText("CTRL+A to select all.");
+            ImGui::Text("Tip: Use 'Debug Log->Selection' to see selection requests as they happen.");
 
-            // The BeginListBox() has no actual purpose for selection logic (other that offering a scrolling region).
+            // Use default selection.Adapter: Pass index to SetNextItemSelectionUserData(), store index in Selection
             const int ITEMS_COUNT = 50;
+            static ImGuiSelectionBasicStorage selection;
             ImGui::Text("Selection: %d/%d", selection.GetSize(), ITEMS_COUNT);
+
+            // The BeginListBox() has no actual purpose for selection logic (other that offering a scrolling region).
             if (ImGui::BeginListBox("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20)))
             {
                 ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape;
@@ -3124,8 +3125,6 @@ static void ShowDemoWindowMultiSelect()
             ImGui::Text("Adding features:");
             ImGui::BulletText("Dynamic list with Delete key support.");
             ImGui::Text("Selection size: %d/%d", selection.GetSize(), items.Size);
-            //if (ImGui::IsItemHovered() && selection.GetSize() > 0)
-            //    selection.DebugTooltip();
 
             // Initialize default list with 50 items + button to add/remove items.
             static int items_next_id = 0;
@@ -3146,10 +3145,9 @@ static void ShowDemoWindowMultiSelect()
                 ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags);
                 selection.ApplyRequests(ms_io, items.Size);
 
-                // FIXME-MULTISELECT: Shortcut(). Hard to demo this? May be helpful to send a helper/optional "delete" signal.
-                // FIXME-MULTISELECT: may turn into 'ms_io->RequestDelete' -> need HasSelection passed.
+                // FIXME-MULTISELECT: Shortcut(). Hard to demo this? May be helpful to turn into 'ms_io->RequestDelete' signal -> need HasSelection passed.
                 // FIXME-MULTISELECT: If pressing Delete + another key we have ambiguous behavior.
-                const bool want_delete = selection.QueueDeletion || ((selection.GetSize() > 0) && ImGui::IsWindowFocused() && ImGui::IsKeyPressed(ImGuiKey_Delete));
+                const bool want_delete = selection.QueueDeletion || ((selection.Size > 0) && ImGui::IsWindowFocused() && ImGui::IsKeyPressed(ImGuiKey_Delete));
                 int item_curr_idx_to_focus = -1;
                 if (want_delete)
                     item_curr_idx_to_focus = selection.ApplyDeletionPreLoop(ms_io, items.Size);
@@ -3309,9 +3307,8 @@ static void ShowDemoWindowMultiSelect()
                 ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags);
                 selection.ApplyRequests(ms_io, items.Size);
 
-                // FIXME-MULTISELECT: Shortcut(). Hard to demo this? May be helpful to send a helper/optional "delete" signal.
-                // FIXME-MULTISELECT: may turn into 'ms_io->RequestDelete' -> need HasSelection passed.
-                const bool want_delete = selection.QueueDeletion || ((selection.GetSize() > 0) && ImGui::IsWindowFocused() && ImGui::IsKeyPressed(ImGuiKey_Delete));
+                // FIXME-MULTISELECT: Shortcut(). Hard to demo this? May be helpful to turn into 'ms_io->RequestDelete' signal -> need HasSelection passed.
+                const bool want_delete = selection.QueueDeletion || ((selection.Size > 0) && ImGui::IsWindowFocused() && ImGui::IsKeyPressed(ImGuiKey_Delete));
                 int item_curr_idx_to_focus = -1;
                 if (want_delete)
                     item_curr_idx_to_focus = selection.ApplyDeletionPreLoop(ms_io, items.Size);

+ 2 - 2
imgui_widgets.cpp

@@ -6858,7 +6858,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
     // Render
     if (hovered || selected)
     {
-        // FIXME-MULTISELECT, FIXME-STYLE: Color for 'selected' elements? ImGuiCol_HeaderSelected
+        // FIXME-MULTISELECT: Styling: Color for 'selected' elements? ImGuiCol_HeaderSelected
         ImU32 col;
         if (selected && !hovered)
             col = GetColorU32(ImLerp(GetStyleColorVec4(ImGuiCol_Header), GetStyleColorVec4(ImGuiCol_HeaderHovered), 0.5f));
@@ -7558,7 +7558,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
         if (is_shift && !is_singleselect)
         {
             // Shift+Arrow always select
-            // Ctrl+Shift+Arrow copy source selection state (alrady stored by BeginMultiSelect() in RangeSelected)
+            // Ctrl+Shift+Arrow copy source selection state (already stored by BeginMultiSelect() in storage->RangeSelected)
             //IM_ASSERT(storage->HasRangeSrc && storage->HasRangeValue);
             if (storage->RangeSrcItem == ImGuiSelectionUserData_Invalid)
                 storage->RangeSrcItem = item_data;