MultiSelect: clarified purpose and use of IsItemToggledSelection(). Added assert. Moved to multi-selection section of imgui.h.

This commit is contained in:
ocornut 2023-09-21 20:40:21 +02:00
parent 2765fdb43e
commit c3998b70cc
3 changed files with 14 additions and 6 deletions

View File

@ -5446,9 +5446,15 @@ bool ImGui::IsItemToggledOpen()
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false; return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
} }
// Call after a Selectable() or TreeNode() involved in multi-selection.
// Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose.
// This is only meant to be called inside a BeginMultiSelect()/EndMultiSelect() block.
// (Outside of multi-select, it would be misleading/ambiguous to report this signal, as widgets
// return e.g. a pressed event and user code is in charge of altering selection in ways we cannot predict.)
bool ImGui::IsItemToggledSelection() bool ImGui::IsItemToggledSelection()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.CurrentMultiSelect != NULL); // Can only be used inside a BeginMultiSelect()/EndMultiSelect()
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false; return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false;
} }

View File

@ -676,6 +676,7 @@ namespace ImGui
IMGUI_API ImGuiMultiSelectIO* BeginMultiSelect(ImGuiMultiSelectFlags flags); IMGUI_API ImGuiMultiSelectIO* BeginMultiSelect(ImGuiMultiSelectFlags flags);
IMGUI_API ImGuiMultiSelectIO* EndMultiSelect(); IMGUI_API ImGuiMultiSelectIO* EndMultiSelect();
IMGUI_API void SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data); IMGUI_API void SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
IMGUI_API bool IsItemToggledSelection(); // Was the last item selection state toggled? Useful if you need the per-item information _before_ reaching EndMultiSelect(). We only returns toggle _event_ in order to handle clipping correctly.
// Widgets: List Boxes // Widgets: List Boxes
// - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label. // - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
@ -909,7 +910,6 @@ namespace ImGui
IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that require continuous editing. IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that require continuous editing.
IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that require continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that require continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).
IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode(). IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode().
IMGUI_API bool IsItemToggledSelection(); // was the last item selection state toggled? (after Selectable(), TreeNode() etc.) We only returns toggle _event_ in order to handle clipping correctly.
IMGUI_API bool IsAnyItemHovered(); // is any item hovered? IMGUI_API bool IsAnyItemHovered(); // is any item hovered?
IMGUI_API bool IsAnyItemActive(); // is any item active? IMGUI_API bool IsAnyItemActive(); // is any item active?
IMGUI_API bool IsAnyItemFocused(); // is any item focused? IMGUI_API bool IsAnyItemFocused(); // is any item focused?

View File

@ -6891,7 +6891,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (disabled_item && !disabled_global) if (disabled_item && !disabled_global)
EndDisabled(); EndDisabled();
// Users of BeginMultiSelect() scope: call ImGui::IsItemToggledSelection() to retrieve selection toggle. Selectable() returns a pressed state! // Selectable() always returns a pressed state!
// Users of BeginMultiSelect()/EndMultiSelect() scope: you may call ImGui::IsItemToggledSelection() to retrieve
// selection toggle, only useful if you need that state updated (e.g. for rendering purpose) before reaching EndMultiSelect().
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
return pressed; //-V1020 return pressed; //-V1020
} }
@ -7335,7 +7337,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
ImGuiSelectionUserData item_data = g.NextItemData.SelectionUserData; ImGuiSelectionUserData item_data = g.NextItemData.SelectionUserData;
const bool is_multiselect = (ms->Flags & ImGuiMultiSelectFlags_SingleSelect) == 0; const bool is_singleselect = (ms->Flags & ImGuiMultiSelectFlags_SingleSelect) != 0;
bool is_ctrl = (ms->KeyMods & ImGuiMod_Ctrl) != 0; bool is_ctrl = (ms->KeyMods & ImGuiMod_Ctrl) != 0;
bool is_shift = (ms->KeyMods & ImGuiMod_Shift) != 0; bool is_shift = (ms->KeyMods & ImGuiMod_Shift) != 0;
@ -7394,16 +7396,16 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
const ImGuiInputSource input_source = (g.NavJustMovedToId == id || g.NavActivateId == id) ? g.NavInputSource : ImGuiInputSource_Mouse; const ImGuiInputSource input_source = (g.NavJustMovedToId == id || g.NavActivateId == id) ? g.NavInputSource : ImGuiInputSource_Mouse;
if (!is_multiselect) if (is_singleselect)
ms->EndIO.RequestClear = true; ms->EndIO.RequestClear = true;
else if ((input_source == ImGuiInputSource_Mouse || g.NavActivateId == id) && !is_ctrl) else if ((input_source == ImGuiInputSource_Mouse || g.NavActivateId == id) && !is_ctrl)
ms->EndIO.RequestClear = true; ms->EndIO.RequestClear = true;
else if ((input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Gamepad) && is_shift && !is_ctrl) else if ((input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Gamepad) && is_shift && !is_ctrl)
ms->EndIO.RequestClear = true; // With is_false==false the RequestClear was done in BeginIO, not necessary to do again. ms->EndIO.RequestClear = true; // With is_shift==false the RequestClear was done in BeginIO, not necessary to do again.
int range_direction; int range_direction;
ms->EndIO.RequestSetRange = true; ms->EndIO.RequestSetRange = true;
if (is_shift && is_multiselect) if (is_shift && !is_singleselect)
{ {
// Shift+Arrow always select // Shift+Arrow always select
// Ctrl+Shift+Arrow copy source selection state (alrady stored by BeginMultiSelect() in RangeSelected) // Ctrl+Shift+Arrow copy source selection state (alrady stored by BeginMultiSelect() in RangeSelected)