diff --git a/CLAUDE.md b/CLAUDE.md index e00a94c..4b6bedd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,7 +14,7 @@ Aplikacja natywna na macOS, która wyświetla w oknie obraz z urządzenia przech ## Struktura - `Sources/main.swift` – cała aplikacja (AppKit + AVFoundation, jedna sesja `AVCaptureSession`, dźwięk przez `AVCaptureAudioPreviewOutput`). - `Resources/{en,pl}.lproj` – `Localizable.strings` i `InfoPlist.strings`. -- `tools/make-icon.swift` – generuje `Resources/AppIcon.icns` (`swift tools/make-icon.swift`). +- `Resources/AppIcon.icon` – ikona w formacie Icon Composer (Liquid Glass; otwórz w Icon Composer, warstwy SVG w `Assets/`); `build.sh` kompiluje ją przez `actool`. - `build.sh` – buduje i podpisuje (ad-hoc) `SecondDisplay.app`; uruchom `./build.sh`, potem `open SecondDisplay.app`. ## Konwencje diff --git a/Resources/AppIcon.icns b/Resources/AppIcon.icns deleted file mode 100644 index 45e55cd..0000000 Binary files a/Resources/AppIcon.icns and /dev/null differ diff --git a/Resources/AppIcon.icon/Assets/body.svg b/Resources/AppIcon.icon/Assets/body.svg new file mode 100644 index 0000000..6f42ccb --- /dev/null +++ b/Resources/AppIcon.icon/Assets/body.svg @@ -0,0 +1,5 @@ + diff --git a/Resources/AppIcon.icon/Assets/screen.svg b/Resources/AppIcon.icon/Assets/screen.svg new file mode 100644 index 0000000..5971afa --- /dev/null +++ b/Resources/AppIcon.icon/Assets/screen.svg @@ -0,0 +1,5 @@ + diff --git a/Resources/AppIcon.icon/icon.json b/Resources/AppIcon.icon/icon.json new file mode 100644 index 0000000..2d0b92d --- /dev/null +++ b/Resources/AppIcon.icon/icon.json @@ -0,0 +1,16 @@ +{ + "fill" : { + "automatic-gradient" : "srgb:0.12157,0.14902,0.24706,1.00000" + }, + "groups" : [ + { + "layers" : [ + { "glass" : true, "image-name" : "body.svg", "name" : "body" }, + { "image-name" : "screen.svg", "name" : "screen" } + ], + "shadow" : { "kind" : "neutral", "opacity" : 0.5 }, + "translucency" : { "enabled" : true, "value" : 0.4 } + } + ], + "supported-platforms" : { "squares" : [ "macOS" ] } +} diff --git a/build.sh b/build.sh index ae6459c..230825b 100755 --- a/build.sh +++ b/build.sh @@ -13,6 +13,7 @@ cat > "$A/Contents/Info.plist" <
CFBundleExecutable
P for L in en pl; do mkdir -p "$A/Contents/Resources/$L.lproj"; cp Resources/$L.lproj/*.strings "$A/Contents/Resources/$L.lproj/"; done -cp Resources/AppIcon.icns "$A/Contents/Resources/" +xcrun actool Resources/AppIcon.icon --compile "$A/Contents/Resources" --platform macosx --minimum-deployment-target 26.0 --app-icon AppIcon --output-partial-info-plist /dev/null >/dev/null codesign --force --sign - "$A" diff --git a/tools/make-icon.swift b/tools/make-icon.swift deleted file mode 100644 index 033eee2..0000000 --- a/tools/make-icon.swift +++ /dev/null @@ -1,34 +0,0 @@ -// Usage: swift tools/make-icon.swift -> writes Resources/AppIcon.icns -import AppKit - -func render(_ px: Int) -> Data { - let rep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: px, pixelsHigh: px, bitsPerSample: 8, samplesPerPixel: 4, - hasAlpha: true, isPlanar: false, colorSpaceName: .deviceRGB, bytesPerRow: 0, bitsPerPixel: 0)! - NSGraphicsContext.saveGraphicsState() - NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: rep) - let s = CGFloat(px) - let r = NSRect(x: s * 0.05, y: s * 0.05, width: s * 0.9, height: s * 0.9) // macOS icon grid margin - let bg = NSBezierPath(roundedRect: r, xRadius: s * 0.2, yRadius: s * 0.2) - NSGradient(starting: NSColor(red: 0.16, green: 0.20, blue: 0.32, alpha: 1), ending: NSColor(red: 0.05, green: 0.06, blue: 0.10, alpha: 1))!.draw(in: bg, angle: -90) - let cfg = NSImage.SymbolConfiguration(pointSize: s * 0.5, weight: .regular).applying(.init(paletteColors: [.white])) - if let sym = NSImage(systemSymbolName: "display", accessibilityDescription: nil)?.withSymbolConfiguration(cfg) { - let sz = sym.size - sym.draw(in: NSRect(x: (s - sz.width) / 2, y: (s - sz.height) / 2, width: sz.width, height: sz.height)) - } - // palette tint paints the whole symbol white; refill the screen area so it reads as a display - let screen = NSBezierPath(roundedRect: NSRect(x: s * 0.255, y: s * 0.385, width: s * 0.49, height: s * 0.315), xRadius: s * 0.02, yRadius: s * 0.02) - NSGradient(starting: NSColor(red: 0.20, green: 0.75, blue: 0.85, alpha: 1), ending: NSColor(red: 0.25, green: 0.35, blue: 0.95, alpha: 1))!.draw(in: screen, angle: -45) - NSGraphicsContext.restoreGraphicsState() - return rep.representation(using: .png, properties: [:])! -} - -let set = NSTemporaryDirectory() + "AppIcon.iconset" -try? FileManager.default.removeItem(atPath: set) -try! FileManager.default.createDirectory(atPath: set, withIntermediateDirectories: true) -for base in [16, 32, 128, 256, 512] { - try! render(base).write(to: URL(fileURLWithPath: "\(set)/icon_\(base)x\(base).png")) - try! render(base * 2).write(to: URL(fileURLWithPath: "\(set)/icon_\(base)x\(base)@2x.png")) -} -let p = Process(); p.executableURL = URL(fileURLWithPath: "/usr/bin/iconutil") -p.arguments = ["-c", "icns", set, "-o", "Resources/AppIcon.icns"] -try! p.run(); p.waitUntilExit()