Add SimpleTopBar menu bar app with collapsible background app list

This commit is contained in:
2026-09-26 22:37:09 +08:00
commit 41a5917b42
12 changed files with 843 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
import AppKit
let size = NSSize(width: 1024, height: 1024)
guard let rep = NSBitmapImageRep(
bitmapDataPlanes: nil, pixelsWide: 1024, pixelsHigh: 1024,
bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false,
colorSpaceName: .deviceRGB, bytesPerRow: 0, bitsPerPixel: 0
) else { exit(1) }
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: rep)
NSGraphicsContext.current?.imageInterpolation = .high
let gradient = NSGradient(colors: [
NSColor(calibratedRed: 0.24, green: 0.30, blue: 0.38, alpha: 1),
NSColor(calibratedRed: 0.10, green: 0.13, blue: 0.18, alpha: 1),
])!
gradient.draw(in: NSRect(origin: .zero, size: size), angle: -90)
// The top bar itself.
let bar = NSBezierPath(roundedRect: NSRect(x: 128, y: 560, width: 768, height: 220), xRadius: 48, yRadius: 48)
NSColor.white.setFill()
bar.fill()
// App dots sitting on the bar.
let dotColors: [NSColor] = [
NSColor(calibratedRed: 0.20, green: 0.42, blue: 0.95, alpha: 1),
NSColor(calibratedRed: 0.95, green: 0.55, blue: 0.15, alpha: 1),
NSColor(calibratedRed: 0.20, green: 0.70, blue: 0.40, alpha: 1),
]
let dotRadius: CGFloat = 44
var dotX: CGFloat = 200
for color in dotColors {
let rect = NSRect(x: dotX, y: 648, width: dotRadius * 2, height: dotRadius * 2)
color.setFill()
NSBezierPath(ovalIn: rect).fill()
dotX += 130
}
// A chevron marking the collapsible background section.
NSColor(calibratedWhite: 0.35, alpha: 1).setStroke()
let chevron = NSBezierPath()
chevron.move(to: NSPoint(x: 700, y: 730))
chevron.line(to: NSPoint(x: 750, y: 680))
chevron.line(to: NSPoint(x: 800, y: 730))
chevron.lineWidth = 34
chevron.lineCapStyle = .round
chevron.lineJoinStyle = .round
chevron.stroke()
NSGraphicsContext.restoreGraphicsState()
guard let data = rep.representation(using: .png, properties: [:]) else { exit(1) }
if CommandLine.arguments.count < 2 { exit(1) }
do {
try data.write(to: URL(fileURLWithPath: CommandLine.arguments[1]))
} catch {
exit(1)
}
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
set -euo pipefail
cd "$(dirname "$0")/.."
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
swift scripts/gen-icon.swift "$TMP/icon-1024.png"
mkdir -p "$TMP/Icon.iconset"
for s in 16 32 128 256 512; do
d=$((s * 2))
sips -z "$s" "$s" "$TMP/icon-1024.png" --out "$TMP/Icon.iconset/icon_${s}x${s}.png" >/dev/null
sips -z "$d" "$d" "$TMP/icon-1024.png" --out "$TMP/Icon.iconset/icon_${s}x${s}@2x.png" >/dev/null
done
iconutil -c icns "$TMP/Icon.iconset" -o "$TMP/Icon.icns"
mkdir -p SimpleTopBar.app/Contents/Resources
cp "$TMP/Icon.icns" SimpleTopBar.app/Contents/Resources/Icon.icns
echo "Generated SimpleTopBar.app/Contents/Resources/Icon.icns"