MultiSelect: (Breaking) Renamed 'RangeSrc -> 'RangeSrcItem', "RangeDst' -> 'RangeDstItem'
This is necessary to have consistent names in upcoming fields (NavIdItem etc.)
This commit is contained in:
parent
a39f9e7661
commit
a83326bc52
22
imgui.h
22
imgui.h
@ -2757,26 +2757,26 @@ enum ImGuiMultiSelectFlags_
|
|||||||
// performance penalty, but requires a little more work on the code. If you only have a few hundreds elements in your possible selection set,
|
// performance penalty, but requires a little more work on the code. If you only have a few hundreds elements in your possible selection set,
|
||||||
// you may as well not bother with clipping, as the cost should be negligible (as least on Dear ImGui side).
|
// you may as well not bother with clipping, as the cost should be negligible (as least on Dear ImGui side).
|
||||||
// If you are not sure, always start without clipping and you can work your way to the more optimized version afterwards.
|
// If you are not sure, always start without clipping and you can work your way to the more optimized version afterwards.
|
||||||
// - The void* RangeSrc/RangeDst value represent a selectable object. They are the values you pass to SetNextItemSelectionUserData().
|
// - The void* RangeSrcItem/RangeDstItem value represent a selectable object. They are the value you pass to SetNextItemSelectionUserData().
|
||||||
// Most likely you will want to store an index here.
|
// Most likely you will want to store an index here.
|
||||||
// Storing an integer index is the easiest thing to do, as SetRange requests will give you two end points and you will need to interpolate
|
// Storing an integer index is the easiest thing to do, as SetRange requests will give you two end points and you will need to interpolate
|
||||||
// between them to honor range selection. But the code never assume that sortable integers are used (you may store pointers to your object,
|
// between them to honor range selection. But the code never assume that sortable integers are used (you may store pointers to your object,
|
||||||
// and then from the pointer have your own way of iterating from RangeSrc to RangeDst).
|
// and then from the pointer have your own way of iterating from RangeSrcItem to RangeDstItem).
|
||||||
// Usage flow:
|
// Usage flow:
|
||||||
// Begin
|
// Begin
|
||||||
// 1) Call BeginMultiSelect() with the last saved value of ->RangeSrc and its selection state.
|
// 1) Call BeginMultiSelect() with the last saved value of ->RangeSrcItem and its selection state.
|
||||||
// It is because you need to pass its selection state (and you own selection) that we don't store this value in Dear ImGui.
|
// It is because you need to pass its selection state (and you own selection) that we don't store this value in Dear ImGui.
|
||||||
// (For the initial frame or when resetting your selection state: you may use the value for your first item or a "null" value that matches the type stored in your void*).
|
// (For the initial frame or when resetting your selection state: you may use the value for your first item or a "null" value that matches the type stored in your void*).
|
||||||
// 2) Honor Clear/SelectAll/SetRange requests by updating your selection data. (Only required if you are using a clipper in step 4: but you can use same code as step 6 anyway.)
|
// 2) Honor Clear/SelectAll/SetRange requests by updating your selection data. (Only required if you are using a clipper in step 4: but you can use same code as step 6 anyway.)
|
||||||
// Loop
|
// Loop
|
||||||
// 3) Set RangeSrcPassedBy=true if the RangeSrc item is part of the items clipped before the first submitted/visible item. [Only required if you are using a clipper in step 4]
|
// 3) Set RangeSrcPassedBy=true if the RangeSrcItem item is part of the items clipped before the first submitted/visible item. [Only required if you are using a clipper in step 4]
|
||||||
// This is because for range-selection we need to know if we are currently "inside" or "outside" the range.
|
// This is because for range-selection we need to know if we are currently "inside" or "outside" the range.
|
||||||
// If you are using integer indices everywhere, this is easy to compute: if (clipper.DisplayStart > (int)data->RangeSrc) { data->RangeSrcPassedBy = true; }
|
// If you are using integer indices everywhere, this is easy to compute: if (clipper.DisplayStart > (int)data->RangeSrcItem) { data->RangeSrcPassedBy = true; }
|
||||||
// 4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls.
|
// 4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls.
|
||||||
// Call IsItemToggledSelection() to query if the selection state has been toggled, if you need the info immediately for your display (before EndMultiSelect()).
|
// Call IsItemToggledSelection() to query if the selection state has been toggled, if you need the info immediately for your display (before EndMultiSelect()).
|
||||||
// When cannot provide a "IsItemSelected()" value because we need to consider clipped/unprocessed items, this is why we return a "Toggled" event instead.
|
// When cannot provide a "IsItemSelected()" value because we need to consider clipped/unprocessed items, this is why we return a "Toggled" event instead.
|
||||||
// End
|
// End
|
||||||
// 5) Call EndMultiSelect(). Save the value of ->RangeSrc for the next frame (you may convert the value in a format that is safe for persistance)
|
// 5) Call EndMultiSelect(). Save the value of ->RangeSrcItem for the next frame (you may convert the value in a format that is safe for persistance)
|
||||||
// 6) Honor Clear/SelectAll/SetRange requests by updating your selection data. Always process them in this order (as you will receive Clear+SetRange request simultaneously)
|
// 6) Honor Clear/SelectAll/SetRange requests by updating your selection data. Always process them in this order (as you will receive Clear+SetRange request simultaneously)
|
||||||
// If you submit all items (no clipper), Step 2 and 3 and will be handled by Selectable() on a per-item basis.
|
// If you submit all items (no clipper), Step 2 and 3 and will be handled by Selectable() on a per-item basis.
|
||||||
struct ImGuiMultiSelectIO
|
struct ImGuiMultiSelectIO
|
||||||
@ -2786,12 +2786,12 @@ struct ImGuiMultiSelectIO
|
|||||||
// // BEGIN / LOOP / END
|
// // BEGIN / LOOP / END
|
||||||
bool RequestClear; // ms:w, app:r / / ms:w, app:r // 1. Request user to clear selection (processed by app code)
|
bool RequestClear; // ms:w, app:r / / ms:w, app:r // 1. Request user to clear selection (processed by app code)
|
||||||
bool RequestSelectAll; // ms:w, app:r / / ms:w, app:r // 2. Request user to select all (processed by app code)
|
bool RequestSelectAll; // ms:w, app:r / / ms:w, app:r // 2. Request user to select all (processed by app code)
|
||||||
bool RequestSetRange; // / / 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.
|
bool RequestSetRange; // / / ms:w, app:r // 3. Request user to alter selection in the [RangeSrcItem..RangeDstItem] 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.
|
void* RangeSrcItem; // ms:w / app:r / ms:w, app:r // Begin: Last known SetNextItemSelectionData() value for RangeSrcItem value. End: parameter from RequestSetRange request.
|
||||||
void* RangeDst; // / / ms:w, app:r // End: parameter from RequestSetRange request.
|
void* RangeDstItem; // / / ms:w, app:r // End: parameter from RequestSetRange request.
|
||||||
ImS8 RangeDirection; // / / 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.
|
ImS8 RangeDirection; // / / ms:w, app:r // End: parameter from RequestSetRange request. +1 if RangeSrcItem came before RangeDstItem, -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.
|
||||||
bool RangeValue; // / / ms:w, app:r // End: parameter from RequestSetRange request. true = Select Range, false = Unselect Range.
|
bool RangeValue; // / / ms:w, app:r // End: parameter from RequestSetRange request. true = Select Range, false = Unselect Range.
|
||||||
bool RangeSrcPassedBy; // / 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.
|
bool RangeSrcPassedBy; // / ms:rw app:w / ms:r // (If using a clipper) Need to be set by user if RangeSrcItem was part of the clipped set before submitting the visible items. Ignore if not clipping.
|
||||||
|
|
||||||
ImGuiMultiSelectIO() { Clear(); }
|
ImGuiMultiSelectIO() { Clear(); }
|
||||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||||
|
@ -2804,7 +2804,7 @@ struct ExampleSelection
|
|||||||
{
|
{
|
||||||
if (ms_io->RequestClear) { Clear(); }
|
if (ms_io->RequestClear) { Clear(); }
|
||||||
if (ms_io->RequestSelectAll) { SelectAll(items_count); }
|
if (ms_io->RequestSelectAll) { SelectAll(items_count); }
|
||||||
if (ms_io->RequestSetRange) { SetRange((int)(intptr_t)ms_io->RangeSrc, (int)(intptr_t)ms_io->RangeDst, ms_io->RangeValue ? 1 : 0); }
|
if (ms_io->RequestSetRange) { SetRange((int)(intptr_t)ms_io->RangeSrcItem, (int)(intptr_t)ms_io->RangeDstItem, ms_io->RangeValue ? 1 : 0); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2893,7 +2893,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.RangeRef = (int)(intptr_t)ms_io->RangeSrc;
|
selection.RangeRef = (int)(intptr_t)ms_io->RangeSrcItem;
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
||||||
|
|
||||||
ImGui::EndListBox();
|
ImGui::EndListBox();
|
||||||
@ -2934,7 +2934,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection->RangeRef = (int)(intptr_t)ms_io->RangeSrc;
|
selection->RangeRef = (int)(intptr_t)ms_io->RangeSrcItem;
|
||||||
selection->ApplyRequests(ms_io, ITEMS_COUNT);
|
selection->ApplyRequests(ms_io, ITEMS_COUNT);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
@ -3001,9 +3001,9 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
while (!use_clipper || clipper.Step())
|
while (!use_clipper || clipper.Step())
|
||||||
{
|
{
|
||||||
// IF clipping is used you need to set 'RangeSrcPassedBy = true' if RangeSrc was passed over.
|
// IF clipping is used you need to set 'RangeSrcPassedBy = true' if RangeSrcItem was passed over.
|
||||||
if (use_clipper)
|
if (use_clipper)
|
||||||
if ((int)(intptr_t)ms_io->RangeSrc <= clipper.DisplayStart)
|
if ((int)(intptr_t)ms_io->RangeSrcItem <= clipper.DisplayStart)
|
||||||
ms_io->RangeSrcPassedBy = true;
|
ms_io->RangeSrcPassedBy = true;
|
||||||
|
|
||||||
const int item_begin = use_clipper ? clipper.DisplayStart : 0;
|
const int item_begin = use_clipper ? clipper.DisplayStart : 0;
|
||||||
@ -3091,7 +3091,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.RangeRef = (int)(intptr_t)ms_io->RangeSrc;
|
selection.RangeRef = (int)(intptr_t)ms_io->RangeSrcItem;
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
||||||
|
|
||||||
if (widget_type == WidgetType_TreeNode)
|
if (widget_type == WidgetType_TreeNode)
|
||||||
|
@ -1724,7 +1724,7 @@ struct IMGUI_API ImGuiMultiSelectTempData
|
|||||||
ImGuiMultiSelectIO EndIO; // Requests are set during the loop and returned by EndMultiSelect().
|
ImGuiMultiSelectIO EndIO; // Requests are set during the loop and returned by EndMultiSelect().
|
||||||
bool IsFocused; // Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
|
bool IsFocused; // Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
|
||||||
bool IsSetRange; // Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
|
bool IsSetRange; // Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
|
||||||
bool SetRangeDstPassedBy; // Set by the the item that matches NavJustMovedToId when IsSetRange is set.
|
bool RangeDstPassedBy; // Set by the item that matches NavJustMovedToId when IsSetRange is set.
|
||||||
//ImRect Rect; // Extent of selection scope between BeginMultiSelect() / EndMultiSelect(), used by ImGuiMultiSelectFlags_ClearOnClickRectVoid.
|
//ImRect Rect; // Extent of selection scope between BeginMultiSelect() / EndMultiSelect(), used by ImGuiMultiSelectFlags_ClearOnClickRectVoid.
|
||||||
|
|
||||||
ImGuiMultiSelectTempData() { Clear(); }
|
ImGuiMultiSelectTempData() { Clear(); }
|
||||||
|
@ -7128,7 +7128,7 @@ static void DebugLogMultiSelectRequests(const char* function, const ImGuiMultiSe
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (data->RequestClear) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestClear\n", function);
|
if (data->RequestClear) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestClear\n", function);
|
||||||
if (data->RequestSelectAll) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestSelectAll\n", function);
|
if (data->RequestSelectAll) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestSelectAll\n", function);
|
||||||
if (data->RequestSetRange) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestSetRange %p..%p = %d (dir %+d)\n", function, data->RangeSrc, data->RangeDst, data->RangeValue, data->RangeDirection);
|
if (data->RequestSetRange) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: RequestSetRange %p..%p = %d (dir %+d)\n", function, data->RangeSrcItem, data->RangeDstItem, data->RangeValue, data->RangeDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
|
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
|
||||||
@ -7152,7 +7152,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* r
|
|||||||
|
|
||||||
if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
|
if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
|
||||||
{
|
{
|
||||||
ms->BeginIO.RangeSrc = ms->EndIO.RangeSrc = range_ref;
|
ms->BeginIO.RangeSrcItem = ms->EndIO.RangeSrcItem = range_ref;
|
||||||
ms->BeginIO.RangeValue = ms->EndIO.RangeValue = range_ref_is_selected;
|
ms->BeginIO.RangeValue = ms->EndIO.RangeValue = range_ref_is_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7229,7 +7229,7 @@ void ImGui::SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_d
|
|||||||
|
|
||||||
// Auto updating RangeSrcPassedBy for cases were clipper is not used (done before ItemAdd() clipping)
|
// Auto updating RangeSrcPassedBy for cases were clipper is not used (done before ItemAdd() clipping)
|
||||||
if (ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect)
|
if (ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect)
|
||||||
if (ms->BeginIO.RangeSrc == (void*)selection_user_data)
|
if (ms->BeginIO.RangeSrcItem == (void*)selection_user_data)
|
||||||
ms->BeginIO.RangeSrcPassedBy = true;
|
ms->BeginIO.RangeSrcPassedBy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7259,11 +7259,11 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
|
|||||||
{
|
{
|
||||||
IM_ASSERT(id != 0);
|
IM_ASSERT(id != 0);
|
||||||
IM_ASSERT((ms->KeyMods & ImGuiMod_Shift) != 0);
|
IM_ASSERT((ms->KeyMods & ImGuiMod_Shift) != 0);
|
||||||
const bool is_range_src = (ms->BeginIO.RangeSrc == item_data);
|
const bool is_range_src = (ms->BeginIO.RangeSrcItem == item_data);
|
||||||
const bool is_range_dst = !ms->SetRangeDstPassedBy && g.NavJustMovedToId == id; // Assume that g.NavJustMovedToId is not clipped.
|
const bool is_range_dst = !ms->RangeDstPassedBy && g.NavJustMovedToId == id; // Assume that g.NavJustMovedToId is not clipped.
|
||||||
if (is_range_dst)
|
if (is_range_dst)
|
||||||
ms->SetRangeDstPassedBy = true;
|
ms->RangeDstPassedBy = true;
|
||||||
if (is_range_src || is_range_dst || ms->BeginIO.RangeSrcPassedBy != ms->SetRangeDstPassedBy)
|
if (is_range_src || is_range_dst || ms->BeginIO.RangeSrcPassedBy != ms->RangeDstPassedBy)
|
||||||
selected = ms->BeginIO.RangeValue;
|
selected = ms->BeginIO.RangeValue;
|
||||||
else if ((ms->KeyMods & ImGuiMod_Ctrl) == 0)
|
else if ((ms->KeyMods & ImGuiMod_Ctrl) == 0)
|
||||||
selected = false;
|
selected = false;
|
||||||
@ -7332,7 +7332,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
{
|
{
|
||||||
// Shift+Arrow always select, Ctrl+Shift+Arrow copy source selection state.
|
// Shift+Arrow always select, Ctrl+Shift+Arrow copy source selection state.
|
||||||
ms->EndIO.RequestSetRange = true;
|
ms->EndIO.RequestSetRange = true;
|
||||||
ms->EndIO.RangeDst = item_data;
|
ms->EndIO.RangeDstItem = item_data;
|
||||||
if (!is_ctrl)
|
if (!is_ctrl)
|
||||||
ms->EndIO.RangeValue = true;
|
ms->EndIO.RangeValue = true;
|
||||||
ms->EndIO.RangeDirection = ms->BeginIO.RangeSrcPassedBy ? +1 : -1;
|
ms->EndIO.RangeDirection = ms->BeginIO.RangeSrcPassedBy ? +1 : -1;
|
||||||
@ -7341,7 +7341,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
{
|
{
|
||||||
// Ctrl inverts selection, otherwise always select
|
// Ctrl inverts selection, otherwise always select
|
||||||
selected = (is_ctrl && (ms->Flags & ImGuiMultiSelectFlags_NoUnselect) == 0) ? !selected : true;
|
selected = (is_ctrl && (ms->Flags & ImGuiMultiSelectFlags_NoUnselect) == 0) ? !selected : true;
|
||||||
ms->EndIO.RangeSrc = ms->EndIO.RangeDst = item_data;
|
ms->EndIO.RangeSrcItem = ms->EndIO.RangeDstItem = item_data;
|
||||||
ms->EndIO.RangeValue = selected;
|
ms->EndIO.RangeValue = selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7353,7 +7353,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
if (is_multiselect && !is_shift && ms->EndIO.RequestClear)
|
if (is_multiselect && !is_shift && ms->EndIO.RequestClear)
|
||||||
{
|
{
|
||||||
// For toggle selection unless there is a Clear request, we can handle it completely locally without sending a RangeSet request.
|
// For toggle selection unless there is a Clear request, we can handle it completely locally without sending a RangeSet request.
|
||||||
IM_ASSERT(ms->EndIO.RangeSrc == ms->EndIO.RangeDst); // Setup by else block above
|
IM_ASSERT(ms->EndIO.RangeSrcItem == ms->EndIO.RangeDstItem); // Setup by else block above
|
||||||
ms->EndIO.RequestSetRange = true;
|
ms->EndIO.RequestSetRange = true;
|
||||||
ms->EndIO.RangeValue = selected;
|
ms->EndIO.RangeValue = selected;
|
||||||
ms->EndIO.RangeDirection = +1;
|
ms->EndIO.RangeDirection = +1;
|
||||||
@ -7361,7 +7361,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
if (!is_multiselect)
|
if (!is_multiselect)
|
||||||
{
|
{
|
||||||
// Clear selection, set single item range
|
// Clear selection, set single item range
|
||||||
IM_ASSERT(ms->EndIO.RangeSrc == item_data && ms->EndIO.RangeDst == item_data); // Setup by block above
|
IM_ASSERT(ms->EndIO.RangeSrcItem == item_data && ms->EndIO.RangeDstItem == item_data); // Setup by block above
|
||||||
ms->EndIO.RequestClear = true;
|
ms->EndIO.RequestClear = true;
|
||||||
ms->EndIO.RequestSetRange = true;
|
ms->EndIO.RequestSetRange = true;
|
||||||
}
|
}
|
||||||
@ -7376,7 +7376,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update/store the selection state of the Source item (used by CTRL+SHIFT, when Source is unselected we perform a range unselect)
|
// Update/store the selection state of the Source item (used by CTRL+SHIFT, when Source is unselected we perform a range unselect)
|
||||||
if (ms->EndIO.RangeSrc == item_data && is_ctrl && is_shift && is_multiselect && !(ms->Flags & ImGuiMultiSelectFlags_NoUnselect))
|
if (ms->EndIO.RangeSrcItem == item_data && is_ctrl && is_shift && is_multiselect && !(ms->Flags & ImGuiMultiSelectFlags_NoUnselect))
|
||||||
ms->EndIO.RangeValue = selected;
|
ms->EndIO.RangeValue = selected;
|
||||||
|
|
||||||
*p_selected = selected;
|
*p_selected = selected;
|
||||||
|
Loading…
Reference in New Issue
Block a user