mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
MultiSelect: refactor before introducing persistant state pool and to facilitate adding recursion + debug log calls.
This is mostly the noisy/shallow stuff committed here, to get this out of the way.
This commit is contained in:
parent
5d71314f71
commit
11bcae1ebd
@ -15799,7 +15799,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
ShowDebugLogFlag("IO", ImGuiDebugLogFlags_EventIO);
|
||||
ShowDebugLogFlag("Nav", ImGuiDebugLogFlags_EventNav);
|
||||
ShowDebugLogFlag("Popup", ImGuiDebugLogFlags_EventPopup);
|
||||
//ShowDebugLogFlag("Selection", ImGuiDebugLogFlags_EventSelection);
|
||||
ShowDebugLogFlag("Selection", ImGuiDebugLogFlags_EventSelection);
|
||||
ShowDebugLogFlag("InputRouting", ImGuiDebugLogFlags_EventInputRouting);
|
||||
|
||||
if (SmallButton("Clear"))
|
||||
|
7
imgui.h
7
imgui.h
@ -2747,6 +2747,10 @@ enum ImGuiMultiSelectFlags_
|
||||
// Note however that if you don't need SHIFT+Click/Arrow range-select + clipping, you can handle a simpler form of multi-selection
|
||||
// yourself, by reacting to click/presses on Selectable() items and checking keyboard modifiers.
|
||||
// The unusual complexity of this system is mostly caused by supporting SHIFT+Click/Arrow range-select with clipped elements.
|
||||
// - In the spirit of Dear ImGui design, your code owns the selection data.
|
||||
// So this is designed to handle all kind of selection data: e.g. instructive selection (store a bool inside each object),
|
||||
// external array (store an array aside from your objects), hash/map/set (store only selected items in a hash/map/set),
|
||||
// or other structures (store indices in an interval tree), etc.
|
||||
// - TreeNode() and Selectable() are supported.
|
||||
// - The work involved to deal with multi-selection differs whether you want to only submit visible items (and clip others) or submit all items
|
||||
// regardless of their visibility. Clipping items is more efficient and will allow you to deal with large lists (1k~100k items) with near zero
|
||||
@ -2758,9 +2762,6 @@ enum ImGuiMultiSelectFlags_
|
||||
// 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,
|
||||
// and then from the pointer have your own way of iterating from RangeSrc to RangeDst).
|
||||
// - In the spirit of Dear ImGui design, your code own the selection data. So this is designed to handle all kind of selection data:
|
||||
// e.g. instructive selection (store a bool inside each object), external array (store an array aside from your objects),
|
||||
// hash/map/set (store only selected items in a hash/map/set), or other structures (store indices in an interval tree), etc.
|
||||
// Usage flow:
|
||||
// Begin
|
||||
// 1) Call BeginMultiSelect() with the last saved value of ->RangeSrc and its selection state.
|
||||
|
@ -134,7 +134,7 @@ struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a de
|
||||
struct ImGuiLastItemData; // Status storage for last submitted items
|
||||
struct ImGuiLocEntry; // A localization entry.
|
||||
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
|
||||
struct ImGuiMultiSelectState; // Multi-selection state
|
||||
struct ImGuiMultiSelectTempData; // Multi-selection temporary state (while traversing).
|
||||
struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result
|
||||
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
|
||||
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
|
||||
@ -1713,7 +1713,7 @@ struct ImGuiOldColumns
|
||||
|
||||
#ifdef IMGUI_HAS_MULTI_SELECT
|
||||
|
||||
struct IMGUI_API ImGuiMultiSelectState
|
||||
struct IMGUI_API ImGuiMultiSelectTempData
|
||||
{
|
||||
ImGuiID FocusScopeId; // Copied from g.CurrentFocusScopeId (unless another selection scope was pushed manually)
|
||||
ImGuiMultiSelectFlags Flags;
|
||||
@ -1726,7 +1726,7 @@ struct IMGUI_API ImGuiMultiSelectState
|
||||
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.
|
||||
//ImRect Rect; // Extent of selection scope between BeginMultiSelect() / EndMultiSelect(), used by ImGuiMultiSelectFlags_ClearOnClickRectVoid.
|
||||
|
||||
ImGuiMultiSelectState() { Clear(); }
|
||||
ImGuiMultiSelectTempData() { Clear(); }
|
||||
void Clear() { FocusScopeId = 0; Flags = ImGuiMultiSelectFlags_None; KeyMods = ImGuiMod_None; Window = NULL; In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
|
||||
};
|
||||
|
||||
@ -2167,7 +2167,8 @@ struct ImGuiContext
|
||||
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
|
||||
|
||||
// Multi-Select state
|
||||
ImGuiMultiSelectState MultiSelectState; // FIXME-MULTISELECT: We currently don't support recursing/stacking multi-select
|
||||
ImGuiMultiSelectTempData* CurrentMultiSelect; // FIXME-MULTISELECT: We currently don't support recursing/stacking multi-select
|
||||
ImGuiMultiSelectTempData MultiSelectTempData[1];
|
||||
|
||||
// Hover Delay system
|
||||
ImGuiID HoverItemDelayId;
|
||||
@ -2409,6 +2410,7 @@ struct ImGuiContext
|
||||
CurrentTable = NULL;
|
||||
TablesTempDataStacked = 0;
|
||||
CurrentTabBar = NULL;
|
||||
CurrentMultiSelect = NULL;
|
||||
|
||||
HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
|
||||
HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
|
||||
|
@ -7122,13 +7122,21 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data)
|
||||
// - MultiSelectItemFooter() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static void DebugLogMultiSelectRequests(const ImGuiMultiSelectData* data)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (data->RequestClear) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestClear\n");
|
||||
if (data->RequestSelectAll) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestSelectAll\n");
|
||||
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)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||
IM_ASSERT(ms->Window == NULL && ms->Flags == 0 && ms->FocusScopeId == 0); // No recursion allowed yet (we could allow it if we deem it useful)
|
||||
ImGuiMultiSelectTempData* ms = &g.MultiSelectTempData[0];;
|
||||
IM_ASSERT(g.CurrentMultiSelect == NULL); // No recursion allowed yet (we could allow it if we deem it useful)
|
||||
g.CurrentMultiSelect = ms;
|
||||
|
||||
// FIXME: BeginFocusScope()
|
||||
ms->Clear();
|
||||
@ -7169,8 +7177,8 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void*
|
||||
if (Shortcut(ImGuiKey_Escape))
|
||||
ms->In.RequestClear = true;
|
||||
|
||||
//if (ms->In.RequestClear) IMGUI_DEBUG_LOG_SELECTION("BeginMultiSelect: RequestClear\n");
|
||||
//if (ms->In.RequestSelectAll) IMGUI_DEBUG_LOG_SELECTION("BeginMultiSelect: RequestSelectAll\n");
|
||||
if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)
|
||||
DebugLogMultiSelectRequests(&ms->In);
|
||||
|
||||
return &ms->In;
|
||||
}
|
||||
@ -7178,8 +7186,9 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void*
|
||||
ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||
IM_ASSERT(g.MultiSelectState.FocusScopeId == g.CurrentFocusScopeId);
|
||||
ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect;
|
||||
IM_ASSERT(ms->FocusScopeId == g.CurrentFocusScopeId);
|
||||
IM_ASSERT(g.CurrentMultiSelect != NULL && g.CurrentMultiSelect->Window == g.CurrentWindow);
|
||||
|
||||
// Clear selection when clicking void?
|
||||
// We specifically test for IsMouseDragPastThreshold(0) == false to allow box-selection!
|
||||
@ -7198,10 +7207,10 @@ ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
||||
ms->Window = NULL;
|
||||
ms->Flags = ImGuiMultiSelectFlags_None;
|
||||
PopFocusScope();
|
||||
g.CurrentMultiSelect = NULL;
|
||||
|
||||
//if (ms->Out.RequestClear) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestClear\n");
|
||||
//if (ms->Out.RequestSelectAll) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestSelectAll\n");
|
||||
//if (ms->Out.RequestSetRange) IMGUI_DEBUG_LOG_SELECTION("EndMultiSelect: RequestSetRange %p..%p = %d (dir %+d)\n", ms->Out.RangeSrc, ms->Out.RangeDst, ms->Out.RangeValue, ms->Out.RangeDirection);
|
||||
if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)
|
||||
DebugLogMultiSelectRequests(&ms->Out);
|
||||
|
||||
return &ms->Out;
|
||||
}
|
||||
@ -7218,16 +7227,17 @@ void ImGui::SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_d
|
||||
g.NextItemData.SelectionUserData = selection_user_data;
|
||||
g.NextItemData.FocusScopeId = g.CurrentFocusScopeId;
|
||||
|
||||
// Auto updating RangeSrcPassedBy for cases were clipper is not used.
|
||||
if (g.MultiSelectState.In.RangeSrc == (void*)selection_user_data)
|
||||
g.MultiSelectState.In.RangeSrcPassedBy = true;
|
||||
// Auto updating RangeSrcPassedBy for cases were clipper is not used (done before ItemAdd() clipping)
|
||||
if (ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect)
|
||||
if (ms->In.RangeSrc == (void*)selection_user_data)
|
||||
ms->In.RangeSrcPassedBy = true;
|
||||
}
|
||||
|
||||
void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||
ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect;
|
||||
|
||||
IM_UNUSED(window);
|
||||
IM_ASSERT(g.NextItemData.FocusScopeId == g.CurrentFocusScopeId && "Forgot to call SetNextItemSelectionUserData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
|
||||
@ -7266,7 +7276,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||
ImGuiMultiSelectTempData* ms = g.CurrentMultiSelect;
|
||||
|
||||
void* item_data = (void*)g.NextItemData.SelectionUserData;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user