Akku wird gezeichnet wie der von macOS
Der Blitz stand neben dem Akku statt darin, und das sah nach zwei Dingen aus statt nach einem. Mit SF Symbols ging es nicht anders: fünf feste Füllstufen, und Blitz-Varianten gibt es nur bei hundert Prozent. Also selbst gezeichnet — ein Rahmen, ein Knubbel, eine Füllung, ein Blitz. Das ist am Ende die kleinere Lösung als die Symbolakrobatik und gibt obendrein, was vorher fehlte: die Füllung läuft stufenlos, 60 % sieht aus wie 60 % und nicht wie 50 %. Der Blitz wird ausgestanzt, nicht daraufgelegt. `destinationOut` nimmt weg, was vorher gezeichnet wurde; übrig bleibt ein Loch in Blitzform, durch das die Menüleiste scheint. Das funktioniert auf hellem wie dunklem Grund, ohne die Hintergrundfarbe zu kennen — und genau so sieht der von macOS aus. Unter zwanzig Prozent wird die Füllung rot, beim Laden nie: eine Warnung vor etwas, das sich schon erledigt, ist keine. Dieselbe Form auch in der Akku-Kachel. Zwei verschiedene Akkus in einer App wären schlechter als gar keiner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,17 +122,14 @@ final class MetricStatusView: NSView, WidthReporting {
|
||||
/// jedes Prozent alle Symbole rechts davon hin und her.
|
||||
private var width: CGFloat {
|
||||
switch presentation {
|
||||
case .symbol: max(MenuBarText.minimumWidth,
|
||||
MenuBarText.symbolWidth(currentSymbol, height: 15) + 4)
|
||||
case .symbol: max(MenuBarText.minimumWidth, symbolSlot + 4)
|
||||
case .graph: 28
|
||||
case .bars: barsWidth
|
||||
case .value: MenuBarText.width(for: reference)
|
||||
case .valueAndGraph: MenuBarText.width(for: reference) + 2 + 28
|
||||
case .labelAndValue: MenuBarText.width(for: "\(label) \(reference)")
|
||||
case .symbolAndValue:
|
||||
MenuBarText.width(for: reference)
|
||||
+ MenuBarText.symbolWidth(currentSymbol, height: 13)
|
||||
+ MenuBarText.innerGap
|
||||
MenuBarText.width(for: reference) + symbolSlot + MenuBarText.innerGap
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,10 +197,15 @@ final class MetricStatusView: NSView, WidthReporting {
|
||||
drawText("\(label) \(displayValue)", color: color)
|
||||
|
||||
case .symbolAndValue:
|
||||
let glyph = MenuBarText.symbolWidth(currentSymbol, height: 13)
|
||||
let symbolRect = NSRect(x: 0, y: bounds.midY - 6.5, width: glyph, height: 13)
|
||||
MenuBarText.drawSymbol(currentSymbol, color: color, in: symbolRect)
|
||||
drawChargingBolt(color: color, over: symbolRect)
|
||||
let glyph = symbolSlot
|
||||
if metric == .battery {
|
||||
drawBattery(color: color,
|
||||
at: NSPoint(x: 0, y: bounds.midY - BatteryGlyph.size.height / 2))
|
||||
} else {
|
||||
MenuBarText.drawSymbol(currentSymbol, color: color,
|
||||
in: NSRect(x: 0, y: bounds.midY - 6.5,
|
||||
width: glyph, height: 13))
|
||||
}
|
||||
drawText(displayValue, color: color,
|
||||
in: NSRect(x: glyph + MenuBarText.innerGap, y: 0,
|
||||
width: bounds.width - glyph - MenuBarText.innerGap,
|
||||
@@ -224,12 +226,39 @@ final class MetricStatusView: NSView, WidthReporting {
|
||||
}
|
||||
|
||||
private func drawSymbol(color: NSColor) {
|
||||
if metric == .battery {
|
||||
drawBattery(color: color,
|
||||
at: NSPoint(x: bounds.midX - BatteryGlyph.size.width / 2,
|
||||
y: bounds.midY - BatteryGlyph.size.height / 2))
|
||||
return
|
||||
}
|
||||
let side: CGFloat = 15
|
||||
let width = MenuBarText.symbolWidth(currentSymbol, height: side)
|
||||
let rect = NSRect(x: bounds.midX - width / 2, y: bounds.midY - side / 2,
|
||||
width: width, height: side)
|
||||
MenuBarText.drawSymbol(currentSymbol, color: color, in: rect)
|
||||
drawChargingBolt(color: color, over: rect)
|
||||
MenuBarText.drawSymbol(currentSymbol, color: color,
|
||||
in: NSRect(x: bounds.midX - width / 2,
|
||||
y: bounds.midY - side / 2,
|
||||
width: width, height: side))
|
||||
}
|
||||
|
||||
/// Der Akku wird selbst gezeichnet — mit stufenloser Füllung und dem Blitz
|
||||
/// mitten drin, so wie macOS es zeigt.
|
||||
private func drawBattery(color: NSColor, at origin: NSPoint) {
|
||||
guard let battery = snapshot.battery else {
|
||||
MenuBarText.drawSymbol(BatterySymbol.unavailable, color: color,
|
||||
in: NSRect(x: origin.x, y: origin.y,
|
||||
width: 15, height: 15))
|
||||
return
|
||||
}
|
||||
BatteryGlyph.draw(charge: battery.charge, isCharging: battery.isCharging,
|
||||
color: color,
|
||||
in: CGRect(origin: origin, size: BatteryGlyph.size))
|
||||
}
|
||||
|
||||
/// Wie breit das Glyph ist. Der Akku wird selbst gezeichnet und hat eigene
|
||||
/// Maße; alles andere ist ein SF-Symbol.
|
||||
private var symbolSlot: CGFloat {
|
||||
metric == .battery ? BatteryGlyph.size.width
|
||||
: MenuBarText.symbolWidth(currentSymbol, height: 13)
|
||||
}
|
||||
|
||||
/// Das Symbol zum **Zustand**, nicht zur Metrik.
|
||||
@@ -244,17 +273,6 @@ final class MetricStatusView: NSView, WidthReporting {
|
||||
return BatterySymbol.name(charge: battery.charge)
|
||||
}
|
||||
|
||||
/// Beim Laden ein kleiner Blitz über dem Füllstand. Zwei Zeichnungen statt
|
||||
/// eines Symbols, weil es die kombinierten Glyphen nur bei 100 % gibt.
|
||||
private func drawChargingBolt(color: NSColor, over rect: NSRect) {
|
||||
guard metric == .battery, snapshot.battery?.isCharging == true else { return }
|
||||
let side: CGFloat = 8
|
||||
MenuBarText.drawSymbol(BatterySymbol.chargingBolt, color: color,
|
||||
in: NSRect(x: rect.maxX - side * 0.75,
|
||||
y: rect.maxY - side * 0.7,
|
||||
width: side, height: side))
|
||||
}
|
||||
|
||||
private func drawGraph(color: NSColor, in rect: NSRect) {
|
||||
guard history.count > 1, let context = NSGraphicsContext.current?.cgContext else { return }
|
||||
let step = rect.width / CGFloat(history.count - 1)
|
||||
|
||||
Reference in New Issue
Block a user