diff --git a/HellionChat/Ui/Components/Settings/ColorPicker.cs b/HellionChat/Ui/Components/Settings/ColorPicker.cs index d13cfcd..b991910 100644 --- a/HellionChat/Ui/Components/Settings/ColorPicker.cs +++ b/HellionChat/Ui/Components/Settings/ColorPicker.cs @@ -88,13 +88,167 @@ internal sealed class ColorPicker ImGui.TextUnformatted($"Editing: {buffer.Name}"); ImGui.Separator(); - // Sections land in Step 2; placeholder keeps the skeleton compiling. - ImGui.TextDisabled("(sections land in next sub-step)"); + DrawSection( + "Surfaces", + buffer, + c => + new[] + { + ("WindowBg", c.WindowBg), + ("ChildBg", c.ChildBg), + ("FrameBg", c.FrameBg), + ("Surface", c.Surface), + ("SurfaceHover", c.SurfaceHover), + }, + (c, edits) => + c with + { + WindowBg = edits[0].color, + ChildBg = edits[1].color, + FrameBg = edits[2].color, + Surface = edits[3].color, + SurfaceHover = edits[4].color, + } + ); + + DrawSection( + "Borders", + buffer, + c => new[] { ("Border", c.Border) }, + (c, edits) => c with { Border = edits[0].color } + ); + + DrawSection( + "Text", + buffer, + c => + new[] + { + ("TextPrimary", c.TextPrimary), + ("TextMuted", c.TextMuted), + ("TextDim", c.TextDim), + }, + (c, edits) => + c with + { + TextPrimary = edits[0].color, + TextMuted = edits[1].color, + TextDim = edits[2].color, + } + ); + + DrawSection( + "Brand — Primary", + buffer, + c => + new[] + { + ("PrimaryDark", c.PrimaryDark), + ("Primary", c.Primary), + ("PrimaryLight", c.PrimaryLight), + ("PrimaryGlow", c.PrimaryGlow), + }, + (c, edits) => + c with + { + PrimaryDark = edits[0].color, + Primary = edits[1].color, + PrimaryLight = edits[2].color, + PrimaryGlow = edits[3].color, + } + ); + + DrawSection( + "Brand — Accent", + buffer, + c => + new[] + { + ("AccentDark", c.AccentDark), + ("Accent", c.Accent), + ("AccentLight", c.AccentLight), + }, + (c, edits) => + c with + { + AccentDark = edits[0].color, + Accent = edits[1].color, + AccentLight = edits[2].color, + } + ); + + DrawSection( + "Identity", + buffer, + c => new[] { ("Identity", c.Identity) }, + (c, edits) => c with { Identity = edits[0].color } + ); + + DrawSection( + "Status", + buffer, + c => + new[] + { + ("StatusSuccess", c.StatusSuccess), + ("StatusDanger", c.StatusDanger), + ("StatusWarning", c.StatusWarning), + ("StatusInfo", c.StatusInfo), + }, + (c, edits) => + c with + { + StatusSuccess = edits[0].color, + StatusDanger = edits[1].color, + StatusWarning = edits[2].color, + StatusInfo = edits[3].color, + } + ); ImGui.Separator(); DrawActionButtons(buffer); } + private void DrawSection( + string title, + Theme buffer, + Func slots, + Func writeBack + ) + { + if (!ImGui.CollapsingHeader(title, ImGuiTreeNodeFlags.DefaultOpen)) + { + return; + } + + var current = slots(buffer.Colors); + var changed = false; + var working = current.ToArray(); + + for (var i = 0; i < working.Length; i++) + { + var (label, color) = working[i]; + var rgba = ColourUtil.RgbaToVector4(color); + if ( + ImGui.ColorEdit4( + $"{label}##slot-{title}-{i}", + ref rgba, + ImGuiColorEditFlags.AlphaBar | ImGuiColorEditFlags.AlphaPreviewHalf + ) + ) + { + working[i] = (label, ColourUtil.Vector4ToRgba(rgba)); + changed = true; + } + } + + if (changed) + { + var mutated = writeBack(buffer.Colors, working); + _themes.UpdateEditingBuffer(mutated); + } + } + private void DrawActionButtons(Theme buffer) { if (ImGui.Button("Save"))