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:
@@ -87,20 +87,26 @@ public enum BatteryGlyph {
|
|||||||
glyph.insetBy(dx: -outlineWidth, dy: -outlineWidth)
|
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
|
/// Bezugsgröße ist der **Innenraum**, nicht die Außenhöhe: der Rahmen
|
||||||
/// oben und unten an den 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 {
|
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
|
let inner = height - 2 * fillInset
|
||||||
// deshalb oben und unten an den Rahmen des Akkus.
|
let usable = max(inner - 2 * outlineWidth, 1)
|
||||||
let usable = height - 1 - 2 * outlineWidth
|
|
||||||
switch indicator {
|
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
|
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.
|
/// Wie lange ein voller Hin- und Rückweg des Blitzes dauert.
|
||||||
public static let fadeDuration: TimeInterval = 2.2
|
public static let fadeDuration: TimeInterval = 2.2
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user