From ef3c860ae36105b54118972afe127f8af6f3bf79 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 Jan 2020 16:18:55 +0100 Subject: [PATCH] RangeSelect/MultiSelect: Renamed SetNextItemMultiSelectData() to SetNextItemSelectionData() --- imgui.h | 4 ++-- imgui_demo.cpp | 10 +++++++++- imgui_internal.h | 2 +- imgui_widgets.cpp | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/imgui.h b/imgui.h index 37a77662..7df1962a 100644 --- a/imgui.h +++ b/imgui.h @@ -2686,7 +2686,7 @@ 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, // you may as well not bother with clipping, as the cost should be negligible (as least on imgui side). // If you are not sure, always start without clipping and you can work your way to the more optimized version afterwards. -// - The void* Src/Dst value represent a selectable object. They are the values you pass to SetNextItemMultiSelectData(). +// - The void* Src/Dst value represent a selectable object. They are the values you pass to SetNextItemSelectionUserData(). // Storing an integer index is the easiest thing to do, as SetRange requests will give you two end points. But the code never assume that sortable integers are used. // - In the spirit of imgui design, your code own the selection data. So this is designed to handle all kind of selection data: instructive (store a bool inside each object), // external array (store an array aside from your objects), set (store only selected items in a hash/map/set), using intervals (store indices in an interval tree), etc. @@ -2697,7 +2697,7 @@ enum ImGuiMultiSelectFlags_ // 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] // 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; } -// 4) Submit your items with SetNextItemMultiSelectData() + Selectable()/TreeNode() calls. +// 4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls. // Call IsItemSelectionToggled() to query with the selection state has been toggled, in which you need the info immediately (before EndMultiSelect()) for your display. // When cannot reliably return a "IsItemSelected()" value because we need to consider clipped (unprocessed) item, this is why we return a toggle event instead. // 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) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 25318cb0..70b1a4b7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2825,7 +2825,7 @@ static void ShowDemoWindowMultiSelect() }; int COUNT = 1000; - HelpMarker("Hold CTRL and click to select multiple items. Hold SHIFT to select a range."); + HelpMarker("Hold CTRL and click to select multiple items. Hold SHIFT to select a range. Keyboard is also supported."); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int*)&ImGui::GetIO().ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); if (ImGui::BeginListBox("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20))) @@ -2833,6 +2833,7 @@ static void ShowDemoWindowMultiSelect() ImGuiMultiSelectData* multi_select_data = ImGui::BeginMultiSelect(ImGuiMultiSelectFlags_None, (void*)(intptr_t)selection_ref, selection.GetSelected((int)selection_ref)); if (multi_select_data->RequestClear) { selection.Clear(); } if (multi_select_data->RequestSelectAll) { selection.SelectAll(COUNT); } + ImVec2 color_button_sz(ImGui::GetFontSize(), ImGui::GetFontSize()); ImGuiListClipper clipper; clipper.Begin(COUNT); while (clipper.Step()) @@ -2845,6 +2846,13 @@ static void ShowDemoWindowMultiSelect() char label[64]; sprintf(label, "Object %05d (category: %s)", n, random_names[n % IM_ARRAYSIZE(random_names)]); bool item_is_selected = selection.GetSelected(n); + + // Emit a color button, to test that Shift+LeftArrow landing on an item that is not part + // of the selection scope doesn't erroneously alter our selection. + ImVec4 dummy_col = ImColor((ImU32)ImGui::GetID(label)); + ImGui::ColorButton("##", dummy_col, ImGuiColorEditFlags_NoTooltip, color_button_sz); + ImGui::SameLine(); + ImGui::SetNextItemSelectionUserData(n); if (ImGui::Selectable(label, item_is_selected)) selection.SetSelected(n, !item_is_selected); diff --git a/imgui_internal.h b/imgui_internal.h index 7e58208b..edebee47 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1597,7 +1597,7 @@ struct ImGuiNavItemData float DistBox; // Move // Best candidate box distance to current NavId float DistCenter; // Move // Best candidate center distance to current NavId float DistAxial; // Move // Best candidate axial distance to current NavId - ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. + ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionUserData() value. ImGuiNavItemData() { Clear(); } void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 6c621777..67aa1d7a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6996,7 +6996,7 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data) //------------------------------------------------------------------------- // - BeginMultiSelect() // - EndMultiSelect() -// - SetNextItemMultiSelectData() +// - SetNextItemSelectionUserData() // - MultiSelectItemHeader() [Internal] // - MultiSelectItemFooter() [Internal] //------------------------------------------------------------------------- @@ -7080,7 +7080,7 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected) ImGuiContext& g = *GImGui; ImGuiMultiSelectState* ms = &g.MultiSelectState; - IM_ASSERT((g.NextItemData.SelectionUserData != ImGuiSelectionUserData_Invalid) && "Forgot to call SetNextItemMultiSelectData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope"); + IM_ASSERT((g.NextItemData.SelectionUserData != ImGuiSelectionUserData_Invalid) && "Forgot to call SetNextItemSelectionUserData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope"); void* item_data = (void*)g.NextItemData.SelectionUserData; // Apply Clear/SelectAll requests requested by BeginMultiSelect().