diff --git a/imgui.h b/imgui.h index 349c77f3e..b18a770ba 100644 --- a/imgui.h +++ b/imgui.h @@ -175,7 +175,7 @@ struct ImGuiIO; // Main configuration and I/O between your a struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use) struct ImGuiKeyData; // Storage for ImGuiIO and IsKeyDown(), IsKeyPressed() etc functions. struct ImGuiListClipper; // Helper to manually clip large list of items -struct ImGuiMultiSelectData; // State for a BeginMultiSelect() block +struct ImGuiMultiSelectIO; // Structure to interact with a BeginMultiSelect()/EndMultiSelect() block struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiPlatformImeData; // Platform IME data for io.PlatformSetImeDataFn() function. @@ -670,10 +670,10 @@ namespace ImGui // Multi-selection system for Selectable() and TreeNode() functions. // This enables standard multi-selection/range-selection idioms (CTRL+Click/Arrow, SHIFT+Click/Arrow, etc) in a way that allow items to be fully clipped (= not submitted at all) when not visible. - // Read comments near ImGuiMultiSelectData for details. + // Read comments near ImGuiMultiSelectIO for details. // When enabled, Selectable() and TreeNode() functions will return true when selection needs toggling. - IMGUI_API ImGuiMultiSelectData* BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected); - IMGUI_API ImGuiMultiSelectData* EndMultiSelect(); + IMGUI_API ImGuiMultiSelectIO* BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected); + IMGUI_API ImGuiMultiSelectIO* EndMultiSelect(); IMGUI_API void SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data); // Widgets: List Boxes @@ -2779,18 +2779,22 @@ enum ImGuiMultiSelectFlags_ // 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) // 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. -struct ImGuiMultiSelectData +struct ImGuiMultiSelectIO { + // Output (return by BeginMultiSelect()/EndMultiSelect() + // - Always process requests in their structure order. bool RequestClear; // Begin, End // 1. Request user to clear selection bool RequestSelectAll; // Begin, End // 2. Request user to select all bool RequestSetRange; // End // 3. Request user to set or clear selection in the [RangeSrc..RangeDst] range - bool RangeSrcPassedBy; // Loop // (If clipping) Need to be set by user if RangeSrc was part of the clipped set before submitting the visible items. Ignore if not clipping. bool RangeValue; // 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. int RangeDirection; // 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. - ImGuiMultiSelectData() { Clear(); } + // Input (written by user between BeginMultiSelect()/EndMultiSelect() + bool RangeSrcPassedBy; // 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. + + ImGuiMultiSelectIO() { Clear(); } void Clear() { RequestClear = RequestSelectAll = RequestSetRange = RangeSrcPassedBy = RangeValue = false; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3008ca946..e476864d8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2800,11 +2800,11 @@ struct ExampleSelection void SelectAll(int count) { Storage.Data.resize(count); for (int idx = 0; idx < count; idx++) Storage.Data[idx] = ImGuiStoragePair((ImGuiID)idx, 1); SelectionSize = count; } // This could be using SetRange(), but it this way is faster. // Apply requests coming from BeginMultiSelect() and EndMultiSelect(). Must be done in this order! Order->SelectAll->SetRange. - void ApplyRequests(ImGuiMultiSelectData* ms_data, int items_count) + void ApplyRequests(ImGuiMultiSelectIO* ms_io, int items_count) { - if (ms_data->RequestClear) { Clear(); } - if (ms_data->RequestSelectAll) { SelectAll(items_count); } - if (ms_data->RequestSetRange) { SetRange((int)(intptr_t)ms_data->RangeSrc, (int)(intptr_t)ms_data->RangeDst, ms_data->RangeValue ? 1 : 0); } + if (ms_io->RequestClear) { Clear(); } + 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); } } }; @@ -2876,8 +2876,8 @@ static void ShowDemoWindowMultiSelect() if (ImGui::BeginListBox("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20))) { ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape; - ImGuiMultiSelectData* multi_select_data = ImGui::BeginMultiSelect(flags, (void*)(intptr_t)selection.RangeRef, selection.GetSelected(selection.RangeRef)); - selection.ApplyRequests(multi_select_data, ITEMS_COUNT); + ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, (void*)(intptr_t)selection.RangeRef, selection.GetSelected(selection.RangeRef)); + selection.ApplyRequests(ms_io, ITEMS_COUNT); for (int n = 0; n < ITEMS_COUNT; n++) { @@ -2891,9 +2891,9 @@ static void ShowDemoWindowMultiSelect() } // Apply multi-select requests - multi_select_data = ImGui::EndMultiSelect(); - selection.RangeRef = (int)(intptr_t)multi_select_data->RangeSrc; - selection.ApplyRequests(multi_select_data, ITEMS_COUNT); + ms_io = ImGui::EndMultiSelect(); + selection.RangeRef = (int)(intptr_t)ms_io->RangeSrc; + selection.ApplyRequests(ms_io, ITEMS_COUNT); ImGui::EndListBox(); } @@ -2963,8 +2963,8 @@ static void ShowDemoWindowMultiSelect() ImGuiMultiSelectFlags local_flags = flags; if (use_multiple_scopes) local_flags &= ~ImGuiMultiSelectFlags_ClearOnClickWindowVoid; // local_flags |= ImGuiMultiSelectFlags_ClearOnClickRectVoid; - ImGuiMultiSelectData* multi_select_data = ImGui::BeginMultiSelect(local_flags, (void*)(intptr_t)selection->RangeRef, selection->GetSelected(selection->RangeRef)); - selection->ApplyRequests(multi_select_data, ITEMS_COUNT); + ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(local_flags, (void*)(intptr_t)selection->RangeRef, selection->GetSelected(selection->RangeRef)); + selection->ApplyRequests(ms_io, ITEMS_COUNT); if (use_multiple_scopes) ImGui::Text("Selection size: %d", selection->GetSize()); // Draw counter below Separator and after BeginMultiSelect() @@ -2983,8 +2983,8 @@ static void ShowDemoWindowMultiSelect() while (clipper.Step()) { // IF clipping is used you need to set 'RangeSrcPassedBy = true' if RangeSrc was passed over. - if ((int)(intptr_t)multi_select_data->RangeSrc <= clipper.DisplayStart) - multi_select_data->RangeSrcPassedBy = true; + if ((int)(intptr_t)ms_io->RangeSrc <= clipper.DisplayStart) + ms_io->RangeSrcPassedBy = true; for (int n = clipper.DisplayStart; n < clipper.DisplayEnd; n++) { @@ -3062,9 +3062,9 @@ static void ShowDemoWindowMultiSelect() } // Apply multi-select requests - multi_select_data = ImGui::EndMultiSelect(); - selection->RangeRef = (int)(intptr_t)multi_select_data->RangeSrc; - selection->ApplyRequests(multi_select_data, ITEMS_COUNT); + ms_io = ImGui::EndMultiSelect(); + selection->RangeRef = (int)(intptr_t)ms_io->RangeSrc; + selection->ApplyRequests(ms_io, ITEMS_COUNT); if (widget_type == WidgetType_TreeNode) ImGui::PopStyleVar(); diff --git a/imgui_internal.h b/imgui_internal.h index ad5366765..4770a2fd6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1719,8 +1719,8 @@ struct IMGUI_API ImGuiMultiSelectTempData ImGuiMultiSelectFlags Flags; ImGuiKeyChord KeyMods; ImGuiWindow* Window; - ImGuiMultiSelectData In; // The In requests are set and returned by BeginMultiSelect() - ImGuiMultiSelectData Out; // The Out requests are finalized and returned by EndMultiSelect() + ImGuiMultiSelectIO In; // The In requests are set and returned by BeginMultiSelect() + ImGuiMultiSelectIO Out; // The Out requests are finalized 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 InRangeDstPassedBy; // (Internal) set by the the item that match NavJustMovedToId when InRequestRangeSetNav is set. bool InRequestSetRangeNav; // (Internal) set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 55453dd50..de53de54d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7122,7 +7122,7 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data) // - MultiSelectItemFooter() [Internal] //------------------------------------------------------------------------- -static void DebugLogMultiSelectRequests(const ImGuiMultiSelectData* data) +static void DebugLogMultiSelectRequests(const ImGuiMultiSelectIO* data) { ImGuiContext& g = *GImGui; if (data->RequestClear) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestClear\n"); @@ -7130,7 +7130,7 @@ static void DebugLogMultiSelectRequests(const ImGuiMultiSelectData* data) if (data->RequestSetRange) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestSetRange %p..%p = %d (dir %+d)\n", data->RangeSrc, data->RangeDst, data->RangeValue, data->RangeDirection); } -ImGuiMultiSelectData* 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) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -7183,7 +7183,7 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* return &ms->In; } -ImGuiMultiSelectData* ImGui::EndMultiSelect() +ImGuiMultiSelectIO* ImGui::EndMultiSelect() { ImGuiContext& g = *GImGui; ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect;