mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 23:10:40 +00:00
fixed profile update
This commit is contained in:
parent
bf540e062a
commit
b17629f4d8
6 changed files with 98 additions and 43 deletions
|
@ -37,16 +37,14 @@
|
|||
"equipment": "Equipment",
|
||||
"equipmentProfileName": "Equipment profile name",
|
||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||
"equipmentProfileValuesCount": "{count} values",
|
||||
"equipmentProfileValuesCount" : "{count, plural, zero{0 values} one{1 value} other{{count} values}}",
|
||||
"@equipmentProfileValuesCount": {
|
||||
"count": {
|
||||
"min": {
|
||||
"type": "int",
|
||||
"format": "decimalPattern"
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"equipmentProfileAllValues": "All",
|
||||
"apertureValues": "Aperture values",
|
||||
"apertureValuesFilterDescription": "Select the range of aperture values to display. This is usually determined by the lens you are using.",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class EquipmentProfileProvider extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
@ -48,7 +49,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
/// Creates a default equipment profile
|
||||
void addProfile(String name) {
|
||||
_profiles.add(EquipmentProfileData(
|
||||
id: 'default',
|
||||
id: const Uuid().v1(),
|
||||
name: name,
|
||||
apertureValues: apertureValues,
|
||||
ndValues: ndValues,
|
||||
|
@ -59,7 +60,11 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
}
|
||||
|
||||
void updateProdile(EquipmentProfileData data) {
|
||||
//
|
||||
final indexToUpdate = _profiles.indexWhere((element) => element.id == data.id);
|
||||
if (indexToUpdate >= 0) {
|
||||
_profiles[indexToUpdate] = data;
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void deleteProfile(EquipmentProfileData data) {
|
||||
|
|
|
@ -112,17 +112,22 @@ class _EquipmentListTile<T extends PhotographyValue> extends StatelessWidget {
|
|||
title: Text(title),
|
||||
trailing: Text(valuesCount),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
showDialog<List<T>>(
|
||||
context: context,
|
||||
builder: (_) => DialogFilter<T>(
|
||||
icon: Icon(icon),
|
||||
title: title,
|
||||
description: description,
|
||||
values: values,
|
||||
selectedValues: selectedValues,
|
||||
titleAdapter: (_, value) => value.toString(),
|
||||
rangeSelect: rangeSelect,
|
||||
),
|
||||
);
|
||||
).then((values) {
|
||||
if (values != null) {
|
||||
onChanged(values);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,31 @@ class EquipmentProfileContainer extends StatefulWidget {
|
|||
}
|
||||
|
||||
class EquipmentProfileContainerState extends State<EquipmentProfileContainer> {
|
||||
late final TextEditingController _nameController = TextEditingController(text: widget.data.name);
|
||||
final FocusNode _fieldFocusNode = FocusNode();
|
||||
late EquipmentProfileData _equipmentProfileData = EquipmentProfileData(
|
||||
id: widget.data.id,
|
||||
name: widget.data.name,
|
||||
apertureValues: widget.data.apertureValues,
|
||||
ndValues: widget.data.ndValues,
|
||||
shutterSpeedValues: widget.data.shutterSpeedValues,
|
||||
isoValues: widget.data.isoValues,
|
||||
);
|
||||
late final _nameController = TextEditingController(text: _equipmentProfileData.name);
|
||||
final _fieldFocusNode = FocusNode();
|
||||
bool _expanded = false;
|
||||
|
||||
@override
|
||||
void didUpdateWidget(EquipmentProfileContainer oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
_equipmentProfileData = EquipmentProfileData(
|
||||
id: widget.data.id,
|
||||
name: widget.data.name,
|
||||
apertureValues: widget.data.apertureValues,
|
||||
ndValues: widget.data.ndValues,
|
||||
shutterSpeedValues: widget.data.shutterSpeedValues,
|
||||
isoValues: widget.data.isoValues,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameController.dispose();
|
||||
|
@ -59,7 +80,10 @@ class EquipmentProfileContainerState extends State<EquipmentProfileContainer> {
|
|||
child: TextFormField(
|
||||
focusNode: _fieldFocusNode,
|
||||
controller: _nameController,
|
||||
onChanged: (value) {},
|
||||
onFieldSubmitted: (value) {
|
||||
_equipmentProfileData = _equipmentProfileData.copyWith(name: value);
|
||||
widget.onUpdate(_equipmentProfileData);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: S.of(context).equipmentProfileNameHint,
|
||||
border: InputBorder.none,
|
||||
|
@ -81,14 +105,26 @@ class EquipmentProfileContainerState extends State<EquipmentProfileContainer> {
|
|||
),
|
||||
if (_expanded)
|
||||
EquipmentListTiles(
|
||||
selectedApertureValues: widget.data.apertureValues,
|
||||
selectedIsoValues: widget.data.isoValues,
|
||||
selectedNdValues: widget.data.ndValues,
|
||||
selectedShutterSpeedValues: widget.data.shutterSpeedValues,
|
||||
onApertureValuesSelected: (value) {},
|
||||
onIsoValuesSelecred: (value) {},
|
||||
onNdValuesSelected: (value) {},
|
||||
onShutterSpeedValuesSelected: (value) {},
|
||||
selectedApertureValues: _equipmentProfileData.apertureValues,
|
||||
selectedIsoValues: _equipmentProfileData.isoValues,
|
||||
selectedNdValues: _equipmentProfileData.ndValues,
|
||||
selectedShutterSpeedValues: _equipmentProfileData.shutterSpeedValues,
|
||||
onApertureValuesSelected: (value) {
|
||||
_equipmentProfileData = _equipmentProfileData.copyWith(apertureValues: value);
|
||||
widget.onUpdate(_equipmentProfileData);
|
||||
},
|
||||
onIsoValuesSelecred: (value) {
|
||||
_equipmentProfileData = _equipmentProfileData.copyWith(isoValues: value);
|
||||
widget.onUpdate(_equipmentProfileData);
|
||||
},
|
||||
onNdValuesSelected: (value) {
|
||||
_equipmentProfileData = _equipmentProfileData.copyWith(ndValues: value);
|
||||
widget.onUpdate(_equipmentProfileData);
|
||||
},
|
||||
onShutterSpeedValuesSelected: (value) {
|
||||
_equipmentProfileData = _equipmentProfileData.copyWith(shutterSpeedValues: value);
|
||||
widget.onUpdate(_equipmentProfileData);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -55,7 +55,7 @@ class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
|||
key: profileContainersKeys[index],
|
||||
data: EquipmentProfiles.of(context)![index],
|
||||
onExpand: () => _keepExpandedAt(index),
|
||||
onUpdate: _updateProfile,
|
||||
onUpdate: (profileData) => _updateProfileAt(profileData, index),
|
||||
onDelete: () => _removeProfileAt(index),
|
||||
),
|
||||
),
|
||||
|
@ -82,8 +82,8 @@ class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
|||
});
|
||||
}
|
||||
|
||||
void _updateProfile(EquipmentProfileData data) {
|
||||
//
|
||||
void _updateProfileAt(EquipmentProfileData data, int index) {
|
||||
EquipmentProfileProvider.of(context).updateProdile(data);
|
||||
}
|
||||
|
||||
void _removeProfileAt(int index) {
|
||||
|
|
|
@ -7,6 +7,7 @@ class DialogFilter<T extends PhotographyValue> extends StatefulWidget {
|
|||
final String title;
|
||||
final String description;
|
||||
final List<T> values;
|
||||
final List<T> selectedValues;
|
||||
final String Function(BuildContext context, T value) titleAdapter;
|
||||
final bool rangeSelect;
|
||||
|
||||
|
@ -15,6 +16,7 @@ class DialogFilter<T extends PhotographyValue> extends StatefulWidget {
|
|||
required this.title,
|
||||
required this.description,
|
||||
required this.values,
|
||||
required this.selectedValues,
|
||||
required this.titleAdapter,
|
||||
this.rangeSelect = false,
|
||||
super.key,
|
||||
|
@ -25,14 +27,14 @@ class DialogFilter<T extends PhotographyValue> extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _DialogFilterState<T extends PhotographyValue> extends State<DialogFilter<T>> {
|
||||
late final List<bool> _selectedValues = List.generate(
|
||||
late final List<bool> checkboxValues = List.generate(
|
||||
widget.values.length,
|
||||
(_) => true,
|
||||
(index) => widget.selectedValues.any((element) => element.value == widget.values[index].value),
|
||||
growable: false,
|
||||
);
|
||||
|
||||
bool get _hasAnySelected => _selectedValues.contains(true);
|
||||
bool get _hasAnyUnselected => _selectedValues.contains(false);
|
||||
bool get _hasAnySelected => checkboxValues.contains(true);
|
||||
bool get _hasAnyUnselected => checkboxValues.contains(false);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -57,7 +59,7 @@ class _DialogFilterState<T extends PhotographyValue> extends State<DialogFilter<
|
|||
children: List.generate(
|
||||
widget.values.length,
|
||||
(index) => CheckboxListTile(
|
||||
value: _selectedValues[index],
|
||||
value: checkboxValues[index],
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
title: Text(
|
||||
widget.titleAdapter(context, widget.values[index]),
|
||||
|
@ -68,25 +70,25 @@ class _DialogFilterState<T extends PhotographyValue> extends State<DialogFilter<
|
|||
setState(() {
|
||||
if (widget.rangeSelect) {
|
||||
if (value) {
|
||||
final indexOfChecked = _selectedValues.indexOf(value);
|
||||
final indexOfChecked = checkboxValues.indexOf(value);
|
||||
if (indexOfChecked == -1) {
|
||||
_selectedValues[index] = value;
|
||||
checkboxValues[index] = value;
|
||||
} else if (indexOfChecked < index) {
|
||||
_selectedValues.fillRange(indexOfChecked, index + 1, value);
|
||||
checkboxValues.fillRange(indexOfChecked, index + 1, value);
|
||||
} else {
|
||||
_selectedValues.fillRange(index, indexOfChecked, value);
|
||||
checkboxValues.fillRange(index, indexOfChecked, value);
|
||||
}
|
||||
} else {
|
||||
if (index > _selectedValues.length / 2) {
|
||||
_selectedValues.fillRange(index, _selectedValues.length, false);
|
||||
_selectedValues[index] = value;
|
||||
if (index > checkboxValues.length / 2) {
|
||||
checkboxValues.fillRange(index, checkboxValues.length, false);
|
||||
checkboxValues[index] = value;
|
||||
} else {
|
||||
_selectedValues.fillRange(0, index, false);
|
||||
_selectedValues[index] = value;
|
||||
checkboxValues.fillRange(0, index, false);
|
||||
checkboxValues[index] = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_selectedValues[index] = value;
|
||||
checkboxValues[index] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -115,8 +117,17 @@ class _DialogFilterState<T extends PhotographyValue> extends State<DialogFilter<
|
|||
child: Text(S.of(context).cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed:
|
||||
_hasAnySelected ? () => Navigator.of(context).pop(_selectedValues) : null,
|
||||
onPressed: _hasAnySelected
|
||||
? () {
|
||||
List<T> selectedValues = [];
|
||||
for (int i = 0; i < widget.values.length; i++) {
|
||||
if (checkboxValues[i]) {
|
||||
selectedValues.add(widget.values[i]);
|
||||
}
|
||||
}
|
||||
Navigator.of(context).pop(selectedValues);
|
||||
}
|
||||
: null,
|
||||
child: Text(S.of(context).save),
|
||||
),
|
||||
],
|
||||
|
@ -130,9 +141,9 @@ class _DialogFilterState<T extends PhotographyValue> extends State<DialogFilter<
|
|||
void _toggleAll() {
|
||||
setState(() {
|
||||
if (_hasAnyUnselected) {
|
||||
_selectedValues.fillRange(0, _selectedValues.length, true);
|
||||
checkboxValues.fillRange(0, checkboxValues.length, true);
|
||||
} else {
|
||||
_selectedValues.fillRange(0, _selectedValues.length, false);
|
||||
checkboxValues.fillRange(0, checkboxValues.length, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue