// If you submit all items (no clipper), Step 2 and 3 and will be handled by Selectable() on a per-item basis.
structImGuiMultiSelectIO
{
// Output (return by BeginMultiSelect()/EndMultiSelect()
// - Always process requests in their structure order.
boolRequestClear;// Begin, End // 1. Request user to clear selection
boolRequestSelectAll;// Begin, End // 2. Request user to select all
boolRequestSetRange;// End // 3. Request user to set or clear selection in the [RangeSrc..RangeDst] range
boolRangeValue;// End // End: parameter from RequestSetRange request. true = Select Range, false = Unselect Range.
void*RangeSrc;// Begin, End // End: parameter from RequestSetRange request + you need to save this value so you can pass it again next frame. / Begin: this is the value you passed to BeginMultiSelect()
void*RangeDst;// End // End: parameter from RequestSetRange request.
intRangeDirection;// End // End: parameter from RequestSetRange request. +1 if RangeSrc came before RangeDst, -1 otherwise. Available as an indicator in case you cannot infer order from the void* values. If your void* values are storing indices you will never need this.
// Input (written by user between BeginMultiSelect()/EndMultiSelect()
boolRangeSrcPassedBy;// Loop // (If using a clipper) Need to be set by user if RangeSrc was part of the clipped set before submitting the visible items. Ignore if not clipping.
// - Always process requests in this order: Clear, SelectAll, SetRange.
// - Below: who reads/writes each fields? 'r'=read, 'w'=write, 'ms'=multi-select code, 'app'=application/user code.
// // BEGIN / LOOP / END
boolRequestClear;// ms:w, app:r / / ms:w, app:r // 1. Request user to clear selection (processed by app code)
boolRequestSelectAll;// ms:w, app:r / / ms:w, app:r // 2. Request user to select all (processed by app code)
boolRequestSetRange;// / / ms:w, app:r // 3. Request user to alter selection in the [RangeSrc..RangeDst] range using RangeValue. In practice, only EndMultiSelect() request this, app code can read after BeginMultiSelect() and it will always be false.
void*RangeSrc;// ms:w / app:r / ms:w, app:r // Begin: Last known RangeSrc value. End: parameter from RequestSetRange request.
ImS8RangeDirection;// / / ms:w, app:r // End: parameter from RequestSetRange request. +1 if RangeSrc came before RangeDst, -1 otherwise. Available as an indicator in case you cannot infer order from the void* values. If your void* values are storing indices you will never need this.
boolRangeSrcPassedBy;// / ms:rw app:w / ms:r // (If using a clipper) Need to be set by user if RangeSrc was part of the clipped set before submitting the visible items. Ignore if not clipping.
intSelectionSize;// Number of selected items (== number of 1 in the Storage, maintained by this class)
intSelectionSize;// Number of selected items (== number of 1 in the Storage, maintained by this class) // FIXME-RANGESELECT: Imply more difficult to track with intrusive selection schemes?
intRangeRef;// Reference/pivot item (generally last clicked item)
ImGuiIDFocusScopeId;// Copied from g.CurrentFocusScopeId (unless another selection scope was pushed manually)
ImGuiMultiSelectFlagsFlags;
ImGuiKeyChordKeyMods;
ImGuiWindow*Window;
ImGuiMultiSelectIOIn;// The In requests are set and returned by BeginMultiSelect()
ImGuiMultiSelectIOOut;// The Out requests are finalized and returned by EndMultiSelect()
ImGuiMultiSelectIOBeginIO;// Requests are set and returned by BeginMultiSelect(), written to by user during the loop.
ImGuiMultiSelectIOEndIO;// Requests are set during the loop and returned by EndMultiSelect().
boolIsFocused;// Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
boolInRangeDstPassedBy;// (Internal) set by the the item that match NavJustMovedToId when InRequestRangeSetNav is set.
boolInRequestSetRangeNav;// (Internal) set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
boolIsSetRange;// Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
boolSetRangeDstPassedBy;// Set by the the item that matches NavJustMovedToId when IsSetRange is set.
//ImRect Rect; // Extent of selection scope between BeginMultiSelect() / EndMultiSelect(), used by ImGuiMultiSelectFlags_ClearOnClickRectVoid.
// Auto clear when using Navigation to move within the selection (we compare SelectScopeId so it possible to use multiple lists inside a same window)
// FIXME: Polling key mods after the fact (frame following the move request) is incorrect, but latching it would requires non-trivial change in MultiSelectItemFooter()
// 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()
boolselected=*p_selected;
if(ms->In.RequestClear)
if(ms->BeginIO.RequestClear)
selected=false;
elseif(ms->In.RequestSelectAll)
elseif(ms->BeginIO.RequestSelectAll)
selected=true;
// 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, IF the user is clipping items, they need to set RangeSrcPassedBy = true to notify the system.