Blitz misst sich am Innenraum, nicht an der Außenhöhe

Bezugsgröße war die volle Höhe des Akkus. Der Rahmen nimmt aber oben und
unten je einen Punkt, die Füllung sitzt zwei Punkte eingerückt, und um das
Zeichen kommt noch sein eigener Rand — so füllte der Blitz mitsamt Rand elf
von zwölf Punkten und stieß an den Rahmen.

Jetzt ist der Innenraum die Bezugsgröße: sechs Punkte Zeichen plus zwei Rand
in acht Punkten Innenraum. Ein Test hält fest, dass jedes Zeichen samt Rand
hineinpasst — und dass es nicht ins andere Extrem fällt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-13 14:13:41 +02:00
parent 2bf76eb060
commit 80b083259e
2 changed files with 36 additions and 7 deletions

View File

@@ -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

View File

@@ -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)
}
}