Blitz aus der mitgelieferten Vorlage, weiterhin fadend
`bolt.fill` aus SF Symbols ist eine massive Fläche; die neue Datei ist eine Kontur mit kräftigem Strich und trifft die Form besser. Gezeichnet wird sie zweifach wie zuvor: einmal etwas größer in der Gegenfarbe als Rand, einmal in der fadenden Farbe darüber. Damit bleibt der Blitz in jedem Moment des Fadens lesbar — über der hellen Füllung trägt ihn der Rand, über dem leeren Teil er sich selbst. Fehlt die Datei, bleibt das Systemsymbol. Dieselbe Vorlage auch in der Akku-Kachel, damit nicht zwei verschiedene Blitze in einer App stehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,17 @@ public enum BatteryGlyph {
|
||||
return (filled, empty)
|
||||
}
|
||||
|
||||
/// Der Blitz als eigene Vorlage.
|
||||
///
|
||||
/// SF Symbols' `bolt.fill` ist eine massive Fläche; die mitgelieferte
|
||||
/// Kontur trifft die Form besser und bringt schon einen kräftigen Strich
|
||||
/// mit. Fehlt die Datei, bleibt das Systemsymbol.
|
||||
public static let chargingGlyph: NSImage? = {
|
||||
guard let url = Bundle.main.url(forResource: "thunder", withExtension: "svg")
|
||||
else { return nil }
|
||||
return NSImage(contentsOf: url)
|
||||
}()
|
||||
|
||||
/// Wie dick der Rand um das Zeichen ist.
|
||||
public static let outlineWidth: CGFloat = 1
|
||||
|
||||
@@ -186,18 +197,26 @@ public enum BatteryGlyph {
|
||||
return
|
||||
}
|
||||
|
||||
// Der Blitz: weiß mit dünnem dunklem Rand, und fadend.
|
||||
// Der Blitz: mit dunklem Rand, und fadend.
|
||||
//
|
||||
// Der Rand ist immer die Gegenfarbe zur Füllung. Damit bleibt er in
|
||||
// **jedem** Moment des Fadens lesbar: über der hellen Füllung trägt ihn
|
||||
// der Rand, über dem leeren Teil die Füllung selbst.
|
||||
// Der Rand ist immer die Gegenfarbe zum Blitz selbst. Damit bleibt er
|
||||
// in **jedem** Moment des Fadens lesbar: über der hellen Füllung trägt
|
||||
// ihn der Rand, über dem leeren Teil der Blitz.
|
||||
let whiteness = boltWhiteness(phase: fadePhase)
|
||||
if let outline = tint(glyph, with: NSColor(white: 1 - whiteness, alpha: 1)) {
|
||||
let inverseColor = NSColor(white: 1 - whiteness, alpha: 1)
|
||||
let boltColor = NSColor(white: whiteness, alpha: 1)
|
||||
|
||||
if let custom = chargingGlyph {
|
||||
MenuBarText.drawTemplate(custom, color: inverseColor, in: outlineRect(glyphRect))
|
||||
MenuBarText.drawTemplate(custom, color: boltColor, in: glyphRect)
|
||||
return
|
||||
}
|
||||
if let outline = tint(glyph, with: inverseColor) {
|
||||
outline.draw(in: outlineRect(glyphRect), from: .zero,
|
||||
operation: .sourceOver, fraction: 1)
|
||||
}
|
||||
if let body = tint(glyph, with: NSColor(white: whiteness, alpha: 1)) {
|
||||
body.draw(in: glyphRect, from: .zero, operation: .sourceOver, fraction: 1)
|
||||
if let filled = tint(glyph, with: boltColor) {
|
||||
filled.draw(in: glyphRect, from: .zero, operation: .sourceOver, fraction: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,11 +277,9 @@ public struct BatteryGlyphView: View {
|
||||
/ BatteryGlyph.fadeDuration
|
||||
let whiteness = BatteryGlyph.boltWhiteness(phase: phase)
|
||||
ZStack {
|
||||
Image(systemName: name)
|
||||
.font(.system(size: size + 2 * BatteryGlyph.outlineWidth))
|
||||
bolt(name: name, side: size + 2 * BatteryGlyph.outlineWidth)
|
||||
.foregroundStyle(Color(white: 1 - whiteness))
|
||||
Image(systemName: name)
|
||||
.font(.system(size: size))
|
||||
bolt(name: name, side: size)
|
||||
.foregroundStyle(Color(white: whiteness))
|
||||
}
|
||||
}
|
||||
@@ -282,6 +299,20 @@ public struct BatteryGlyphView: View {
|
||||
.frame(width: width, height: height)
|
||||
}
|
||||
|
||||
/// Dieselbe Vorlage wie in der Menüleiste, sonst das Systemsymbol.
|
||||
@ViewBuilder
|
||||
private func bolt(name: String, side: CGFloat) -> some View {
|
||||
if let custom = BatteryGlyph.chargingGlyph {
|
||||
Image(nsImage: custom)
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: side, height: side)
|
||||
} else {
|
||||
Image(systemName: name).font(.system(size: side))
|
||||
}
|
||||
}
|
||||
|
||||
private var fillColor: Color {
|
||||
BatteryGlyph.isLow(charge: charge, isCharging: isCharging) ? .red : .primary
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user