From e28b1078f55945b815ceeeb1a4dfa785e002815b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 23 Aug 2018 13:21:01 +0200 Subject: [PATCH] Added IsItemEdited() to query if the last item modified its value (or was pressed). This is equivalent to the bool returned by most widgets. It is useful in some situation e.g. using InputText() with ImGuiInputTextFlags_EnterReturnsTrue. (#2034) --- CHANGELOG.txt | 2 ++ imgui.cpp | 12 +++++++++++- imgui.h | 1 + imgui_demo.cpp | 4 +++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4478bcba6..662f065a0 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -54,6 +54,8 @@ Other Changes: - Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909) - Window: Added global io.OptResizeWindowsFromEdges option to enable resizing windows from their edges and from the lower-left corner. (#1495) - Window: Collapse button shows hovering highlight + clicking and dragging on it allows to drag the window as well. + - Added IsItemEdited() to query if the last item modified its value (or was pressed). This is equivalent to the bool returned by most widgets. + It is useful in some situation e.g. using InputText() with ImGuiInputTextFlags_EnterReturnsTrue. (#2034) - InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008). - InputText: Fixed not tracking the cursor horizontally When modifying the text buffer through a callback. - InputText: Fixed minor off-by-one issue when submitting a buffer size smaller than the initial zero-terminated buffer contents. diff --git a/imgui.cpp b/imgui.cpp index 1e36dc839..8eeb9e0fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5246,6 +5246,12 @@ bool ImGui::IsItemVisible() return window->ClipRect.Overlaps(window->DC.LastItemRect); } +bool ImGui::IsItemEdited() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_ValueChanged) != 0; +} + // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. void ImGui::SetItemAllowOverlap() { @@ -11954,6 +11960,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v return false; // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. + ImGuiContext& g = *GImGui; bool value_changed = false; ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. while (clipper.Step()) @@ -11975,6 +11982,9 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v PopID(); } ListBoxFooter(); + if (value_changed) + MarkItemValueChanged(g.CurrentWindow->DC.LastItemId); + return value_changed; } @@ -13268,7 +13278,7 @@ void ImGui::EndGroup() } // 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. + // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would 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.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId) // && g.ActiveIdWindow->RootWindow == window->RootWindow) window->DC.LastItemId = g.ActiveId; diff --git a/imgui.h b/imgui.h index 78ebc51b6..678024b41 100644 --- a/imgui.h +++ b/imgui.h @@ -521,6 +521,7 @@ namespace ImGui 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(mouse_button) && IsItemHovered() IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling) + IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets. IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing. IMGUI_API bool IsItemDeactivatedAfterChange(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). IMGUI_API bool IsAnyItemHovered(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 35754e00b..b05f27209 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1275,7 +1275,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Active, Focused, Hovered & Focused Tests")) + if (ImGui::TreeNode("Active, Focused and Hovered Tests")) { // Display the value of IsItemHovered() and other common item state functions. Note that the flags can be combined. // (because BulletText is an item itself and that would affect the output of IsItemHovered() we pass all state in a single call to simplify the code). @@ -1304,6 +1304,7 @@ void ImGui::ShowDemoWindow(bool* p_open) "IsItemHovered(_AllowWhenOverlapped) = %d\n" "IsItemHovered(_RectOnly) = %d\n" "IsItemActive() = %d\n" + "IsItemEdited() = %d\n" "IsItemDeactivated() = %d\n" "IsItemDeactivatedAfterChange() = %d\n" "IsItemVisible() = %d\n", @@ -1315,6 +1316,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly), ImGui::IsItemActive(), + ImGui::IsItemEdited(), ImGui::IsItemDeactivated(), ImGui::IsItemDeactivatedAfterChange(), ImGui::IsItemVisible()