diff --git a/Packages/OnyxKit/Sources/MetricsProvider/BatteryGlyph.swift b/Packages/OnyxKit/Sources/MetricsProvider/BatteryGlyph.swift index 50a0b6c..e529483 100644 --- a/Packages/OnyxKit/Sources/MetricsProvider/BatteryGlyph.swift +++ b/Packages/OnyxKit/Sources/MetricsProvider/BatteryGlyph.swift @@ -87,20 +87,26 @@ public enum BatteryGlyph { glyph.insetBy(dx: -outlineWidth, dy: -outlineWidth) } - /// Wie hoch das Zeichen im Verhältnis zum Akku ist. + /// Wie hoch das Zeichen im Akku ist. /// - /// Das Pausenzeichen ist von Haus aus höher als der Blitz und stößt sonst - /// oben und unten an den Rahmen. + /// Bezugsgröße ist der **Innenraum**, nicht die Außenhöhe: der Rahmen + /// nimmt oben und unten je einen Punkt, die Füllung sitzt zwei Punkte + /// eingerückt, und um das Zeichen kommt noch sein eigener Rand. Wer von + /// der Außenhöhe ausgeht, landet bei einem Blitz, der den ganzen Akku + /// ausfüllt und an den Rahmen stößt. public static func glyphHeight(for indicator: Indicator, in height: CGFloat) -> CGFloat { - // Der Rand kommt außen noch dazu — bei voller Höhe stößt das Zeichen - // deshalb oben und unten an den Rahmen des Akkus. - let usable = height - 1 - 2 * outlineWidth + let inner = height - 2 * fillInset + let usable = max(inner - 2 * outlineWidth, 1) switch indicator { - case .paused: return usable * 0.7 + // Das Pausenzeichen ist von Haus aus höher gebaut als der Blitz. + case .paused: return usable * 0.8 default: return usable } } + /// Wie weit die Füllung vom Rahmen abrückt. + public static let fillInset: CGFloat = 2 + /// Wie lange ein voller Hin- und Rückweg des Blitzes dauert. public static let fadeDuration: TimeInterval = 2.2 diff --git a/Packages/OnyxKit/Tests/MetricsProviderTests/BatteryGlyphTests.swift b/Packages/OnyxKit/Tests/MetricsProviderTests/BatteryGlyphTests.swift index faccd02..7e890e5 100644 --- a/Packages/OnyxKit/Tests/MetricsProviderTests/BatteryGlyphTests.swift +++ b/Packages/OnyxKit/Tests/MetricsProviderTests/BatteryGlyphTests.swift @@ -231,3 +231,26 @@ struct BatteryOutlineTests { } } } + +@Suite("Größe des Zeichens") +struct BatteryGlyphSizeTests { + + private let height = BatteryGlyph.size.height + + @Test("Das Zeichen passt samt Rand in den Innenraum") + func glyphAndOutlineFitInside() { + // Der Fehler, um den es ging: von der Außenhöhe ausgegangen, füllte der + // Blitz den ganzen Akku und stieß an den Rahmen. + let inner = height - 2 * BatteryGlyph.fillInset + for indicator in BatteryGlyph.Indicator.allCases { + let glyph = BatteryGlyph.glyphHeight(for: indicator, in: height) + #expect(glyph + 2 * BatteryGlyph.outlineWidth <= inner + 0.001) + } + } + + @Test("Es bleibt trotzdem sichtbar groß") + func glyphIsNotTiny() { + // Auf die andere Seite zu übertreiben hilft auch niemandem. + #expect(BatteryGlyph.glyphHeight(for: .bolt, in: height) >= height * 0.4) + } +}