overlay: address small polish issues (#543)

* Make a custom widget for truncated text that shows a tooltip only when
truncated
* Use the above widget more consistently in various places
* Ensure tooltips still show even when the preceding widget is disabled
This commit is contained in:
bicarus
2026-01-30 19:17:44 -08:00
committed by GitHub
parent 3ad88ef15c
commit 875a0f0765
4 changed files with 45 additions and 60 deletions
+14 -2
View File
@@ -93,14 +93,14 @@ namespace ImGui {
thickness); thickness);
} }
std::string TruncateText(const std::string& p_text, float p_truncated_width, bool &truncated) {
std::string TruncateText(const std::string& p_text, float p_truncated_width) {
std::string truncated_text = p_text; std::string truncated_text = p_text;
const float text_width = const float text_width =
ImGui::CalcTextSize(p_text.c_str(), nullptr, true).x; ImGui::CalcTextSize(p_text.c_str(), nullptr, true).x;
if (text_width > p_truncated_width) { if (text_width > p_truncated_width) {
truncated = true;
constexpr const char* ELLIPSIS = " ..."; constexpr const char* ELLIPSIS = " ...";
const float ellipsis_size = ImGui::CalcTextSize(ELLIPSIS).x; const float ellipsis_size = ImGui::CalcTextSize(ELLIPSIS).x;
@@ -122,6 +122,18 @@ namespace ImGui {
return truncated_text; return truncated_text;
} }
void TextTruncated(const std::string& p_text, float p_truncated_width) {
if (p_text.empty()) {
ImGui::TextDisabled("-");
return;
}
bool truncated = false;
ImGui::TextUnformatted(TruncateText(p_text, p_truncated_width, truncated).c_str());
if (truncated && ImGui::IsItemHovered()) {
ImGui::HelpTooltip(p_text.c_str());
}
}
bool AddButton(const std::string& tooltip) { bool AddButton(const std::string& tooltip) {
ImGui::PushID(tooltip.c_str()); ImGui::PushID(tooltip.c_str());
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.6f, 0.1f, 0.3f)); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.6f, 0.1f, 0.3f));
+1 -1
View File
@@ -13,7 +13,7 @@ namespace ImGui {
void Knob(float fraction, float size, float thickness = 2.f, void Knob(float fraction, float size, float thickness = 2.f,
float pos_x = -1.f, float pos_y = -1.f); float pos_x = -1.f, float pos_y = -1.f);
std::string TruncateText(const std::string& p_text, float p_truncated_width); void TextTruncated(const std::string& p_text, float p_truncated_width);
bool AddButton(const std::string& tooltip); bool AddButton(const std::string& tooltip);
bool DeleteButton(const std::string& tooltip); bool DeleteButton(const std::string& tooltip);
bool ClearButton(const std::string& tooltip); bool ClearButton(const std::string& tooltip);
+25 -52
View File
@@ -294,8 +294,9 @@ namespace overlay::windows {
buttons_many_index = -1; buttons_many_index = -1;
buttons_many_delay = 0; buttons_many_delay = 0;
} }
ImGui::SameLine(); if (ImGui::IsItemHovered()) {
ImGui::HelpMarker("Immediately query for the next button after binding one."); ImGui::HelpTooltip("Immediately query for the next button after binding one.");
}
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
@@ -641,7 +642,7 @@ namespace overlay::windows {
if (button_state) { if (button_state) {
ImGui::PushStyleColor(ImGuiCol_Text, TEXT_COLOR_GREEN); ImGui::PushStyleColor(ImGuiCol_Text, TEXT_COLOR_GREEN);
} }
ImGui::TextUnformatted(button_name.c_str()); ImGui::TextTruncated(button_name, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
if (button_state) { if (button_state) {
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
@@ -650,23 +651,13 @@ namespace overlay::windows {
// column for key binding display // column for key binding display
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
if (button_display.size() > 0) { if (button_state) {
if (button_state) { ImGui::PushStyleColor(ImGuiCol_Text, TEXT_COLOR_GREEN);
ImGui::PushStyleColor(ImGuiCol_Text, TEXT_COLOR_GREEN); }
} ImGui::TextTruncated(
std::string button_text = ImGui::TruncateText( button_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
button_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20)); if (button_state) {
ImGui::TextUnformatted(button_text.c_str()); ImGui::PopStyleColor();
if (button_state) {
ImGui::PopStyleColor();
}
if (ImGui::IsItemHovered()) {
ImGui::SameLine();
ImGui::HelpTooltip(button_display.c_str());
}
} else {
// placeholder
ImGui::TextDisabled("-");
} }
// clear button // clear button
@@ -1759,21 +1750,13 @@ namespace overlay::windows {
if (analog_display.empty()) { if (analog_display.empty()) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 0.7f, 0.7f, 1.f)); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 0.7f, 0.7f, 1.f));
} }
ImGui::TextUnformatted(analog_name.c_str()); ImGui::TextTruncated(
analog_name, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
if (analog_display.size() > 0) { ImGui::TextTruncated(
std::string analog_text = ImGui::TruncateText( analog_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
analog_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
ImGui::TextUnformatted(analog_text.c_str());
if (ImGui::IsItemHovered()) {
ImGui::SameLine();
ImGui::HelpTooltip(analog_display.c_str());
}
} else {
ImGui::TextDisabled("-");
}
// clear analog // clear analog
if (analog_display.size() > 0) { if (analog_display.size() > 0) {
@@ -2230,22 +2213,13 @@ namespace overlay::windows {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::ProgressBar(light_state, ImVec2(32.f, 0)); ImGui::ProgressBar(light_state, ImVec2(32.f, 0));
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(light_name.c_str()); ImGui::TextTruncated(light_name, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
// binding name // binding name
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
if (light_display.size() > 0) { ImGui::TextTruncated(
std::string light_text = ImGui::TruncateText( light_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
light_display, ImGui::GetContentRegionAvail().x - overlay::apply_scaling(20));
ImGui::TextUnformatted(light_text.c_str());
if (ImGui::IsItemHovered()) {
ImGui::SameLine();
ImGui::HelpTooltip(light_display.c_str());
}
} else {
ImGui::TextDisabled("-");
}
// clear light // clear light
if (light_display.size() > 0) { if (light_display.size() > 0) {
@@ -2828,7 +2802,7 @@ namespace overlay::windows {
ImGui::TextUnformatted(definition.title.c_str()); ImGui::TextUnformatted(definition.title.c_str());
} }
ImGui::Unindent(INDENT); ImGui::Unindent(INDENT);
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
@@ -2842,7 +2816,7 @@ namespace overlay::windows {
param += definition.display_name; param += definition.display_name;
} }
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.f), "%s", param.c_str()); ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.f), "%s", param.c_str());
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
const auto help = const auto help =
param + param +
"\n\nClick to copy the parameter to the clipboard.\n\n" "\n\nClick to copy the parameter to the clipboard.\n\n"
@@ -2850,7 +2824,6 @@ namespace overlay::windows {
"Example: spice.exe -w -ea\n" "Example: spice.exe -w -ea\n"
" spice64.exe -api 1337 -apipass changeme"; " spice64.exe -api 1337 -apipass changeme";
ImGui::HelpTooltip(help.c_str()); ImGui::HelpTooltip(help.c_str());
} }
if (ImGui::IsItemClicked()) { if (ImGui::IsItemClicked()) {
clipboard::copy_text(param.c_str()); clipboard::copy_text(param.c_str());
@@ -2871,7 +2844,7 @@ namespace overlay::windows {
option.value = state ? "/ENABLED" : ""; option.value = state ? "/ENABLED" : "";
::Config::getInstance().updateBinding(games_list[games_selected], option); ::Config::getInstance().updateBinding(games_list[games_selected], option);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
break; break;
@@ -2900,7 +2873,7 @@ namespace overlay::windows {
option.value = buffer; option.value = buffer;
::Config::getInstance().updateBinding(games_list[games_selected], option); ::Config::getInstance().updateBinding(games_list[games_selected], option);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
break; break;
@@ -2936,7 +2909,7 @@ namespace overlay::windows {
option.value = buffer; option.value = buffer;
::Config::getInstance().updateBinding(games_list[games_selected], option); ::Config::getInstance().updateBinding(games_list[games_selected], option);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
break; break;
@@ -2956,7 +2929,7 @@ namespace overlay::windows {
option.value = buffer; option.value = buffer;
::Config::getInstance().updateBinding(games_list[games_selected], option); ::Config::getInstance().updateBinding(games_list[games_selected], option);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
break; break;
@@ -2993,7 +2966,7 @@ namespace overlay::windows {
} }
ImGui::EndCombo(); ImGui::EndCombo();
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::HelpTooltip(definition.desc.c_str()); ImGui::HelpTooltip(definition.desc.c_str());
} }
break; break;
@@ -721,7 +721,7 @@ namespace overlay::windows {
if (style_color_pushed) { if (style_color_pushed) {
ImGui::PopStyleColor(style_color_pushed); ImGui::PopStyleColor(style_color_pushed);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
show_patch_tooltip(patch); show_patch_tooltip(patch);
} }
@@ -762,7 +762,7 @@ namespace overlay::windows {
patch.last_status = is_patch_active(patch); patch.last_status = is_patch_active(patch);
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
show_patch_tooltip(patch); show_patch_tooltip(patch);
} }
@@ -791,7 +791,7 @@ namespace overlay::windows {
} }
ImGui::EndCombo(); ImGui::EndCombo();
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
show_patch_tooltip(patch); show_patch_tooltip(patch);
} }
} else if (patch.type == PatchType::Integer) { } else if (patch.type == PatchType::Integer) {
@@ -807,7 +807,7 @@ namespace overlay::windows {
apply_patch(patch, true); apply_patch(patch, true);
config_dirty = true; config_dirty = true;
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
show_patch_tooltip(patch); show_patch_tooltip(patch);
} }
} }
@@ -824,7 +824,7 @@ namespace overlay::windows {
ImGui::InputInt("##dummy_int_input", &patch.patch_number.value); ImGui::InputInt("##dummy_int_input", &patch.patch_number.value);
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
show_patch_tooltip(patch); show_patch_tooltip(patch);
} }
} }