From 9c6d9d412fc32152b2b92c479f3bb34411e3c43f Mon Sep 17 00:00:00 2001 From: Ying Zhong <0x00eeee@gmail.com> Date: Sun, 13 Sep 2026 13:08:43 +0800 Subject: [PATCH] Redesign color swatch in theme picker --- MarkEditMac/Sources/Main/AppTheme.swift | 87 ++++++++++++++----------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/MarkEditMac/Sources/Main/AppTheme.swift b/MarkEditMac/Sources/Main/AppTheme.swift index a958ceda0..3b5b997e5 100644 --- a/MarkEditMac/Sources/Main/AppTheme.swift +++ b/MarkEditMac/Sources/Main/AppTheme.swift @@ -31,38 +31,47 @@ struct AppTheme { /// Illustration of the theme's color pattern. @MainActor var patternImage: NSImage { - let length = 10.0 - let spacing = 2.0 - let colors = colorPattern.map { - NSColor(hexCode: UInt32($0.dropFirst(), radix: 16) ?? 0) - } + let length = 8.0 + let spacing = 2.5 + let padding = 3.0 + + let allColors = colorPattern.map { NSColor(hexCode: UInt32($0.dropFirst(), radix: 16) ?? 0) } + let circleColors = allColors.dropFirst() let size = CGSize( - width: Double(colors.count) * length + Double(max(colors.count - 1, 0)) * spacing + 4, - height: length + width: Double(circleColors.count) * length + Double(max(circleColors.count - 1, 0)) * spacing + padding * 2, + height: length + padding * 2 ) - return NSImage(size: size, flipped: false) { _ in - for (index, color) in colors.enumerated() { - let rect = CGRect( - x: Double(index) * (length + spacing), - y: 0, - width: length, - height: length - ) + return NSImage(size: CGSize(width: size.width + 4, height: size.height), flipped: false) { _ in + let backgroundRect = CGRect(origin: .zero, size: size) + let radius = size.height * 0.5 + (allColors.first ?? .clear).setFill() + NSBezierPath(roundedRect: backgroundRect, xRadius: radius, yRadius: radius).fill() + NSColor.black.withAlphaComponent(0.4).setStroke() + let border = NSBezierPath( + roundedRect: backgroundRect.insetBy(dx: 0.25, dy: 0.25), + xRadius: radius - 0.25, + yRadius: radius - 0.25 + ) + + border.lineWidth = 0.5 + border.stroke() + + for (index, color) in circleColors.enumerated() { color.setFill() - NSBezierPath(roundedRect: rect, xRadius: 2, yRadius: 2).fill() - NSColor.black.withAlphaComponent(0.4).setStroke() - let border = NSBezierPath( - roundedRect: rect.insetBy(dx: 0.25, dy: 0.25), - xRadius: 1.75, - yRadius: 1.75 + let rect = CGRect( + x: padding + Double(index) * (length + spacing), + y: padding, + width: length, + height: length ) - border.lineWidth = 0.5 - border.stroke() + // Bright circles appear larger on dark backgrounds + let inset = isDark ? 0.25 : 0.0 + NSBezierPath(ovalIn: rect.insetBy(dx: inset, dy: inset)).fill() } return true @@ -101,7 +110,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "github-light", windowBackground: NSColor(hexCode: 0xffffff), - colorPattern: ["#ffffff", "#1f2328", "#0550ae", "#cf222e", "#0a3069"], + colorPattern: ["#ffffff", "#1f2328", "#0550ae", "#cf222e", "#0a3069", "#6e7781"], prefersTintedColors: false ) } @@ -111,7 +120,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "github-dark", windowBackground: NSColor(hexCode: 0x0d1117), - colorPattern: ["#0d1117", "#e6edf3", "#79c0ff", "#ff7b72", "#a5d6ff"], + colorPattern: ["#0d1117", "#e6edf3", "#79c0ff", "#ff7b72", "#a5d6ff", "#8b949e"], prefersTintedColors: true ) } @@ -121,7 +130,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "xcode-light", windowBackground: NSColor(hexCode: 0xffffff), - colorPattern: ["#ffffff", "#000000", "#0b4f79", "#9b2393", "#c41a16"], + colorPattern: ["#ffffff", "#000000", "#0b4f79", "#9b2393", "#c41a16", "#5d6c79"], prefersTintedColors: false ) } @@ -131,7 +140,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "xcode-dark", windowBackground: NSColor(hexCode: 0x1f1f24), - colorPattern: ["#1f1f24", "#dedede", "#5dd8ff", "#fc5fa3", "#fc6a5d"], + colorPattern: ["#1f1f24", "#dedede", "#5dd8ff", "#fc5fa3", "#fc6a5d", "#6c7986"], prefersTintedColors: true ) } @@ -141,7 +150,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "dracula", windowBackground: NSColor(hexCode: 0x282a36), - colorPattern: ["#282a36", "#f8f8f2", "#bd93f9", "#ff79c6", "#f1fa8c"], + colorPattern: ["#282a36", "#f8f8f2", "#bd93f9", "#ff79c6", "#f1fa8c", "#6272a4"], prefersTintedColors: true ) } @@ -151,7 +160,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "cobalt", windowBackground: NSColor(hexCode: 0x193549), - colorPattern: ["#193549", "#e1efff", "#ffc600", "#ff9d00", "#a5ff90"], + colorPattern: ["#193549", "#e1efff", "#ffc600", "#ff9d00", "#a5ff90", "#0088ff"], prefersTintedColors: true ) } @@ -161,7 +170,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "winter-is-coming-light", windowBackground: NSColor(hexCode: 0xffffff), - colorPattern: ["#ffffff", "#3e3e3e", "#034c7c", "#0991b6", "#a44185"], + colorPattern: ["#ffffff", "#3e3e3e", "#034c7c", "#0991b6", "#a44185", "#357b42"], prefersTintedColors: false ) } @@ -171,7 +180,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "winter-is-coming-dark", windowBackground: NSColor(hexCode: 0x282822), - colorPattern: ["#282822", "#ffffff", "#5abeb0", "#00bff9", "#bcf0c0"], + colorPattern: ["#282822", "#ffffff", "#5abeb0", "#00bff9", "#bcf0c0", "#999999"], prefersTintedColors: true ) } @@ -181,7 +190,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "minimal-light", windowBackground: NSColor(hexCode: 0xffffff), - colorPattern: ["#ffffff", "#3a3a3c", "#000000", "#3a3a3c", "#000000"], + colorPattern: ["#ffffff", "#3a3a3c", "#000000", "#3a3a3c", "#000000", "#8e8e93"], prefersTintedColors: false ) } @@ -191,7 +200,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "minimal-dark", windowBackground: NSColor(hexCode: 0x1e1e1e), - colorPattern: ["#1e1e1e", "#d1d1d6", "#ffffff", "#d1d1d6", "#ffffff"], + colorPattern: ["#1e1e1e", "#d1d1d6", "#ffffff", "#d1d1d6", "#ffffff", "#8e8e93"], prefersTintedColors: true ) } @@ -201,7 +210,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "synthwave84", windowBackground: NSColor(hexCode: 0x262335), - colorPattern: ["#262335", "#f0eff1", "#f92aad", "#f4eee4", "#ff8b39"], + colorPattern: ["#262335", "#f0eff1", "#f92aad", "#f4eee4", "#ff8b39", "#848bbd"], prefersTintedColors: true ) } @@ -211,7 +220,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "night-owl", windowBackground: NSColor(hexCode: 0x011627), - colorPattern: ["#011627", "#d6deeb", "#82b1ff", "#c792ea", "#ecc48d"], + colorPattern: ["#011627", "#d6deeb", "#82b1ff", "#c792ea", "#ecc48d", "#637777"], prefersTintedColors: true ) } @@ -221,7 +230,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "rose-pine-dawn", windowBackground: NSColor(hexCode: 0xfaf4ed), - colorPattern: ["#faf4ed", "#575279", "#56949f", "#286983", "#ea9d34"], + colorPattern: ["#faf4ed", "#575279", "#56949f", "#286983", "#ea9d34", "#9893a5"], prefersTintedColors: true ) } @@ -231,7 +240,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "rose-pine", windowBackground: NSColor(hexCode: 0x191724), - colorPattern: ["#191724", "#e0def4", "#9ccfd8", "#31748f", "#f6c177"], + colorPattern: ["#191724", "#e0def4", "#9ccfd8", "#31748f", "#f6c177", "#6e6a86"], prefersTintedColors: true ) } @@ -241,7 +250,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: false, editorTheme: "solarized-light", windowBackground: NSColor(hexCode: 0xfdf6e3), - colorPattern: ["#fdf6e3", "#586e75", "#268bd2", "#859900", "#2aa198"], + colorPattern: ["#fdf6e3", "#586e75", "#268bd2", "#859900", "#2aa198", "#93a1a1"], prefersTintedColors: true ) } @@ -251,7 +260,7 @@ extension AppTheme: CaseIterable, Hashable { isDark: true, editorTheme: "solarized-dark", windowBackground: NSColor(hexCode: 0x002b36), - colorPattern: ["#002b36", "#93a1a1", "#268bd2", "#859900", "#2aa198"], + colorPattern: ["#002b36", "#93a1a1", "#268bd2", "#859900", "#2aa198", "#657b83"], prefersTintedColors: true ) }