Das Grün, das überall auftauchte, war die System-Akzentfarbe: `.tint` und `.accentColor` werden ohne eigene Angabe dorthin durchgereicht, und das betraf alle Popovers und das ganze Einstellungsfenster. Die Notch-Widgets dagegen benutzten Onyx' eigenes Blau. Zwei Farben, ungewollt. Jetzt eine, und die ist einstellbar. Ein neuer Reiter „Farben": Akzentfarbe mit sechs Vorschlägen und einem Knopf, der die Systemfarbe übernimmt, dazu das Paar für Herunter- und Hochladen samt Tauschknopf. Die Signalfarben bleiben fest und stehen nur zur Ansicht dort. Gelb heißt Warnung, Rot heißt kritisch, Grün heißt in Ordnung — bei Temperatur, Akku, Lüfter und Fehlern. Wer sie umstellen kann, kann ihre Bedeutung zerstören; ein rotes „alles gut" liest niemand richtig. Sichtbar sind sie trotzdem, sonst sucht man die Warnfarbe im Reiter und findet sie nirgends. Umgesetzt über die Tokens statt über vierzig Fundstellen: `Onyx.Color.accent` ist keine Konstante mehr, sondern liest bei jedem Zugriff aus `OnyxTheme`. Damit merkt SwiftUI die Abhängigkeit und zeichnet neu, sobald die Farbe sich ändert. Dazu ein `.tint` an den vier Wurzeln — Panel, Popovers, Einstellungen, Einrichtung —, damit auch Haken, Regler und Auswahlfelder mitziehen. Nebenbei die Beschriftung: „Je Programm" heißt jetzt „Programme". Großgesetzt las sich das als englisches „J-E". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
81 lines
4.2 KiB
Swift
81 lines
4.2 KiB
Swift
// swift-tools-version: 6.2
|
|
import PackageDescription
|
|
|
|
let package = Package(
|
|
name: "OnyxKit",
|
|
// Quellsprache ist Englisch, damit die Schlüssel im Code lesbar bleiben.
|
|
// Deutsch kommt als Übersetzung dazu; die Systemsprache entscheidet.
|
|
defaultLocalization: "en",
|
|
platforms: [.macOS(.v26)],
|
|
products: [
|
|
.library(name: "OnyxCore", targets: ["OnyxCore"]),
|
|
.library(name: "OnyxHelperProtocol", targets: ["OnyxHelperProtocol"]),
|
|
.library(name: "OnyxDesign", targets: ["OnyxDesign"]),
|
|
.library(name: "OnyxNotch", targets: ["OnyxNotch"]),
|
|
.library(name: "OnyxWidgetKit", targets: ["OnyxWidgetKit"]),
|
|
.library(name: "OnyxMenuBar", targets: ["OnyxMenuBar"]),
|
|
.library(name: "CalendarProvider", targets: ["CalendarProvider"]),
|
|
.library(name: "WeatherProvider", targets: ["WeatherProvider"]),
|
|
.library(name: "MediaProvider", targets: ["MediaProvider"]),
|
|
.library(name: "MetricsProvider", targets: ["MetricsProvider"]),
|
|
.library(name: "NetworkProvider", targets: ["NetworkProvider"]),
|
|
.library(name: "AudioProvider", targets: ["AudioProvider"]),
|
|
.library(name: "ShelfProvider", targets: ["ShelfProvider"]),
|
|
],
|
|
targets: [
|
|
// Der String-Katalog muss ausdrücklich als Ressource stehen — sonst gibt
|
|
// es kein `Bundle.module`, und die Übersetzungen wären zur Laufzeit
|
|
// unauffindbar.
|
|
.target(name: "OnyxCore", resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "OnyxCoreTests", dependencies: ["OnyxCore"]),
|
|
|
|
// Geteilt zwischen App und privilegiertem Helfer — deshalb ohne jede
|
|
// Abhängigkeit: der Helfer läuft als root und soll so wenig Code wie
|
|
// möglich enthalten.
|
|
.target(name: "OnyxHelperProtocol"),
|
|
.testTarget(name: "OnyxHelperProtocolTests", dependencies: ["OnyxHelperProtocol"]),
|
|
|
|
.target(name: "OnyxDesign"),
|
|
|
|
.target(name: "OnyxNotch", dependencies: ["OnyxDesign"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "OnyxNotchTests", dependencies: ["OnyxNotch"]),
|
|
|
|
.testTarget(name: "OnyxDesignTests", dependencies: ["OnyxDesign"]),
|
|
|
|
.target(name: "OnyxWidgetKit", dependencies: ["OnyxDesign"]),
|
|
.testTarget(name: "OnyxWidgetKitTests", dependencies: ["OnyxWidgetKit"]),
|
|
|
|
.target(name: "OnyxMenuBar", dependencies: ["OnyxDesign", "OnyxWidgetKit"]),
|
|
.testTarget(name: "OnyxMenuBarTests", dependencies: ["OnyxMenuBar"]),
|
|
|
|
.target(name: "CalendarProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "CalendarProviderTests", dependencies: ["CalendarProvider"]),
|
|
|
|
.target(name: "WeatherProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "WeatherProviderTests", dependencies: ["WeatherProvider"]),
|
|
|
|
.target(name: "MediaProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "MediaProviderTests", dependencies: ["MediaProvider"]),
|
|
|
|
.target(name: "MetricsProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit", "OnyxMenuBar", "OnyxHelperProtocol"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "MetricsProviderTests", dependencies: ["MetricsProvider"]),
|
|
|
|
.target(name: "NetworkProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit", "OnyxMenuBar", "MetricsProvider"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "NetworkProviderTests", dependencies: ["NetworkProvider"]),
|
|
|
|
.target(name: "AudioProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "AudioProviderTests", dependencies: ["AudioProvider"]),
|
|
|
|
.target(name: "ShelfProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
|
|
resources: [.process("Localizable.xcstrings")]),
|
|
.testTarget(name: "ShelfProviderTests", dependencies: ["ShelfProvider"]),
|
|
]
|
|
)
|