Kacheln und Fenster sprechen dieselbe Sprache
Alle Kacheln, Popovers und Fenster auf die Designschicht umgestellt: rund hundert gesetzte Schriftgrößen und 159 gesetzte Abstände und Radien sind jetzt Token. Übrig bleibt `spacing: 0` — das ist eine Aussage, keine geratene Zahl. Die Einstellungen bekommen eine Seitenleiste statt sieben Reitern, deren deutsche Beschriftungen zusammen 880 Punkte brauchten. Panel-Token stehen nicht mehr in Fenstern: dort gilt Systemsemantik, damit der Hellmodus nicht schwarz auf schwarz endet. Neu ist ein Schaufenster, das alle Bauteile nebeneinander zeigt — ohne das lässt sich eine Änderung an einem Token nur prüfen, indem man die App bedient, bis jede Kachel einmal zu sehen war. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9b600de9a9
commit
edb327cabe
@@ -20,6 +20,9 @@ final class AppModel {
|
||||
var onLayoutChanged: (([WidgetPlacement]) -> Void)?
|
||||
/// Wird gerufen, wenn Panels auf anderen Displays erscheinen sollen.
|
||||
var onDisplayPolicyChanged: ((DisplayPolicy) -> Void)?
|
||||
var onShowsIdleIslandChanged: ((Bool) -> Void)?
|
||||
var onNotchStyleChanged: ((NotchStyle) -> Void)?
|
||||
var onNotchWidthsChanged: (([CGDirectDisplayID: CGFloat]) -> Void)?
|
||||
|
||||
var layout: [WidgetPlacement] {
|
||||
didSet {
|
||||
@@ -37,6 +40,68 @@ final class AppModel {
|
||||
}
|
||||
}
|
||||
|
||||
/// Abweichende Inselbreiten, je Bildschirm — leer heißt „Standardbreite".
|
||||
///
|
||||
/// Als Wörterbuch über die `CGDirectDisplayID` und nicht als Liste über den
|
||||
/// Index in `NSScreen.screens`: der Index ändert sich beim Umstecken, die
|
||||
/// Kennung nicht. Sonst gälte die Einstellung des einen Monitors plötzlich
|
||||
/// für den anderen.
|
||||
private(set) var notchWidths: [CGDirectDisplayID: CGFloat] = [:]
|
||||
|
||||
/// Die eingestellte Breite dieses Bildschirms, falls es eine gibt.
|
||||
func notchWidth(for displayID: CGDirectDisplayID) -> CGFloat? {
|
||||
notchWidths[displayID]
|
||||
}
|
||||
|
||||
/// Setzt eine abweichende Breite — oder nimmt sie mit `nil` zurück.
|
||||
func setNotchWidth(_ width: CGFloat?, for displayID: CGDirectDisplayID) {
|
||||
if let width { notchWidths[displayID] = width } else { notchWidths[displayID] = nil }
|
||||
// Als Zeichenkette gespeichert, weil `UserDefaults` keine Wörterbücher
|
||||
// mit Zahlenschlüsseln kann.
|
||||
let raw = notchWidths.reduce(into: [String: Double]()) { $0[String($1.key)] = Double($1.value) }
|
||||
defaults.set(raw, forKey: Keys.notchWidths)
|
||||
onNotchWidthsChanged?(notchWidths)
|
||||
}
|
||||
|
||||
/// Was links neben der Notch steht.
|
||||
var bandLeading: BandAccessory {
|
||||
didSet {
|
||||
guard bandLeading != oldValue else { return }
|
||||
defaults.set(bandLeading.rawValue, forKey: Keys.bandLeading)
|
||||
}
|
||||
}
|
||||
|
||||
/// Was rechts daneben steht.
|
||||
var bandTrailing: BandAccessory {
|
||||
didSet {
|
||||
guard bandTrailing != oldValue else { return }
|
||||
defaults.set(bandTrailing.rawValue, forKey: Keys.bandTrailing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Notch oder Insel — die Form, die Onyx oben annimmt.
|
||||
var notchStyle: NotchStyle {
|
||||
didSet {
|
||||
guard notchStyle != oldValue else { return }
|
||||
defaults.set(notchStyle.rawValue, forKey: Keys.notchStyle)
|
||||
onNotchStyleChanged?(notchStyle)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ob die eingeklappte Insel sichtbar stehen bleibt.
|
||||
///
|
||||
/// Standardmäßig an: ohne sie wächst das Panel auf externen Bildschirmen
|
||||
/// aus dem Nichts. Abschaltbar, weil ein schwarzer Balken auf vier
|
||||
/// Monitoren eine Geschmacksfrage ist und keine Voreinstellung sein darf,
|
||||
/// von der man nicht wegkommt.
|
||||
var showsIdleIsland: Bool {
|
||||
didSet {
|
||||
guard showsIdleIsland != oldValue else { return }
|
||||
defaults.set(showsIdleIsland, forKey: Keys.showsIdleIsland)
|
||||
onShowsIdleIslandChanged?(showsIdleIsland)
|
||||
}
|
||||
}
|
||||
|
||||
var showsMenuBarIcon: Bool {
|
||||
didSet { defaults.set(showsMenuBarIcon, forKey: Keys.showsMenuBarIcon) }
|
||||
}
|
||||
@@ -86,6 +151,11 @@ final class AppModel {
|
||||
private enum Keys {
|
||||
static func menuBarModule(_ id: String) -> String { "onyx.menubar.module.\(id)" }
|
||||
static let displayPolicy = "onyx.displayPolicy"
|
||||
static let showsIdleIsland = "onyx.showsIdleIsland"
|
||||
static let notchStyle = "onyx.notchStyle"
|
||||
static let notchWidths = "onyx.notchWidths"
|
||||
static let bandLeading = "onyx.band.leading"
|
||||
static let bandTrailing = "onyx.band.trailing"
|
||||
static let showsMenuBarIcon = "onyx.showsMenuBarIcon"
|
||||
static let showsDockIcon = "onyx.showsDockIcon"
|
||||
static let triggerArea = "onyx.triggerArea"
|
||||
@@ -101,6 +171,21 @@ final class AppModel {
|
||||
self.displayPolicy = defaults.string(forKey: Keys.displayPolicy)
|
||||
.flatMap(DisplayPolicy.init(rawValue:)) ?? .builtInOnly
|
||||
|
||||
self.showsIdleIsland = defaults.object(forKey: Keys.showsIdleIsland) as? Bool ?? true
|
||||
self.notchStyle = defaults.string(forKey: Keys.notchStyle)
|
||||
.flatMap(NotchStyle.init(rawValue:)) ?? .automatic
|
||||
// Die bisherige feste Verdrahtung als Voreinstellung: wer nichts
|
||||
// einstellt, sieht, was vorher auch dastand.
|
||||
self.bandLeading = defaults.string(forKey: Keys.bandLeading)
|
||||
.flatMap(BandAccessory.init(rawValue:)) ?? .weather
|
||||
self.bandTrailing = defaults.string(forKey: Keys.bandTrailing)
|
||||
.flatMap(BandAccessory.init(rawValue:)) ?? .battery
|
||||
self.notchWidths = (defaults.dictionary(forKey: Keys.notchWidths) as? [String: Double] ?? [:])
|
||||
.reduce(into: [CGDirectDisplayID: CGFloat]()) { result, entry in
|
||||
guard let id = CGDirectDisplayID(entry.key) else { return }
|
||||
result[id] = CGFloat(entry.value)
|
||||
}
|
||||
|
||||
// Standardmäßig sichtbar: das Menüleistensymbol ist der einzige Weg
|
||||
// zurück, wenn die Notch einmal nicht reagiert.
|
||||
self.showsMenuBarIcon = defaults.object(forKey: Keys.showsMenuBarIcon) as? Bool ?? true
|
||||
|
||||
Reference in New Issue
Block a user