diff --git a/SPECS.md b/SPECS.md index b1709fb..d82f798 100644 --- a/SPECS.md +++ b/SPECS.md @@ -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`). diff --git a/app/build.gradle b/app/build.gradle index 937ede9..66fa525 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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. diff --git a/app/src/main/java/com/evsuite/abrp/HalloweenView.java b/app/src/main/java/com/evsuite/abrp/HalloweenView.java index b49c67d..4e87aea 100644 --- a/app/src/main/java/com/evsuite/abrp/HalloweenView.java +++ b/app/src/main/java/com/evsuite/abrp/HalloweenView.java @@ -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 ---------- diff --git a/screenshots/themes/halloween-panel.png b/screenshots/themes/halloween-panel.png index 3fa386e..b724082 100644 Binary files a/screenshots/themes/halloween-panel.png and b/screenshots/themes/halloween-panel.png differ diff --git a/screenshots/themes/halloween.png b/screenshots/themes/halloween.png index de4e848..98eee26 100644 Binary files a/screenshots/themes/halloween.png and b/screenshots/themes/halloween.png differ