Multi-Select: reworked ImGuiMultiSelectFlags_NoAutoSelect as it carried side-effects that were hardcoded/designed to use multi-selection on checkboxes. (#9391)

This commit is contained in:
ocornut
2026-06-25 14:03:35 +02:00
parent ac6f9683b5
commit 60fbdbb8d8
4 changed files with 15 additions and 6 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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; }

View File

@@ -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;