Internals: track WasSelected/WasSoleSelected data for ActiveId. (#8337)

This commit is contained in:
ocornut
2026-07-01 14:42:23 +02:00
parent e408733ecc
commit 0edad6d097
3 changed files with 18 additions and 0 deletions

View File

@@ -4234,6 +4234,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
ActiveIdIsAlive = 0;
ActiveIdTimer = 0.0f;
ActiveIdIsJustActivated = false;
ActiveIdWasSelected = ActiveIdWasSoleSelected = false;
ActiveIdAllowOverlap = false;
ActiveIdNoClearOnFocusLoss = false;
ActiveIdHasBeenPressedBefore = false;
@@ -4250,6 +4251,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
memset(&ActiveIdValueOnActivation, 0, sizeof(ActiveIdValueOnActivation));
LastActiveId = 0;
LastActiveIdTimer = 0.0f;
LastActiveIdWasSelected = LastActiveIdWasSoleSelected = false;
LastKeyboardKeyPressTime = LastKeyModsChangeTime = LastKeyModsChangeFromNoneTime = -1.0;
@@ -5629,6 +5631,11 @@ void ImGui::NewFrame()
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
if (g.ActiveId)
g.ActiveIdTimer += g.IO.DeltaTime;
if (g.ActiveId && g.ActiveId == g.LastActiveId)
{
g.LastActiveIdWasSelected = g.ActiveIdWasSelected;
g.LastActiveIdWasSoleSelected = g.ActiveIdWasSoleSelected;
}
g.LastActiveIdTimer += g.IO.DeltaTime;
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = 0;

View File

@@ -1940,6 +1940,7 @@ struct IMGUI_API ImGuiMultiSelectTempData
bool NavIdPassedBy;
bool RangeSrcPassedBy; // Set by the item that matches RangeSrcItem.
bool RangeDstPassedBy; // Set by the item that matches NavJustMovedToId when IsSetRange is set.
bool IsSoleOrUnknownSelectionSize;
ImGuiMultiSelectTempData() { Clear(); }
void Clear() { size_t io_sz = sizeof(IO); ClearIO(); memset((void*)(&IO + 1), 0, sizeof(*this) - io_sz); } // Zero-clear except IO as we preserve IO.Requests[] buffer allocation.
@@ -2281,6 +2282,8 @@ struct ImGuiContext
ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame)
float ActiveIdTimer;
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdWasSelected; // Active ID was selected at the time of activating
bool ActiveIdWasSoleSelected; // Active ID was sole selection at the time of activating
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused.
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
@@ -2297,6 +2300,8 @@ struct ImGuiContext
ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX.
ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
bool LastActiveIdWasSelected;
bool LastActiveIdWasSoleSelected;
// Key/Input Ownership + Shortcut Routing system
// - The idea is that instead of "eating" a given key, we can link to an owner.

View File

@@ -7489,6 +7489,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (selected != was_selected)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
if (g.ActiveId == id && g.ActiveIdIsJustActivated)
{
g.ActiveIdWasSelected = was_selected;
g.ActiveIdWasSoleSelected = was_selected && (!is_multi_select || g.CurrentMultiSelect->IsSoleOrUnknownSelectionSize);
}
// Render
if (is_visible)
@@ -8116,6 +8121,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel
storage->LastSelectionSize = 0;
}
ms->LoopRequestSetAll = request_select_all ? 1 : request_clear ? 0 : -1;
ms->IsSoleOrUnknownSelectionSize = (storage->LastSelectionSize == 1) || (storage->LastSelectionSize == -1);
//ms->PrevSubmittedItem = ImGuiSelectionUserData_Invalid;
if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)