diff --git a/AGENTS.md b/AGENTS.md index 42eaa83..697b8e7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,7 +69,7 @@ Repository: `ssh://git@git.stinnesbeck.com:2222/nils/mg4.git` (remote `origin`), | Tab | Contents | |---|---| -| Overview | value tiles (battery, range, range/usage/energy since start, 5-min averages of range, usage, power, speed), vehicle info (odometer, lease allowance and the odometer against it), tyre pressures; read every 0.2 s on a background thread. Five styles (Settings → Overview style): Tiles, Gauges (`GaugeView` needles), Cockpit (`RingView` rings, `TraceView` power trace), Retro (`RetroView`, seven-segment VFD), Futuristic (`FlowView`, animated energy flow) | +| Overview | value tiles (battery, range, range/usage/energy since start, 5-min averages of range, usage, power, speed), vehicle info (odometer, lease allowance and the odometer against it), tyre pressures; read every 0.2 s on a background thread. Styles (Settings → Overview style): Tiles, Gauges (`GaugeView` needles), Cockpit (`RingView` rings, `TraceView` power trace), Retro (`RetroView`, seven-segment VFD, classic or in the accent colour), Futuristic (`FlowView`, animated energy flow) | | Consumption / Charging | period totals, daily log, charging sessions and curve | | Live data | on/off, ABRP API key and user token, upload frequency | | Server | URL, pairing by QR, ingest token, installation ID (read-only), config import | diff --git a/README.md b/README.md index bad9809..291826d 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ with the server using a token of its own, obtained by pairing with a phone (belo | Tab | What it shows | |---|---| -| **Overview** | Battery, range, power and speed; range, usage and energy since start; 5-minute averages of range, usage, power and speed; vehicle info (odometer, climate setpoint) and tyre pressures. Read five times a second. Five looks to choose from in Settings → Overview style: Tiles, Gauges, Cockpit, Retro and Futuristic | +| **Overview** | Battery, range, power and speed; range, usage and energy since start; 5-minute averages of range, usage, power and speed; vehicle info (odometer, climate setpoint) and tyre pressures. Read five times a second. Looks to choose from in Settings → Overview style: Tiles, Gauges, Cockpit, Retro (classic turquoise or in your accent colour) and Futuristic | | **Consumption** | Lifetime, last 7 and 30 days, Trip A and B (distance, energy, average consumption and speed, SOC change), and a daily log of the last four months | | **Charging** | The current session (SOC, voltage, current, power, energy into the battery and from the grid, time, cost) and its SOC/power curve | | **Live data** | Live data on/off, ABRP credentials for sending directly from the car, upload frequency | diff --git a/SPECS.md b/SPECS.md index 273edef..a65574f 100644 --- a/SPECS.md +++ b/SPECS.md @@ -131,6 +131,12 @@ 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-24 — App 2.23.1 (branch `styles-retro-future`): "Retro (accent colour)", the Retro + style in the chosen paint colour — display in `evAccent`, labels in `evAccentLight`; + regeneration stays green, a low battery turns amber (not red, so it never looks like Dynamic + Red). Same `RetroView`, `setAccentPalette`; listed under Retro, stored as `RETRO_ACCENT`. + Checked on the emulator in Dynamic Red with sample values + (`screenshots/nilsmg4-2.23.1-retro-accent.png`). Not tried on the car. - 2026-10-24 — App 2.23.0 (branch `styles-retro-future`): two more Overview styles, each one Canvas view fed a `ClusterValues` per reading. **Retro** (`RetroView`): an 80s digital cluster as a vacuum fluorescent display — slanted seven-segment digits (`SevenSegment`, unit-tested) diff --git a/app/build.gradle b/app/build.gradle index ad19ae0..55868d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.stinnesbeck.nilsmg4" minSdk 27 targetSdk 36 - versionCode 115 - versionName "2.23.0" + versionCode 116 + versionName "2.23.1" // 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/MainActivity.java b/app/src/main/java/com/evsuite/abrp/MainActivity.java index 1411ecf..871b480 100644 --- a/app/src/main/java/com/evsuite/abrp/MainActivity.java +++ b/app/src/main/java/com/evsuite/abrp/MainActivity.java @@ -1442,7 +1442,7 @@ public class MainActivity extends AppCompatActivity { private Double dashTripKm; /** The stored values of the Overview styles, in the order of the drop-down. */ - private static final String[] OVERVIEW_STYLES = { "TILES", "GAUGES", "COCKPIT", "RETRO", "FUTURISTIC" }; + private static final String[] OVERVIEW_STYLES = { "TILES", "GAUGES", "COCKPIT", "RETRO", "RETRO_ACCENT", "FUTURISTIC" }; /** The chosen style's index in {@link #OVERVIEW_STYLES}; anything unknown is Tiles. */ private int overviewStyle() { @@ -1457,15 +1457,17 @@ public class MainActivity extends AppCompatActivity { vehiclePane.setVisibility(style == 0 ? View.VISIBLE : View.GONE); gaugesPane.setVisibility(style == 1 ? View.VISIBLE : View.GONE); cockpitPane.setVisibility(style == 2 ? View.VISIBLE : View.GONE); - retroPane.setVisibility(style == 3 ? View.VISIBLE : View.GONE); - futuristicPane.setVisibility(style == 4 ? View.VISIBLE : View.GONE); + // Retro in either palette: one pane, the view told which. + retroPane.setVisibility(style == 3 || style == 4 ? View.VISIBLE : View.GONE); + ((RetroView) retroPane.findViewById(R.id.retro_view)).setAccentPalette(style == 4); + futuristicPane.setVisibility(style == 5 ? View.VISIBLE : View.GONE); } - /** Tiles, Gauges, Cockpit, Retro or Futuristic; all are fed on every reading. */ + /** Tiles, Gauges, Cockpit, Retro (classic or accent colour) or Futuristic; all are fed on every reading. */ private void bindOverviewStyle() { String[] labels = { getString(R.string.overview_style_tiles), getString(R.string.overview_style_gauges), getString(R.string.overview_style_cockpit), getString(R.string.overview_style_retro), - getString(R.string.overview_style_futuristic) }; + getString(R.string.overview_style_retro_accent), getString(R.string.overview_style_futuristic) }; bindChoices(settingsPane.findViewById(R.id.overview_style_choices), labels, overviewStyle(), position -> { prefs.edit().putString(PREF_OVERVIEW_STYLE, OVERVIEW_STYLES[position]).apply(); diff --git a/app/src/main/java/com/evsuite/abrp/RetroView.java b/app/src/main/java/com/evsuite/abrp/RetroView.java index b14743f..dc7427e 100644 --- a/app/src/main/java/com/evsuite/abrp/RetroView.java +++ b/app/src/main/java/com/evsuite/abrp/RetroView.java @@ -20,6 +20,11 @@ import java.util.Locale; * Left: charge as a bar, the percentage and range. Right: 5-minute usage, the average since * start and the distance. Bottom: climate, clock, odometer. Unread values show dashes and light * no bar segments. The whole pane is one Canvas, redrawn only when a reading arrives. + * + * Two palettes: the classic one (turquoise display, amber labels), or the chosen accent colour + * for the display and its light shade for the labels ({@link #setAccentPalette}). Regeneration + * stays green in both; a low battery is red in the classic palette and amber in the accent one, + * so it never looks like the accent itself. */ public final class RetroView extends View { @@ -33,24 +38,36 @@ public final class RetroView extends View { private final Paint bezel = new Paint(Paint.ANTI_ALIAS_FLAG); private final Path path = new Path(); private final RectF rect = new RectF(); - private final int lit, regen, amber, warn; + private final int classicLit, classicLabel, classicWarn, accentLit, accentLabel, regen; + private int lit, amber, warn; private ClusterValues v = new ClusterValues(); public RetroView(Context context, AttributeSet attrs) { super(context, attrs); - lit = context.getColor(R.color.retro_lit); + classicLit = context.getColor(R.color.retro_lit); + classicLabel = context.getColor(R.color.retro_label); + classicWarn = context.getColor(R.color.retro_warn); + accentLit = AccentColor.resolve(context, R.attr.evAccent); + accentLabel = AccentColor.resolve(context, R.attr.evAccentLight); regen = context.getColor(R.color.retro_regen); - amber = context.getColor(R.color.retro_label); - warn = context.getColor(R.color.retro_warn); - ghost.setColor(AccentColor.withAlpha(lit, 0x14)); glow.setStyle(Paint.Style.STROKE); glow.setStrokeJoin(Paint.Join.ROUND); - label.setColor(amber); label.setTypeface(Typeface.create(Typeface.MONOSPACE, Typeface.BOLD)); label.setLetterSpacing(0.12f); panel.setColor(context.getColor(R.color.retro_panel)); bezel.setStyle(Paint.Style.STROKE); bezel.setColor(context.getColor(R.color.retro_bezel)); + setAccentPalette(false); + } + + /** The chosen accent colour instead of the classic turquoise and amber. */ + void setAccentPalette(boolean accent) { + lit = accent ? accentLit : classicLit; + amber = accent ? accentLabel : classicLabel; + warn = accent ? classicLabel : classicWarn; + ghost.setColor(AccentColor.withAlpha(lit, 0x14)); + label.setColor(amber); + invalidate(); } void setValues(ClusterValues values) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b199b6..2323bca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -130,6 +130,7 @@ Cockpit Retro Futuristic + Retro (accent colour) BATTERY USAGE · 5 MIN kWh/100 km diff --git a/screenshots/nilsmg4-2.23.1-retro-accent.png b/screenshots/nilsmg4-2.23.1-retro-accent.png new file mode 100644 index 0000000..4a48cec Binary files /dev/null and b/screenshots/nilsmg4-2.23.1-retro-accent.png differ