App 2.43.2: Halloween's teeth are triangles in the right colour

They hang from the grin's upper lip, each in the colour of the rib behind
it: the right one was the darker orange on the lighter rib. Not tried on
the car.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
2026-10-31 13:06:35 +01:00
co-authored by Claude Opus 5.5
parent 1686b791bc
commit ee7cf85255
5 changed files with 24 additions and 11 deletions
+1
View File
@@ -140,6 +140,7 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does *
confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces
upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator`
(Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked).
- 2026-10-31 — App 2.43.2: Halloween's teeth are triangles hanging from the grin's upper lip, each in the colour of the rib behind it (the right one was the darker orange on the lighter rib; owner: "the color on the right side is off"). Two screenshots redone. Tested: unit tests, lint, emulator with sample values (drawing in panel and full screen, regenerating in full screen) and with no data. Not tried on the car.
- 2026-10-31 — App 2.43.1 published (`car-2.43.1`).
- 2026-10-31 — App 2.43.1: Halloween's bats can be seen. They were near-black and small on the darkest part of the sky, and the owner did not spot them; now a moonlit purple-grey with a light edge, a third larger. Two screenshots redone. Tested: unit tests, lint, emulator with sample values (panel and full screen) and with no data (no bats). Not tried on the car.
- 2026-10-31 — App 2.43.0 published (`car-2.43.0`).
+2 -2
View File
@@ -34,8 +34,8 @@ android {
applicationId "com.stinnesbeck.nilsmg4"
minSdk 27
targetSdk 36
versionCode 154
versionName "2.43.1"
versionCode 155
versionName "2.43.2"
// Nothing about the server ships in the APK: its URL and ingest token are entered in
// the app's Server tab (ServerConfig), and the database is only reachable by the server.
@@ -339,10 +339,9 @@ final class HalloweenView extends ClusterCanvasView {
fill.setColor(burn);
c.drawPath(path, fill);
c.restore();
// Two teeth at the grin's corners, clear of the digits.
fill.setColor(PUMPKIN);
tooth(c, cx - 120f * u, gt + 12f * u, 15f * u, 28f * u);
tooth(c, cx + 120f * u, gt + 12f * u, 15f * u, 28f * u);
// Two teeth at the grin's corners, clear of the digits, each the colour of the rib it hangs from.
tooth(c, cx, -120f * u, gw, gt, 26f * u, 17f * u, gt + 40f * u, PUMPKIN, u);
tooth(c, cx, 120f * u, gw, gt, 26f * u, 17f * u, gt + 40f * u, PUMPKIN_LIT, u);
label(c, fmt(v.speedKmh, "%.0f", "—"), cx, gb - 18f * u, 92f * u, INK, serif, Paint.Align.CENTER);
label(c, "KM/H", cx + 80f * u, cy + 64f * u, 16f * u, INK, face, Paint.Align.LEFT);
// The power under the pumpkin, above the ridge.
@@ -364,14 +363,27 @@ final class HalloweenView extends ClusterCanvasView {
c.drawPath(path, line);
}
private void tooth(Canvas c, float x, float y, float halfW, float tall) {
/** A triangle hanging from the grin's upper lip (a curve sagging by {@code sag}) to {@code tipY}. */
private void tooth(Canvas c, float cx, float dx, float gw, float gt, float sag, float halfW, float tipY, int colour, float u) {
float left = lip(dx - halfW, gw, gt, sag), right = lip(dx + halfW, gw, gt, sag);
path.reset();
path.moveTo(x - halfW, y - tall * 0.3f);
path.lineTo(x + halfW, y - tall * 0.3f);
path.lineTo(x + halfW, y + tall * 0.7f);
path.lineTo(x - halfW, y + tall * 0.7f);
// A little above the lip, so none of its dark edge shows across the tooth's root.
path.moveTo(cx + dx - halfW, left - 1.5f * u);
path.lineTo(cx + dx + halfW, right - 1.5f * u);
path.lineTo(cx + dx, tipY);
path.close();
fill.setColor(colour);
c.drawPath(path, fill);
line.setColor(0xFF4A1F04);
line.setStrokeWidth(3f * u);
c.drawLine(cx + dx - halfW, left + 2f * u, cx + dx, tipY, line);
c.drawLine(cx + dx + halfW, right + 2f * u, cx + dx, tipY, line);
}
/** The height of the grin's upper lip {@code dx} from the middle. */
private static float lip(float dx, float gw, float gt, float sag) {
float t = (gw - Math.abs(dx)) / (2f * gw);
return gt + 2f * t * (1f - t) * sag;
}
// ---------- Left: the sign under the cobweb ----------
Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

After

Width:  |  Height:  |  Size: 304 KiB