diff --git a/CLAUDE.md b/CLAUDE.md index f782807fe..fbdba1520 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -167,13 +167,27 @@ Gradle needs JDK 17+ (Crashlytics plugin); the shell default may be JDK 11 and f so it must stay in `TRIP_INFO_STATUS_PIDS`. Any PID injected into queries the same way needs adding there too. * The Trip Info PID dialog offers the full registry, but the defaults and the current selection are added unfiltered: a selected PID hidden by the ECU/stable filters would be dropped on save. -* Top grid: labels drawn by `AbstractDrawer.drawTitle`, 6 columns (`MAX_ITEM_IN_THE_ROW`), row height `1.8 × textSizeBase` — labels have no width clamp, and a 3+ line label would overlap the next row. Above 18 items `TripInfoMetrics.grid()` shrinks text and adds columns within the same 3-row height (min scale 0.75 = 8 × 4 = 32 tiles; past that the last cell is "+N" for the undrawn ones). The floor was 0.5 (72 tiles) until "select all" on an 800 × 480 DHU gave ~4 px labels — readability, not capacity, sets the floor; up to 18 the layout is unchanged. `maxItemWidth` uses `layoutCache.grid.columns` — Performance calls `drawMetric` without `drawScreen`, so it keeps 6. +* Top grid: labels drawn by `AbstractDrawer.drawTitle`, 6 columns (`MAX_ITEM_IN_THE_ROW`), row height `1.8 × textSizeBase` — labels have no width clamp, and a 3+ line label would overlap the next row. Above 18 items `TripInfoMetrics.grid()` shrinks text and adds columns within the same 3-row height (min scale 0.75 = 8 × 4 = 32 tiles; past that the last cell is "+N" for the undrawn ones). The floor was 0.5 (72 tiles) until "select all" on an 800 × 480 DHU gave ~4 px labels — readability, not capacity, sets the floor; up to 18 the layout is unchanged. `maxItemWidth` uses `layoutCache.grid.columns`, which is never laid out for Performance (it calls `drawMetric` without `drawScreen`) — so Performance passes its own column width as `drawMetric(maxWidth = …)`; any other reuse of `drawMetric` must too. * Bottom row: max 4 (`MAX_BOTTOM_ITEMS`, extras go to the grid), drawn via `GiuliaDrawer.drawMetric`; text size is computed once in `calculateLayout` and cached. Any input that changes label geometry (area, top/bottom metric counts, bottom PID ids, break-label flag) must be part of `TripInfoLayoutCache.requiresLayoutUpdate` — the non-area ones live in the testable `TripInfoLabelLayout`. A count is not enough once PIDs are user-chosen: swapping a bottom PID keeps the count and left the old text size. Label width must be measured the same way it is drawn (split on `\n` only when breaking is enabled). +* `TripInfoMetrics.grid()` takes base columns/rows so Performance shares it; `drawHiddenCount` is non-private for the same reason. * AA label splitting is controlled by `pref.aa.trip_info.break_label` (default `true`), independent of Giulia virtual screens. Phone Trip Info always splits (`TripInfoSettings`). ### Performance screen (AA + phone) * `renderer/performance/PerformanceSurfaceRenderer.kt` wraps settings in the internal `PerformanceScreenSettings` delegate (same name as the `api.PerformanceScreenSettings` data class — mind the imports). Its top grid reuses `TripInfoDrawer.drawMetric`; gauges use the gauge drawer. * AA label splitting is controlled by `pref.aa.performance.break_label` (default `true`) via that delegate. Phone Performance always splits (`PerformanceSettings`). +* **Draws any selected PID, like Trip Info** (`PerformanceMetrics.plan()`, spec `doc/specs/performance-dynamic-pids.md`). + Profile lists `pref.query.performance.top`/`bottom`/`hidden` stay the backward-compatible layout: top + PIDs first in their order, other selected PIDs after in dialog order. Gauges come from + `pref.aa.performance.bottom.pids.selected` (no XML defaultValue; unset = profile `bottom`, empty = none, + max `PERFORMANCE_MAX_GAUGES = 5`). `VEHICLE_STATUS` is excluded via `PERFORMANCE_STATUS_PIDS`. + Saving the main Performance selection prunes deselected PIDs from a *stored* gauge set (never + creates one), else a gauge came back as a gauge on reselect. +* `MetricsCache` reads the profile lists from `Prefs` when it rebuilds the plan, not from listener-updated + copies: the renderer's listener only flags the plan outdated, and a copy updated by a second listener + could be read half-applied. Grid fit reuses `TripInfoMetrics.grid(count, 5, 3)` (unchanged up to 15). +* `MetricsCache` serves phone and AA alike, so the AA gauge pref and order keys also drive the phone + screen, which has no setting of its own. Gauges past `PERFORMANCE_MAX_GAUGES` fall back into the grid, + not nowhere; the gauge dialog only warns (toast), it does not block. ### Connectors (`:datalogger/.../connectors`) * One `AdapterConnection` per transport, chosen by `ConnectionManager.obtain()` on diff --git a/app/build.gradle b/app/build.gradle index ac5f7d441..ef1c27887 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -81,7 +81,7 @@ android { resValue "string", "DEFAULT_PROFILE", "profile_8" resValue "string", "applicationId", "org.obd.graphs.my.giulia.aa" applicationId "org.obd.graphs.my.giulia.aa" - versionCode 246 + versionCode 247 } giuliaPerformanceMonitor { @@ -89,7 +89,7 @@ android { resValue "string", "DEFAULT_PROFILE", "profile_8" resValue "string", "applicationId", "org.obd.graphs.my.giulia.performance_monitor" applicationId "org.obd.graphs.my.giulia.performance_monitor" - versionCode 126 + versionCode 127 } giulia { diff --git a/app/src/main/java/org/obd/graphs/preferences/pid/PidDefinitionDialogFragment.kt b/app/src/main/java/org/obd/graphs/preferences/pid/PidDefinitionDialogFragment.kt index 4fae6e07f..040234250 100644 --- a/app/src/main/java/org/obd/graphs/preferences/pid/PidDefinitionDialogFragment.kt +++ b/app/src/main/java/org/obd/graphs/preferences/pid/PidDefinitionDialogFragment.kt @@ -32,6 +32,7 @@ import android.widget.FrameLayout import android.widget.LinearLayout import android.widget.RelativeLayout import android.widget.TextView +import android.widget.Toast import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat @@ -421,6 +422,11 @@ open class PidDefinitionDialogFragment( val btnSave = root.findViewById