fix imgui id conflicts (#6764)

ImGui derives a control's ID from its visible label, and the menu search
page renders every widget in a single scope. Randomizer options that share
a label with an enhancement (e.g. "Blue Fire Arrows") therefore produced an
ID conflict on the search page.

Append a "##Randomizer" suffix to randomizer widget labels so their ImGui ID
is unique. The option's own name is left untouched since it is used as a
serialization key (spoiler logs, settings lookup); only the menu widget gets
the suffix.

SliderInt/SliderFloat draw their label themselves via ImGui::Text/CalcTextSize,
which (unlike ImGui's labeled widgets) don't strip a "##" suffix, so add a
visibleLabel with the suffix chopped off for display while keeping the full
label for the unique ID.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
briaguya
2026-06-17 22:52:58 -04:00
committed by GitHub
parent e93ea5b919
commit 7925f27bff
2 changed files with 17 additions and 13 deletions
+1 -1
View File
@@ -309,7 +309,7 @@ bool Option::RenderSlider() {
}
void Option::AddWidget(WidgetPath& path) {
auto widget = SohGui::mSohMenu->AddWidget(path, name, widgetType)
auto widget = SohGui::mSohMenu->AddWidget(path, name + "##Randomizer", widgetType)
.Callback(callback)
.PreFunc([this](WidgetInfo& info) {
info.isHidden = this->IsHidden();
+16 -12
View File
@@ -516,6 +516,8 @@ void PopStyleSlider() {
bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options) {
bool dirty = false;
std::string visibleLabelStr = std::string(label).substr(0, std::string(label).find("#"));
const char* visibleLabel = visibleLabelStr.c_str();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
@@ -524,11 +526,11 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option
PushStyleSlider(options.color);
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.labelPosition == LabelPositions::Near || options.labelPosition == LabelPositions::Far) {
width = width - (ImGui::CalcTextSize(label).x + ImGui::GetStyle().FramePadding.x);
width = width - (ImGui::CalcTextSize(visibleLabel).x + ImGui::GetStyle().FramePadding.x);
}
ImGui::AlignTextToFramePadding();
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
@@ -539,7 +541,7 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option
}
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
}
}
if (options.showButtons) {
@@ -584,11 +586,11 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x +
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(visibleLabel).x +
ImGui::GetStyle().ItemSpacing.x);
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
}
}
PopStyleSlider();
@@ -648,6 +650,8 @@ void ClampFloat(float* value, float min, float max, float step) {
bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options) {
bool dirty = false;
std::string visibleLabelStr = std::string(label).substr(0, std::string(label).find("#"));
const char* visibleLabel = visibleLabelStr.c_str();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
float valueToDisplay = options.isPercentage ? *value * 100.0f : *value;
@@ -657,14 +661,14 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleSlider(options.color);
float labelSpacing = ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x;
float labelSpacing = ImGui::CalcTextSize(visibleLabel).x + ImGui::GetStyle().ItemSpacing.x;
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.labelPosition == LabelPositions::Near || options.labelPosition == LabelPositions::Far) {
width = width - (ImGui::CalcTextSize(label).x + ImGui::GetStyle().FramePadding.x);
width = width - (ImGui::CalcTextSize(visibleLabel).x + ImGui::GetStyle().FramePadding.x);
}
ImGui::AlignTextToFramePadding();
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
@@ -677,7 +681,7 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti
}
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
}
}
if (options.showButtons) {
@@ -716,10 +720,10 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - labelSpacing);
ImGui::Text(label, *value);
ImGui::Text(visibleLabel, *value);
}
}
PopStyleSlider();