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