MultiSelect: Transition to use FocusScope bits merged in master.
Preserve ability to shift+arrow into an item that is part of FocusScope but doesn't carry a selection without breaking selection.
This commit is contained in:
parent
4afbfd5e71
commit
9c7183dd04
@ -3822,7 +3822,6 @@ void ImGui::Shutdown()
|
|||||||
g.MenusIdSubmittedThisFrame.clear();
|
g.MenusIdSubmittedThisFrame.clear();
|
||||||
g.InputTextState.ClearFreeMemory();
|
g.InputTextState.ClearFreeMemory();
|
||||||
g.InputTextDeactivatedState.ClearFreeMemory();
|
g.InputTextDeactivatedState.ClearFreeMemory();
|
||||||
g.MultiSelectScopeWindow = NULL;
|
|
||||||
|
|
||||||
g.SettingsWindows.clear();
|
g.SettingsWindows.clear();
|
||||||
g.SettingsHandlers.clear();
|
g.SettingsHandlers.clear();
|
||||||
|
@ -1210,6 +1210,7 @@ enum ImGuiNextItemDataFlags_
|
|||||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||||
|
ImGuiNextItemDataFlags_HasSelectionData = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImGuiNextItemData
|
struct ImGuiNextItemData
|
||||||
@ -1217,6 +1218,7 @@ struct ImGuiNextItemData
|
|||||||
ImGuiNextItemDataFlags Flags;
|
ImGuiNextItemDataFlags Flags;
|
||||||
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap.
|
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap.
|
||||||
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
|
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
|
||||||
|
ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData() (!= 0 signify value has been set)
|
||||||
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
|
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
|
||||||
float Width; // Set by SetNextItemWidth()
|
float Width; // Set by SetNextItemWidth()
|
||||||
ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut()
|
ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut()
|
||||||
@ -1713,13 +1715,14 @@ struct ImGuiOldColumns
|
|||||||
|
|
||||||
struct IMGUI_API ImGuiMultiSelectState
|
struct IMGUI_API ImGuiMultiSelectState
|
||||||
{
|
{
|
||||||
|
ImGuiID FocusScopeId; // Same as CurrentWindow->DC.FocusScopeIdCurrent (unless another selection scope was pushed manually)
|
||||||
ImGuiMultiSelectData In; // The In requests are set and returned by BeginMultiSelect()
|
ImGuiMultiSelectData In; // The In requests are set and returned by BeginMultiSelect()
|
||||||
ImGuiMultiSelectData Out; // The Out requests are finalized and returned by EndMultiSelect()
|
ImGuiMultiSelectData Out; // The Out requests are finalized and returned by EndMultiSelect()
|
||||||
bool InRangeDstPassedBy; // (Internal) set by the the item that match NavJustMovedToId when InRequestRangeSetNav is set.
|
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.
|
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.
|
||||||
|
|
||||||
ImGuiMultiSelectState() { Clear(); }
|
ImGuiMultiSelectState() { Clear(); }
|
||||||
void Clear() { In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
|
void Clear() { FocusScopeId = 0; In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifdef IMGUI_HAS_MULTI_SELECT
|
#endif // #ifdef IMGUI_HAS_MULTI_SELECT
|
||||||
@ -2117,10 +2120,9 @@ struct ImGuiContext
|
|||||||
ImVec2 NavWindowingAccumDeltaSize;
|
ImVec2 NavWindowingAccumDeltaSize;
|
||||||
|
|
||||||
// Range-Select/Multi-Select
|
// Range-Select/Multi-Select
|
||||||
ImGuiID MultiSelectScopeId;
|
bool MultiSelectEnabled;
|
||||||
ImGuiWindow* MultiSelectScopeWindow;
|
|
||||||
ImGuiMultiSelectFlags MultiSelectFlags;
|
ImGuiMultiSelectFlags MultiSelectFlags;
|
||||||
ImGuiMultiSelectState MultiSelectState;
|
ImGuiMultiSelectState MultiSelectState; // We currently don't support recursing/stacking multi-select
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
|
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
|
||||||
@ -2385,9 +2387,8 @@ struct ImGuiContext
|
|||||||
NavWindowingToggleLayer = false;
|
NavWindowingToggleLayer = false;
|
||||||
NavWindowingToggleKey = ImGuiKey_None;
|
NavWindowingToggleKey = ImGuiKey_None;
|
||||||
|
|
||||||
MultiSelectScopeId = 0;
|
MultiSelectEnabled = false;
|
||||||
MultiSelectScopeWindow = NULL;
|
MultiSelectFlags = ImGuiMultiSelectFlags_None;
|
||||||
MultiSelectFlags = 0;
|
|
||||||
|
|
||||||
DimBgRatio = 0.0f;
|
DimBgRatio = 0.0f;
|
||||||
|
|
||||||
|
@ -6466,7 +6466,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags
|
|||||||
const bool was_selected = selected;
|
const bool was_selected = selected;
|
||||||
|
|
||||||
// Multi-selection support (header)
|
// Multi-selection support (header)
|
||||||
const bool is_multi_select = (g.MultiSelectScopeWindow == window);
|
const bool is_multi_select = g.MultiSelectEnabled;
|
||||||
if (is_multi_select)
|
if (is_multi_select)
|
||||||
{
|
{
|
||||||
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
||||||
@ -6814,7 +6814,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
|
if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
|
||||||
|
|
||||||
// Multi-selection support (header)
|
// Multi-selection support (header)
|
||||||
const bool is_multi_select = (g.MultiSelectScopeWindow == window);
|
const bool is_multi_select = g.MultiSelectEnabled;
|
||||||
const bool was_selected = selected;
|
const bool was_selected = selected;
|
||||||
if (is_multi_select)
|
if (is_multi_select)
|
||||||
{
|
{
|
||||||
@ -7120,17 +7120,20 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data)
|
|||||||
|
|
||||||
ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
|
ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
IM_ASSERT(g.MultiSelectScopeId == 0); // No recursion allowed yet (we could allow it if we deem it useful)
|
IM_ASSERT(g.MultiSelectEnabled == false); // No recursion allowed yet (we could allow it if we deem it useful)
|
||||||
IM_ASSERT(g.MultiSelectFlags == 0);
|
IM_ASSERT(g.MultiSelectFlags == 0);
|
||||||
|
IM_ASSERT(g.MultiSelectState.FocusScopeId == 0);
|
||||||
|
|
||||||
|
// FIXME: BeginFocusScope()
|
||||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||||
g.MultiSelectScopeId = window->IDStack.back();
|
|
||||||
g.MultiSelectScopeWindow = window;
|
|
||||||
g.MultiSelectFlags = flags;
|
|
||||||
ms->Clear();
|
ms->Clear();
|
||||||
|
ms->FocusScopeId = window->IDStack.back();
|
||||||
|
PushFocusScope(ms->FocusScopeId);
|
||||||
|
g.MultiSelectEnabled = true;
|
||||||
|
g.MultiSelectFlags = flags;
|
||||||
|
|
||||||
if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
|
if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
|
||||||
{
|
{
|
||||||
@ -7139,7 +7142,7 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto clear when using Navigation to move within the selection (we compare SelectScopeId so it possible to use multiple lists inside a same window)
|
// Auto clear when using Navigation to move within the selection (we compare SelectScopeId so it possible to use multiple lists inside a same window)
|
||||||
if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.MultiSelectScopeId)
|
if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == ms->FocusScopeId && g.NavJustMovedToHasSelectionData)
|
||||||
{
|
{
|
||||||
if (g.IO.KeyShift)
|
if (g.IO.KeyShift)
|
||||||
ms->InRequestSetRangeNav = true;
|
ms->InRequestSetRangeNav = true;
|
||||||
@ -7162,14 +7165,16 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void*
|
|||||||
|
|
||||||
ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||||
IM_ASSERT(g.MultiSelectScopeId != 0);
|
IM_ASSERT(g.MultiSelectState.FocusScopeId == g.CurrentFocusScopeId);
|
||||||
|
|
||||||
if (g.MultiSelectFlags & ImGuiMultiSelectFlags_NoUnselect)
|
if (g.MultiSelectFlags & ImGuiMultiSelectFlags_NoUnselect)
|
||||||
ms->Out.RangeValue = true;
|
ms->Out.RangeValue = true;
|
||||||
g.MultiSelectScopeId = 0;
|
g.MultiSelectState.FocusScopeId = 0;
|
||||||
g.MultiSelectScopeWindow = NULL;
|
PopFocusScope();
|
||||||
g.MultiSelectFlags = 0;
|
g.MultiSelectEnabled = false;
|
||||||
|
g.MultiSelectFlags = ImGuiMultiSelectFlags_None;
|
||||||
|
|
||||||
#ifdef IMGUI_DEBUG_MULTISELECT
|
#ifdef IMGUI_DEBUG_MULTISELECT
|
||||||
if (ms->Out.RequestClear) printf("[%05d] EndMultiSelect: RequestClear\n", g.FrameCount);
|
if (ms->Out.RequestClear) printf("[%05d] EndMultiSelect: RequestClear\n", g.FrameCount);
|
||||||
@ -7185,18 +7190,22 @@ void ImGui::SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_d
|
|||||||
// Note that flags will be cleared by ItemAdd(), so it's only useful for Navigation code!
|
// Note that flags will be cleared by ItemAdd(), so it's only useful for Navigation code!
|
||||||
// This designed so widgets can also cheaply set this before calling ItemAdd(), so we are not tied to MultiSelect api.
|
// This designed so widgets can also cheaply set this before calling ItemAdd(), so we are not tied to MultiSelect api.
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.MultiSelectScopeId != 0)
|
if (g.MultiSelectState.FocusScopeId != 0)
|
||||||
g.NextItemData.ItemFlags |= ImGuiItemFlags_HasSelectionUserData | ImGuiItemFlags_IsMultiSelect;
|
g.NextItemData.ItemFlags |= ImGuiItemFlags_HasSelectionUserData | ImGuiItemFlags_IsMultiSelect;
|
||||||
else
|
else
|
||||||
g.NextItemData.ItemFlags |= ImGuiItemFlags_HasSelectionUserData;
|
g.NextItemData.ItemFlags |= ImGuiItemFlags_HasSelectionUserData;
|
||||||
g.NextItemData.SelectionUserData = selection_user_data;
|
g.NextItemData.SelectionUserData = selection_user_data;
|
||||||
|
g.NextItemData.FocusScopeId = g.CurrentFocusScopeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
|
void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
ImGuiMultiSelectState* ms = &g.MultiSelectState;
|
||||||
|
|
||||||
|
IM_UNUSED(window);
|
||||||
|
IM_ASSERT(g.NextItemData.FocusScopeId == g.CurrentFocusScopeId && "Forgot to call SetNextItemSelectionUserData() 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");
|
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;
|
void* item_data = (void*)g.NextItemData.SelectionUserData;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user