mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Added IsItemDeactivated() to query if the last item was active previously but isn't anymore. Useful for Undo/Redo patterns. (#820, #956, #1875)
This commit is contained in:
parent
c725710c6d
commit
cd455a4600
@ -63,6 +63,7 @@ Other Changes:
|
|||||||
- Each example still has its own main.cpp which you may refer you to understand how to initialize and glue everything together.
|
- Each example still has its own main.cpp which you may refer you to understand how to initialize and glue everything together.
|
||||||
- Some frameworks (such as the Allegro, Marmalade) handle both the "platform" and "rendering" part, and your custom engine may as well.
|
- Some frameworks (such as the Allegro, Marmalade) handle both the "platform" and "rendering" part, and your custom engine may as well.
|
||||||
- Read examples/README.txt for details.
|
- Read examples/README.txt for details.
|
||||||
|
- Added IsItemDeactivated() to query if the last item was active previously but isn't anymore. Useful for Undo/Redo patterns. (#820, #956, #1875)
|
||||||
- Nav: Added support for PageUp/PageDown (explorer-style: first aim at bottom/top most item, when scroll a page worth of contents). (#787)
|
- Nav: Added support for PageUp/PageDown (explorer-style: first aim at bottom/top most item, when scroll a page worth of contents). (#787)
|
||||||
- Nav: To keep the navigated item in view we also attempt to scroll the parent window as well as the current window. (#787)
|
- Nav: To keep the navigated item in view we also attempt to scroll the parent window as well as the current window. (#787)
|
||||||
- TreeNode: Fixed nodes with ImGuiTreeNodeFlags_Leaf flag always returning true which was meaningless.
|
- TreeNode: Fixed nodes with ImGuiTreeNodeFlags_Leaf flag always returning true which was meaningless.
|
||||||
|
25
imgui.cpp
25
imgui.cpp
@ -2251,6 +2251,8 @@ void ImGui::KeepAliveID(ImGuiID id)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.ActiveId == id)
|
if (g.ActiveId == id)
|
||||||
g.ActiveIdIsAlive = true;
|
g.ActiveIdIsAlive = true;
|
||||||
|
if (g.ActiveIdPreviousFrame == id)
|
||||||
|
g.ActiveIdPreviousFrameIsAlive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
|
static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
|
||||||
@ -3719,7 +3721,8 @@ void ImGui::NewFrame()
|
|||||||
g.ActiveIdTimer += g.IO.DeltaTime;
|
g.ActiveIdTimer += g.IO.DeltaTime;
|
||||||
g.LastActiveIdTimer += g.IO.DeltaTime;
|
g.LastActiveIdTimer += g.IO.DeltaTime;
|
||||||
g.ActiveIdPreviousFrame = g.ActiveId;
|
g.ActiveIdPreviousFrame = g.ActiveId;
|
||||||
g.ActiveIdIsAlive = false;
|
g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow;
|
||||||
|
g.ActiveIdIsAlive = g.ActiveIdPreviousFrameIsAlive = false;
|
||||||
g.ActiveIdIsJustActivated = false;
|
g.ActiveIdIsJustActivated = false;
|
||||||
if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId)
|
if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId)
|
||||||
g.ScalarAsInputTextId = 0;
|
g.ScalarAsInputTextId = 0;
|
||||||
@ -3940,7 +3943,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|||||||
g.NavWindow = NULL;
|
g.NavWindow = NULL;
|
||||||
g.HoveredWindow = NULL;
|
g.HoveredWindow = NULL;
|
||||||
g.HoveredRootWindow = NULL;
|
g.HoveredRootWindow = NULL;
|
||||||
g.ActiveIdWindow = NULL;
|
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
||||||
g.MovingWindow = NULL;
|
g.MovingWindow = NULL;
|
||||||
g.ColorModifiers.clear();
|
g.ColorModifiers.clear();
|
||||||
g.StyleModifiers.clear();
|
g.StyleModifiers.clear();
|
||||||
@ -4978,6 +4981,13 @@ bool ImGui::IsItemActive()
|
|||||||
return false;
|
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()
|
bool ImGui::IsItemFocused()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -12804,6 +12814,7 @@ void ImGui::BeginGroup()
|
|||||||
group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset;
|
group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset;
|
||||||
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
|
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
|
||||||
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
||||||
|
group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
|
||||||
group_data.AdvanceCursor = true;
|
group_data.AdvanceCursor = true;
|
||||||
|
|
||||||
window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX;
|
window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX;
|
||||||
@ -12839,11 +12850,13 @@ void ImGui::EndGroup()
|
|||||||
ItemAdd(group_bb, 0);
|
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.
|
// 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 if you search for LastItemId you'll notice it is only used in that context.
|
// 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.
|
||||||
const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow);
|
// (and if you grep for LastItemId you'll notice it is only used in that context.
|
||||||
if (active_id_within_group)
|
if (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId) // && g.ActiveIdWindow->RootWindow == window->RootWindow)
|
||||||
window->DC.LastItemId = g.ActiveId;
|
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.LastItemRect = group_bb;
|
||||||
|
|
||||||
window->DC.GroupStack.pop_back();
|
window->DC.GroupStack.pop_back();
|
||||||
|
1
imgui.h
1
imgui.h
@ -504,6 +504,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?
|
IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?
|
||||||
IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) == IsMouseClicked(0) && IsItemHovered()
|
IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) == IsMouseClicked(0) && IsItemHovered()
|
||||||
IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.)
|
IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.)
|
||||||
|
IMGUI_API bool IsItemDeactivated(); // is the last item just made inactive (item was previously active), useful for Undo/Redo patterns.
|
||||||
IMGUI_API bool IsAnyItemHovered();
|
IMGUI_API bool IsAnyItemHovered();
|
||||||
IMGUI_API bool IsAnyItemActive();
|
IMGUI_API bool IsAnyItemActive();
|
||||||
IMGUI_API bool IsAnyItemFocused();
|
IMGUI_API bool IsAnyItemFocused();
|
||||||
|
@ -2028,7 +2028,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TreeNode("Focused & Hovered Test"))
|
if (ImGui::TreeNode("Active, Focused & Hovered Test"))
|
||||||
{
|
{
|
||||||
static bool embed_all_inside_a_child_window = false;
|
static bool embed_all_inside_a_child_window = false;
|
||||||
ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window);
|
ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window);
|
||||||
@ -2068,16 +2068,22 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
|||||||
// Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code)
|
// Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code)
|
||||||
ImGui::Button("ITEM");
|
ImGui::Button("ITEM");
|
||||||
ImGui::BulletText(
|
ImGui::BulletText(
|
||||||
|
"IsItemFocused() = %d\n"
|
||||||
"IsItemHovered() = %d\n"
|
"IsItemHovered() = %d\n"
|
||||||
"IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
|
"IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
|
||||||
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
|
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
|
||||||
"IsItemHovered(_AllowWhenOverlapped) = %d\n"
|
"IsItemHovered(_AllowWhenOverlapped) = %d\n"
|
||||||
"IsItemhovered(_RectOnly) = %d\n",
|
"IsItemHovered(_RectOnly) = %d\n"
|
||||||
|
"IsItemActive() = %d\n"
|
||||||
|
"IsItemDeactivated() = %d\n",
|
||||||
|
ImGui::IsItemFocused(),
|
||||||
ImGui::IsItemHovered(),
|
ImGui::IsItemHovered(),
|
||||||
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
|
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
|
||||||
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
|
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
|
||||||
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
|
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
|
||||||
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly));
|
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
|
||||||
|
ImGui::IsItemActive(),
|
||||||
|
ImGui::IsItemDeactivated());
|
||||||
|
|
||||||
ImGui::BeginChild("child", ImVec2(0,50), true);
|
ImGui::BeginChild("child", ImVec2(0,50), true);
|
||||||
ImGui::Text("This is another child window for testing IsWindowHovered() flags.");
|
ImGui::Text("This is another child window for testing IsWindowHovered() flags.");
|
||||||
|
@ -394,6 +394,7 @@ struct ImGuiGroupData
|
|||||||
float BackupCurrentLineTextBaseOffset;
|
float BackupCurrentLineTextBaseOffset;
|
||||||
float BackupLogLinePosY;
|
float BackupLogLinePosY;
|
||||||
bool BackupActiveIdIsAlive;
|
bool BackupActiveIdIsAlive;
|
||||||
|
bool BackupActiveIdPreviousFrameIsAlive;
|
||||||
bool AdvanceCursor;
|
bool AdvanceCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -624,9 +625,11 @@ struct ImGuiContext
|
|||||||
bool ActiveIdIsAlive; // Active widget has been seen this frame
|
bool ActiveIdIsAlive; // Active widget has been seen this frame
|
||||||
bool ActiveIdIsJustActivated; // Set at the time of activation for one 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)
|
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
|
||||||
|
bool ActiveIdPreviousFrameIsAlive;
|
||||||
int ActiveIdAllowNavDirFlags; // Active widget allows using directional navigation (e.g. can activate a button and move away from it)
|
int ActiveIdAllowNavDirFlags; // Active widget allows using directional navigation (e.g. can activate a button and move away from it)
|
||||||
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
|
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
|
||||||
ImGuiWindow* ActiveIdWindow;
|
ImGuiWindow* ActiveIdWindow;
|
||||||
|
ImGuiWindow* ActiveIdPreviousFrameWindow;
|
||||||
ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard)
|
ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard)
|
||||||
ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
|
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.
|
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
|
||||||
@ -762,9 +765,10 @@ struct ImGuiContext
|
|||||||
ActiveIdIsAlive = false;
|
ActiveIdIsAlive = false;
|
||||||
ActiveIdIsJustActivated = false;
|
ActiveIdIsJustActivated = false;
|
||||||
ActiveIdAllowOverlap = false;
|
ActiveIdAllowOverlap = false;
|
||||||
|
ActiveIdPreviousFrameIsAlive = false;
|
||||||
ActiveIdAllowNavDirFlags = 0;
|
ActiveIdAllowNavDirFlags = 0;
|
||||||
ActiveIdClickOffset = ImVec2(-1,-1);
|
ActiveIdClickOffset = ImVec2(-1,-1);
|
||||||
ActiveIdWindow = NULL;
|
ActiveIdWindow = ActiveIdPreviousFrameWindow = NULL;
|
||||||
ActiveIdSource = ImGuiInputSource_None;
|
ActiveIdSource = ImGuiInputSource_None;
|
||||||
LastActiveId = 0;
|
LastActiveId = 0;
|
||||||
LastActiveIdTimer = 0.0f;
|
LastActiveIdTimer = 0.0f;
|
||||||
|
Loading…
Reference in New Issue
Block a user