made AnimatedDialogPicker more generic

This commit is contained in:
Vadim 2023-03-21 20:57:40 +03:00
parent 29404e2f87
commit 18210caf7d
3 changed files with 24 additions and 26 deletions

View file

@ -2,38 +2,36 @@ import 'package:flutter/material.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
typedef DialogPickerItemBuilder<T extends PhotographyValue> = Widget Function(BuildContext, T);
typedef DialogPickerEvDifferenceBuilder<T extends PhotographyValue> = String Function(
T selected, T other);
typedef DialogPickerItemTitleBuilder<T> = Widget Function(BuildContext context, T value);
typedef DialogPickerItemTrailingBuilder<T> = Widget? Function(T selected, T value);
class PhotographyValuePickerDialog<T extends PhotographyValue> extends StatefulWidget {
class DialogPicker<T> extends StatefulWidget {
final String title;
final String subtitle;
final T initialValue;
final List<T> values;
final DialogPickerItemBuilder<T> itemTitleBuilder;
final DialogPickerEvDifferenceBuilder<T> evDifferenceBuilder;
final DialogPickerItemTitleBuilder<T> itemTitleBuilder;
final DialogPickerItemTrailingBuilder<T> itemTrailingBuilder;
final VoidCallback onCancel;
final ValueChanged onSelect;
const PhotographyValuePickerDialog({
const DialogPicker({
required this.title,
required this.subtitle,
required this.initialValue,
required this.values,
required this.itemTitleBuilder,
required this.evDifferenceBuilder,
required this.itemTrailingBuilder,
required this.onCancel,
required this.onSelect,
super.key,
});
@override
State<PhotographyValuePickerDialog<T>> createState() => _PhotographyValuePickerDialogState<T>();
State<DialogPicker<T>> createState() => _DialogPickerState<T>();
}
class _PhotographyValuePickerDialogState<T extends PhotographyValue>
extends State<PhotographyValuePickerDialog<T>> {
class _DialogPickerState<T> extends State<DialogPicker<T>> {
late T _selectedValue = widget.initialValue;
late final _scrollController =
ScrollController(initialScrollOffset: Dimens.grid56 * widget.values.indexOf(_selectedValue));
@ -81,10 +79,7 @@ class _PhotographyValuePickerDialogState<T extends PhotographyValue>
style: Theme.of(context).textTheme.bodyLarge!,
child: widget.itemTitleBuilder(context, widget.values[index]),
),
secondary: widget.values[index].value != _selectedValue.value
? Text(S.of(context).evValue(
widget.evDifferenceBuilder.call(_selectedValue, widget.values[index])))
: null,
secondary: widget.itemTrailingBuilder(_selectedValue, widget.values[index]),
onChanged: (value) {
if (value != null) {
setState(() {

View file

@ -1,17 +1,16 @@
import 'package:flutter/material.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'components/animated_dialog/widget_dialog_animated.dart';
import 'components/photography_value_picker_dialog/widget_dialog_picker_photography_value.dart';
import 'components/dialog_picker/widget_picker_dialog.dart';
class AnimatedDialogPicker<T extends PhotographyValue> extends StatelessWidget {
class AnimatedDialogPicker<T> extends StatelessWidget {
final _key = GlobalKey<AnimatedDialogState>();
final String title;
final String subtitle;
final T selectedValue;
final List<T> values;
final DialogPickerItemBuilder<T> itemTitleBuilder;
final DialogPickerEvDifferenceBuilder<T> evDifferenceBuilder;
final DialogPickerItemTitleBuilder<T> itemTitleBuilder;
final DialogPickerItemTrailingBuilder<T> itemTrailingBuilder;
final ValueChanged<T> onChanged;
final Widget closedChild;
@ -21,7 +20,7 @@ class AnimatedDialogPicker<T extends PhotographyValue> extends StatelessWidget {
required this.selectedValue,
required this.values,
required this.itemTitleBuilder,
required this.evDifferenceBuilder,
required this.itemTrailingBuilder,
required this.onChanged,
required this.closedChild,
super.key,
@ -32,13 +31,13 @@ class AnimatedDialogPicker<T extends PhotographyValue> extends StatelessWidget {
return AnimatedDialog(
key: _key,
closedChild: closedChild,
openedChild: PhotographyValuePickerDialog<T>(
openedChild: DialogPicker<T>(
title: title,
subtitle: subtitle,
initialValue: selectedValue,
values: values,
itemTitleBuilder: itemTitleBuilder,
evDifferenceBuilder: evDifferenceBuilder,
itemTrailingBuilder: itemTrailingBuilder,
onCancel: () {
_key.currentState?.close();
},

View file

@ -4,7 +4,7 @@ import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/equipment_profile_provider.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'components/animated_dialog_picker/widget_dialog_animated_picker.dart';
import 'components/animated_dialog_picker/widget_picker_dialog_animated.dart';
import 'components/reading_value_container/widget_container_reading_value.dart';
/// Contains a column of fastest & slowest exposure pairs + a row of ISO and ND pickers
@ -107,7 +107,9 @@ class _IsoValueTile extends StatelessWidget {
values: values,
itemTitleBuilder: (_, value) => Text(value.value.toString()),
// using ascending order, because increase in film speed rises EV
evDifferenceBuilder: (selected, other) => selected.toStringDifference(other),
itemTrailingBuilder: (selected, value) => value.value != selected.value
? Text(S.of(context).evValue(selected.toStringDifference(value)))
: null,
onChanged: onChanged,
closedChild: ReadingValueContainer.singleValue(
value: ReadingValue(
@ -141,7 +143,9 @@ class _NdValueTile extends StatelessWidget {
value.value == 0 ? S.of(context).none : value.value.toString(),
),
// using descending order, because ND filter darkens image & lowers EV
evDifferenceBuilder: (selected, other) => other.toStringDifference(selected),
itemTrailingBuilder: (selected, value) => value.value != selected.value
? Text(S.of(context).evValue(value.toStringDifference(selected)))
: null,
onChanged: onChanged,
closedChild: ReadingValueContainer.singleValue(
value: ReadingValue(