From 8312c75fef0a174fa277b5538f39e4f4ef317f5f Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 4 Jan 2024 18:41:20 +0100 Subject: [PATCH] MultiSelect: Added ImGuiMultiSelectFlags_NoRangeSelect. Fixed ImGuiMultiSelectFlags_ScopeRect not querying proper window hover. --- imgui.h | 19 ++++++++++--------- imgui_demo.cpp | 1 + imgui_widgets.cpp | 6 +++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index be79eb665..54c4b0264 100644 --- a/imgui.h +++ b/imgui.h @@ -2772,15 +2772,16 @@ 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 (only supporting 1D list when using clipper, not 2D grids). Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space. - ImGuiMultiSelectFlags_BoxSelect2d = 1 << 3, // Enable box-selection with 2D layout/grid support. This alters clipping logic so that e.g. horizontal movements will update selection of normally clipped items. - ImGuiMultiSelectFlags_BoxSelectNoScroll = 1 << 4, // Disable scrolling when box-selecting near edges of scope. - ImGuiMultiSelectFlags_ClearOnEscape = 1 << 5, // Clear selection when pressing Escape while scope is focused. - ImGuiMultiSelectFlags_ClearOnClickVoid = 1 << 6, // Clear selection when clicking on empty location within scope. - ImGuiMultiSelectFlags_ScopeWindow = 1 << 7, // Scope for _ClearOnClickVoid and _BoxSelect is whole window (Default). Use if BeginMultiSelect() covers a whole window. - ImGuiMultiSelectFlags_ScopeRect = 1 << 8, // Scope for _ClearOnClickVoid and _BoxSelect is rectangle covering submitted items. Use if multiple BeginMultiSelect() are used in the same host window. - ImGuiMultiSelectFlags_SelectOnClick = 1 << 9, // Apply selection on mouse down when clicking on unselected item. (Default) - ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 10, // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection. + ImGuiMultiSelectFlags_NoRangeSelect = 1 << 2, // Disable Shift+Click/Shift+Keyboard handling (useful for unordered 2D selection). + ImGuiMultiSelectFlags_BoxSelect = 1 << 3, // Enable box-selection (only supporting 1D list when using clipper, not 2D grids). Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space. + ImGuiMultiSelectFlags_BoxSelect2d = 1 << 4, // Enable box-selection with 2D layout/grid support. This alters clipping logic so that e.g. horizontal movements will update selection of normally clipped items. + ImGuiMultiSelectFlags_BoxSelectNoScroll = 1 << 5, // Disable scrolling when box-selecting near edges of scope. + ImGuiMultiSelectFlags_ClearOnEscape = 1 << 6, // Clear selection when pressing Escape while scope is focused. + ImGuiMultiSelectFlags_ClearOnClickVoid = 1 << 7, // Clear selection when clicking on empty location within scope. + ImGuiMultiSelectFlags_ScopeWindow = 1 << 8, // Use if BeginMultiSelect() covers a whole window (Default): Scope for _ClearOnClickVoid and _BoxSelect is whole window (Default). + ImGuiMultiSelectFlags_ScopeRect = 1 << 9, // Use if multiple BeginMultiSelect() are used in the same host window: Scope for _ClearOnClickVoid and _BoxSelect is rectangle covering submitted items. + ImGuiMultiSelectFlags_SelectOnClick = 1 << 10, // Apply selection on mouse down when clicking on unselected item. (Default) + ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 11, // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection. }; // Main IO structure returned by BeginMultiSelect()/EndMultiSelect(). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0df16adb8..9f8a80f8d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3277,6 +3277,7 @@ static void ShowDemoWindowMultiSelect() ImGui::Checkbox("Show color button", &show_color_button); ImGui::CheckboxFlags("ImGuiMultiSelectFlags_SingleSelect", &flags, ImGuiMultiSelectFlags_SingleSelect); ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoSelectAll", &flags, ImGuiMultiSelectFlags_NoSelectAll); + ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoRangeSelect", &flags, ImGuiMultiSelectFlags_NoRangeSelect); ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect", &flags, ImGuiMultiSelectFlags_BoxSelect); ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelectNoScroll", &flags, ImGuiMultiSelectFlags_BoxSelectNoScroll); ImGui::CheckboxFlags("ImGuiMultiSelectFlags_ClearOnEscape", &flags, ImGuiMultiSelectFlags_ClearOnEscape); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 98569ead2..4ca36d17e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7303,6 +7303,8 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags) // Use copy of keyboard mods at the time of the request, otherwise we would requires mods to be held for an extra frame. ms->KeyMods = g.NavJustMovedToId ? g.NavJustMovedToKeyMods : g.IO.KeyMods; + if (flags & ImGuiMultiSelectFlags_NoRangeSelect) + ms->KeyMods &= ~ImGuiMod_Shift; // Bind storage ImGuiMultiSelectState* storage = g.MultiSelectStorage.GetOrAddByKey(id); @@ -7416,7 +7418,9 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect() // Clear selection when clicking void? // We specifically test for IsMouseDragPastThreshold(0) == false to allow box-selection! - const bool scope_hovered = (ms->Flags & ImGuiMultiSelectFlags_ScopeRect) ? scope_rect.Contains(g.IO.MousePos) : IsWindowHovered(); + bool scope_hovered = IsWindowHovered(); + if (scope_hovered && (ms->Flags & ImGuiMultiSelectFlags_ScopeRect)) + scope_hovered &= scope_rect.Contains(g.IO.MousePos); if (scope_hovered && g.HoveredId == 0 && g.ActiveId == 0) { if (ms->Flags & ImGuiMultiSelectFlags_BoxSelect)