diff --git a/AGENTS.md b/AGENTS.md index 41d01b4..e1b5a3f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -75,7 +75,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. Styles (Settings → Overview style): Tiles, Gauges (`GaugeView` needles), Cockpit (`RingView` rings, `TraceView` power trace), Retro (`RetroView`, seven-segment VFD), Futuristic (`FlowView`, animated energy flow), Sci-fi (`SciFiView`, starship console), Cartoon (`CartoonView`), Blueprint (`BlueprintView`, top-view drawing with tyre pressures), MG (`OctagonView`, octagonal dials after the classic MG dashboards), and on `ClusterCanvasView`: Minimal, Terminal, Aviation, Nixie tubes, Chronograph, Mascot (`MascotView`, an anime co-pilot whose face follows `MascotMood`; classic, `ChibiFigure` or `FoxFigure` on `ChibiBase`, chosen by `MascotCharacter`); the drawn styles share `ClusterValues`. A button in the navigation's header hides the navigation for a full-width Overview (`PREF_OVERVIEW_FULLSCREEN`); a swipe in from the left edge (`EdgeSwipe`) brings it back. Pages change only by the navigation (the pager's own swiping is off) | +| 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), Futuristic (`FlowView`, animated energy flow), Sci-fi (`SciFiView`, starship console), Cartoon (`CartoonView`), Blueprint (`BlueprintView`, top-view drawing with tyre pressures), MG (`OctagonView`, octagonal dials after the classic MG dashboards), and on `ClusterCanvasView`: Minimal, Terminal, Aviation, Nixie tubes, Chronograph, Mascot (`MascotView`, an anime co-pilot whose face follows `MascotMood`; classic, `ChibiFigure` or `FoxFigure` on `ChibiBase`, chosen by `MascotCharacter`); the drawn styles share `ClusterValues`. A button in the navigation's header hides the navigation for a full-width Overview (`PREF_OVERVIEW_FULLSCREEN`); a swipe in from the left edge (`EdgeSwipe`) brings it back; without the app's own full screen the car's sidebar takes that edge, so a tab at the left edge (`edge_tab`) is tapped or swiped instead. Pages change only by the navigation (the pager's own swiping is off) | | 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 f4dee9f..faa8959 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. Looks to choose from in Settings → Overview style: Tiles, Gauges, Cockpit, Retro, Futuristic, Sci-fi, Cartoon, Blueprint, MG, Minimal, Terminal, Aviation, Nixie tubes, Chronograph and Mascot (an anime co-pilot who reacts to the drive, classic, chibi or a chibi fox). The small button next to the MG4 logo in the navigation hides the navigation for a full-width Overview; swipe in from the left edge (a faint handle marks it) to bring it back. Pages change only by the navigation, not by swiping sideways | +| **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, Futuristic, Sci-fi, Cartoon, Blueprint, MG, Minimal, Terminal, Aviation, Nixie tubes, Chronograph and Mascot (an anime co-pilot who reacts to the drive, classic, chibi or a chibi fox). The small button next to the MG4 logo in the navigation hides the navigation for a full-width Overview; swipe in from the left edge (a faint handle marks it) to bring it back; with Settings → Full screen off, the car's own sidebar sits at that edge, so tap the small tab at the left edge (›) instead. Pages change only by the navigation, not by swiping sideways | | **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 eb20ec0..c1c68d6 100644 --- a/SPECS.md +++ b/SPECS.md @@ -138,6 +138,15 @@ 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-25 — App 2.34.1 (branch `styles-retro-future`): the Overview's full screen without the + app's full screen. With the car's bars shown, the car's own sidebar sits at the left edge, so a + swipe from the edge lands on it, not on the app (owner, on the car). There a small tab now sits + at the app's left edge instead of the faint handle (48 × 96 dp touch area, a dark tongue with + ›): a tap brings the navigation back, and so does a swipe starting in the app's first 56 dp + (`tabSwipe`). In the app's full screen nothing changed (handle and edge swipe, the owner's + preference: least clutter). Switching Full screen on Settings updates it at once. Emulator: + the tab shows, a tap and a swipe on the left strip both bring the navigation back. Not tried + on the car. - 2026-10-25 — App 2.34.0 (branch `styles-retro-future`): **drive mode at start.** The car falls back to its own default mode when switched on; with "Set at start" (on by default, the switch in the drive mode card) the app sets the mode last chosen on Settings again. Only a choice the diff --git a/app/build.gradle b/app/build.gradle index 5f6327b..8e63af3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.stinnesbeck.nilsmg4" minSdk 27 targetSdk 36 - versionCode 133 - versionName "2.34.0" + versionCode 134 + versionName "2.34.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 b885c44..9df9492 100644 --- a/app/src/main/java/com/evsuite/abrp/MainActivity.java +++ b/app/src/main/java/com/evsuite/abrp/MainActivity.java @@ -192,6 +192,7 @@ public class MainActivity extends AppCompatActivity { applyOverviewFullScreen(position); } }); + findViewById(R.id.edge_tab).setOnClickListener(v -> leaveOverviewFullScreen()); findViewById(R.id.overview_fullscreen).setOnClickListener(v -> { prefs.edit().putBoolean(PREF_OVERVIEW_FULLSCREEN, !prefs.getBoolean(PREF_OVERVIEW_FULLSCREEN, false)).apply(); applyOverviewFullScreen(pager.getCurrentItem()); @@ -221,12 +222,22 @@ public class MainActivity extends AppCompatActivity { boolean overview = position == 0; overviewFull = overview && prefs.getBoolean(PREF_OVERVIEW_FULLSCREEN, false); findViewById(R.id.nav_bar).setVisibility(overviewFull ? View.GONE : View.VISIBLE); - findViewById(R.id.edge_handle).setVisibility(overviewFull ? View.VISIBLE : View.GONE); + // The way back: the edge swipe with a faint handle in the app's full screen; with the + // car's bars shown its sidebar takes the left edge, so a tab to tap (or swipe from). + boolean appFull = UploadSettings.fullScreen(prefs); + findViewById(R.id.edge_handle).setVisibility(overviewFull && appFull ? View.VISIBLE : View.GONE); + findViewById(R.id.edge_tab).setVisibility(overviewFull && !appFull ? View.VISIBLE : View.GONE); findViewById(R.id.overview_fullscreen).setVisibility(overview ? View.VISIBLE : View.INVISIBLE); } - /** The swipe in from the left edge, set up with this screen's density. */ - private EdgeSwipe edgeSwipe; + /** Back to the navigation: the edge swipe or the tab. */ + private void leaveOverviewFullScreen() { + prefs.edit().putBoolean(PREF_OVERVIEW_FULLSCREEN, false).apply(); + applyOverviewFullScreen(((ViewPager2) findViewById(R.id.content)).getCurrentItem()); + } + + /** The swipe in from the left edge, set up with this screen's density; null until first used. */ + private EdgeSwipe edgeSwipe, tabSwipe; /** The rest of a touch that became the edge swipe: kept from the page underneath. */ private boolean swallowTouch; @@ -247,21 +258,23 @@ public class MainActivity extends AppCompatActivity { if (edgeSwipe == null) { float density = getResources().getDisplayMetrics().density; edgeSwipe = new EdgeSwipe(48 * density, 64 * density); + // With the car's sidebar beside the app, the swipe starts on the tab instead. + tabSwipe = new EdgeSwipe(56 * density, 64 * density); } + EdgeSwipe swipe = UploadSettings.fullScreen(prefs) ? edgeSwipe : tabSwipe; if (action == android.view.MotionEvent.ACTION_DOWN) { - edgeSwipe.down(ev.getX(), ev.getY()); - } else if (action == android.view.MotionEvent.ACTION_MOVE && edgeSwipe.move(ev.getX(), ev.getY())) { + swipe.down(ev.getX(), ev.getY()); + } else if (action == android.view.MotionEvent.ACTION_MOVE && swipe.move(ev.getX(), ev.getY())) { android.view.MotionEvent cancel = android.view.MotionEvent.obtain(ev); cancel.setAction(android.view.MotionEvent.ACTION_CANCEL); super.dispatchTouchEvent(cancel); cancel.recycle(); swallowTouch = true; - prefs.edit().putBoolean(PREF_OVERVIEW_FULLSCREEN, false).apply(); - applyOverviewFullScreen(((ViewPager2) findViewById(R.id.content)).getCurrentItem()); + leaveOverviewFullScreen(); return true; } else if (action == android.view.MotionEvent.ACTION_UP || action == android.view.MotionEvent.ACTION_CANCEL) { - edgeSwipe.up(); + swipe.up(); } } return super.dispatchTouchEvent(ev); @@ -1185,6 +1198,7 @@ public class MainActivity extends AppCompatActivity { fullScreenSwitch.setOnCheckedChangeListener((btn, checked) -> { prefs.edit().putBoolean(UploadSettings.KEY_FULL_SCREEN, checked).apply(); applyFullScreen(); + applyOverviewFullScreen(((ViewPager2) findViewById(R.id.content)).getCurrentItem()); }); clearCarPlayFullScreen(); liveTelemetrySwitch = servicePane.findViewById(R.id.abrp_upload_switch); diff --git a/app/src/main/res/drawable/bg_edge_tab.xml b/app/src/main/res/drawable/bg_edge_tab.xml new file mode 100644 index 0000000..3b943ef --- /dev/null +++ b/app/src/main/res/drawable/bg_edge_tab.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml new file mode 100644 index 0000000..92c61ee --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_right.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/layout-w1000dp/activity_main.xml b/app/src/main/res/layout-w1000dp/activity_main.xml index 4f6c4ad..157fa79 100644 --- a/app/src/main/res/layout-w1000dp/activity_main.xml +++ b/app/src/main/res/layout-w1000dp/activity_main.xml @@ -22,10 +22,12 @@ - + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index cb6f151..53e411c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -2,10 +2,12 @@ - + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 685d0f8..e138fc4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -132,6 +132,7 @@ MG %1$s has its own colours. To change the accent colour, pick a style that uses it. Overview full screen: hide the navigation + Show the navigation again Minimal Terminal Original