Skip to content

Commit ea95177

Browse files
committed
[Bundle] add GetID_AssertUnique: warns if the ID was already used in common widgets
Applies to ButtonEx, ArrowButtonEx, Checkbox, RadioButton , DragScalar, SliderScalar, Drag, InputTextEx
1 parent 8b45d6b commit ea95177

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

imgui.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8857,6 +8857,28 @@ ImGuiID ImGuiWindow::GetID(int n)
88578857
return id;
88588858
}
88598859

8860+
// Addition to ImGui Bundle: a version of GetID that warns if the ID was already used
8861+
IMGUI_API ImGuiID ImGuiWindow::GetID_AssertUnique(const char* str_id)
8862+
{
8863+
static ImVector<ImGuiID> sIdsThisFrame;
8864+
static int sLastFrame = -1;
8865+
int currentFrame = ImGui::GetFrameCount();
8866+
8867+
if (currentFrame != sLastFrame)
8868+
sIdsThisFrame.clear();
8869+
8870+
ImGuiID r = GetID(str_id);
8871+
if (sIdsThisFrame.contains(r))
8872+
IM_ASSERT(false && "Either your widgets names/ids must be distinct, or you shall call ImGui::PushID before reusing an id");
8873+
8874+
sIdsThisFrame.push_back(r);
8875+
sLastFrame = currentFrame;
8876+
8877+
return r;
8878+
}
8879+
8880+
8881+
88608882
// This is only used in rare/specific situations to manufacture an ID out of nowhere.
88618883
ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
88628884
{

imgui_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,6 +2883,10 @@ struct IMGUI_API ImGuiWindow
28832883
ImGuiID GetID(const char* str, const char* str_end = NULL);
28842884
ImGuiID GetID(const void* ptr);
28852885
ImGuiID GetID(int n);
2886+
2887+
// Addition to ImGui Bundle: a version of GetID that warns if the ID was already used
2888+
IMGUI_API ImGuiID GetID_AssertUnique(const char* str_id); // (Specific to ImGui Bundle) Calculate unique ID (hash of whole ID stack + given parameter). Will warn if the ID was already used, and advise to call ImGui::PushID() before
2889+
28862890
ImGuiID GetIDFromRectangle(const ImRect& r_abs);
28872891

28882892
// We don't use g.FontSize because the window may be != g.CurrentWindow.

imgui_widgets.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
701701

702702
ImGuiContext& g = *GImGui;
703703
const ImGuiStyle& style = g.Style;
704-
const ImGuiID id = window->GetID(label);
704+
const ImGuiID id = window->GetID_AssertUnique(label);
705705
const ImVec2 label_size = CalcTextSize(label, NULL, true);
706706

707707
ImVec2 pos = window->DC.CursorPos;
@@ -783,7 +783,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu
783783
if (window->SkipItems)
784784
return false;
785785

786-
const ImGuiID id = window->GetID(str_id);
786+
const ImGuiID id = window->GetID_AssertUnique(str_id);
787787
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
788788
const float default_size = GetFrameHeight();
789789
ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f);
@@ -1121,7 +1121,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
11211121

11221122
ImGuiContext& g = *GImGui;
11231123
const ImGuiStyle& style = g.Style;
1124-
const ImGuiID id = window->GetID(label);
1124+
const ImGuiID id = window->GetID_AssertUnique(label);
11251125
const ImVec2 label_size = CalcTextSize(label, NULL, true);
11261126

11271127
const float square_sz = GetFrameHeight();
@@ -1225,7 +1225,7 @@ bool ImGui::RadioButton(const char* label, bool active)
12251225

12261226
ImGuiContext& g = *GImGui;
12271227
const ImGuiStyle& style = g.Style;
1228-
const ImGuiID id = window->GetID(label);
1228+
const ImGuiID id = window->GetID_AssertUnique(label);
12291229
const ImVec2 label_size = CalcTextSize(label, NULL, true);
12301230

12311231
const float square_sz = GetFrameHeight();
@@ -2453,7 +2453,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
24532453

24542454
ImGuiContext& g = *GImGui;
24552455
const ImGuiStyle& style = g.Style;
2456-
const ImGuiID id = window->GetID(label);
2456+
const ImGuiID id = window->GetID_AssertUnique(label);
24572457
const float w = CalcItemWidth();
24582458

24592459
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -3044,7 +3044,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
30443044

30453045
ImGuiContext& g = *GImGui;
30463046
const ImGuiStyle& style = g.Style;
3047-
const ImGuiID id = window->GetID(label);
3047+
const ImGuiID id = window->GetID_AssertUnique(label);
30483048
const float w = CalcItemWidth();
30493049

30503050
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -4134,7 +4134,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
41344134

41354135
if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar)
41364136
BeginGroup();
4137-
const ImGuiID id = window->GetID(label);
4137+
const ImGuiID id = window->GetID_AssertUnique(label);
41384138
const ImVec2 label_size = CalcTextSize(label, NULL, true);
41394139
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
41404140
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);

0 commit comments

Comments
 (0)