aves/lib/widgets/dialogs/aves_selection_dialog.dart
Thibault Deckers c9041c9beb #156 export/import covers & favourites
dart 2.15 static analysis
2022-01-19 16:15:40 +09:00

97 lines
2.7 KiB
Dart

import 'package:aves/widgets/common/basic/reselectable_radio_list_tile.dart';
import 'package:flutter/material.dart';
import 'aves_dialog.dart';
typedef TextBuilder<T> = String Function(T value);
class AvesSelectionDialog<T> extends StatefulWidget {
final T initialValue;
final Map<T, String> options;
final TextBuilder<T>? optionSubtitleBuilder;
final String? title, message, confirmationButtonLabel;
const AvesSelectionDialog({
Key? key,
required this.initialValue,
required this.options,
this.optionSubtitleBuilder,
this.title,
this.message,
this.confirmationButtonLabel,
}) : super(key: key);
@override
_AvesSelectionDialogState<T> createState() => _AvesSelectionDialogState<T>();
}
class _AvesSelectionDialogState<T> extends State<AvesSelectionDialog<T>> {
late T _selectedValue;
@override
void initState() {
super.initState();
_selectedValue = widget.initialValue;
}
@override
Widget build(BuildContext context) {
final message = widget.message;
final confirmationButtonLabel = widget.confirmationButtonLabel;
final needConfirmation = confirmationButtonLabel != null;
return AvesDialog(
title: widget.title,
scrollableContent: [
if (message != null)
Padding(
padding: const EdgeInsets.all(16),
child: Text(message),
),
...widget.options.entries.map((kv) => _buildRadioListTile(kv.key, kv.value, needConfirmation)),
],
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
),
if (needConfirmation)
TextButton(
onPressed: () => Navigator.pop(context, _selectedValue),
child: Text(confirmationButtonLabel),
),
],
);
}
Widget _buildRadioListTile(T value, String title, bool needConfirmation) {
final subtitle = widget.optionSubtitleBuilder?.call(value);
return ReselectableRadioListTile<T>(
// key is expected by test driver
key: Key(value.toString()),
value: value,
groupValue: _selectedValue,
onChanged: (v) {
if (needConfirmation) {
setState(() => _selectedValue = v!);
} else {
Navigator.pop(context, v);
}
},
reselectable: true,
title: Text(
title,
softWrap: false,
overflow: TextOverflow.fade,
maxLines: 1,
),
subtitle: subtitle != null
? Text(
subtitle,
softWrap: false,
overflow: TextOverflow.fade,
maxLines: 1,
)
: null,
);
}
}