Compare commits
2 Commits
3b6aed2fa2
...
a7ccd67632
| Author | SHA1 | Date | |
|---|---|---|---|
| a7ccd67632 | |||
| a96a22aabc |
Binary file not shown.
@@ -138,6 +138,11 @@ class _ShellNavBar extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => NavigationBar(
|
Widget build(BuildContext context) => NavigationBar(
|
||||||
key: const Key('shell-nav-bar'),
|
key: const Key('shell-nav-bar'),
|
||||||
|
// Material 3's own default (80dp) reads as oversized for a 4-item bar with plain
|
||||||
|
// icon+label destinations -- direct feedback (`docs/FEEDBACK.md`) called this out.
|
||||||
|
// 64dp keeps every icon/label pair at its default size, just with less surrounding
|
||||||
|
// padding, and stays comfortably above the 48dp minimum touch target.
|
||||||
|
height: 64,
|
||||||
selectedIndex: currentIndex,
|
selectedIndex: currentIndex,
|
||||||
onDestinationSelected: onDestinationSelected,
|
onDestinationSelected: onDestinationSelected,
|
||||||
destinations: const [
|
destinations: const [
|
||||||
|
|||||||
@@ -156,11 +156,21 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 72dp normally, 96dp mounted -- one constant height regardless of how many
|
/// 56dp normally, 96dp mounted -- one constant height regardless of how many
|
||||||
/// segments the control bar has (one/two/three), so the HUD area above it is always
|
/// segments the control bar has (one/two/three), so the HUD area above it is always
|
||||||
/// the same size and a widget's saved fractional position never jumps between ride
|
/// the same size and a widget's saved fractional position never jumps between ride
|
||||||
/// states.
|
/// states. Mounted mode stays at 96dp (V3-05: not enough at speed, with gloves,
|
||||||
double _controlBarHeight(bool mountedMode) => mountedMode ? 96 : 72;
|
/// below that); the handheld case only needs a comfortable tap target, not a glove
|
||||||
|
/// target, and 56dp is still well above the 48dp accessibility floor.
|
||||||
|
double _controlBarHeight(bool mountedMode) => mountedMode ? 96 : 56;
|
||||||
|
|
||||||
|
/// The HUD stat grid used to fill the entire area down to the control bar, which
|
||||||
|
/// made even a two-row default layout balloon to take up most of the screen on a
|
||||||
|
/// tall phone -- direct feedback (`docs/FEEDBACK.md`) called this out explicitly.
|
||||||
|
/// Capping it to a fixed, compact band keeps every grid cell a sane physical size
|
||||||
|
/// regardless of screen height, leaving the rest of the screen as pure map. Mounted
|
||||||
|
/// mode gets a taller band to match its own larger text scale ([mountedTextScale]).
|
||||||
|
double _hudAreaHeight(bool mountedMode) => mountedMode ? 320 : 260;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -195,8 +205,11 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
if (!ui.isIdle)
|
if (!ui.isIdle)
|
||||||
Positioned.fill(
|
Positioned(
|
||||||
bottom: _controlBarHeight(mountedMode),
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
height: _hudAreaHeight(mountedMode),
|
||||||
child: HudEditOverlay(
|
child: HudEditOverlay(
|
||||||
metricBuilder: (context, metric) => _HudMetricValue(
|
metricBuilder: (context, metric) => _HudMetricValue(
|
||||||
metric: metric,
|
metric: metric,
|
||||||
@@ -237,6 +250,7 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
|
|||||||
height: _controlBarHeight(mountedMode),
|
height: _controlBarHeight(mountedMode),
|
||||||
child: _ControlBar(
|
child: _ControlBar(
|
||||||
ui: ui,
|
ui: ui,
|
||||||
|
mountedMode: mountedMode,
|
||||||
onStart: () => _guard(engine.start),
|
onStart: () => _guard(engine.start),
|
||||||
onPause: () => _guard(engine.pause),
|
onPause: () => _guard(engine.pause),
|
||||||
onStop: () => _guard(() async => engine.stop()),
|
onStop: () => _guard(() async => engine.stop()),
|
||||||
@@ -379,6 +393,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
required this.onPause,
|
required this.onPause,
|
||||||
required this.onStop,
|
required this.onStop,
|
||||||
required this.onDiscard,
|
required this.onDiscard,
|
||||||
|
this.mountedMode = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final RecordUiState ui;
|
final RecordUiState ui;
|
||||||
@@ -387,6 +402,11 @@ class _ControlBar extends StatelessWidget {
|
|||||||
final VoidCallback onStop;
|
final VoidCallback onStop;
|
||||||
final VoidCallback onDiscard;
|
final VoidCallback onDiscard;
|
||||||
|
|
||||||
|
/// V3-05: mounted mode keeps full-size, glove-friendly icons. The handheld case
|
||||||
|
/// only needs a comfortable tap target, not a glove target, so its icons shrink
|
||||||
|
/// along with the bar itself (`_controlBarHeight`) -- see [_Segment.iconSize].
|
||||||
|
final bool mountedMode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (ui.isIdle) {
|
if (ui.isIdle) {
|
||||||
@@ -397,6 +417,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
background: Theme.of(context).colorScheme.tertiaryContainer,
|
background: Theme.of(context).colorScheme.tertiaryContainer,
|
||||||
foreground: Theme.of(context).colorScheme.onTertiaryContainer,
|
foreground: Theme.of(context).colorScheme.onTertiaryContainer,
|
||||||
onTap: onStart,
|
onTap: onStart,
|
||||||
|
mountedMode: mountedMode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,6 +433,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
foreground: colors.onTertiaryContainer,
|
foreground: colors.onTertiaryContainer,
|
||||||
onTap: onPause,
|
onTap: onPause,
|
||||||
trailingBorder: true,
|
trailingBorder: true,
|
||||||
|
mountedMode: mountedMode,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -421,6 +443,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
background: colors.errorContainer,
|
background: colors.errorContainer,
|
||||||
foreground: colors.onErrorContainer,
|
foreground: colors.onErrorContainer,
|
||||||
onTap: onStop,
|
onTap: onStop,
|
||||||
|
mountedMode: mountedMode,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -441,6 +464,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
foreground: colors.onTertiaryContainer,
|
foreground: colors.onTertiaryContainer,
|
||||||
onTap: onStart,
|
onTap: onStart,
|
||||||
trailingBorder: true,
|
trailingBorder: true,
|
||||||
|
mountedMode: mountedMode,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -451,6 +475,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
foreground: colors.onErrorContainer,
|
foreground: colors.onErrorContainer,
|
||||||
onTap: onStop,
|
onTap: onStop,
|
||||||
trailingBorder: true,
|
trailingBorder: true,
|
||||||
|
mountedMode: mountedMode,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -460,6 +485,7 @@ class _ControlBar extends StatelessWidget {
|
|||||||
background: colors.surfaceContainerHighest,
|
background: colors.surfaceContainerHighest,
|
||||||
foreground: colors.error,
|
foreground: colors.error,
|
||||||
onTap: onDiscard,
|
onTap: onDiscard,
|
||||||
|
mountedMode: mountedMode,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -476,6 +502,7 @@ class _Segment extends StatelessWidget {
|
|||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.label,
|
this.label,
|
||||||
this.trailingBorder = false,
|
this.trailingBorder = false,
|
||||||
|
this.mountedMode = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String keyName;
|
final String keyName;
|
||||||
@@ -485,6 +512,9 @@ class _Segment extends StatelessWidget {
|
|||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final String? label;
|
final String? label;
|
||||||
final bool trailingBorder;
|
final bool trailingBorder;
|
||||||
|
final bool mountedMode;
|
||||||
|
|
||||||
|
double get _iconSize => mountedMode ? 32 : 24;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Material(
|
Widget build(BuildContext context) => Material(
|
||||||
@@ -505,18 +535,18 @@ class _Segment extends StatelessWidget {
|
|||||||
child: SizedBox.expand(
|
child: SizedBox.expand(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: label == null
|
child: label == null
|
||||||
? Icon(icon, color: foreground, size: 32)
|
? Icon(icon, color: foreground, size: _iconSize)
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(icon, color: foreground),
|
Icon(icon, color: foreground, size: _iconSize),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
label!,
|
label!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: foreground,
|
color: foreground,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 16,
|
fontSize: mountedMode ? 16 : 14,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user