mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-21 19:37:01 +00:00
RangeSelect/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
abfa8487eb
commit
dd52a2854c
@ -4554,7 +4554,6 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.ClipboardHandlerData.clear();
|
||||
g.MenusIdSubmittedThisFrame.clear();
|
||||
g.InputTextState.ClearFreeMemory();
|
||||
g.MultiSelectScopeWindow = NULL;
|
||||
|
||||
g.SettingsWindows.clear();
|
||||
g.SettingsHandlers.clear();
|
||||
@ -9735,6 +9734,7 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
|
||||
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
result->InFlags = g.LastItemData.InFlags;
|
||||
result->RectRel = WindowRectAbsToRel(window, g.LastItemData.NavRect);
|
||||
result->HasSelectionData = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasSelectionData) != 0; // FIXME: Bizarre but valid we are calling NavApplyItemToResult() before clering the NextItemData
|
||||
}
|
||||
|
||||
// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
|
||||
@ -10491,6 +10491,7 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
g.NavJustMovedToId = result->ID;
|
||||
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
|
||||
g.NavJustMovedToKeyMods = g.NavMoveKeyMods;
|
||||
g.NavJustMovedToHasSelectionData = result->HasSelectionData;
|
||||
}
|
||||
|
||||
// Focus
|
||||
|
@ -1082,9 +1082,10 @@ struct ImGuiNextWindowData
|
||||
|
||||
enum ImGuiNextItemDataFlags_
|
||||
{
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasSelectionData = 1 << 2
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@ -1094,7 +1095,6 @@ struct ImGuiNextItemData
|
||||
ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging)
|
||||
ImGuiCond OpenCond;
|
||||
bool OpenVal; // Set by SetNextItemOpen()
|
||||
ImGuiID MultiSelectScopeId; // Set by SetNextItemMultiSelectData()
|
||||
void* SelectionData; // Set by SetNextItemSelectionData() (note that NULL/0 is a valid value)
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); }
|
||||
@ -1338,9 +1338,10 @@ 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
|
||||
bool HasSelectionData; // Move // Copy of (NextItemData.Flags & ImGuiNextItemDataFlags_HasSelection)
|
||||
|
||||
ImGuiNavItemData() { Clear(); }
|
||||
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
|
||||
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; HasSelectionData = false; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1403,18 +1404,19 @@ struct ImGuiOldColumns
|
||||
// [SECTION] Multi-select support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//#define IMGUI_HAS_MULTI_SELECT 1
|
||||
#ifdef IMGUI_HAS_MULTI_SELECT
|
||||
|
||||
struct IMGUI_API ImGuiMultiSelectState
|
||||
{
|
||||
ImGuiID FocusScopeId; // Same as CurrentWindow->DC.FocusScopeIdCurrent (unless another selection scope was pushed manually)
|
||||
ImGuiID BackupFocusScopeId;
|
||||
ImGuiMultiSelectData In; // The In requests are set and returned by BeginMultiSelect()
|
||||
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 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(); }
|
||||
void Clear() { In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
|
||||
void Clear() { FocusScopeId = BackupFocusScopeId = 0; In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
|
||||
};
|
||||
|
||||
#endif // #ifdef IMGUI_HAS_MULTI_SELECT
|
||||
@ -1672,6 +1674,7 @@ struct ImGuiContext
|
||||
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
|
||||
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
|
||||
ImGuiKeyModFlags NavJustMovedToKeyMods;
|
||||
bool NavJustMovedToHasSelectionData; // " (FIXME-NAV: We should maybe just store ImGuiNavMoveResult)
|
||||
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
|
||||
ImGuiActivateFlags NavNextActivateFlags;
|
||||
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
|
||||
@ -1715,10 +1718,9 @@ struct ImGuiContext
|
||||
bool NavWindowingToggleLayer;
|
||||
|
||||
// Range-Select/Multi-Select
|
||||
ImGuiID MultiSelectScopeId;
|
||||
ImGuiWindow* MultiSelectScopeWindow;
|
||||
bool MultiSelectEnabled;
|
||||
ImGuiMultiSelectFlags MultiSelectFlags;
|
||||
ImGuiMultiSelectState MultiSelectState;
|
||||
ImGuiMultiSelectState MultiSelectState; // We currently don't support recursing/stacking multi-select
|
||||
|
||||
// Render
|
||||
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
|
||||
@ -1890,6 +1892,7 @@ struct ImGuiContext
|
||||
NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
|
||||
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
|
||||
NavJustMovedToKeyMods = ImGuiKeyModFlags_None;
|
||||
NavJustMovedToHasSelectionData = false;
|
||||
NavInputSource = ImGuiInputSource_None;
|
||||
NavLayer = ImGuiNavLayer_Main;
|
||||
NavIdIsAlive = false;
|
||||
@ -1915,9 +1918,8 @@ struct ImGuiContext
|
||||
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
|
||||
NavWindowingToggleLayer = false;
|
||||
|
||||
MultiSelectScopeId = 0;
|
||||
MultiSelectScopeWindow = NULL;
|
||||
MultiSelectFlags = 0;
|
||||
MultiSelectEnabled = false;
|
||||
MultiSelectFlags = ImGuiMultiSelectFlags_None;
|
||||
|
||||
DimBgRatio = 0.0f;
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
|
@ -5924,7 +5924,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
const bool was_selected = selected;
|
||||
|
||||
// Multi-selection support (header)
|
||||
const bool is_multi_select = (g.MultiSelectScopeWindow == window);
|
||||
const bool is_multi_select = g.MultiSelectEnabled;
|
||||
if (is_multi_select)
|
||||
{
|
||||
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
@ -6253,7 +6253,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
|
||||
|
||||
// Multi-selection support (header)
|
||||
const bool is_multi_select = (g.MultiSelectScopeWindow == window);
|
||||
const bool is_multi_select = g.MultiSelectEnabled;
|
||||
const bool was_selected = selected;
|
||||
if (is_multi_select)
|
||||
{
|
||||
@ -6369,17 +6369,20 @@ bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags
|
||||
|
||||
ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
|
||||
{
|
||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
||||
ImGuiContext& g = *GImGui;
|
||||
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.MultiSelectState.FocusScopeId == 0);
|
||||
|
||||
// FIXME: BeginFocusScope()
|
||||
ImGuiMultiSelectState* state = &g.MultiSelectState;
|
||||
g.MultiSelectScopeId = window->IDStack.back();
|
||||
g.MultiSelectScopeWindow = window;
|
||||
g.MultiSelectFlags = flags;
|
||||
state->Clear();
|
||||
state->BackupFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
state->FocusScopeId = window->DC.NavFocusScopeIdCurrent = window->IDStack.back();
|
||||
g.MultiSelectEnabled = true;
|
||||
g.MultiSelectFlags = flags;
|
||||
|
||||
if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
|
||||
{
|
||||
@ -6388,7 +6391,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)
|
||||
if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.MultiSelectScopeId)
|
||||
if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == state->FocusScopeId && g.NavJustMovedToHasSelectionData)
|
||||
{
|
||||
if (g.IO.KeyShift)
|
||||
state->InRequestSetRangeNav = true;
|
||||
@ -6411,14 +6414,19 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void*
|
||||
|
||||
ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
||||
{
|
||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiMultiSelectState* state = &g.MultiSelectState;
|
||||
IM_ASSERT(g.MultiSelectScopeId != 0);
|
||||
|
||||
IM_ASSERT(g.MultiSelectState.FocusScopeId != 0);
|
||||
IM_ASSERT(g.MultiSelectState.FocusScopeId == window->DC.NavFocusScopeIdCurrent);
|
||||
|
||||
if (g.MultiSelectFlags & ImGuiMultiSelectFlags_NoUnselect)
|
||||
state->Out.RangeValue = true;
|
||||
g.MultiSelectScopeId = 0;
|
||||
g.MultiSelectScopeWindow = NULL;
|
||||
g.MultiSelectFlags = 0;
|
||||
g.MultiSelectState.FocusScopeId = 0;
|
||||
window->DC.NavFocusScopeIdCurrent = g.MultiSelectState.BackupFocusScopeId;
|
||||
g.MultiSelectEnabled = false;
|
||||
g.MultiSelectFlags = ImGuiMultiSelectFlags_None;
|
||||
|
||||
#ifdef IMGUI_DEBUG_MULTISELECT
|
||||
if (state->Out.RequestClear) printf("[%05d] EndMultiSelect: RequestClear\n", g.FrameCount);
|
||||
@ -6432,17 +6440,24 @@ ImGuiMultiSelectData* ImGui::EndMultiSelect()
|
||||
void ImGui::SetNextItemSelectionData(void* item_data)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.MultiSelectScopeId != 0);
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(window->DC.NavFocusScopeIdCurrent != 0);
|
||||
g.NextItemData.SelectionData = item_data;
|
||||
g.NextItemData.MultiSelectScopeId = g.MultiSelectScopeId;
|
||||
g.NextItemData.FocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
|
||||
// Note that the flag 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.
|
||||
g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasSelectionData;
|
||||
}
|
||||
|
||||
void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiMultiSelectState* state = &g.MultiSelectState;
|
||||
|
||||
IM_ASSERT(g.NextItemData.MultiSelectScopeId == g.MultiSelectScopeId && "Forgot to call SetNextItemSelectionData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
|
||||
IM_UNUSED(window);
|
||||
IM_ASSERT(g.NextItemData.FocusScopeId == window->DC.NavFocusScopeIdCurrent && "Forgot to call SetNextItemSelectionData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
|
||||
void* item_data = g.NextItemData.SelectionData;
|
||||
|
||||
// Apply Clear/SelectAll requests requested by BeginMultiSelect().
|
||||
@ -6483,7 +6498,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
||||
ImGuiMultiSelectState* state = &g.MultiSelectState;
|
||||
|
||||
void* item_data = g.NextItemData.SelectionData;
|
||||
g.NextItemData.MultiSelectScopeId = 0;
|
||||
g.NextItemData.FocusScopeId = 0;
|
||||
|
||||
bool selected = *p_selected;
|
||||
bool pressed = *p_pressed;
|
||||
|
Loading…
Reference in New Issue
Block a user