From 1e21d8cd608d9886ffbdc247b306d06db95b36fc Mon Sep 17 00:00:00 2001 From: rzen Date: Fri, 7 Aug 2026 11:23:54 -0400 Subject: [PATCH] =?UTF-8?q?The=20combo's=20swatch=20takes=20a=20berth=20?= =?UTF-8?q?=E2=80=94=20a=20bar=20sitting=20in=20the=20field,=20not=20a=20f?= =?UTF-8?q?ill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The swatch's padding goes asymmetric and user-tuned — a wider berth at the sides than above and below, out of the swatch rather than the control's size — so the colour reads as a bar in the field instead of wall-to-wall. The field's fill moves to controlColor, the push-button neutral grey, whose ring stayed legible where controlBackgroundColor's near-black dark-mode reading drowned it; and the trigger square keeps its own two-point inset, decoupled from the swatch's padding so the indicator stays a legible square through any padding tweak the swatch takes. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy --- Kanban/UI/ColorCombo.swift | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Kanban/UI/ColorCombo.swift b/Kanban/UI/ColorCombo.swift index 1972568..c354ac0 100644 --- a/Kanban/UI/ColorCombo.swift +++ b/Kanban/UI/ColorCombo.swift @@ -460,10 +460,15 @@ final class ColorComboControl: NSControl { /// control exists to draw: "a flat swatch occupying the control, a chevron trigger at the /// trailing edge." private static let triggerWidth: CGFloat = 16 - /// The swatch zone's padding before its rounded rect — two points rather than a bare hairline, - /// so the control's own field (`drawField()`) reads as a visible ring around the colour instead - /// of being covered by it. - private static let swatchPadding: CGFloat = 2 + /// The swatch's padding inside its zone, asymmetric and user-tuned: a wider berth at the sides + /// than above and below, so the colour reads as a bar sitting in the field rather than filling + /// it wall to wall. The space comes out of the swatch — the control's overall size is untouched. + private static let swatchPaddingH: CGFloat = 7 + private static let swatchPaddingV: CGFloat = 4 + /// The trigger square's own inset from the zone's height — kept at the old ring width rather + /// than the swatch's larger padding, so the indicator stays a legible ~10pt square instead of + /// shrinking with every padding tweak the swatch takes. + private static let triggerInset: CGFloat = 2 private static let cornerRadius: CGFloat = 3 /// The field's own radius — a point more than the swatch's, so the two rounded rects run /// concentric instead of pinching at the corners. @@ -501,7 +506,8 @@ final class ColorComboControl: NSControl { /// The control's own field: a bordered, filled rounded rect over the whole bounds, under both /// zones — what makes the swatch and the trigger read as one control rather than two shapes - /// floating beside each other. Standard control materials: `controlBackgroundColor` fill, + /// floating beside each other. `controlColor` fill — the push-button neutral grey, not + /// `controlBackgroundColor`, whose near-black dark-mode reading drowned the padding ring — /// `separatorColor` hairline, the half-point inset keeping the stroke on whole pixels. private func drawField() { let path = NSBezierPath( @@ -509,7 +515,7 @@ final class ColorComboControl: NSControl { xRadius: Self.fieldRadius, yRadius: Self.fieldRadius ) - NSColor.controlBackgroundColor.setFill() + NSColor.controlColor.setFill() path.fill() NSColor.separatorColor.setStroke() path.lineWidth = 1 @@ -521,7 +527,7 @@ final class ColorComboControl: NSControl { /// resolved colour on top, a `separatorColor` hairline stroke last. `nil`/unresolvable value → /// underlay + stroke only, the same "there is no colour, so show none" rule. private func drawSwatch() { - let inset = swatchZone.insetBy(dx: Self.swatchPadding, dy: Self.swatchPadding) + let inset = swatchZone.insetBy(dx: Self.swatchPaddingH, dy: Self.swatchPaddingV) let path = NSBezierPath(roundedRect: inset, xRadius: Self.cornerRadius, yRadius: Self.cornerRadius) NSColor.textBackgroundColor.setFill() path.fill() @@ -538,7 +544,7 @@ final class ColorComboControl: NSControl { /// a white `chevron.up.chevron.down` centred inside — the standard `NSPopUpButton` indicator's /// own look, redrawn here since this control has no bezel of its own to borrow one from. private func drawTrigger() { - let side = triggerRect.height - 2 * Self.swatchPadding + let side = triggerRect.height - 2 * Self.triggerInset let square = NSRect( x: triggerRect.midX - side / 2, y: triggerRect.midY - side / 2,