implemented MeteringScreenLayoutFeaturesDialog

This commit is contained in:
Vadim 2023-04-03 20:05:48 +03:00
parent f084efde5d
commit 02e2803d97
7 changed files with 138 additions and 16 deletions

View file

@ -34,6 +34,10 @@
"calibrationMessageCameraOnly": "The accuracy of the readings measured by this application depends entirely on the rear camera of the device. Therefore, consider testing this application and setting up an EV calibration value that will give you the desired measurement results.", "calibrationMessageCameraOnly": "The accuracy of the readings measured by this application depends entirely on the rear camera of the device. Therefore, consider testing this application and setting up an EV calibration value that will give you the desired measurement results.",
"camera": "Camera", "camera": "Camera",
"lightSensor": "Light sensor", "lightSensor": "Light sensor",
"meteringScreenLayout": "Metering screen layout",
"meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.",
"meteringScreenFeatureExtremeExposurePairs": "Extreme exposure pairs",
"meteringScreenFeatureFilmPicker": "Film picker",
"film": "Film", "film": "Film",
"equipment": "Equipment", "equipment": "Equipment",
"equipmentProfileName": "Equipment profile name", "equipmentProfileName": "Equipment profile name",

View file

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
enum MeteringScreenLayoutFeature { extremeExposurePairs, reciprocity } enum MeteringScreenLayoutFeature { extremeExposurePairs, filmPicker }
class MeteringScreenLayoutProvider extends StatefulWidget { class MeteringScreenLayoutProvider extends StatefulWidget {
final Widget child; final Widget child;
@ -18,25 +18,27 @@ class MeteringScreenLayoutProvider extends StatefulWidget {
class MeteringScreenLayoutProviderState extends State<MeteringScreenLayoutProvider> { class MeteringScreenLayoutProviderState extends State<MeteringScreenLayoutProvider> {
final Map<MeteringScreenLayoutFeature, bool> _features = { final Map<MeteringScreenLayoutFeature, bool> _features = {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.reciprocity: true, MeteringScreenLayoutFeature.filmPicker: true,
}; };
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MeteringScreenLayout( return MeteringScreenLayout(
features: _features, features: Map<MeteringScreenLayoutFeature, bool>.from(_features),
child: widget.child, child: widget.child,
); );
} }
void setFeature(MeteringScreenLayoutFeature feature, {required bool enabled}) { void updateFeatures(Map<MeteringScreenLayoutFeature, bool> features) {
setState(() { setState(() {
features.forEach((key, value) {
_features.update( _features.update(
feature, key,
(_) => enabled, (_) => value,
ifAbsent: () => enabled, ifAbsent: () => value,
); );
}); });
});
} }
} }
@ -49,14 +51,19 @@ class MeteringScreenLayout extends InheritedModel<MeteringScreenLayoutFeature> {
super.key, super.key,
}); });
static bool of(BuildContext context, MeteringScreenLayoutFeature feature, {bool listen = true}) { static Map<MeteringScreenLayoutFeature, bool> of(BuildContext context, {bool listen = true}) {
if (listen) { if (listen) {
return context.dependOnInheritedWidgetOfExactType<MeteringScreenLayout>()!.features[feature]!; return context.dependOnInheritedWidgetOfExactType<MeteringScreenLayout>()!.features;
} else { } else {
return context.findAncestorWidgetOfExactType<MeteringScreenLayout>()!.features[feature]!; return context.findAncestorWidgetOfExactType<MeteringScreenLayout>()!.features;
} }
} }
static bool featureStatusOf(BuildContext context, MeteringScreenLayoutFeature feature) {
return InheritedModel.inheritFrom<MeteringScreenLayout>(context, aspect: feature)!
.features[feature]!;
}
@override @override
bool updateShouldNotify(MeteringScreenLayout oldWidget) => true; bool updateShouldNotify(MeteringScreenLayout oldWidget) => true;

View file

@ -56,11 +56,17 @@ class CameraContainer extends StatelessWidget {
topBarOverflow += Dimens.readingContainerSingleValueHeight; topBarOverflow += Dimens.readingContainerSingleValueHeight;
topBarOverflow += Dimens.paddingS; topBarOverflow += Dimens.paddingS;
} }
if (MeteringScreenLayout.of(context, MeteringScreenLayoutFeature.extremeExposurePairs)) { if (MeteringScreenLayout.featureStatusOf(
context,
MeteringScreenLayoutFeature.extremeExposurePairs,
)) {
topBarOverflow += Dimens.readingContainerDoubleValueHeight; topBarOverflow += Dimens.readingContainerDoubleValueHeight;
topBarOverflow += Dimens.paddingS; topBarOverflow += Dimens.paddingS;
} }
if (MeteringScreenLayout.of(context, MeteringScreenLayoutFeature.reciprocity)) { if (MeteringScreenLayout.featureStatusOf(
context,
MeteringScreenLayoutFeature.filmPicker,
)) {
topBarOverflow += Dimens.readingContainerSingleValueHeight; topBarOverflow += Dimens.readingContainerSingleValueHeight;
topBarOverflow += Dimens.paddingS; topBarOverflow += Dimens.paddingS;
} }

View file

@ -43,7 +43,10 @@ class ReadingsContainer extends StatelessWidget {
const _EquipmentProfilePicker(), const _EquipmentProfilePicker(),
const _InnerPadding(), const _InnerPadding(),
], ],
if (MeteringScreenLayout.of(context, MeteringScreenLayoutFeature.extremeExposurePairs)) ...[ if (MeteringScreenLayout.featureStatusOf(
context,
MeteringScreenLayoutFeature.extremeExposurePairs,
)) ...[
ReadingValueContainer( ReadingValueContainer(
values: [ values: [
ReadingValue( ReadingValue(
@ -58,7 +61,10 @@ class ReadingsContainer extends StatelessWidget {
), ),
const _InnerPadding(), const _InnerPadding(),
], ],
if (MeteringScreenLayout.of(context, MeteringScreenLayoutFeature.reciprocity)) ...[ if (MeteringScreenLayout.featureStatusOf(
context,
MeteringScreenLayoutFeature.filmPicker,
)) ...[
_FilmPicker( _FilmPicker(
values: Film.values, values: Film.values,
selectedValue: film, selectedValue: film,

View file

@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/features_provider.dart';
import 'package:lightmeter/res/dimens.dart';
class MeteringScreenLayoutFeaturesDialog extends StatefulWidget {
const MeteringScreenLayoutFeaturesDialog({super.key});
@override
State<MeteringScreenLayoutFeaturesDialog> createState() =>
_MeteringScreenLayoutFeaturesDialogState();
}
class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayoutFeaturesDialog> {
late final _features =
Map<MeteringScreenLayoutFeature, bool>.from(MeteringScreenLayout.of(context, listen: false));
@override
Widget build(BuildContext context) {
return AlertDialog(
icon: const Icon(Icons.layers_outlined),
titlePadding: Dimens.dialogIconTitlePadding,
title: Text(S.of(context).meteringScreenLayout),
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: double.maxFinite,
child: ListView(
shrinkWrap: true,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
child: Text(S.of(context).meteringScreenLayoutHint),
),
const SizedBox(height: Dimens.grid16),
...MeteringScreenLayoutFeature.values.map(
(f) => SwitchListTile(
contentPadding: EdgeInsets.symmetric(horizontal: Dimens.dialogTitlePadding.left),
title: Text(_toStringLocalized(context, f)),
value: _features[f]!,
onChanged: (value) {
setState(() {
_features.update(f, (_) => value);
});
},
),
),
],
),
),
actionsPadding: Dimens.dialogActionsPadding,
actions: [
TextButton(
onPressed: Navigator.of(context).pop,
child: Text(S.of(context).cancel),
),
TextButton(
onPressed: () {
MeteringScreenLayoutProvider.of(context).updateFeatures(_features);
Navigator.of(context).pop();
},
child: Text(S.of(context).save),
),
],
);
}
String _toStringLocalized(BuildContext context, MeteringScreenLayoutFeature feature) {
switch (feature) {
case MeteringScreenLayoutFeature.extremeExposurePairs:
return S.of(context).meteringScreenFeatureExtremeExposurePairs;
case MeteringScreenLayoutFeature.filmPicker:
return S.of(context).meteringScreenFeatureFilmPicker;
}
}
}

View file

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'components/meterins_screen_layout_features_dialog/widget_dialog_metering_screen_layout_features.dart';
class MeteringScreenLayoutListTile extends StatelessWidget {
const MeteringScreenLayoutListTile({super.key});
@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.layers_outlined),
title: Text(S.of(context).meteringScreenLayout),
onTap: () {
showDialog(
context: context,
builder: (_) => const MeteringScreenLayoutFeaturesDialog(),
);
},
);
}
}

View file

@ -4,6 +4,7 @@ import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart'; import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart';
import 'components/calibration/widget_list_tile_calibration.dart'; import 'components/calibration/widget_list_tile_calibration.dart';
import 'components/metering_screen_layout/widget_list_tile_metering_screen_layout.dart';
import 'components/equipment_profiles/widget_list_tile_equipment_profiles.dart'; import 'components/equipment_profiles/widget_list_tile_equipment_profiles.dart';
import 'components/fractional_stops/widget_list_tile_fractional_stops.dart'; import 'components/fractional_stops/widget_list_tile_fractional_stops.dart';
@ -17,6 +18,7 @@ class MeteringSettingsSection extends StatelessWidget {
children: const [ children: const [
StopTypeListTile(), StopTypeListTile(),
CalibrationListTile(), CalibrationListTile(),
MeteringScreenLayoutListTile(),
if (FeaturesConfig.equipmentProfilesEnabled) EquipmentProfilesListTile(), if (FeaturesConfig.equipmentProfilesEnabled) EquipmentProfilesListTile(),
], ],
); );