RangeSelect/MultiSelect: (Breaking) merge ImGuiSelectionRequestType_Clear and ImGuiSelectionRequestType_SelectAll into ImGuiSelectionRequestType_SetAll., rename ImGuiSelectionRequest::RangeSelected to Selected.
// - Store and maintain actual selection data using persistent object identifiers.
// - 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.
// - (2) [If using clipper] Honor request list (SetAll/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.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.
// - (6) Honor request list (SetAll/SetRange requests) by updating your selection data. Same code as Step 2.
// If you submit all items (no clipper), Step 2 and 3 are optional and will be handled by each item themselves. It is fine to always honor those steps.
// About ImGuiSelectionUserData:
// - For each item is it submitted by your call to SetNextItemSelectionUserData().
@ -2708,7 +2708,7 @@ 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_NoSelectAll=1<<1,// Disable CTRL+A shortcut to select all.
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.
@ -2740,9 +2740,8 @@ struct ImGuiMultiSelectIO
enumImGuiSelectionRequestType
{
ImGuiSelectionRequestType_None=0,
ImGuiSelectionRequestType_Clear,// Request app to clear selection.
ImGuiSelectionRequestType_SelectAll,// Request app to select all.
ImGuiSelectionRequestType_SetRange,// Request app to select/unselect [RangeFirstItem..RangeLastItem] items based on 'bool RangeSelected'. Only EndMultiSelect() request this, app code can read after BeginMultiSelect() and it will always be false.
ImGuiSelectionRequestType_SetAll,// Request app to clear selection (if Selected==false) or select all items (if Selected==true)
ImGuiSelectionRequestType_SetRange,// Request app to select/unselect [RangeFirstItem..RangeLastItem] items (inclusive) based on value of Selected. Only EndMultiSelect() request this, app code can read after BeginMultiSelect() and it will always be false.
ImGuiSelectionUserDataRangeFirstItem;// / ms:w, app:r // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from top to bottom)
ImGuiSelectionUserDataRangeLastItem;// / ms:w, app:r // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from bottom to top)
ImS8LoopRequestSetAll;// -1: no operation, 0: clear all, 1: select all.
boolIsEndIO;// Set when switching IO from BeginMultiSelect() to EndMultiSelect() state.
boolIsFocused;// Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
boolIsSetRange;// Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
IM_ASSERT(g.NextItemData.FocusScopeId==g.CurrentFocusScopeId&&"Forgot to call SetNextItemSelectionUserData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
// Apply Clear/SelectAll requests requested by BeginMultiSelect().
// Apply SetAll (Clear/SelectAll )requests requested by BeginMultiSelect().
// This is only useful if the user hasn't processed them already, and this only works if the user isn't using the clipper.
// If you are using a clipper (aka not submitting every element of the list) you need to process the Clear/SelectAll request after calling BeginMultiSelect()
if(ms->LoopRequestClear)
selected=false;
elseif(ms->LoopRequestSelectAll)
selected=true;
// If you are using a clipper you need to process the SetAll request after calling BeginMultiSelect()
if(ms->LoopRequestSetAll!=-1)
selected=(ms->LoopRequestSetAll==1);
// When using SHIFT+Nav: because it can incur scrolling we cannot afford a frame of lag with the selection highlight (otherwise scrolling would happen before selection)
// For this to work, we need someone to set 'RangeSrcPassedBy = true' at some point (either clipper either SetNextItemSelectionUserData() function)
// The most simple implementation (using indices everywhere) would look like:
// for (ImGuiSelectionRequest& req : ms_io->Requests)
// {
// if (req.Type == ImGuiSelectionRequestType_Clear) { Clear(); }
// if (req.Type == ImGuiSelectionRequestType_SelectAll) { Clear(); for (int n = 0; n < items_count; n++) { AddItem(n); } }
// if (req.Type == ImGuiSelectionRequestType_SetRange) { for (int n = (int)ms_io->RangeFirstItem; n <= (int)ms_io->RangeLastItem; n++) { UpdateItem(n, ms_io->RangeSelected); } }
// if (req.Type == ImGuiSelectionRequestType_SetAll) { Clear(); if (req.Selected) { for (int n = 0; n < items_count; n++) { AddItem(n); } }
// if (req.Type == ImGuiSelectionRequestType_SetRange) { for (int n = (int)ms_io->RangeFirstItem; n <= (int)ms_io->RangeLastItem; n++) { UpdateItem(n, ms_io->Selected); } }