|
@@ -2251,6 +2251,8 @@ void ImGui::KeepAliveID(ImGuiID id)
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
if (g.ActiveId == id)
|
|
|
g.ActiveIdIsAlive = true;
|
|
|
+ if (g.ActiveIdPreviousFrame == id)
|
|
|
+ g.ActiveIdPreviousFrameIsAlive = true;
|
|
|
}
|
|
|
|
|
|
static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
|
|
@@ -3719,7 +3721,8 @@ void ImGui::NewFrame()
|
|
|
g.ActiveIdTimer += g.IO.DeltaTime;
|
|
|
g.LastActiveIdTimer += g.IO.DeltaTime;
|
|
|
g.ActiveIdPreviousFrame = g.ActiveId;
|
|
|
- g.ActiveIdIsAlive = false;
|
|
|
+ g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow;
|
|
|
+ g.ActiveIdIsAlive = g.ActiveIdPreviousFrameIsAlive = false;
|
|
|
g.ActiveIdIsJustActivated = false;
|
|
|
if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId)
|
|
|
g.ScalarAsInputTextId = 0;
|
|
@@ -3940,7 +3943,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|
|
g.NavWindow = NULL;
|
|
|
g.HoveredWindow = NULL;
|
|
|
g.HoveredRootWindow = NULL;
|
|
|
- g.ActiveIdWindow = NULL;
|
|
|
+ g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
|
|
g.MovingWindow = NULL;
|
|
|
g.ColorModifiers.clear();
|
|
|
g.StyleModifiers.clear();
|
|
@@ -4978,6 +4981,13 @@ bool ImGui::IsItemActive()
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+bool ImGui::IsItemDeactivated()
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+ return (g.ActiveIdPreviousFrame == window->DC.LastItemId && g.ActiveIdPreviousFrame != 0 && g.ActiveId != window->DC.LastItemId);
|
|
|
+}
|
|
|
+
|
|
|
bool ImGui::IsItemFocused()
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -12804,6 +12814,7 @@ void ImGui::BeginGroup()
|
|
|
group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset;
|
|
|
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
|
|
|
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
|
|
+ group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
|
|
|
group_data.AdvanceCursor = true;
|
|
|
|
|
|
window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX;
|
|
@@ -12839,11 +12850,13 @@ void ImGui::EndGroup()
|
|
|
ItemAdd(group_bb, 0);
|
|
|
}
|
|
|
|
|
|
- // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will be functional on the entire group.
|
|
|
- // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but if you search for LastItemId you'll notice it is only used in that context.
|
|
|
- const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow);
|
|
|
- if (active_id_within_group)
|
|
|
+ // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group.
|
|
|
+ // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but put a little more burden on individual widgets.
|
|
|
+ // (and if you grep for LastItemId you'll notice it is only used in that context.
|
|
|
+ if (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId) // && g.ActiveIdWindow->RootWindow == window->RootWindow)
|
|
|
window->DC.LastItemId = g.ActiveId;
|
|
|
+ else if (!group_data.BackupActiveIdPreviousFrameIsAlive && g.ActiveIdPreviousFrameIsAlive) // && g.ActiveIdPreviousFrameWindow->RootWindow == window->RootWindow)
|
|
|
+ window->DC.LastItemId = g.ActiveIdPreviousFrame;
|
|
|
window->DC.LastItemRect = group_bb;
|
|
|
|
|
|
window->DC.GroupStack.pop_back();
|