moved EquipmentProfileProvider from iap repo

This commit is contained in:
Vadim 2023-03-17 14:47:58 +03:00
parent bc2f211cf6
commit c5179e71ea
10 changed files with 176 additions and 2 deletions

View file

@ -8,7 +8,6 @@ import 'package:lightmeter/data/caffeine_service.dart';
import 'package:lightmeter/data/haptics_service.dart'; import 'package:lightmeter/data/haptics_service.dart';
import 'package:lightmeter/data/models/supported_locale.dart'; import 'package:lightmeter/data/models/supported_locale.dart';
import 'package:lightmeter/providers/supported_locale_provider.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:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -17,6 +16,7 @@ import 'data/permissions_service.dart';
import 'data/shared_prefs_service.dart'; import 'data/shared_prefs_service.dart';
import 'environment.dart'; import 'environment.dart';
import 'generated/l10n.dart'; import 'generated/l10n.dart';
import 'providers/equipment_profile_provider.dart';
import 'providers/ev_source_type_provider.dart'; import 'providers/ev_source_type_provider.dart';
import 'providers/theme_provider.dart'; import 'providers/theme_provider.dart';
import 'screens/metering/flow_metering.dart'; import 'screens/metering/flow_metering.dart';

View file

@ -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<EquipmentProfileProviderState>()!;
}
@override
State<EquipmentProfileProvider> createState() => EquipmentProfileProviderState();
}
class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
final List<EquipmentProfileData> _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<EquipmentProfileData> profiles;
const EquipmentProfiles({
required this.profiles,
required super.child,
super.key,
});
static List<EquipmentProfileData>? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<EquipmentProfiles>()?.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<EquipmentProfile>()?.data;
}
@override
bool updateShouldNotify(EquipmentProfile oldWidget) => true;
}

View file

@ -49,6 +49,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
.map((state) => state as communication_states.ScreenState) .map((state) => state as communication_states.ScreenState)
.listen(_onCommunicationState); .listen(_onCommunicationState);
on<EquipmentProfileChangedEvent>(_onEquipmentProfileChanged);
on<StopTypeChangedEvent>(_onStopTypeChanged); on<StopTypeChangedEvent>(_onStopTypeChanged);
on<IsoChangedEvent>(_onIsoChanged); on<IsoChangedEvent>(_onIsoChanged);
on<NdChangedEvent>(_onNdChanged); on<NdChangedEvent>(_onNdChanged);
@ -74,6 +75,24 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
_emitMeasuredState(emit); _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) { void _onIsoChanged(IsoChangedEvent event, Emitter emit) {
_userPreferencesService.iso = event.isoValue; _userPreferencesService.iso = event.isoValue;
_ev = _ev + log2(event.isoValue.value / _iso.value); _ev = _ev + log2(event.isoValue.value / _iso.value);

View file

@ -10,6 +10,7 @@ import 'bloc_container_camera.dart';
import 'widget_container_camera.dart'; import 'widget_container_camera.dart';
class CameraContainerProvider extends StatelessWidget { class CameraContainerProvider extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final IsoValue iso; final IsoValue iso;
@ -19,6 +20,7 @@ class CameraContainerProvider extends StatelessWidget {
final List<ExposurePair> exposurePairs; final List<ExposurePair> exposurePairs;
const CameraContainerProvider({ const CameraContainerProvider({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.iso, required this.iso,
@ -38,6 +40,7 @@ class CameraContainerProvider extends StatelessWidget {
context.read<MeteringCommunicationBloc>(), context.read<MeteringCommunicationBloc>(),
), ),
child: CameraContainer( child: CameraContainer(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues, isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues,

View file

@ -17,6 +17,7 @@ import 'event_container_camera.dart';
import 'state_container_camera.dart'; import 'state_container_camera.dart';
class CameraContainer extends StatelessWidget { class CameraContainer extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final List<IsoValue> isoValues; final List<IsoValue> isoValues;
@ -28,6 +29,7 @@ class CameraContainer extends StatelessWidget {
final List<ExposurePair> exposurePairs; final List<ExposurePair> exposurePairs;
const CameraContainer({ const CameraContainer({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.isoValues, required this.isoValues,
@ -49,6 +51,7 @@ class CameraContainer extends StatelessWidget {
children: [ children: [
MeteringTopBar( MeteringTopBar(
readingsContainer: ReadingsContainer( readingsContainer: ReadingsContainer(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
isoValues: isoValues, isoValues: isoValues,

View file

@ -10,6 +10,7 @@ import 'bloc_container_light_sensor.dart';
import 'widget_container_light_sensor.dart'; import 'widget_container_light_sensor.dart';
class LightSensorContainerProvider extends StatelessWidget { class LightSensorContainerProvider extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final IsoValue iso; final IsoValue iso;
@ -19,6 +20,7 @@ class LightSensorContainerProvider extends StatelessWidget {
final List<ExposurePair> exposurePairs; final List<ExposurePair> exposurePairs;
const LightSensorContainerProvider({ const LightSensorContainerProvider({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.iso, required this.iso,
@ -38,6 +40,7 @@ class LightSensorContainerProvider extends StatelessWidget {
context.read<MeteringCommunicationBloc>(), context.read<MeteringCommunicationBloc>(),
), ),
child: LightSensorContainer( child: LightSensorContainer(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues, isoValues: EquipmentProfile.of(context)?.isoValues ?? isoValues,

View file

@ -6,6 +6,7 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class LightSensorContainer extends StatelessWidget { class LightSensorContainer extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final List<IsoValue> isoValues; final List<IsoValue> isoValues;
@ -17,6 +18,7 @@ class LightSensorContainer extends StatelessWidget {
final List<ExposurePair> exposurePairs; final List<ExposurePair> exposurePairs;
const LightSensorContainer({ const LightSensorContainer({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.isoValues, required this.isoValues,
@ -35,6 +37,7 @@ class LightSensorContainer extends StatelessWidget {
children: [ children: [
MeteringTopBar( MeteringTopBar(
readingsContainer: ReadingsContainer( readingsContainer: ReadingsContainer(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
isoValues: isoValues, isoValues: isoValues,

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/generated/l10n.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 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'components/animated_dialog_picker/widget_dialog_animated_picker.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 /// Contains a column of fastest & slowest exposure pairs + a row of ISO and ND pickers
class ReadingsContainer extends StatelessWidget { class ReadingsContainer extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final List<IsoValue> isoValues; final List<IsoValue> isoValues;
@ -18,6 +20,7 @@ class ReadingsContainer extends StatelessWidget {
final ValueChanged<NdValue> onNdChanged; final ValueChanged<NdValue> onNdChanged;
const ReadingsContainer({ const ReadingsContainer({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.isoValues, required this.isoValues,
@ -34,6 +37,15 @@ class ReadingsContainer extends StatelessWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
if (EquipmentProfiles.of(context)!.isNotEmpty) ...[
ReadingValueContainer.singleValue(
value: ReadingValue(
label: S.of(context).equipment,
value: 'Parktica + Zenitar',
),
),
const _InnerPadding(),
],
ReadingValueContainer( ReadingValueContainer(
values: [ values: [
ReadingValue( 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); const _InnerPadding() : super(height: Dimens.grid8, width: Dimens.grid8);
} }
class _EquipmentProfileDataTile extends StatelessWidget {
final List<IsoValue> values;
final IsoValue selectedValue;
final ValueChanged<IsoValue> onChanged;
const _EquipmentProfileDataTile({
required this.selectedValue,
required this.values,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return AnimatedDialogPicker<IsoValue>(
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 { class _IsoValueTile extends StatelessWidget {
final List<IsoValue> values; final List<IsoValue> values;
final IsoValue selectedValue; final IsoValue selectedValue;

View file

@ -10,6 +10,12 @@ class StopTypeChangedEvent extends MeteringEvent {
const StopTypeChangedEvent(this.stopType); const StopTypeChangedEvent(this.stopType);
} }
class EquipmentProfileChangedEvent extends MeteringEvent {
final EquipmentProfileData equipmentProfileData;
const EquipmentProfileChangedEvent(this.equipmentProfileData);
}
class IsoChangedEvent extends MeteringEvent { class IsoChangedEvent extends MeteringEvent {
final IsoValue isoValue; final IsoValue isoValue;

View file

@ -40,6 +40,8 @@ class _MeteringScreenState extends State<MeteringScreen> {
buildWhen: (_, current) => current is MeteringDataState, buildWhen: (_, current) => current is MeteringDataState,
builder: (_, state) => state is MeteringDataState builder: (_, state) => state is MeteringDataState
? _MeteringContainerBuidler( ? _MeteringContainerBuidler(
onEquipmentProfileChanged: (value) =>
_bloc.add(EquipmentProfileChangedEvent(value)),
fastest: state.fastest, fastest: state.fastest,
slowest: state.slowest, slowest: state.slowest,
iso: state.iso, iso: state.iso,
@ -69,6 +71,7 @@ class _MeteringScreenState extends State<MeteringScreen> {
} }
class _MeteringContainerBuidler extends StatelessWidget { class _MeteringContainerBuidler extends StatelessWidget {
final ValueChanged<EquipmentProfileData> onEquipmentProfileChanged;
final ExposurePair? fastest; final ExposurePair? fastest;
final ExposurePair? slowest; final ExposurePair? slowest;
final IsoValue iso; final IsoValue iso;
@ -78,6 +81,7 @@ class _MeteringContainerBuidler extends StatelessWidget {
final List<ExposurePair> exposurePairs; final List<ExposurePair> exposurePairs;
const _MeteringContainerBuidler({ const _MeteringContainerBuidler({
required this.onEquipmentProfileChanged,
required this.fastest, required this.fastest,
required this.slowest, required this.slowest,
required this.iso, required this.iso,
@ -91,6 +95,7 @@ class _MeteringContainerBuidler extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return context.watch<EvSourceType>() == EvSourceType.camera return context.watch<EvSourceType>() == EvSourceType.camera
? CameraContainerProvider( ? CameraContainerProvider(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
iso: iso, iso: iso,
@ -100,6 +105,7 @@ class _MeteringContainerBuidler extends StatelessWidget {
exposurePairs: exposurePairs, exposurePairs: exposurePairs,
) )
: LightSensorContainerProvider( : LightSensorContainerProvider(
onEquipmentProfileChanged: onEquipmentProfileChanged,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
iso: iso, iso: iso,