diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 736a2b67c..c90713b14 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -77,6 +77,14 @@ Other Changes: - Headers: fixed label being clipped early to reserve space for a sort marker even when no sort marker is displayed. Auto-fitting a column still accounts for the possible marker, so that sorting after an auto-fit doesn't clip the label. +- Multi-Select + - Reworked ImGuiMultiSelectFlags_NoAutoSelect as it carried side-effects that + were hardcoded/designed to use multi-selection on checkboxes. (#9391) + Specifically removed those undocumented behaviors from _NoAutoSelect: + - Clicking a selected/checked item always unselect/uncheck. + - Shift+Click inverts targets value and copy to range. + - Shift+Keyboard copy selection source value to range. + Those behaviors are still happening on checkboxes used within multi-selection. - Fonts: - Added `IMGUI_DISABLE_DEFAULT_FONT_BITMAP`/`IMGUI_DISABLE_DEFAULT_FONT_VECTOR` to disable embedding either fonts separately. (#9407) diff --git a/imgui.h b/imgui.h index 14c695b9f..d498355f4 100644 --- a/imgui.h +++ b/imgui.h @@ -3056,6 +3056,7 @@ enum ImGuiMultiSelectFlags_ ImGuiMultiSelectFlags_NavWrapX = 1 << 16, // [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one. ImGuiMultiSelectFlags_NoSelectOnRightClick = 1 << 17, // Disable default right-click processing, which selects item on mouse down, and is designed for context-menus. ImGuiMultiSelectFlags_SelectOnMask_ = ImGuiMultiSelectFlags_SelectOnAuto | ImGuiMultiSelectFlags_SelectOnClickAlways | ImGuiMultiSelectFlags_SelectOnClickRelease, + ImGuiMultiSelectFlags_CheckboxMode_ = 1 << 20, // [Internal] // Obsolete names #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS diff --git a/imgui_internal.h b/imgui_internal.h index df7ea651e..36b205d3c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3637,7 +3637,7 @@ namespace ImGui // Multi-Select API IMGUI_API void MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags* p_button_flags); - IMGUI_API void MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed); + IMGUI_API void MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed, ImGuiMultiSelectFlags extra_flags = 0); IMGUI_API void MultiSelectAddSetAll(ImGuiMultiSelectTempData* ms, bool selected); IMGUI_API void MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item); inline ImGuiBoxSelectState* GetBoxSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.BoxSelectState.ID == id && g.BoxSelectState.IsActive) ? &g.BoxSelectState : NULL; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index cb9e97441..c8458eba1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1274,7 +1274,7 @@ bool ImGui::Checkbox(const char* label, bool* v) // Range-Selection/Multi-selection support (footer) if (is_multi_select) - MultiSelectItemFooter(id, &checked, &pressed); + MultiSelectItemFooter(id, &checked, &pressed, ImGuiMultiSelectFlags_CheckboxMode_); else if (pressed) checked = !checked; @@ -8307,7 +8307,7 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags // - Altering selection based on Ctrl/Shift modifiers, both for keyboard and mouse. // - Record current selection state for RangeSrc // This is all rather complex, best to run and refer to "widgets_multiselect_xxx" tests in imgui_test_suite. -void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) +void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed, ImGuiMultiSelectFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -8327,7 +8327,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) ImGuiSelectionUserData item_data = g.NextItemData.SelectionUserData; - ImGuiMultiSelectFlags flags = ms->Flags; + ImGuiMultiSelectFlags flags = ms->Flags | extra_flags; const bool is_singleselect = (flags & ImGuiMultiSelectFlags_SingleSelect) != 0; bool is_ctrl = (ms->KeyMods & ImGuiMod_Ctrl) != 0; bool is_shift = (ms->KeyMods & ImGuiMod_Shift) != 0; @@ -8481,7 +8481,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) //IM_ASSERT(storage->HasRangeSrc && storage->HasRangeValue); if (storage->RangeSrcItem == ImGuiSelectionUserData_Invalid) storage->RangeSrcItem = item_data; - if ((flags & ImGuiMultiSelectFlags_NoAutoSelect) == 0) + if ((flags & ImGuiMultiSelectFlags_CheckboxMode_) == 0) { // Shift+Arrow always select // Ctrl+Shift+Arrow copy source selection state (already stored by BeginMultiSelect() in storage->RangeSelected) @@ -8501,7 +8501,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) else { // Ctrl inverts selection, otherwise always select - if ((flags & ImGuiMultiSelectFlags_NoAutoSelect) == 0) + if ((flags & ImGuiMultiSelectFlags_CheckboxMode_) == 0) selected = is_ctrl ? !selected : true; else selected = !selected;