Mixed Value: use ImGuiCol_TextMixedValue (= ImGuiCol_TextDisabled). Set MixedValueLabel to null to display original value. (#5518, #5677, #6865)

This commit is contained in:
ocornut 2026-09-08 16:46:08 +02:00
parent 334f484892
commit 148d128f6e
3 changed files with 30 additions and 10 deletions

View File

@ -3945,6 +3945,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take // Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
// better advantage of the render function taking size into account for coarse clipping. // better advantage of the render function taking size into account for coarse clipping.
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
// DOES NOT CALL LogRenderedText(), unlike RenderTextClipped!!!
{ {
// Perform CPU side clipping for single clipped element to avoid using scissor state // Perform CPU side clipping for single clipped element to avoid using scissor state
ImVec2 pos = pos_min; ImVec2 pos = pos_min;

View File

@ -932,6 +932,8 @@ struct ImFontStackData
// [SECTION] Style support // [SECTION] Style support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define ImGuiCol_TextMixedValue ImGuiCol_TextDisabled
struct ImGuiStyleVarInfo struct ImGuiStyleVarInfo
{ {
ImU32 Count : 8; // 1+ ImU32 Count : 8; // 1+
@ -2304,7 +2306,7 @@ struct ImGuiContext
ImVec2 WheelingAxisAvg; ImVec2 WheelingAxisAvg;
// Item/widgets state and tracking information // Item/widgets state and tracking information
const char* MixedValueLabel; // Value replacement when displaying a mixed value. Default to "-" (Unreal uses "Multiple values", Unity uses "---"). May be interpreted as a format: must not contain single %. const char* MixedValueLabel; // Value replacement when displaying a mixed value. Default to "-" (Unreal uses "Multiple values", Unity uses "---"). May be interpreted as a format: must not contain single %. Set to NULL to display original value.
ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier
ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredId; // Hovered widget, filled during the frame

View File

@ -2817,12 +2817,16 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
MarkItemEdited(id); MarkItemEdited(id);
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format; const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
char value_buf[64]; char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display); const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
if (g.LogEnabled) if (g.LogEnabled)
LogSetNextTextDecoration("{", "}"); LogSetNextTextDecoration("{", "}");
if (is_mixed)
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (is_mixed)
PopStyleColor();
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
@ -3425,12 +3429,16 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format; const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
char value_buf[64]; char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display); const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
if (g.LogEnabled) if (g.LogEnabled)
LogSetNextTextDecoration("{", "}"); LogSetNextTextDecoration("{", "}");
if (is_mixed)
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (is_mixed)
PopStyleColor();
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
@ -3580,10 +3588,15 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
// For the vertical slider we allow centered text to overlap the frame padding // For the vertical slider we allow centered text to overlap the frame padding
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format; const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
char value_buf[64]; char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display); const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
if (is_mixed)
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f)); RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
if (is_mixed)
PopStyleColor();
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
@ -5560,7 +5573,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_password && !is_displaying_hint) if (is_password && !is_displaying_hint)
PushPasswordFont(); PushPasswordFont();
} }
if (is_mixed && g.ActiveId != id && apply_new_text == NULL) const bool is_displaying_mixed = is_mixed && g.ActiveId != id && apply_new_text == NULL;
if (is_displaying_mixed && g.MixedValueLabel != NULL)
{ {
buf_display = g.MixedValueLabel; buf_display = g.MixedValueLabel;
buf_display_end = buf_display + strlen(g.MixedValueLabel); buf_display_end = buf_display + strlen(g.MixedValueLabel);
@ -5609,7 +5623,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImVec2 draw_scroll; ImVec2 draw_scroll;
// Render text. We currently only render selection when the widget is active or while scrolling. // Render text. We currently only render selection when the widget is active or while scrolling.
const ImU32 text_col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); const ImU32 text_col = GetColorU32(is_displaying_mixed ? ImGuiCol_TextMixedValue : is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
if (render_cursor || render_selection) if (render_cursor || render_selection)
{ {
// Render text (with cursor and selection) // Render text (with cursor and selection)
@ -6583,7 +6597,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
if (is_mixed) if (is_mixed)
{ {
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding);
RenderTextClipped(ImVec2(bb.Min.x, bb.Min.y + g.Style.FramePadding.y), bb.Max, g.MixedValueLabel, NULL, NULL, ImVec2(0.5f, 0.0f)); PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
if (g.MixedValueLabel != NULL)
RenderTextClipped(ImVec2(bb.Min.x, bb.Min.y + g.Style.FramePadding.y), bb.Max, g.MixedValueLabel, NULL, NULL, ImVec2(0.5f, 0.0f));
PopStyleColor();
} }
else if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f) else if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
{ {