From c5179e71ea7a75d1cce23c10bcb05242a758b92c Mon Sep 17 00:00:00 2001 From: Vadim Date: Fri, 17 Mar 2023 14:47:58 +0300 Subject: [PATCH] moved `EquipmentProfileProvider` from iap repo --- lib/application.dart | 2 +- lib/providers/equipment_profile_provider.dart | 86 +++++++++++++++++++ lib/screens/metering/bloc_metering.dart | 19 ++++ .../provider_container_camera.dart | 3 + .../widget_container_camera.dart | 3 + .../provider_container_light_sensor.dart | 3 + .../widget_container_light_sensor.dart | 3 + .../widget_container_readings.dart | 47 +++++++++- lib/screens/metering/event_metering.dart | 6 ++ lib/screens/metering/screen_metering.dart | 6 ++ 10 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 lib/providers/equipment_profile_provider.dart diff --git a/lib/application.dart b/lib/application.dart index 9c82a6d..ed596a5 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -8,7 +8,6 @@ import 'package:lightmeter/data/caffeine_service.dart'; import 'package:lightmeter/data/haptics_service.dart'; import 'package:lightmeter/data/models/supported_locale.dart'; import 'package:lightmeter/providers/supported_locale_provider.dart'; -import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -17,6 +16,7 @@ import 'data/permissions_service.dart'; import 'data/shared_prefs_service.dart'; import 'environment.dart'; import 'generated/l10n.dart'; +import 'providers/equipment_profile_provider.dart'; import 'providers/ev_source_type_provider.dart'; import 'providers/theme_provider.dart'; import 'screens/metering/flow_metering.dart'; diff --git a/lib/providers/equipment_profile_provider.dart b/lib/providers/equipment_profile_provider.dart new file mode 100644 index 0000000..7f3f6be --- /dev/null +++ b/lib/providers/equipment_profile_provider.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; +import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; + +class EquipmentProfileProvider extends StatefulWidget { + final Widget child; + + const EquipmentProfileProvider({required this.child, super.key}); + + static EquipmentProfileProviderState of(BuildContext context) { + return context.findAncestorStateOfType()!; + } + + @override + State createState() => EquipmentProfileProviderState(); +} + +class EquipmentProfileProviderState extends State { + final List _profiles = [ + const EquipmentProfileData( + id: '0', + name: 'Default', + apertureValues: apertureValues, + ndValues: ndValues, + shutterSpeedValues: shutterSpeedValues, + isoValues: isoValues, + ), + ]; + late EquipmentProfileData? _selectedProfile = _profiles.isNotEmpty ? _profiles.first : null; + + @override + Widget build(BuildContext context) { + return EquipmentProfiles( + profiles: _profiles, + child: EquipmentProfile( + data: _selectedProfile, + child: widget.child, + ), + ); + } + + void setProfile(EquipmentProfileData data) { + setState(() { + _selectedProfile = data; + }); + } + + void addProfile(EquipmentProfileData data) {} + + void updateProdile(EquipmentProfileData data) {} + + void deleteProfile(EquipmentProfileData data) {} +} + +class EquipmentProfiles extends InheritedWidget { + final List profiles; + + const EquipmentProfiles({ + required this.profiles, + required super.child, + super.key, + }); + + static List? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType()?.profiles; + } + + @override + bool updateShouldNotify(EquipmentProfiles oldWidget) => true; +} + +class EquipmentProfile extends InheritedWidget { + final EquipmentProfileData? data; + + const EquipmentProfile({ + required this.data, + required super.child, + super.key, + }); + + static EquipmentProfileData? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType()?.data; + } + + @override + bool updateShouldNotify(EquipmentProfile oldWidget) => true; +} diff --git a/lib/screens/metering/bloc_metering.dart b/lib/screens/metering/bloc_metering.dart index ac38249..d351cdf 100644 --- a/lib/screens/metering/bloc_metering.dart +++ b/lib/screens/metering/bloc_metering.dart @@ -49,6 +49,7 @@ class MeteringBloc extends Bloc { .map((state) => state as communication_states.ScreenState) .listen(_onCommunicationState); + on(_onEquipmentProfileChanged); on(_onStopTypeChanged); on(_onIsoChanged); on(_onNdChanged); @@ -74,6 +75,24 @@ class MeteringBloc extends Bloc { _emitMeasuredState(emit); } + void _onEquipmentProfileChanged(EquipmentProfileChangedEvent event, Emitter emit) { + /// Update selected ISO value, if selected equipment profile + /// doesn't contain currently selected value + if (!event.equipmentProfileData.isoValues.any((v) => _iso.value == v.value)) { + _userPreferencesService.iso = event.equipmentProfileData.isoValues.first; + _ev = _ev + log2(event.equipmentProfileData.isoValues.first.value / _iso.value); + _iso = event.equipmentProfileData.isoValues.first; + } + + /// The same for ND filter + if (!event.equipmentProfileData.ndValues.any((v) => _nd.value == v.value)) { + _userPreferencesService.ndFilter = event.equipmentProfileData.ndValues.first; + _ev = _ev - event.equipmentProfileData.ndValues.first.stopReduction + _nd.stopReduction; + _nd = event.equipmentProfileData.ndValues.first; + } + _emitMeasuredState(emit); + } + void _onIsoChanged(IsoChangedEvent event, Emitter emit) { _userPreferencesService.iso = event.isoValue; _ev = _ev + log2(event.isoValue.value / _iso.value); diff --git a/lib/screens/metering/components/camera_container/provider_container_camera.dart b/lib/screens/metering/components/camera_container/provider_container_camera.dart index 8afa4a6..a5aab1c 100644 --- a/lib/screens/metering/components/camera_container/provider_container_camera.dart +++ b/lib/screens/metering/components/camera_container/provider_container_camera.dart @@ -10,6 +10,7 @@ import 'bloc_container_camera.dart'; import 'widget_container_camera.dart'; class CameraContainerProvider extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final IsoValue iso; @@ -19,6 +20,7 @@ class CameraContainerProvider extends StatelessWidget { final List exposurePairs; const CameraContainerProvider({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.iso, @@ -38,6 +40,7 @@ class CameraContainerProvider extends StatelessWidget { context.read(), ), child: CameraContainer( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues, diff --git a/lib/screens/metering/components/camera_container/widget_container_camera.dart b/lib/screens/metering/components/camera_container/widget_container_camera.dart index 394e253..05877bf 100644 --- a/lib/screens/metering/components/camera_container/widget_container_camera.dart +++ b/lib/screens/metering/components/camera_container/widget_container_camera.dart @@ -17,6 +17,7 @@ import 'event_container_camera.dart'; import 'state_container_camera.dart'; class CameraContainer extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final List isoValues; @@ -28,6 +29,7 @@ class CameraContainer extends StatelessWidget { final List exposurePairs; const CameraContainer({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.isoValues, @@ -49,6 +51,7 @@ class CameraContainer extends StatelessWidget { children: [ MeteringTopBar( readingsContainer: ReadingsContainer( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, isoValues: isoValues, diff --git a/lib/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart b/lib/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart index ddcea71..c7072b5 100644 --- a/lib/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart +++ b/lib/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart @@ -10,6 +10,7 @@ import 'bloc_container_light_sensor.dart'; import 'widget_container_light_sensor.dart'; class LightSensorContainerProvider extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final IsoValue iso; @@ -19,6 +20,7 @@ class LightSensorContainerProvider extends StatelessWidget { final List exposurePairs; const LightSensorContainerProvider({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.iso, @@ -38,6 +40,7 @@ class LightSensorContainerProvider extends StatelessWidget { context.read(), ), child: LightSensorContainer( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues, diff --git a/lib/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart b/lib/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart index be9f516..de2cc14 100644 --- a/lib/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart +++ b/lib/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart @@ -6,6 +6,7 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; class LightSensorContainer extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final List isoValues; @@ -17,6 +18,7 @@ class LightSensorContainer extends StatelessWidget { final List exposurePairs; const LightSensorContainer({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.isoValues, @@ -35,6 +37,7 @@ class LightSensorContainer extends StatelessWidget { children: [ MeteringTopBar( readingsContainer: ReadingsContainer( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, isoValues: isoValues, diff --git a/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart b/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart index d3ad211..97071c3 100644 --- a/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart +++ b/lib/screens/metering/components/shared/readings_container/widget_container_readings.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/data/models/exposure_pair.dart'; 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'; @@ -8,6 +9,7 @@ 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 class ReadingsContainer extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final List isoValues; @@ -18,6 +20,7 @@ class ReadingsContainer extends StatelessWidget { final ValueChanged onNdChanged; const ReadingsContainer({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.isoValues, @@ -34,6 +37,15 @@ class ReadingsContainer extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ + if (EquipmentProfiles.of(context)!.isNotEmpty) ...[ + ReadingValueContainer.singleValue( + value: ReadingValue( + label: S.of(context).equipment, + value: 'Parktica + Zenitar', + ), + ), + const _InnerPadding(), + ], ReadingValueContainer( values: [ ReadingValue( @@ -65,7 +77,7 @@ class ReadingsContainer extends StatelessWidget { ), ), ], - ) + ), ], ); } @@ -75,6 +87,39 @@ class _InnerPadding extends SizedBox { const _InnerPadding() : super(height: Dimens.grid8, width: Dimens.grid8); } + +class _EquipmentProfileDataTile extends StatelessWidget { + final List values; + final IsoValue selectedValue; + final ValueChanged onChanged; + + const _EquipmentProfileDataTile({ + required this.selectedValue, + required this.values, + required this.onChanged, + }); + + @override + Widget build(BuildContext context) { + return AnimatedDialogPicker( + title: S.of(context).iso, + subtitle: S.of(context).filmSpeed, + selectedValue: selectedValue, + values: values, + itemTitleBuilder: (_, value) => Text(value.value.toString()), + // using ascending order, because increase in film speed rises EV + evDifferenceBuilder: (selected, other) => selected.toStringDifference(other), + onChanged: onChanged, + closedChild: ReadingValueContainer.singleValue( + value: ReadingValue( + label: S.of(context).iso, + value: selectedValue.value.toString(), + ), + ), + ); + } +} + class _IsoValueTile extends StatelessWidget { final List values; final IsoValue selectedValue; diff --git a/lib/screens/metering/event_metering.dart b/lib/screens/metering/event_metering.dart index 98f4727..95166dd 100644 --- a/lib/screens/metering/event_metering.dart +++ b/lib/screens/metering/event_metering.dart @@ -10,6 +10,12 @@ class StopTypeChangedEvent extends MeteringEvent { const StopTypeChangedEvent(this.stopType); } +class EquipmentProfileChangedEvent extends MeteringEvent { + final EquipmentProfileData equipmentProfileData; + + const EquipmentProfileChangedEvent(this.equipmentProfileData); +} + class IsoChangedEvent extends MeteringEvent { final IsoValue isoValue; diff --git a/lib/screens/metering/screen_metering.dart b/lib/screens/metering/screen_metering.dart index 12c1596..e5e921b 100644 --- a/lib/screens/metering/screen_metering.dart +++ b/lib/screens/metering/screen_metering.dart @@ -40,6 +40,8 @@ class _MeteringScreenState extends State { buildWhen: (_, current) => current is MeteringDataState, builder: (_, state) => state is MeteringDataState ? _MeteringContainerBuidler( + onEquipmentProfileChanged: (value) => + _bloc.add(EquipmentProfileChangedEvent(value)), fastest: state.fastest, slowest: state.slowest, iso: state.iso, @@ -69,6 +71,7 @@ class _MeteringScreenState extends State { } class _MeteringContainerBuidler extends StatelessWidget { + final ValueChanged onEquipmentProfileChanged; final ExposurePair? fastest; final ExposurePair? slowest; final IsoValue iso; @@ -78,6 +81,7 @@ class _MeteringContainerBuidler extends StatelessWidget { final List exposurePairs; const _MeteringContainerBuidler({ + required this.onEquipmentProfileChanged, required this.fastest, required this.slowest, required this.iso, @@ -91,6 +95,7 @@ class _MeteringContainerBuidler extends StatelessWidget { Widget build(BuildContext context) { return context.watch() == EvSourceType.camera ? CameraContainerProvider( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, iso: iso, @@ -100,6 +105,7 @@ class _MeteringContainerBuidler extends StatelessWidget { exposurePairs: exposurePairs, ) : LightSensorContainerProvider( + onEquipmentProfileChanged: onEquipmentProfileChanged, fastest: fastest, slowest: slowest, iso: iso,