From 19ead810d2496e6da0d3d3984ed68c211ffa004f Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 31 Aug 2026 16:37:00 +0200 Subject: [PATCH] ColorButton, ColorEdit, ColorPicker: cancel-out alpha caused by BeginDisabled() so disabled color buttons have the same color. (#9511) --- docs/CHANGELOG.txt | 2 ++ imgui_draw.cpp | 2 +- imgui_widgets.cpp | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 492b9eff8..4b79c8095 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,8 @@ Other Changes: to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of ProggyClean on most Apple/Retina setups by default. - Misc: + - ColorButton, ColorEdit, ColorPicker: cancel-out alpha caused by BeginDisabled() so + disabled color buttons have the same color as non-disabled oness. (#9511) - Fixed `GetBackgroundDrawList()`/`GetForegroundDrawList()` not being properly reset every frame when cumulated session time is very large (e.g. a few days). [@lailoken] - ImDrawList: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b4739b8be..e42014745 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -6214,7 +6214,7 @@ ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRe void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags) { if ((flags & ImDrawFlags_RoundCornersMask_) == 0) - flags = ImDrawFlags_RoundCornersDefault_; + flags = ImDrawFlags_RoundCornersAll; if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col)); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e2a6771bd..bffd52e1d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6129,6 +6129,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl const bool is_readonly = ((g.NextItemData.ItemFlagsSet | g.CurrentItemFlags) & ImGuiItemFlags_ReadOnly) != 0; g.NextItemData.ClearFlags(); + const float backup_alpha = g.Style.Alpha; + if (g.DisabledStackSize > 0) + g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches. + PushID(label); const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0); if (set_current_color_edit_id) @@ -6468,7 +6472,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl { float alpha = ImSaturate(col[3]); ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); - RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); + RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK); float bar1_line_y = IM_ROUND(picker_pos.y + (1.0f - alpha) * sv_picker_size); RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); @@ -6486,6 +6490,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl g.ColorEditCurrentID = 0; PopID(); + if (g.DisabledStackSize > 0) + g.Style.Alpha = backup_alpha; + return value_changed; } @@ -6528,6 +6535,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. bb_inner.Expand(off); } + + const float backup_alpha = g.Style.Alpha; + if (g.DisabledStackSize > 0) + g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches. if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f) { float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f); @@ -6546,6 +6557,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl else window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding); } + if (g.DisabledStackSize > 0) + g.Style.Alpha = backup_alpha; RenderNavCursor(bb, id); if ((flags & ImGuiColorEditFlags_NoBorder) == 0) {