diff --git a/imgui.cpp b/imgui.cpp index 0c2e72a59..1c101e0f4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1883,6 +1883,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; g.ActiveIdIsJustActivated = (g.ActiveId != id); + if (g.ActiveIdIsJustActivated) + g.ActiveIdTimer = 0.0f; g.ActiveId = id; g.ActiveIdAllowOverlap = false; g.ActiveIdIsAlive |= (id != 0); @@ -1899,6 +1901,7 @@ void ImGui::SetHoveredID(ImGuiID id) ImGuiContext& g = *GImGui; g.HoveredId = id; g.HoveredIdAllowOverlap = false; + g.HoveredIdTimer = (id != 0 && g.HoveredIdPreviousFrame == id) ? (g.HoveredIdTimer + g.IO.DeltaTime) : 0.0f; } void ImGui::KeepAliveID(ImGuiID id) @@ -2220,11 +2223,15 @@ void ImGui::NewFrame() g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; // Clear reference to active widget if the widget isn't alive anymore + if (!g.HoveredIdPreviousFrame) + g.HoveredIdTimer = 0.0f; g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) ClearActiveID(); + if (g.ActiveId) + g.ActiveIdTimer += g.IO.DeltaTime; g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; @@ -10820,8 +10827,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) { ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); - ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not - ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); + ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not + ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec)", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::TreePop(); diff --git a/imgui_internal.h b/imgui_internal.h index 1cb723ca7..ccfc3bf47 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -429,8 +429,10 @@ struct ImGuiContext ImGuiID HoveredId; // Hovered widget bool HoveredIdAllowOverlap; ImGuiID HoveredIdPreviousFrame; + float HoveredIdTimer; ImGuiID ActiveId; // Active widget ImGuiID ActiveIdPreviousFrame; + float ActiveIdTimer; bool ActiveIdIsAlive; // Active widget has been seen this frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) @@ -521,8 +523,10 @@ struct ImGuiContext HoveredId = 0; HoveredIdAllowOverlap = false; HoveredIdPreviousFrame = 0; + HoveredIdTimer = 0.0f; ActiveId = 0; ActiveIdPreviousFrame = 0; + ActiveIdTimer = 0.0f; ActiveIdIsAlive = false; ActiveIdIsJustActivated = false; ActiveIdAllowOverlap = false;