feat: ui rework and gear generator
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:abawo_bt_app/model/gear_ratio_codec.dart';
|
||||
import 'package:abawo_bt_app/widgets/gear_configurator_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GearRatioPreset {
|
||||
@ -76,8 +78,8 @@ class GearRatioEditorCard extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
static const double _sliderMin = 0.10;
|
||||
static const double _sliderMax = 3.90;
|
||||
static const double _sliderMin = gearRatioMin;
|
||||
static const double _sliderMax = gearRatioMax;
|
||||
static const double _sliderPivotT = 0.50;
|
||||
static const double _sliderPivotV = 1.00;
|
||||
static const Duration _animDuration = Duration(milliseconds: 280);
|
||||
@ -165,10 +167,22 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
TextStyle(fontSize: 17, fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
if (!_isEditing)
|
||||
IconButton(
|
||||
tooltip: 'Configure drivetrain',
|
||||
onPressed: (widget.isLoading ||
|
||||
widget.errorText != null ||
|
||||
_isSaving)
|
||||
? null
|
||||
: _openGearConfigurator,
|
||||
icon: const Icon(Icons.settings_input_component_outlined),
|
||||
),
|
||||
if (!_isEditing)
|
||||
IconButton(
|
||||
tooltip: 'Edit ratios',
|
||||
onPressed: (widget.isLoading || widget.errorText != null)
|
||||
onPressed: (widget.isLoading ||
|
||||
widget.errorText != null ||
|
||||
_isSaving)
|
||||
? null
|
||||
: _enterEditMode,
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
@ -830,6 +844,62 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
_loadPreset(selected);
|
||||
}
|
||||
|
||||
Future<void> _openGearConfigurator() async {
|
||||
final calculation = await showGearConfiguratorDialog(context);
|
||||
if (!mounted || calculation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isSaving = true;
|
||||
});
|
||||
|
||||
final ratios = List<double>.from(calculation.ratios);
|
||||
final message =
|
||||
await widget.onSave(ratios, _normalizeDefaultIndex(0, ratios.length));
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isSaving = false;
|
||||
if (message == null) {
|
||||
_committed = ratios;
|
||||
_draft = List<double>.from(ratios);
|
||||
_committedDefaultGearIndex = _normalizeDefaultIndex(0, ratios.length);
|
||||
_draftDefaultGearIndex = _committedDefaultGearIndex;
|
||||
_isEditing = false;
|
||||
_isExpanded = true;
|
||||
}
|
||||
});
|
||||
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
if (message != null) {
|
||||
messenger.showSnackBar(SnackBar(content: Text(message)));
|
||||
return;
|
||||
}
|
||||
|
||||
final notices = <String>[
|
||||
if (calculation.discardedBelowRange > 0)
|
||||
'${calculation.discardedBelowRange} below range skipped',
|
||||
if (calculation.discardedAboveRange > 0)
|
||||
'${calculation.discardedAboveRange} above range skipped',
|
||||
if (calculation.duplicateCount > 0)
|
||||
'${calculation.duplicateCount} duplicates removed',
|
||||
if (calculation.truncatedCount > 0)
|
||||
'${calculation.truncatedCount} high gears truncated',
|
||||
];
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
notices.isEmpty
|
||||
? 'Applied ${ratios.length} calculated gear ratios.'
|
||||
: 'Applied ${ratios.length} calculated gear ratios (${notices.join(', ')}).',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _applyNamedPreset(String name) {
|
||||
for (final preset in widget.presets) {
|
||||
if (preset.name.toLowerCase() == name.toLowerCase()) {
|
||||
@ -995,8 +1065,7 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
}
|
||||
|
||||
double _quantizeRatio(double raw) {
|
||||
final clamped = raw.clamp(_sliderMin, _sliderMax);
|
||||
return ((clamped * 64).round() / 64.0).clamp(_sliderMin, _sliderMax);
|
||||
return quantizeGearRatio(raw).clamp(_sliderMin, _sliderMax);
|
||||
}
|
||||
|
||||
(List<double>, int) _sortedWithDefault(
|
||||
|
||||
Reference in New Issue
Block a user