feat(ui): add gear preset shortcuts
This commit is contained in:
@ -14,6 +14,42 @@ class GearRatioPreset {
|
||||
final List<double> ratios;
|
||||
}
|
||||
|
||||
class _QuickPresetButton extends StatelessWidget {
|
||||
const _QuickPresetButton({
|
||||
required this.label,
|
||||
required this.onPressed,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
final String label;
|
||||
final VoidCallback onPressed;
|
||||
final IconData? icon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final buttonStyle = OutlinedButton.styleFrom(
|
||||
minimumSize: const Size(0, 42),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
||||
);
|
||||
|
||||
if (icon != null) {
|
||||
return OutlinedButton.icon(
|
||||
onPressed: onPressed,
|
||||
style: buttonStyle,
|
||||
icon: Icon(icon, size: 18),
|
||||
label: Text(label),
|
||||
);
|
||||
}
|
||||
|
||||
return OutlinedButton(
|
||||
onPressed: onPressed,
|
||||
style: buttonStyle,
|
||||
child: Text(label),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GearRatioEditorCard extends StatefulWidget {
|
||||
const GearRatioEditorCard({
|
||||
required this.ratios,
|
||||
@ -60,6 +96,12 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
List<double>? _stretchBase;
|
||||
int _gearLayoutVersion = 0;
|
||||
|
||||
static const List<String> _quickPresetNames = [
|
||||
'Road',
|
||||
'Gravel',
|
||||
'MTB',
|
||||
];
|
||||
|
||||
List<double> _committed = const [];
|
||||
List<double> _draft = const [];
|
||||
int _committedDefaultGearIndex = 0;
|
||||
@ -235,6 +277,25 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
if (_isEditing) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 0, 14, 10),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
for (final presetName in _quickPresetNames)
|
||||
_QuickPresetButton(
|
||||
label: presetName,
|
||||
onPressed: () => _applyNamedPreset(presetName),
|
||||
),
|
||||
_QuickPresetButton(
|
||||
label: 'Load',
|
||||
icon: Icons.folder_open_rounded,
|
||||
onPressed: _openPresetPicker,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 0, 14, 8),
|
||||
child: Row(
|
||||
@ -251,12 +312,6 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
});
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
OutlinedButton.icon(
|
||||
onPressed: _openPresetPicker,
|
||||
icon: const Icon(Icons.tune),
|
||||
label: const Text('Load preset'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -749,8 +804,21 @@ class _GearRatioEditorCardState extends State<GearRatioEditorCard> {
|
||||
return;
|
||||
}
|
||||
|
||||
_loadPreset(selected);
|
||||
}
|
||||
|
||||
void _applyNamedPreset(String name) {
|
||||
for (final preset in widget.presets) {
|
||||
if (preset.name.toLowerCase() == name.toLowerCase()) {
|
||||
_loadPreset(preset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _loadPreset(GearRatioPreset preset) {
|
||||
setState(() {
|
||||
_draft = selected.ratios.map(_quantizeRatio).toList(growable: false);
|
||||
_draft = preset.ratios.map(_quantizeRatio).toList(growable: false);
|
||||
_draftDefaultGearIndex = _normalizeDefaultIndex(0, _draft.length);
|
||||
if (_sortAscending) {
|
||||
_sortDraft(animate: true);
|
||||
|
||||
Reference in New Issue
Block a user