diff --git a/lib/data/permissions_service.dart b/lib/data/permissions_service.dart index d01e022..6d0e64c 100644 --- a/lib/data/permissions_service.dart +++ b/lib/data/permissions_service.dart @@ -1,8 +1,8 @@ import 'package:permission_handler/permission_handler.dart'; class PermissionsService { - const PermissionsService(); + Future checkCameraPermission() async => Permission.camera.status; Future requestCameraPermission() async => Permission.camera.request(); diff --git a/lib/providers/metering_screen_layout_provider.dart b/lib/providers/metering_screen_layout_provider.dart index 965b275..405c1a7 100644 --- a/lib/providers/metering_screen_layout_provider.dart +++ b/lib/providers/metering_screen_layout_provider.dart @@ -3,35 +3,6 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; -class MeteringScreenLayout extends InheritedModelBase { - const MeteringScreenLayout({ - required super.data, - required super.child, - super.key, - }); - - static MeteringScreenLayoutConfig of(BuildContext context, {bool listen = true}) { - if (listen) { - return context - .dependOnInheritedWidgetOfExactType< - InheritedModelBase>()! - .data; - } else { - return context - .findAncestorWidgetOfExactType>()! - .data; - } - } - - static bool featureOf(BuildContext context, MeteringScreenLayoutFeature aspect) { - return InheritedModel.inheritFrom>( - context, - aspect: aspect, - )! - .data[aspect]!; - } -} - class MeteringScreenLayoutProvider extends StatefulWidget { final Widget child; @@ -70,3 +41,20 @@ class MeteringScreenLayoutProviderState extends State().meteringScreenLayout = _config; } } + +typedef _MeteringScreenLayoutModel = InheritedModelBase; + +extension MeteringScreenLayout on InheritedModelBase { + static MeteringScreenLayoutConfig of(BuildContext context, {bool listen = true}) { + if (listen) { + return context.dependOnInheritedWidgetOfExactType<_MeteringScreenLayoutModel>()!.data; + } else { + return context.findAncestorWidgetOfExactType<_MeteringScreenLayoutModel>()!.data; + } + } + + static bool featureOf(BuildContext context, MeteringScreenLayoutFeature aspect) { + return InheritedModel.inheritFrom<_MeteringScreenLayoutModel>(context, aspect: aspect)! + .data[aspect]!; + } +} diff --git a/lib/screens/metering/bloc_metering.dart b/lib/screens/metering/bloc_metering.dart index 1b52882..34d5a3c 100644 --- a/lib/screens/metering/bloc_metering.dart +++ b/lib/screens/metering/bloc_metering.dart @@ -40,7 +40,7 @@ class MeteringBloc extends Bloc { this.stopType, ) : super( MeteringDataState( - ev: 0.0, + ev: null, film: _meteringInteractor.film, iso: _meteringInteractor.iso, nd: _meteringInteractor.ndFilter, @@ -77,55 +77,75 @@ class MeteringBloc extends Bloc { } void _onStopTypeChanged(StopTypeChangedEvent event, Emitter emit) { - stopType = event.stopType; - _updateMeasurements(); + if (stopType != event.stopType) { + stopType = event.stopType; + _updateMeasurements(); + } } void _onEquipmentProfileChanged(EquipmentProfileChangedEvent event, Emitter emit) { _equipmentProfileData = event.equipmentProfileData; + bool willUpdateMeasurements = false; /// Update selected ISO value, if selected equipment profile /// doesn't contain currently selected value if (!event.equipmentProfileData.isoValues.any((v) => _iso.value == v.value)) { _meteringInteractor.iso = event.equipmentProfileData.isoValues.first; _iso = event.equipmentProfileData.isoValues.first; + willUpdateMeasurements &= true; } /// The same for ND filter if (!event.equipmentProfileData.ndValues.any((v) => _nd.value == v.value)) { _meteringInteractor.ndFilter = event.equipmentProfileData.ndValues.first; _nd = event.equipmentProfileData.ndValues.first; + willUpdateMeasurements &= true; } - _updateMeasurements(); + if (willUpdateMeasurements) { + _updateMeasurements(); + } } void _onFilmChanged(FilmChangedEvent event, Emitter emit) { - if (_iso.value != event.data.iso) { - final newIso = IsoValue.values.firstWhere( - (e) => e.value == event.data.iso, - orElse: () => _iso, - ); - add(IsoChangedEvent(newIso)); + if (_film.name != event.data.name) { + _film = event.data; + _meteringInteractor.film = event.data; + + /// If user selects 'Other' film we preserve currently selected ISO + /// and therefore only discard reciprocity formula + if (_iso.value != event.data.iso && event.data != const Film.other()) { + final newIso = IsoValue.values.firstWhere( + (e) => e.value == event.data.iso, + orElse: () => _iso, + ); + _meteringInteractor.iso = newIso; + _iso = newIso; + } + + _updateMeasurements(); } - _film = event.data; - _meteringInteractor.film = event.data; - _updateMeasurements(); } void _onIsoChanged(IsoChangedEvent event, Emitter emit) { - if (event.isoValue.value != _film.iso) { - _film = Film.values.first; + /// Discard currently selected film even if ISO is the same, + /// because, for example, Fomapan 400 and any Ilford 400 + /// have different reciprocity formulas + _film = Film.values.first; + + if (_iso != event.isoValue) { + _meteringInteractor.iso = event.isoValue; + _iso = event.isoValue; + _updateMeasurements(); } - _meteringInteractor.iso = event.isoValue; - _iso = event.isoValue; - _updateMeasurements(); } void _onNdChanged(NdChangedEvent event, Emitter emit) { - _meteringInteractor.ndFilter = event.ndValue; - _nd = event.ndValue; - _updateMeasurements(); + if (_nd != event.ndValue) { + _meteringInteractor.ndFilter = event.ndValue; + _nd = event.ndValue; + _updateMeasurements(); + } } void _onMeasure(MeasureEvent _, Emitter emit) {