From 90bf996e1a0abc1e798c175d403706464230c874 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 19 Jul 2021 21:17:34 +0200 Subject: [PATCH] Internals: widgets always read back from g.LastItemData.InFlags (so we can now modify per-item disable state more easily). (#211) --- imgui.cpp | 5 +++-- imgui_internal.h | 6 +++--- imgui_widgets.cpp | 14 +++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7d1521fe..5d3f92b2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3232,7 +3232,8 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) SetHoveredID(id); // When disabled we'll return false but still set HoveredId - if (g.CurrentItemFlags & ImGuiItemFlags_Disabled) + ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); + if (item_flags & ImGuiItemFlags_Disabled) { // Release active id if turning disabled if (g.ActiveId == id) @@ -3277,7 +3278,7 @@ void ImGui::ItemFocusable(ImGuiWindow* window, ImGuiID id) // Increment counters // FIXME: ImGuiItemFlags_Disabled should disable more. - const bool is_tab_stop = (g.CurrentItemFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; + const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; window->DC.FocusCounterRegular++; if (is_tab_stop) { diff --git a/imgui_internal.h b/imgui_internal.h index d6bc20f0..68ae41a4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1176,8 +1176,8 @@ struct ImGuiNextItemData struct ImGuiLastItemData { ImGuiID ID; - ImGuiItemFlags InFlags; - ImGuiItemStatusFlags StatusFlags; + ImGuiItemFlags InFlags; // See ImGuiItemFlags_ + ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ ImRect Rect; ImRect DisplayRect; @@ -1479,7 +1479,7 @@ struct ImGuiContext float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. // Next window/item data - ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() + ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd) ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 50d384bd..acb54f9e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -680,7 +680,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags if (!ItemAdd(bb, id)) return false; - if (g.CurrentItemFlags & ImGuiItemFlags_ButtonRepeat) + if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; bool hovered, held; @@ -757,7 +757,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu if (!ItemAdd(bb, id)) return false; - if (g.CurrentItemFlags & ImGuiItemFlags_ButtonRepeat) + if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; bool hovered, held; @@ -1092,7 +1092,7 @@ bool ImGui::Checkbox(const char* label, bool* v) RenderNavHighlight(total_bb, id); RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); - bool mixed_value = (g.CurrentItemFlags & ImGuiItemFlags_MixedValue) != 0; + bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; if (mixed_value) { // Undocumented tristate/mixed/indeterminate checkbox (#2644) @@ -2345,7 +2345,7 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v } if (g.ActiveId != id) return false; - if ((g.CurrentItemFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) + if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) return false; switch (data_type) @@ -2949,7 +2949,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); ImGuiContext& g = *GImGui; - if ((g.CurrentItemFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) + if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) return false; switch (data_type) @@ -6157,7 +6157,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl return false; const bool disabled_global = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; - if (disabled_item && !disabled_global) + if (disabled_item && !disabled_global) // Only testing this as an optimization PushDisabled(true); // FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only, @@ -6227,7 +6227,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb); // Automatically close popups - if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) + if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.LastItemData.InFlags & ImGuiItemFlags_SelectableDontClosePopup)) CloseCurrentPopup(); if (disabled_item && !disabled_global)