The combo's swatch takes a berth — a bar sitting in the field, not a fill
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
This commit is contained in:
@@ -460,10 +460,15 @@ final class ColorComboControl: NSControl {
|
|||||||
/// control exists to draw: "a flat swatch occupying the control, a chevron trigger at the
|
/// control exists to draw: "a flat swatch occupying the control, a chevron trigger at the
|
||||||
/// trailing edge."
|
/// trailing edge."
|
||||||
private static let triggerWidth: CGFloat = 16
|
private static let triggerWidth: CGFloat = 16
|
||||||
/// The swatch zone's padding before its rounded rect — two points rather than a bare hairline,
|
/// The swatch's padding inside its zone, asymmetric and user-tuned: a wider berth at the sides
|
||||||
/// so the control's own field (`drawField()`) reads as a visible ring around the colour instead
|
/// than above and below, so the colour reads as a bar sitting in the field rather than filling
|
||||||
/// of being covered by it.
|
/// it wall to wall. The space comes out of the swatch — the control's overall size is untouched.
|
||||||
private static let swatchPadding: CGFloat = 2
|
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
|
private static let cornerRadius: CGFloat = 3
|
||||||
/// The field's own radius — a point more than the swatch's, so the two rounded rects run
|
/// 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.
|
/// 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
|
/// 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
|
/// 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.
|
/// `separatorColor` hairline, the half-point inset keeping the stroke on whole pixels.
|
||||||
private func drawField() {
|
private func drawField() {
|
||||||
let path = NSBezierPath(
|
let path = NSBezierPath(
|
||||||
@@ -509,7 +515,7 @@ final class ColorComboControl: NSControl {
|
|||||||
xRadius: Self.fieldRadius,
|
xRadius: Self.fieldRadius,
|
||||||
yRadius: Self.fieldRadius
|
yRadius: Self.fieldRadius
|
||||||
)
|
)
|
||||||
NSColor.controlBackgroundColor.setFill()
|
NSColor.controlColor.setFill()
|
||||||
path.fill()
|
path.fill()
|
||||||
NSColor.separatorColor.setStroke()
|
NSColor.separatorColor.setStroke()
|
||||||
path.lineWidth = 1
|
path.lineWidth = 1
|
||||||
@@ -521,7 +527,7 @@ final class ColorComboControl: NSControl {
|
|||||||
/// resolved colour on top, a `separatorColor` hairline stroke last. `nil`/unresolvable value →
|
/// 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.
|
/// underlay + stroke only, the same "there is no colour, so show none" rule.
|
||||||
private func drawSwatch() {
|
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)
|
let path = NSBezierPath(roundedRect: inset, xRadius: Self.cornerRadius, yRadius: Self.cornerRadius)
|
||||||
NSColor.textBackgroundColor.setFill()
|
NSColor.textBackgroundColor.setFill()
|
||||||
path.fill()
|
path.fill()
|
||||||
@@ -538,7 +544,7 @@ final class ColorComboControl: NSControl {
|
|||||||
/// a white `chevron.up.chevron.down` centred inside — the standard `NSPopUpButton` indicator's
|
/// 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.
|
/// own look, redrawn here since this control has no bezel of its own to borrow one from.
|
||||||
private func drawTrigger() {
|
private func drawTrigger() {
|
||||||
let side = triggerRect.height - 2 * Self.swatchPadding
|
let side = triggerRect.height - 2 * Self.triggerInset
|
||||||
let square = NSRect(
|
let square = NSRect(
|
||||||
x: triggerRect.midX - side / 2,
|
x: triggerRect.midX - side / 2,
|
||||||
y: triggerRect.midY - side / 2,
|
y: triggerRect.midY - side / 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user